Merge "VNFRQTS - updating ansible examples"
[vnfrqts/requirements.git] / docs / Chapter8 / Ansible-Playbook-Examples.rst
1 .. Modifications Copyright © 2017-2018 AT&T Intellectual Property.
2
3 .. Licensed under the Creative Commons License, Attribution 4.0 Intl.
4    (the "License"); you may not use this documentation except in compliance
5    with the License. You may obtain a copy of the License at
6
7 .. https://creativecommons.org/licenses/by/4.0/
8
9 .. Unless required by applicable law or agreed to in writing, software
10    distributed under the License is distributed on an "AS IS" BASIS,
11    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12    See the License for the specific language governing permissions and
13    limitations under the License.
14
15
16 Ansible Playbook Examples
17 -----------------------------------------------
18
19 The following sections contain examples of Ansible playbooks
20 which follow the guidelines.
21
22 To see specific documentation for the Ansible Adapter please refer
23 to: :doc:`APPC Ansible Adapter <../../../../appc/deployment.git/docs/APPC Ansible Adapter/APPC Ansible Adapter>`
24
25
26 Guidelines for Playbooks to properly integrate with APPC/SDN-C
27 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
28
29 **NOTE**: To support concurrent requests to multiple playbooks, targeting VNF
30 instances of same or different type, VNF files dynamically created by playbooks
31 with VNF specific default values are kept or created in separate directories.
32
33 VNF inventory hosts file names include the VNF instance name and are now
34 created under base ``inventory`` directory to preserve properties of (global)
35 ``inventory/group_vars`` files with variables, example, site specific
36 attributes for DNS, NTP, etc.
37
38 **Example of an Ansible command (after pwd) to run playbook again
39 vfdb9904v VNF instance:**
40
41 .. code-block:: text
42
43  $ pwd
44  /storage/vfdb/V16.1/ansible/configure
45  $ ansible-playbook -i ../inventory/vfdb9904vhosts site.yml --extra-vars "vnf_instance=vfdb9904v"
46
47  NOTE: To preserve Ansible inventory/group_vars capability, that makes
48  group_vars contents global variables available to all playbooks, when they
49  reside in the inventory directory, guidelines were updated to name the
50  VNF inventory hosts file as (a flat file) <VNFName>hosts, stored in the
51  inventory directory, not a subdirectory under inventory.
52
53 **Example of corresponding APPC/SDN-C API Call from ONAP – Ansible Server
54 Specifications:**
55
56 Using a curl request simulating a Rest API POST requesting execution
57 of configure Playbook (using playbook relative path):
58
59 .. code-block:: text
60
61  curl -u APIUser:APIPassword -H "Content-type:application/json" -X POST
62  -d '{"Id": "8412", "PlaybookName": "vfdb/V5.x.x/ansible/configure/site.yml",
63  "Timeout":"600", "EnvParameters": { "vnf_instance": "vfdb9904v" }}'
64  http://ansible.server.com:5000/Dispatch
65
66 Rest API GET request to obtain response/results for prior request
67 (same ID as POST request above):
68
69 .. code-block:: text
70
71  curl -u APIUser:APIPassword -H 'Content-type: application/json' -X GET
72  'http://ansible.server.com:5000/Dispatch/?Id=8412&Type=GetResult'
73
74 Comments:
75
76 -  An ID number is assigned to each request. This ID number is used to
77    track request down to completion and provide status to APPC/SDN-C
78    upon request for status.
79
80 -  Playbook Name relative path provided in the request as PlaybookName.
81
82 -  Ansible Server Rest API is aware of playbook's root directory which may
83    vary from instance to instance or Ansible Server cluster to cluster.
84
85 Ansible Playbooks will use the VNF instance name (passed using
86 --extra-vars "vnf_instance=vfdb9904v") to identify other default values
87 to run the playbook(s) against the target VNF instance. Same example as
88 above:
89
90 .. code-block:: text
91
92  $ ansible-playbook -i ../inventory/vfdb9904vhosts site.yml --extra-vars "vnf_instance=vfdb9904v"
93
94 Each Ansible Server or cluster is assigned its own identification to be used
95 to authenticate to VNF VMs using Ansible Server or cluster specific set of
96 SSH keys that may be rotated regularly. Here a hosts file, without any SSH key
97 credentials, to run ansible-playbook command, listed in example above (NOTE: IP
98 addresses were scrubbed):
99
100 .. code-block:: text
101
102  $ more ../inventory/vfdb9904vhosts
103  [host]
104  localhost ansible_connection=local
105
106  [oamvip]
107  1xx.2yy.zzz.108
108
109  [oam]
110  1xx.2yy.zzz.109
111  1xx.2yy.zzz.110
112
113  [rdb]
114  1xx.2yy.zzz.105
115  1xx.2yy.zzz.106
116
117  [wp0ny:children]
118  oam
119  rdb
120  oamvip
121
122 Virtual IP addresses that can be used by multiple VMs, usually, used by the
123 active VM of an active-standby pair, are placed under a group named after the
124 VNFC (VM) type, plus "vip" string, example of such a group name "oamvip". An
125 inventory hosts file site also contains a (group) with all groups as children
126 (see last four lines in above example), to load site specific variables like
127 NTP, DNS IP addresses, and other site specific variables, making them global
128 variables to be used by playbooks, namely, configure playbook.
129
130 **NOTE**: APPC/SDN-C requests to run Playbooks/Cookbooks target a specific VNF
131 instance, but could be limited to one VM or one type of VM by the request
132 parameters. Actions that may impact a site (LCP), a service, or an
133 entire platform must be orchestrated by MSO in order to execute requests
134 via APPC/SDN-C which then invoke VNF level playbooks. Playbooks that
135 impact more than a single VNF instance are not the current focus of these
136 guidelines.
137
138 Creating group_vars sub-directories in the same directory that contains the
139 command/action main playbook, while following Ansible standards, to auto load
140 these variables as global variables is supported as are the majority of
141 Ansible standard capabilities.
142
143 Certain VNF Type global variables, for example site specific variables, were
144 moved under inventory/group_vars files in the Beijing release. This way those
145 variables and respective values are available to all playbooks without
146 being explicitly referenced through an include vars statement. Also creating
147 templates that are VNF Type specific moving away from static files that
148 are VNF instance specific.
149
150 Any remaining VNF instance specific variables that cannot be obtained from
151 inventory (A&AI) or other sources, that still need to be created or edited
152 manually, in advance of VNF instantiation, shall be created under
153 ``ansible/vars`` directory. Recommendation is to use JSON or YAML files,
154 explicitly referenced by the playbooks, for this purpose, example:
155 ``<VNF_instance_name>.json``.
156
157 **Example of playbook task explicitly referencing a VNF instance specific json
158 file and loading the contents as global variables**:
159
160 .. code-block:: text
161
162  $ cat site.yml
163  ---
164
165  ...
166
167  - name: get json vars
168    hosts: localhost
169    gather_facts: False
170    tasks:
171      - name: json attributes and values
172        include_vars: "../vars/{{ vnf_instance }}.json"
173
174  - name: show variables
175    hosts: localhost
176    gather_facts: False
177    roles:
178      - debug
179  ...
180
181  # Just another example using YAML file
182  - name: load vars in a file
183   hosts: rdb
184  ...
185   vars_files:
186     - ../vars/{{ vnf_instance }}.yml
187
188  $ ls -1 ../vars
189  vfdb9904v.json
190  vfdb9905v.json
191  vfdb9906v.json
192  vfdb9904v.yml
193  vfdb9905v.yml
194  vfdb9906v.yml
195
196
197
198 Parameters like VNF names, VNFC names, OA&M IP addresses are extracted
199 from the inventory database (A&AI) by APPC/SDN-C and then passed down to
200 Ansible Server in a NodeList attribute, as part of APPC/SDN-C request through
201 REST API. The Ansible Server Rest API uses the NodeList contents and
202 InventoryNames parameter to build the inventory hosts file for the request,
203 according to VNF playbook design needs, with or without VM or VNFC names.
204 For parameterized playbooks, attribute-value pairs passed down by APPC/SDN-C
205 to Ansible Server, always takes precedence over template or VNF instance
206 specific defaults stored in defaults file(s) as they are made part of the
207 ``ansible-playbook`` run command's ``"—extra-vars"`` list.
208
209 **Example**:
210
211 .. code-block:: text
212
213  $ pwd
214  /storage/vfdb/latest/ansible
215  Again, originated from previously re-factored playbooks now being phased out:
216
217  $ more vars/vfdb9904v/default_args.yml
218
219  vm_config_oam1_vnfc_name: vfdb9904vm001oam001
220  vm_config_oam1_hostname: vfdb9904vm001
221  vm_config_oam1_provider_ip_address: 1xx.2yy.zzz.109
222
223  vm_config_oam2_vnfc_name: vfdb9904vm002oam001
224  vm_config_oam2_hostname: vfdb9904vm002
225  vm_config_oam2_provider_ip_address: 1xx.2yy.zzz.110
226
227  vm_config_rdb1_vnfc_name: vfdb9904vm003rdb001
228  vm_config_rdb1_hostname: vfdb9904vm003
229  vm_config_rdb1_provider_ip_address: 1xx.2yy.zzz.105
230
231  vm_config_rdb2_vnfc_name: vfdb9904vm004rdb001
232  vm_config_rdb2_hostname: vfdb9904vm004
233  vm_config_rdb2_provider_ip_address: 1xx.2yy.zzz.106
234
235  vm_config_rdb3_vnfc_name: vfdb9904vm005rdb001
236  vm_config_rdb3_hostname: vfdb9904vm005
237  vm_config_rdb3_provider_ip_address: 1xx.2yy.zzz.xxx
238
239  vm_config_rdb4_vnfc_name: vfdb9904vm006rdb001
240  vm_config_rdb4_hostname: vfdb9904vm006
241  vm_config_rdb4_provider_ip_address: 1xx.2yy.zzz.yyy
242
243 One of the first tasks on the Ansible Playbooks is to combine the VNF
244 type generic templates, stored on the Ansible Server with playbooks, with
245 the overriding parameters passed down from APPC/SDN-C, to create the
246 VNF instance specific set of attribute-value pairs to be used for the run, in
247 INI format.
248
249 Here is an excerpt from such a file that should look somewhat similar to ENV
250 files:
251
252 .. code-block:: text
253
254  $ more tmp/vfdb9904v/all.yml
255
256  deployment_prefix: vfdb9904v
257  ...
258  timezone: Etc/UTC
259  ...
260  template_version: '2014-10-16'
261  stack_name: vfdb9904v
262  c3dbtype: OAM
263  stackName: vfdb9904v
264  juno_base: true
265  ...
266
267 # logins list contains 'login name', 'login group', 'login password'
268
269 .. code-block:: text
270
271  logins:
272  - { name: 'm99999', group: 'm99999', password: 'abcdefgha' }
273  - { name: 'gsuser', group: 'gsuser', password: ' abcdefgha' }
274  - { name: 'peruser', group: 'peruser', password: ' abcdefgha' }
275  - { name: 'dbuser', group: 'dbuser', password: ' abcdefgha' }
276
277 **NOTE**: Arguments passed by APPC/SDN-C to Ansible Server to run a
278 playbook take precedence over any defaults stored in Ansible Server.
279
280 Ansible Playbooks – Notes On Artifacts Required to Run Playbooks
281 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
282
283 Inventory hosts file: should be VNF instance specific.
284
285 Default variables: should be VNF instance specific.
286
287 Playbooks and paths to referenced files: Playbooks shall not use
288 absolute paths in include or import entries (variables or playbooks) or
289 other types of references.
290
291 For this to work properly, when running playbooks, the directory where
292 the main playbook resides shall be the current directory.
293
294 Playbook imports, when used, shall use paths relative to the main
295 playbook directory.
296
297 Root directory named ansible - Any files provided with playbooks,
298 included, imported, or referenced by playbooks, shall reside under the ansible
299 playbooks (root) directory, containing all playbook subdirectories, or
300 below that ansible root directory, in other subdirectories to support
301 on-boarding and portability of VNF collection of playbooks and related
302 artifacts.
303
304 **Designing for a shared environment, concurrently running playbooks,
305 targeting multiple VNF instances – inventory hosts file:**
306
307 To avoid inventory hosts file overwrites or collisions between multiple
308 concurrently running VNF instance requests, chosen approach is for each
309 VNF instance hosts file, to be stored under the Ansible Server Playbooks
310 root directory (ansible), under the inventory subdirectory, on an inventory
311 hosts file named after the VNF instance, as follows:
312
313 .. code-block:: text
314
315  ansible/inventory/<VNF_instance_name>hosts
316
317 Example of inventory hosts file path, relative to ansible playbooks (ansible)
318 root directory (playbooks_dir):
319
320 .. code-block:: text
321
322  ansible/inventory/vnfx0001vhosts
323
324 **Designing for a shared environment, concurrently running multiple playbooks,
325 targeting multiple VNF instances – default argument variables for
326 specific VNF instances:**
327
328 VNF instance specific files referenced/included by playbooks, containing
329 default values, example, ``default_args.yml``, shall be stored under a
330 directory with VNF instance name on the path (backwards compatibility) or
331 contain VNF instance name as part of the name.
332
333 **Example**:
334
335 .. code-block:: text
336
337  ansible/vars/<VNF_instance_name>/default_args.yml
338
339 **Example of include statement**:
340
341 .. code-block:: text
342
343  include_vars: ../vars/{{ vnf_instance }}/default_args.yml
344
345 **Example – all in vars directory**:
346
347 .. code-block:: text
348
349  ansible/vars/<VNF_instance_name>default_args.yml
350
351 **Example of include statement without vars subdirectory**:
352
353 .. code-block:: text
354
355  include_vars: ../vars/{{ vnf_instance }}default_args.yml
356
357 Above example has originated from previously re-factored playbooks now being
358 phased out. Direction is to move away from having to create VNF instance
359 specific files with VNF instance default variables to the extent possible.
360 Moving to extract these values from inventory databases and provide them to
361 Ansible Server as part of APPC/SDN-C request, may be used in a transition
362 from having everything stored in the Ansible Server to APPC/SDN-C
363 extracting and providing VNF instance specific attribute-value pairs to the
364 Ansible Server as part of the request.
365
366 **Files containing attribute name value pairs (variable name and default
367 values), referenced/included by playbooks – created dynamically by
368 playbooks:**
369
370 To avoid overwrites or collisions of multiple concurrently running VNF instance
371 requests, files created dynamically by playbooks, based on VNF generic
372 templates, combined with default values and arguments passed down by
373 APPC/SDN-C (as part of the request), shall be stored under a directory
374 with VNF instance name on the path.
375
376 **Example**:
377
378 .. code-block:: text
379
380  tmp/<VNF_instance_name>/all.yml
381
382 Files containing site specific (Openstack location non-instance specific)
383 attribute name value pairs, like NTP server and DNS server's IP addresses and
384 other parameters, referenced/included by playbooks, not VNF specific –
385 Could/should be stored under inventory/group_vars directory, in a subdirectory
386 named after the string used to identify the site (nyc1, lax2,...).
387
388 **Examples**:
389
390
391 .. code-block:: text
392
393  ansible/inventory/group_vars/<Site>
394
395  ansible/inventory/group_vars/wp0ny
396
397  ansible/inventory/group_vars/la0ca
398
399 **Ansible Server Design - Directory Structure**
400
401 To help understanding the contents of this section, here are few basic
402 definitions:
403
404 **VNF type a.k.a VNF Function Code** - Based on current  naming convention,
405 each Virtual Network Function is assigned a 4 character string (example vfdb),
406 these are 4 characters in the VNF instance name, followed by (4) numbers,
407 ending in a "v". The naming convention has evolved to include geographical
408 location. VNF instance name in some cases corresponds to the stack name for the
409 VNF when VNF instance is built based on a single module, single stack. Example
410 of VNF instance name: vfdb9904v. All VNF performing this function, running the
411 same software, coming from the same VNF provider will have the same 4
412 characters in the VNF instance name, in this example, vfdb.
413
414 **NOTE**: New naming convention includes a prefix indicating geographical
415 location where VNF is instantiated.
416
417 VNF type, determined through these 4 characters, is also known as VNF
418 Function Code. All VNF Function Codes can be found in A&AI as well as
419 other Network Design Documents.
420
421 **Version** – VNF software version is the release of the software
422 running on the VNF for which the playbooks were developed. VNF
423 configuration steps may change from release to release and this
424 <Version> in the path will allow the Ansible Server to host playbooks
425 associated with each software release. And run the playbooks that match
426 the software release running on each VNF instance. APPC/SDN-C now support
427 playbook versioning passed as a variable to APP-C to allow multiple
428 actively, in use, playbook versions to be picked to match VNF release/version.
429
430 **Playbook Function** - A name associated with a life cycle management
431 task(s) performed by the playbook(s) stored in this directory. It should
432 clearly identify the type of action(s) performed by the main playbook
433 and possibly other playbooks stored in this same directory. Ideally,
434 playbook function would match APPC/SDN-C corresponding command or function
435 that is performed by the main playbook in this directory. Following Ansible
436 naming standards, main playbook, is named site.yml. There can be other
437 playbooks on the same directory that use a subset of the roles used by the
438 main playbook site.yml. Examples of Playbook Function directory names(matching
439 APPC/SDN-C command name in lowercase):
440
441 -  ``configure`` – Contains post-instantiation (bulk) configuration
442    playbook(s), roles,...
443
444 -  ``healthcheck`` – Contains VNF health check playbook(s), roles,...
445
446 -  ``stopapplication`` – Contains VNF application stop (stopApplication)
447    playbook(s), roles,...
448
449 -  ``startapplication`` – Contains VNF application start (startApplication)
450    playbook(s), roles,...
451
452 -  ``restartapplication`` – Contains VNF application restart
453    (restartApplication) playbook(s), roles,...
454
455 -  ``configbackup`` – Contains VNF configuration backup (ConfigBackup)
456    playbook(s), roles,...
457
458 -  ``configrestore`` – Contains VNF configuration restore (ConfigBackup)
459    playbook(s), roles,...
460
461 -  ``configmodify`` – Contains VNF configuration modification (ConfigModify)
462    playbook(s), roles,...
463
464 -  ``configscaleout`` – Contains VNF scale-out configuration/reconfiguration
465    (ConfigBackup) playbook(s), roles,...
466
467 -  ``quiescetraffic`` – Contains VNF traffic graceful drain/quiesce
468    (QuiesceTraffic) playbook(s), roles,...
469
470 -  ``resumetraffic`` – Contains VNF resume/restore traffic (ResumeTraffic)
471    playbook(s), roles,...
472
473 -  ``upgradeprecheck`` – Contains VNF current (old) SW version check
474    (UpgradePreCheck) playbook(s), roles,...
475
476 -  ``upgradebackup`` – Contains VNF backup prior to SW upgrade (UpgradeBackup)
477    playbook(s), roles,...
478
479 -  ``upgradesoftware`` – Contains VNF SW upgrade (UpgradeSoftware)
480    playbook(s), roles,...
481
482 -  ``upgradepostcheck`` – Contains VNF upgraded (new) SW version check
483    (UpgradePostCheck) playbook(s), roles,...
484
485 -  ``upgradebackout`` – Contains VNF (SoftwareUpgrade) back out
486    (UpgradeBackout) playbook(s), roles,...
487
488 -  ``license`` – Contains a playbook to manage licenses, add, upgrade,
489    delete, renew, etc.
490
491 -  ``starttraffic`` – Contains a playbook used for traffic management (start)
492
493 -  ``stoptraffic`` – Contains a playbook used for traffic management (stop)
494
495 -  ``distributetraffic`` – Contains a playbook used for traffic management
496    (distribute/redistribute)
497
498 -  ``statustraffic`` – Contains a playbook used to check status of traffic
499    (started, stopped, etc.)
500
501 -  ``preconfigcheck`` – Contains post-instantiation pre-configuration check
502    playbook(s) that makes no configuration changes to the VNF instance, just
503    verifies all conditions are met to successfully run preconfig and/or
504    configure playbooks
505
506 -  ``preconfig`` – Contains post-instantiation pre-configuration playbook(s),
507    that is to run before running the configure playbook
508
509 -  ``postconfig`` – Contains post-instantiation post-configuration playbook(s),
510    that is to run after running the configure playbook, example, to integrate
511    VNFs of different types
512
513 -  ``provision`` – Contains a playbook to run on demand, as needed, load or
514    update provisioning data onto VNF instances
515
516 Other playbook actions were added and are supported, example of playbooks
517 supported to run before and after Openstack nova commands:
518
519 -  prerebuild  & postrebuild
520
521 -  premigrate  & postmigrate
522
523 -  preevacuate  & postevacuate
524
525 Other playbook actions in use not yet supported by APP-C:
526
527 -  ``postrestart`` – Contains a playbook used to perform tasks after restarting
528    VNF application or VNF instance or a single VM
529
530 -  ``restartpods`` – Contains a playbook used to perform tasks to restart
531    application containers
532
533 -  ``user_management`` – Contains a playbook used to manage user accounts on
534    demand (add, update, delete) as part of VNF instance life cycle management
535
536 -  ``preinstantiate`` – Contains pre-instantiation playbook(s) to perform
537    preparation tasks in advance of instantiation of a VNF instance
538
539 Directory structure to allow hosting multiple version sets of playbooks,
540 for the same VNF type, to be hosted in the runtime environment on the
541 Ansible Servers. Generic directory structure:
542
543 **Ansible Playbooks – Function directory and main playbook**:
544
545 .. code-block:: text
546
547  <VNF type>/<Version>/ansible/<Playbook Function>/site.yml
548
549 **Example – Post-instantiation (bulk) configuration – APPC/SDN-C Function -
550 Configure**:
551
552 .. code-block:: text
553
554  <VNF type>/<Version>/ansible/configure/site.yml
555
556 **Example – Post-instantiation (bulk) configuration – APPC/SDN-C Function
557 – Configure – VNF software version 16.1**:
558
559 .. code-block:: text
560
561  vfdb/V16.1/ansible/configure/site.yml
562
563 **Example – Health-check - APPC/SDN-C Function - HealthCheck**:
564
565 .. code-block:: text
566
567  <VNF type>/<Version>/ansible/healthcheck/site.yml
568
569 OR (Function directory name is not required to match APPC/SDN-C function name
570 exactly)
571
572 .. code-block:: text
573
574  <VNF type>/<Version>/ansible/check/site.yml
575
576 **Ansible Directories for other artifacts – VNF inventory hosts file -
577 Required**:
578
579 .. code-block:: text
580
581  <VNF type>/<Version>/ansible/inventory/<VNF instance name>hosts
582
583 **NOTE**: Default groups, in inventory hosts file, will be created based on
584 VNFC type (represented by 3 characters) in VNFC name. Example: "oam", "rdb",
585 "dbs", "man", "iox", "app",...
586
587 **Ansible Directories for other artifacts – VNF instance specific default
588 arguments – Optional**:
589
590 .. code-block:: text
591
592  <VNF type>/<Version>/ansible/vars/<VNF instance name>.json (Preferred)
593
594 OR
595
596 .. code-block:: text
597
598  <VNF type>/<Version>/ansible/vars/<VNF instance name>.yml
599  (INI format accepted/supported by Ansible)
600
601 **NOTE**: Requirement remains while manual actions to create or edit VNF or PNF
602 instance specific files are supported all files manually created or edited
603 should be placed in this one directory (``ansible/vars``).
604
605 **Ansible Directory for site specific attribute-value pairs (in INI format)
606 - VNF Site files:**:
607
608 .. code-block:: text
609
610  <VNF type>/<Version>/ansible/inventory/group_vars/<Site name>
611
612 **Ansible Directories for other artifacts – VNF (special) other files –
613 Optional – Example – License file**:
614
615 .. code-block:: text
616
617  <VNF type>/<Version>/ansible/<Other directory(s)>
618
619 **CAUTION**: On referenced files used/required by playbooks.
620
621 -  To avoid missing files, during on-boarding or uploading of Ansible
622    Playbooks and related artifacts, all permanent files (not generated
623    by playbooks as part of execution), required to run any playbook,
624    shall reside under the ansible root directory or below on other
625    subdirectories.
626
627 -  Any references to files, on includes or other playbook entries, shall
628    use relative paths.
629
630 -  This is the ansible (root) directory referenced on this
631    note (Ansible Server mount point not included):
632
633 .. code-block:: text
634
635  <VNF type>/<Version>/ansible/
636
637 VNF type directories use A&AI inventory VNF function code. Ansible
638 Playbooks will be stored on a (Cinder) Volume mounted on the Ansible
639 Servers as /storage that is used as a local cache for playbooks and other
640 related artifacts cloned or pulled (updates) from central (git) repository.
641
642 Example:
643
644 ``/storage/vfdb/V16.1/ansible`` – Root directory for database VNF Ansible
645 Playbooks for release 16.1
646
647 **CAUTION**: To support this directory structure as the repository to store
648 Ansible Playbooks run by APPC/SDN-C, APPC/SDN-C API in the Ansible
649 Server side needs to be configured to run playbooks from this directory.
650
651 Ansible Server HTTP will be configured to support APPC/SDN-C REST API
652 requests to run playbooks as needed, against specific VNF instances, or
653 specific VM(s) as specified in the request. When a playbook action is expected
654 to target a subset of VMs in a VNF instance, VNF instance inventory hosts file
655 is expected to be used, and an extra-vars parameter, named target_vm_list with
656 the list of VMs to be targeted by the playbook, is expected to be provided to
657 run specific actions targeting the VM subset. The attribute target_vm_list may
658 point to a single name or single IP address or a list of names or IP addresses
659 in between double-quotes with names or IPs seprated by comma, example,
660 target_vm_list="name1,name2".
661
662 APPC/SDN-C REST API to Ansible Server is documented separately and
663 can be found under ONAP (onap.org).
664
665
666 Ansible Inventory Hosts File – Supported Formats
667 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
668
669 Supported inventory hosts file examples, built from this NodeList model,
670 extracted from A&AI by APPC/SDN-C and passed to the Ansible
671 Server via Rest API as part of request:
672
673 .. code-block:: json
674
675   {
676     "NodeList": [
677         {
678             "vnfc_type": "oam",
679             "ne_id_vip": "vfdb9904vm001oam001",
680             "floating_ip_address_vip": "1xx.2yy.zzz.109",
681             "site": "wp0ny",
682             "vm_info": [
683                  {
684                      "ne_id": "vfdb9904vm001oam001",
685                      "fixed_ip_address": "1xx.2yy.zzz.109"
686                  },
687                  {
688                      "ne_id": "vfdb9904vm002oam001",
689                      "fixed_ip_address": "1xx.2yy.zzz.110"
690                  }
691             ]
692         },
693         {
694             " vnfc_type": "rdb",
695             "site": "wp0ny",
696             "vm_info": [
697                  {
698                      "ne_id": "vfdb9904vm003rdb001",
699                      "fixed_ip_address": "1xx.2yy.zzz.105"
700                  },
701                  {
702                      "ne_id": "vfdb9904vm004rdb001",
703                      "fixed_ip_address": "1xx.2yy.zzz.106"
704                  }
705             ]
706         }
707     ]
708   }
709
710 With no names, only IP addresses, template "InventoryNames": "None" (Default)
711
712 .. code-block:: text
713
714  $ more ../inventory/vfdb9904vhosts
715  [host]
716  localhost ansible_connection=local
717
718  [oamvip]
719  1xx.2yy.zzz.108
720
721  [oam]
722  1xx.2yy.zzz.109
723  1xx.2yy.zzz.110
724
725  [rdb]
726  1xx.2yy.zzz.105
727  1xx.2yy.zzz.106
728
729  [wp0ny:children]
730  oam
731  rdb
732  oamvip
733
734 With VM names and IP addresses, template inventory names setting
735 "InventoryNames": "VM"
736
737 .. code-block:: text
738
739  $ more ../inventory/vfdb9904vhosts
740  [host]
741  localhost ansible_connection=local
742
743  [oamvip]
744  vfdb9904vm001vip ansible_host=1xx.2yy.zzz.108
745
746  [oam]
747  vfdb9904vm001 ansible_host=1xx.2yy.zzz.109
748  vfdb9904vm002 ansible_host=1xx.2yy.zzz.110
749
750  [rdb]
751  vfdb9904vm003 ansible_host=1xx.2yy.zzz.105
752  vfdb9904vm004 ansible_host=1xx.2yy.zzz.106
753
754  [wp0ny:children]
755  oam
756  rdb
757  oamvip
758
759 With VNFC names and IP addresses, template inventory names setting
760 "InventoryNames": "VNFC"
761
762 .. code-block:: text
763
764  $ more ../inventory/vfdb9904vhosts
765  [host]
766  localhost ansible_connection=local
767
768  [oamvip]
769  vfdb9904vm001oam001vip ansible_host=1xx.2yy.zzz.108
770
771  [oam]
772  vfdb9904vm001oam001 ansible_host=1xx.2yy.zzz.109
773  vfdb9904vm002oam001 ansible_host=1xx.2yy.zzz.110
774
775  [rdb]
776  vfdb9904vm003rdb001 ansible_host=1xx.2yy.zzz.105
777  vfdb9904vm004rdb001 ansible_host=1xx.2yy.zzz.106
778
779  [wp0ny:children]
780  oam
781  rdb
782  oamvip
783
784
785
786 Ansible Server – On-boarding Ansible Playbooks
787 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
788
789 Once playbooks are developed following these guidelines, playbooks need to be
790 on-boarded onto Development Ansible Server(s), and placed under (git) code
791 control. Once a (git) repository is created for the set of playbooks, playbooks
792 are then pushed to the central repository. Using mechanized identification that
793 leverages SSH key based authentication, a mechanism is in place to regularly
794 clone or pull updates from central repository to runtime Ansible Server
795 Clusters, to perform an automated controlled distribution of playbooks and
796 related artifacts to clustered runtime Ansible Servers.
797
798 These are the basic steps to on-board playbooks manually onto the
799 Ansible Server.
800
801 #. Upload CSAR, zip, or tar file containing VNF playbooks and related
802    artifacts to Development Ansible Server with connectivity to central
803    repository.
804
805 #. Unzip packaged playbooks or manually create full directory (using –p
806    option below) to store Ansible Playbooks and other artifacts under /storage
807    (or other configured) file system.
808
809    Includes VNF type using VNF function code 4 characters under
810    /storage.
811
812    Includes VNF "Version" directory as part of the path to store
813    playbooks for this VNF version.
814
815    Include generic ansible root directory. Creating full directory
816    path as an example:
817
818 .. code-block:: text
819
820  $ mkdir –p /storage/vfdb/V16.1/ansible
821
822 #. When manually creating directory structure make this directory (VNF
823    ansible root directory) current directory for next few steps:
824
825 .. code-block:: text
826
827  cd /storage/vfdb/V16.1/ansible/
828
829 #. Extract Ansible Playbooks and other Ansible artifacts associated with
830    the playbooks onto the ansible directory. Command depends on the type
831    of file uploaded, examples would be:
832
833 .. code-block:: text
834
835  tar xvf ..
836  unzip ... # Usually, unzip creates the entire directory structure
837
838 #. Create VNF inventory hosts file with all VMs and OA&M IP addresses, and VM
839    or VNFC names as required for the VNF type, grouped by VM/VNFC type. Add
840    site with all groups as children. Inventory hosts file are required for all
841    VNF instances, to be configured and managed through Ansible. Inventory hosts
842    file example:
843
844 .. code-block:: text
845
846  $ mkdir inventory
847
848  $ touch inventory/vfdb9904vhosts
849
850  $ cat inventory/vfdb9904vhosts
851
852  [host]
853  localhost ansible_connection=local
854
855  [oamvip]
856  1xx.2yy.zzz.108
857
858  [oam]
859  1xx.2yy.zzz.109
860  1xx.2yy.zzz.110
861
862  [rdb]
863  1xx.2yy.zzz.105
864  1xx.2yy.zzz.106
865
866  [wp0ny:children]
867  oam
868  rdb
869  oamvip
870
871
872 Virtual IP addresses that can be used by multiple VMs, usually, used by the
873 active VM of an active-standby pair, are placed under a group named after the
874 VNFC (VM) type, plus "vip" string, example of such a group name "oamvip".
875
876 #. (Optional) Create directory to hold default arguments for VNF instance,
877    and respective file(s), when required by VNF type, example:
878
879 .. code-block:: text
880
881  $ mkdir –p vars/vfdb9904v.json
882  $
883  $ cat vfdb9904v.json
884  ...
885  {
886    "json_var1": "vfdb9904v_test_var1",
887    "json_var2": "vfdb9904v_test_var2",
888    "json_var3": "vfdb9904v_test_var3"
889  }
890  ...
891
892
893 **NOTE**: Please note names in this file shall use underscore "_" not dots
894 "." or dashes "-".
895
896 #. Perform some basic playbook validation running with "--check" option,
897    running dummy playbooks or other.
898
899 #. Make <VNF version> directory current directory to add playbooks and other
900    artifacts under (git) code control:
901
902 .. code-block:: text
903
904  cd /storage/vfdb/V16.1
905
906 **NOTE**: After creating the repository for the playbooks in the central
907 repository a list of (git) commands is provided to add playbooks
908 under (git) code control and push them to the newly created repository. Each
909 Ansible Server or cluster of Ansible Servers will have its own
910 credentials to authenticate to VNF VMs. Ansible Server SSH public key(s)
911 have to be loaded onto VNF VMs during instantiation or another way before
912 Ansible Server can access VNF VMs and run playbooks. Heat templates used
913 to instantiate VNFs to be configured by these Ansible Servers running
914 playbooks shall include the same SSH public key and load them onto VNF VM(s)
915 as part of instantiation. Same Ansible Server Cluster SSH public keys are to be
916 added to repositories to provide each authorized cluster access, to clone and
917 pull updates, to each VNF collection of playbooks, from central repository.
918
919 Other non-vendor specific playbook tasks, required by customer, need to be
920 incorporated in overall post-instantiation configuration playbook. Alternative
921 is for company developed playbooks to be pushed to a repository, distributed
922 and executed, after VNF vendor provided playbooks are run.
923
924 **A couple of playbooks used for proof-of-concept testing as examples:**
925
926 UpgradePreCheck:
927
928 .. code-block:: text
929
930  $ pwd
931  /storage/comx/V5.3.1.3/ansible/upgradeprecheck
932
933  $ more site.yml
934  ---
935
936  - import_playbook: ../common/create_vars.yml
937  - import_playbook: ../common/create_hosts.yml
938
939  - name: upgrade software pre check
940    hosts: oam,dbs,cpm
941    gather_facts: no
942    become: true
943    become_method: sudo
944    become_user: root
945    max_fail_percentage: 0
946    any_errors_fatal: True
947    roles:
948      - precheck
949    tags: precheck
950
951  $ more roles/precheck/tasks/main.yml
952  ---
953
954  - include_vars: /tmp/{{ vnf_instance }}/all.yml
955
956  - name: get software version installed on vnf
957    shell: grep "^SW_VERSION =" /vendor/software/config/param_common.cfg | grep -c "{{ existing_software_version }}"
958    register: version_line
959    ignore_errors: yes
960
961  - name: send msg when matches expected version
962    debug:  msg="*** OK *** VNF software release matches (old) release to be upgraded."
963     verbosity=1
964    when: version_line.stdout.find('1') != -1
965
966  # send warning message and failure when release is not a match
967  - fail:
968      msg="*** WARNING *** VNF software release does not match expected (pre-upgrade) release."
969    when: (version_line | failed) or version_line.stdout.find('1') == -1
970
971
972 UpgradePostCheck:
973
974 .. code-block:: text
975
976  $ pwd
977  /storage/comx/V5.3.1.3/ansible/upgradepostcheck
978
979  $ more site.yml
980  ---
981
982  - import_playbook: ../common/create_vars.yml
983  - import_playbook: ../common/create_hosts.yml
984
985  - name: upgrade software post check
986    hosts: oam,dbs,cpm
987    gather_facts: no
988    become: true
989    become_method: sudo
990    become_user: root
991    max_fail_percentage: 0
992    any_errors_fatal: True
993    roles:
994      - postcheck
995    tags: postcheck
996
997  $ more roles/postcheck/tasks/main.yml
998  ---
999
1000  - include_vars: /tmp/{{ vnf_instance }}/all.yml
1001
1002  - name: get post upgrade software version installed on vnf
1003    shell: grep "^SW_VERSION =" /vendor/software/config/param_common.cfg | grep -c "{{ new_software_version }}"
1004    register: version_line
1005    ignore_errors: yes
1006
1007  - name: send msg when matches expected version
1008    debug:  msg="*** OK *** VNF software release matches new release."
1009      verbosity=1
1010    when: version_line.stdout.find('1') != -1
1011
1012  # send warning message and failure when release is not a match
1013  - fail:
1014      msg="*** WARNING *** VNF software release does not match expected new (post-upgrade) release."
1015    when: (version_line | failed) or version_line.stdout.find('1') == -1
1016
1017
1018 Ansible Server – Playbook Example to Discover Ansible Server Mechanized User ID
1019 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1020
1021 Example of playbook role discovering runtime Ansible Server mechanized user ID
1022 and setting it up on target VNF VM(s) with issued and assigned SSH public key
1023 with "from=" clause stored onto xxxxx_id_rsa.frompub file:
1024
1025 .. code-block:: text
1026
1027  $ cat roles/setup_ansible_mechid/tasks/main.yml
1028  ---
1029
1030  - name: set mechid
1031    set_fact:
1032      ansible_mechid: "{{lookup('ini', 'remote_user section=defaults file=/etc/ansible/ansible.cfg') }}"
1033
1034  - name: set mechid uid
1035    set_fact:
1036      ansible_mechuid: "{{lookup('ini', 'remote_user section=defaults file=/etc/ansible/ansible.cfg')[1:] }}"
1037
1038  - debug: msg="mechid {{ ansible_mechid }} ansible_mechuid {{ ansible_mechuid }}"
1039      verbosity=1
1040
1041  # Create ansible server Mech ID group
1042  - group:
1043      name: "{{ ansible_mechid }}"
1044      state: present
1045
1046  # add ansible server mech id user
1047  - user:
1048      name: "{{ ansible_mechid }}"
1049      group: "{{ ansible_mechid }}"
1050      state: present
1051      comment: "Ansible Server Mech ID"
1052      expires: 99999
1053      groups: 0
1054      uid: "{{ ansible_mechuid }}"
1055
1056  - name: create ansible mech id .ssh directory
1057    file: path=/home/{{ ansible_mechid }}/.ssh owner={{ ansible_mechid }} group={{ ansible_mechid }} mode=0700 state=directory
1058
1059  - name: touch ansible mech id authorized_keys file
1060    file: path=/home/{{ ansible_mechid }}/.ssh/authorized_keys owner={{ ansible_mechid }} group={{ ansible_mechid }} mode=0600 state=touch
1061
1062  - name: get path to mechid id_rsa.pub
1063    set_fact:
1064      public_key: "{{lookup('ini', 'private_key_file section=defaults file=/etc/ansible/ansible.cfg') }}.frompub"
1065  #   public_key: "{{lookup('ini', 'private_key_file section=defaults file=/etc/ansible/ansible.cfg') }}.pub"
1066
1067  - name: setup authorized_keys file
1068    authorized_key:
1069      user: "{{ ansible_mechid }}"
1070      state: present
1071      key: "{{ lookup('file', '{{ public_key}}') }}"
1072  …
1073