Ansible installer update

  * Moved Ansible to version 2.10
  * Python Virtual env
  * New option to use a custom SSH key
  * Use of cloud-init file supported
  * Increased the number of options to be passed to the remote installer

Change-Id: I70131f1a24707656c9390445df91d17abab95763
Signed-off-by: Antonio Marsico <antonio.marsico@bt.com>
(cherry picked from commit 75a38c73867914a576062a3b50d5c80ace795f6c)
diff --git a/installers/openstack/README.md b/installers/openstack/README.md
index a8e4356..3972928 100644
--- a/installers/openstack/README.md
+++ b/installers/openstack/README.md
@@ -23,7 +23,7 @@
 ## Prerequisites
 The ansible playbook requires `ansible` and `openstacksdk` to be executed. `python-openstackclient` is not mandatory but highly recommended. They are part of Python pip and can be installed as follows:
 
-`$ sudo -H pip install python-openstackclient "openstacksdk<1" "ansible>=2.9,<3"`
+`$ sudo -H pip install python-openstackclient "openstacksdk<1" "ansible>=2.10,<2.11"`
 
 ## Execute the playbook
 
diff --git a/installers/openstack/group_vars/all.yml b/installers/openstack/group_vars/all.yml
index ce0f9c1..62cabc3 100644
--- a/installers/openstack/group_vars/all.yml
+++ b/installers/openstack/group_vars/all.yml
@@ -17,7 +17,7 @@
 
 osm_installer_path: /usr/share/osm-devops/installers/install_osm.sh
 
-prefix: server
+server_name: server-osm
 
 cloud_name:
 
@@ -27,7 +27,13 @@
 
 installer_args:
 
-os_key_name: ansible-key
+userdata_file:
+
+local_userdata:
+
+os_key_name: osm-ansible-key
+
+key_file:
 
 os_flavor:
   name: medium-4-cpu-8-gb-40-disk
@@ -36,7 +42,7 @@
   disk: 40
 
 servers:
-  - name: osm
+  - name: '1'
     user: ubuntu
     image: ubuntu1804
     image_url: https://cloud-images.ubuntu.com/bionic/current/bionic-server-cloudimg-amd64.img
diff --git a/installers/openstack/roles/create_instances/tasks/main.yml b/installers/openstack/roles/create_instances/tasks/main.yml
index 03c0b4c..c97b1a8 100644
--- a/installers/openstack/roles/create_instances/tasks/main.yml
+++ b/installers/openstack/roles/create_instances/tasks/main.yml
@@ -14,15 +14,20 @@
 #   limitations under the License.
 #   Author: Antonio Marsico (antonio.marsico@bt.com)
 
+- set_fact:
+    local_userdata: "{{ lookup('file', userdata_file) }}"
+  when: userdata_file != none
+
 - name: Launch OSM instances
-  os_server:
+  openstack.cloud.server:
     cloud: "{{ cloud_name }}"
-    name: "{{ prefix }}-{{ item.name }}"
+    name: "{{ server_name }}-{{ item.name }}"
     state: present
     key_name: "{{ item.key }}"
     nics: "{{ item.nics }}"
     image: "{{ item.image }}"
     flavor: "{{ item.flavor }}"
+    userdata: "{{ local_userdata }}"
     security_groups:
       - default
       - "{{external_network_name}}_access"
@@ -31,14 +36,16 @@
   when: setup_volume|bool == False
 
 - name: Launch OSM instances with a volume
-  os_server:
+  openstack.cloud.server:
     cloud: "{{ cloud_name }}"
-    name: "{{ prefix }}-{{ item.name }}"
+    name: "{{ server_name }}-{{ item.name }}"
     state: present
     key_name: "{{ item.key }}"
     nics: "{{ item.nics }}"
     image: "{{ item.image }}"
     flavor: "{{ item.flavor }}"
+    volume_size: "{{ os_flavor.disk }}"
+    userdata: "{{ local_userdata }}"
     boot_from_volume: yes
     terminate_volume: yes
     security_groups:
@@ -59,3 +66,13 @@
     ansible_private_key_file: "~/.ssh/{{ os_key_name }}"
     ansible_user: "{{ item['item']['user'] }}"
   with_items: "{{ os_hosts.results }}"
+  when: key_file == none
+
+- name: Add OSM host to the local Ansible inventory
+  add_host:
+    name: "{{ item.openstack.accessIPv4 }}"
+    groups: "{{ item['item']['meta']['group'] }}"
+    ansible_private_key_file: "{{ key_file | regex_replace('.pub') }}"
+    ansible_user: "{{ item['item']['user'] }}"
+  with_items: "{{ os_hosts.results }}"
+  when: key_file != none
diff --git a/installers/openstack/roles/osm_installation/tasks/main.yml b/installers/openstack/roles/osm_installation/tasks/main.yml
index c254574..f5b4567 100644
--- a/installers/openstack/roles/osm_installation/tasks/main.yml
+++ b/installers/openstack/roles/osm_installation/tasks/main.yml
@@ -32,13 +32,6 @@
   ignore_errors: yes
   register: curl_result
 
