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