-- name: Pre-configure iptables persistent
-  debconf: name=iptables-persistent question={{ item }} vtype=boolean value=true
-  become: yes
-  with_items:
-  - iptables-persistent/autosave_v4
-  - iptables-persistent/autosave_v6
-
 - debug:
     var: installer_args
     verbosity: 2
diff --git a/installers/openstack/roles/setup_openstack/tasks/main.yml b/installers/openstack/roles/setup_openstack/tasks/main.yml
index 8c729df..fcf4f3e 100644
--- a/installers/openstack/roles/setup_openstack/tasks/main.yml
+++ b/installers/openstack/roles/setup_openstack/tasks/main.yml
@@ -15,7 +15,7 @@
 #   Author: Antonio Marsico (antonio.marsico@bt.com)
 
 - name: Looking for the OpenStack external network
-  os_networks_info:
+  openstack.cloud.networks_info:
     cloud: "{{ cloud_name }}"
     filters:
       name: "{{ external_network_name }}"
@@ -27,7 +27,7 @@
     verbosity: 2
 
 - name: Gather information about previously created subnets
-  os_subnets_info:
+  openstack.cloud.subnets_info:
     cloud: "{{ cloud_name }}"
     name: "{{ openstack_external_networks.openstack_networks[0].subnets[0] }}"
   register: subnet_info
@@ -41,7 +41,7 @@
     cidr: "{{ subnet_info.openstack_subnets[0].cidr }}"
 
 - name: Creating a new openstack flavor
-  os_nova_flavor:
+  openstack.cloud.compute_flavor:
     cloud: "{{ cloud_name }}"
     state: present
     name: "{{os_flavor.name}}"
@@ -50,7 +50,7 @@
     disk: "{{os_flavor.disk}}"
 
 - name: Gather information about OpenStack images
-  os_image_info:
+  openstack.cloud.image_info:
     cloud: "{{ cloud_name }}"
     image: "{{ item.image }}"
   with_items: "{{ servers }}"
@@ -74,7 +74,7 @@
   when: item.1.openstack_image == none and item.0.image == item.1.item.image
 
 - name: Creating images
-  os_image:
+  openstack.cloud.image:
     cloud: "{{ cloud_name }}"
     name: "{{ item.0.image }}"
     container_format: bare
@@ -91,31 +91,50 @@
   with_items: "{{ servers }}"
 
 - name: Creating a security group
-  os_security_group:
+  openstack.cloud.security_group:
     cloud: "{{ cloud_name }}"
     state: present
     name: "{{external_network_name}}_access"
     description: Security group for LAN external access
 
 - name: Creating ICMP rule
-  os_security_group_rule:
+  openstack.cloud.security_group_rule:
     cloud: "{{ cloud_name }}"
     security_group: "{{external_network_name}}_access"
     protocol: icmp
     remote_ip_prefix: 0.0.0.0/0
 
 - name: Creating TCP access rule
-  os_security_group_rule:
+  openstack.cloud.security_group_rule:
     cloud: "{{ cloud_name }}"
     security_group: "{{external_network_name}}_access"
     protocol: tcp
     remote_ip_prefix: "{{ cidr }}"
 
+- name: Allow HTTP from anywhere
+  openstack.cloud.security_group_rule:
+    cloud: "{{ cloud_name }}"
+    security_group: "{{external_network_name}}_access"
+    protocol: tcp
+    port_range_min: 80
+    port_range_max: 80
+    remote_ip_prefix: 0.0.0.0/0
+
+- name: Allow SSH from anywhere
+  openstack.cloud.security_group_rule:
+    cloud: "{{ cloud_name }}"
+    security_group: "{{external_network_name}}_access"
+    protocol: tcp
+    port_range_min: 22
+    port_range_max: 22
+    remote_ip_prefix: 0.0.0.0/0
+
 - name: SSH key check
-  os_keypair:
+  openstack.cloud.keypair:
     cloud: "{{ cloud_name }}"
     state: present
     name: "{{ os_key_name }}"
+    public_key_file: "{{ key_file }}"
   register: keypair
 
 - debug:
@@ -128,7 +147,7 @@
     content: "{{ keypair.key.public_key }}"
     dest: "~/.ssh/{{ keypair.key.name }}.pub"
     mode: '600'
-  when: keypair.key.public_key is not none
+  when: keypair.key.public_key != none and key_file == none
 
 - name: Creating the new ansible private key
   local_action:
@@ -136,4 +155,4 @@
     content: "{{ keypair.key.private_key }}"
     dest: "~/.ssh/{{ keypair.key.name }}"
     mode: '600'
-  when: keypair.key.private_key is not none
\ No newline at end of file
+  when: keypair.key.private_key != none and key_file == none
\ No newline at end of file