diff --git a/.gitignore b/.gitignore index 035469f4..9a3d1803 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ # Ansible external_roles/* +*.retry # Byte-compiled / optimized / DLL files __pycache__/ diff --git a/README.md b/README.md index f9ba7915..4c30f547 100644 --- a/README.md +++ b/README.md @@ -1,30 +1,100 @@ # autodeploy -Deployment automation efforts for PF9 pre-reqs, host agent, and authorization. + +Deployment automation efforts for Platform9's prerequisites, host agent(s), and authorization via the use of Ansible. + + +## Requirements + +* Ansible 2 +* Python 2 + * shade + ## Instructions -After cloning the repo you'll need to create the following files. +Clone the repository. +``` +$ git clone https://github.com/platform9/autodeploy.git +$ cd autodeploy/ +``` + +After cloning the repository, it is required to configure the variables for deployment. +``` +# cp -a group_vars/all_example.yml group_vars/all.yml +# vim group_vars/all.yml +``` + +The SSH connection details for the hypervisor (Nova) and/or image (Glance) nodes should be defined in a new inventory file. +``` +# vim production +``` + +Finally, the Playbook can be run. +``` +# ansible-playbook -i production site.yml +``` + + +### Variables + +Hypervisor required variables: -### group_vars/all.yml +* group_vars/all.yml + * os_region = OpenStack region. + * os_username = OpenStack admin username. + * os_password: OpenStack password. + * os_tenant: OpenStack admin project. + * du_url = The unique URL provided by Platform9 to access the controller resources. - ssh_user: root - os_region: - os_username: - os_password: - os_tenant: - du_url: +Image node required variable: -### inventory/hypervisors +* group_vars/all.yml + * pf9_id - [hypervisors] - ansible_host= +Optional variables: -## Example Playbook +* group_vars/all.yml + * manage_hostname = Boolean value. Set the hostname equal to the Ansible inventory_hostname for the host. + * manage_resolvers = Boolean value. Append servers listed in the "dns_resolvers" variable to the resolvers file. + * dns_resolvers = The DNS resolvers to use for the remote node. + + +### Inventory + +All of the hypervisor nodes should be listed in the inventory file. They should be under the "hypervisors" group. Each node should be named after their fully qualified domain name (FQDN) that will be used as the hostname. Here are a few examples for creating Ansible inventory connection details based on common scenarios. + +* SSH directly in as root. +``` + ansible_host= ansible_port= ansible_user=root +``` + +* SSH in as a privileged user and run Ansible tasks using "sudo." +``` + ansible_host= ansible_port= ansible_become=True ansible_user= ansible_become_method=sudo +``` + +* SSH in as a privileged user and then switch to the root user with "su" to run Ansible tasks. +``` + ansible_host= ansible_port= ansible_become=True ansible_user= ansible_become_method=su ansible_user= +``` + +* Hypervisor and image storage group inventory example: +``` +# vim production +compute01.domain.tld ansible_host=10.0.0.11 ansible_port=2222 ansibler_user=root +compute02.domain.tld ansible_host=10.0.0.12 ansible_become=True ansible_user=bob ansible_become_method=sudo +compute03.domain.tld ansible_host=10.0.0.13 ansible_port=2222 ansible_become=True ansible_user=joe ansible_become_method=su +image01.domain.tld ansible_host=10.0.0.71 +image02.domain.tld ansible_host=10.0.0.72 + +[hypervisors] +compute[01:03].domain.tld + +[image_storage] +image[01:02].domain.tld +``` - - hosts: hypervisors - roles: - - neutron-prerequisites - - pf9-hostagent ## License + Commerical diff --git a/group_vars/.gitignore b/group_vars/.gitignore new file mode 100644 index 00000000..2b632c12 --- /dev/null +++ b/group_vars/.gitignore @@ -0,0 +1,2 @@ +all.yml +all.yaml diff --git a/group_vars/all.yml b/group_vars/all.yml deleted file mode 100644 index b4f48e20..00000000 --- a/group_vars/all.yml +++ /dev/null @@ -1,14 +0,0 @@ ---- -## Playbook defaults - -# Set hostname equal to inventory_hostname -manage_hostname: True - -# Networking defaults -default_resolvers: - - 8.8.8.8 - - 8.8.4.4 - -neutron_plugin: OVS - -ssh_user: root diff --git a/group_vars/all_example.yml b/group_vars/all_example.yml new file mode 100644 index 00000000..8052f6b7 --- /dev/null +++ b/group_vars/all_example.yml @@ -0,0 +1,14 @@ +--- +# Set hostname equal to inventory_hostname +manage_hostname: False +# Append DNS resolvers to /etc/resolv.conf +manage_resolvers: False +dns_resolvers: + - 8.8.8.8 + - 8.8.4.4 +# these variables are required to be filled in for the end-user's environment +os_username: +os_password: +os_region: +os_tenant: +du_url: diff --git a/inventory/pf9.py b/inventory/pf9.py index b294effc..a7f679c2 100755 --- a/inventory/pf9.py +++ b/inventory/pf9.py @@ -41,7 +41,7 @@ def get_du_inventory(self): @os_token: str @rtype: dict """ - # Check if OS Token exits + # Check if OS Token exists if self.pf9_keystone_file and os.path.isfile(self.pf9_keystone_file): try: os_token_file = open(self.pf9_keystone_file) diff --git a/roles/common/tasks/main.yml b/roles/common/tasks/main.yml new file mode 100644 index 00000000..cb852825 --- /dev/null +++ b/roles/common/tasks/main.yml @@ -0,0 +1,40 @@ +--- +- name: Check for hardware virtualization support + # svm - AMD SVM + # vmx - Intel VT-x + command: "grep -Eiq '(svm|vmx)' /proc/cpuinfo" + ignore_errors: True + changed_when: hw_virt.rc != 0 + register: hw_virt + when: inventory_hostname in groups.hypervisors + +- name: Quitting if hardware virtualization is not enabled + fail: + msg: "Hardware virtualization is not present, or not enabled." + when: hw_virt|failed and + inventory_hostname in groups.hypervisors + +- name: Set system hostname + hostname: + name: "{{ inventory_hostname }}" + register: hostname_result + +- name: Update /etc/hosts to reflect hostname change + lineinfile: + state: present + dest: /etc/hosts + regexp: "^(127.0.0.1).*$" + line: "127.0.0.1\t{{ inventory_hostname_short }}\t{{ inventory_hostname }}\tlocalhost" + register: etc_hosts_result + +- name: Set DNS resolvers + lineinfile: + state: present + dest: /etc/resolv.conf + create: yes + line: "nameserver {{ item }}" + with_items: "{{ dns_resolvers }}" + when: manage_resolvers == True + +- include: redhat.yml + when: ansible_os_family == "RedHat" diff --git a/roles/common/tasks/redhat.yml b/roles/common/tasks/redhat.yml new file mode 100644 index 00000000..dc4cf197 --- /dev/null +++ b/roles/common/tasks/redhat.yml @@ -0,0 +1,20 @@ +--- +- name: Install libselinux-python + yum: + state: present + name: libselinux-python + +- name: Modify devpts mount point + mount: + state: present + name: /dev/pts + src: devpts + fstype: devpts + opts: gid=5,mode=620 + dump: 0 + passno: 0 + register: devpts_result + +- name: Remount devpts mount point + command: mount -o remount devpts + when: devpts_result|changed diff --git a/roles/glance-host/defaults/main.yml b/roles/glance-host/defaults/main.yml deleted file mode 100644 index cdd640e2..00000000 --- a/roles/glance-host/defaults/main.yml +++ /dev/null @@ -1,2 +0,0 @@ ---- -glance_images: [] diff --git a/roles/glance-host/tasks/main.yml b/roles/glance-host/tasks/main.yml index b76fed22..d835aed5 100644 --- a/roles/glance-host/tasks/main.yml +++ b/roles/glance-host/tasks/main.yml @@ -3,7 +3,7 @@ uri: url: "{{ du_url }}/resmgr/v1/hosts/{{ pf9_id }}/roles/pf9-glance-role" headers: - X-Auth-Token: "{{ hostvars['localhost']['os_auth_token'] }}" + X-Auth-Token: "{{ hostvars[inventory_hostname]['os_auth_token'] }}" register: glance_role_custom - name: Set glance_datadir path diff --git a/roles/neutron-prerequisites/defaults/main.yml b/roles/neutron-prerequisites/defaults/main.yml index 5a100769..4cf3dab2 100644 --- a/roles/neutron-prerequisites/defaults/main.yml +++ b/roles/neutron-prerequisites/defaults/main.yml @@ -5,3 +5,8 @@ neutron_sysctl: net.ipv4.conf.default.rp_filter: 0 net.ipv4.ip_forward: 1 net.ipv4.tcp_mtu_probing: 1 +neutron_kernel_modules: + - 8021q + - bonding + - bridge + - br_netfilter diff --git a/roles/neutron-prerequisites/tasks/main.yml b/roles/neutron-prerequisites/tasks/main.yml index a206b2aa..3c90c5cc 100644 --- a/roles/neutron-prerequisites/tasks/main.yml +++ b/roles/neutron-prerequisites/tasks/main.yml @@ -1,19 +1,4 @@ --- -- name: Set DNS resolvers if unset - lineinfile: - state: present - dest: /etc/resolv.conf - create: yes - line: "nameserver {{ item }}" - with_items: "{{ default_resolvers }}" - when: ansible_dns.nameservers is undefined - -- name: Install libselinux-python - yum: - state: present - name: libselinux-python - when: ansible_distribution == "CentOS" - - name: Load kernel modules required for Neutron include: modules.yml @@ -25,10 +10,23 @@ sysctl_set: yes with_dict: "{{ neutron_sysctl }}" -- include: centos.yml - when: ansible_distribution == 'CentOS' +- include: redhat.yml + when: ansible_os_family == "RedHat" - include: ubuntu.yml when: ansible_distribution == 'Ubuntu' -- include: networking.yml +- name: Create required OVS bridges + openvswitch_bridge: + bridge: "{{ item }}" + state: present + with_items: + - br-ext + - br-vlan + +- name: Set br-ext external bridge ID + openvswitch_bridge: + bridge: br-ext + state: present + external_ids: + bridge-id: br-ext diff --git a/roles/neutron-prerequisites/tasks/modules.yml b/roles/neutron-prerequisites/tasks/modules.yml index 9868f150..7f86b106 100644 --- a/roles/neutron-prerequisites/tasks/modules.yml +++ b/roles/neutron-prerequisites/tasks/modules.yml @@ -1,20 +1,15 @@ --- -- include_vars: "{{ item }}" - with_first_found: - - "vars/{{ ansible_distribution }}.yml" - - vars/default.yml - - modprobe: state: present name: "{{ item }}" - with_items: "{{ neutron_modules }}" + with_items: "{{ neutron_kernel_modules }}" - name: Persist modules on boot lineinfile: state: present line: "{{ item }}" dest: /etc/modules - with_items: "{{ neutron_modules }}" + with_items: "{{ neutron_kernel_modules }}" when: ansible_os_family == "Debian" - name: Persist modules on boot @@ -23,5 +18,5 @@ dest: /etc/modules-load.d/neutron.conf create: yes line: "{{ item }}" - with_items: "{{ neutron_modules }}" + with_items: "{{ neutron_kernel_modules }}" when: ansible_os_family == "RedHat" diff --git a/roles/neutron-prerequisites/tasks/networking.yml b/roles/neutron-prerequisites/tasks/networking.yml deleted file mode 100644 index 4a784545..00000000 --- a/roles/neutron-prerequisites/tasks/networking.yml +++ /dev/null @@ -1,15 +0,0 @@ ---- -- name: Create required OVS bridges - openvswitch_bridge: - bridge: "{{ item }}" - state: present - with_items: - - br-ext - - br-vlan - -- name: Set br-ext external bridge ID - openvswitch_bridge: - bridge: br-ext - state: present - external_ids: - bridge-id: br-ext diff --git a/roles/neutron-prerequisites/tasks/centos.yml b/roles/neutron-prerequisites/tasks/redhat.yml similarity index 85% rename from roles/neutron-prerequisites/tasks/centos.yml rename to roles/neutron-prerequisites/tasks/redhat.yml index 7a582e75..b1ac510f 100644 --- a/roles/neutron-prerequisites/tasks/centos.yml +++ b/roles/neutron-prerequisites/tasks/redhat.yml @@ -4,13 +4,18 @@ policy: targeted state: permissive -- name: Disable firewall +- name: Disable firewalld service: state: stopped name: firewalld enabled: no ignore_errors: True +- name: Installing iptables-services + yum: + name: iptables-services + state: present + - name: Assemble list of ifcfg scripts find: path: /etc/sysconfig/network-scripts @@ -35,7 +40,7 @@ enabled: no ignore_errors: True -- name: Add PF9 yum repo +- name: Add Platform9 Yum repository yum: name: https://s3-us-west-1.amazonaws.com/platform9-neutron/noarch/platform9-neutron-repo-1-0.noarch.rpm state: present @@ -48,7 +53,7 @@ disablerepo: '*' enablerepo: 'platform9-neutron-el7-repo' -- name: Enable & Start Open vSwitch +- name: Enable and start Open vSwitch service: name: openvswitch state: started diff --git a/roles/neutron-prerequisites/tasks/ubuntu.yml b/roles/neutron-prerequisites/tasks/ubuntu.yml index 87e88f6d..4b9793e6 100644 --- a/roles/neutron-prerequisites/tasks/ubuntu.yml +++ b/roles/neutron-prerequisites/tasks/ubuntu.yml @@ -6,7 +6,7 @@ - ifenslave - vlan -- name: Add PF9 repo +- name: Add Platform9 APT repository apt_repository: repo: 'deb http://platform9-neutron.s3-website-us-west-1.amazonaws.com ubuntu/' state: present @@ -18,7 +18,7 @@ state: present force: yes -- name: Enable & Start Open vSwitch +- name: Enable and start Open vSwitch service: name: openvswitch-switch state: started diff --git a/roles/neutron-prerequisites/vars/CentOS.yml b/roles/neutron-prerequisites/vars/CentOS.yml deleted file mode 100644 index a00ad15a..00000000 --- a/roles/neutron-prerequisites/vars/CentOS.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -neutron_modules: - - 8021q - - bonding - - bridge diff --git a/roles/neutron-prerequisites/vars/Ubuntu.yml b/roles/neutron-prerequisites/vars/Ubuntu.yml deleted file mode 100644 index e4a5d400..00000000 --- a/roles/neutron-prerequisites/vars/Ubuntu.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -neutron_modules: - - 8021q - - bonding - - br_netfilter diff --git a/roles/neutron-prerequisites/vars/default.yml b/roles/neutron-prerequisites/vars/default.yml deleted file mode 100644 index ce430c2e..00000000 --- a/roles/neutron-prerequisites/vars/default.yml +++ /dev/null @@ -1,2 +0,0 @@ ---- -neutron_modules: [] diff --git a/roles/ntp/tasks/main.yml b/roles/ntp/tasks/main.yml index 290d4691..78159cd2 100644 --- a/roles/ntp/tasks/main.yml +++ b/roles/ntp/tasks/main.yml @@ -1,8 +1,5 @@ --- -- include_vars: "{{ item }}" - with_first_found: - - "{{ ansible_distribution }}.yml" - - default.yml +- include_vars: "{{ ansible_os_family|lower }}.yml" - name: Install NTP package: @@ -10,7 +7,7 @@ name: "{{ item }}" with_items: "{{ ntp_packages }}" -- name: Enable & start NTP +- name: Enable and start NTP service: name: "{{ ntp_service_name }}" state: started diff --git a/roles/ntp/vars/Ubuntu.yml b/roles/ntp/vars/debian.yml similarity index 100% rename from roles/ntp/vars/Ubuntu.yml rename to roles/ntp/vars/debian.yml diff --git a/roles/ntp/vars/default.yml b/roles/ntp/vars/default.yml deleted file mode 100644 index 838e9e8d..00000000 --- a/roles/ntp/vars/default.yml +++ /dev/null @@ -1,2 +0,0 @@ ---- -ntp_packages: [] diff --git a/roles/ntp/vars/CentOS.yml b/roles/ntp/vars/redhat.yml similarity index 100% rename from roles/ntp/vars/CentOS.yml rename to roles/ntp/vars/redhat.yml diff --git a/playbooks/keystone.yml b/roles/pf9-auth/tasks/main.yml similarity index 76% rename from playbooks/keystone.yml rename to roles/pf9-auth/tasks/main.yml index d1804b9d..85a9376d 100644 --- a/playbooks/keystone.yml +++ b/roles/pf9-auth/tasks/main.yml @@ -11,15 +11,13 @@ - os_tenant - name: Check if cached Keystone token exists - file: - state: file - name: files/keystone-token.txt - ignore_errors: True + stat: + path: /root/keystone-token.txt register: cached_token - block: - name: Load OS_AUTH_TOKEN into fact - set_fact: "os_auth_token={{ lookup('file', 'keystone-token.txt') | trim }}" + set_fact: "os_auth_token={{ lookup('file', '/root/keystone-token.txt') | trim }}" - name: Validate Keystone token uri: @@ -29,7 +27,7 @@ status_code: 200, 401 validate_certs: no register: validate_response - when: cached_token|success + when: cached_token.stat.exists == True - block: - name: Obtain authentication token from Keystone @@ -41,16 +39,16 @@ project_name: "{{ os_tenant }}" region_name: "{{ os_region }}" validate_certs: False - always_run: True + check_mode: no register: auth_reply - name: Save OS Auth Token copy: content: "{{ auth_reply.ansible_facts.auth_token }}" - dest: files/keystone-token.txt + dest: /root/keystone-token.txt - name: Store OS_AUTH_TOKEN in fact set_fact: "os_auth_token={{ auth_reply.ansible_facts.auth_token }}" - when: cached_token|failed or - (validate_response is defined and validate_response.status != 200) + when: (cached_token.stat.exists == False) or + (validate_response is defined and validate_response.status != 200) diff --git a/roles/pf9-hostagent/handlers/main.yml b/roles/pf9-hostagent/handlers/main.yml deleted file mode 100644 index 06776aff..00000000 --- a/roles/pf9-hostagent/handlers/main.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -- name: restart pf9-hostagent - service: - name: pf9-hostagent - state: restarted diff --git a/roles/pf9-hostagent/tasks/download-installers.yml b/roles/pf9-hostagent/tasks/download-installers.yml deleted file mode 100644 index 3adead48..00000000 --- a/roles/pf9-hostagent/tasks/download-installers.yml +++ /dev/null @@ -1,16 +0,0 @@ -- name: Create pf9 installers directory - connection: local - file: - path: "files/{{ du_host }}" - state: directory - -- name: Download Platform9 installers - connection: local - get_url: - url: "{{ du_url }}/private/platform9-install-{{ item }}.sh" - dest: "files/{{ du_host }}/platform9-install-{{ item }}.sh" - headers: "X-Auth-Token:{{ hostvars['localhost']['os_auth_token'] }}" - validate_certs: no - with_items: - - debian - - redhat diff --git a/roles/pf9-hostagent/tasks/main.yml b/roles/pf9-hostagent/tasks/main.yml index 055af68b..34d90aba 100644 --- a/roles/pf9-hostagent/tasks/main.yml +++ b/roles/pf9-hostagent/tasks/main.yml @@ -1,4 +1,19 @@ --- -- include: download-installers.yml +- name: Download Platform9 installers + connection: local + get_url: + url: "{{ du_url }}/private/platform9-install-{{ item }}.sh" + dest: "/tmp/platform9-install-{{ item }}.sh" + headers: "X-Auth-Token: {{ hostvars[inventory_hostname]['os_auth_token'] }}" + validate_certs: no + with_items: + - debian + - redhat + - include: packages.yml -- include: services.yml + +- name: Enable and start pf9-hostagent + service: + name: pf9-hostagent + state: started + enabled: yes diff --git a/roles/pf9-hostagent/tasks/packages.yml b/roles/pf9-hostagent/tasks/packages.yml index 9c572455..12eb2001 100644 --- a/roles/pf9-hostagent/tasks/packages.yml +++ b/roles/pf9-hostagent/tasks/packages.yml @@ -6,7 +6,7 @@ register: pkg_state changed_when: pkg_state.rc != 0 -- name: Check pf9-hostagent on RedHat +- name: Check pf9-hostagent on Red Hat command: rpm -q pf9-hostagent when: ansible_pkg_mgr == "yum" ignore_errors: True @@ -14,5 +14,5 @@ changed_when: pkg_state.rc != 0 - name: Install pf9-hostagent on hypervisor - script: "{{ du_host }}/platform9-install-{{ ansible_os_family|lower }}.sh --no-proxy" + script: "/tmp/platform9-install-{{ ansible_os_family|lower }}.sh --no-proxy --no-ntpd" when: pkg_state|failed diff --git a/roles/pf9-hostagent/tasks/services.yml b/roles/pf9-hostagent/tasks/services.yml deleted file mode 100644 index 11e4a754..00000000 --- a/roles/pf9-hostagent/tasks/services.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -- name: Enable & start pf9-hostagent - service: - name: pf9-hostagent - state: started - enabled: yes diff --git a/site.yml b/site.yml index fc0ed76f..4f219c2d 100644 --- a/site.yml +++ b/site.yml @@ -1,86 +1,15 @@ --- -- hosts: localhost - tasks: - - include: playbooks/keystone.yml - - hosts: all - tasks: - - group_by: "key={{ ansible_distribution }}" - -- hosts: hypervisors - tasks: - - name: Copy SSH authentication - authorized_key: - state: present - user: "{{ ssh_user }}" - exclusive: no - manage_dir: yes - key: "{{ lookup('file', 'files/root-key.pub') }}" - -- hosts: hypervisors - gather_facts: False - pre_tasks: - # svm - AMD SVM - # vmx - Intel VT-x - - name: Check for hardware virtualization support - command: "grep -Eiq '(svm|vmx)' /proc/cpuinfo" - ignore_errors: True - changed_when: hw_virt.rc != 0 - register: hw_virt - - - name: Quit if hardware virtualization is not enabled - fail: - msg: "Hardware virtualization is not present, or not enabled." - when: hw_virt|failed roles: - - { role: neutron-prerequisites, when: neutron_plugin == 'OVS' } + - common + - ntp + - pf9-auth + - pf9-hostagent -- hosts: all - gather_facts: False - tasks: - - block: - - name: Set system hostname - hostname: - name: "{{ inventory_hostname }}" - register: hostname_result - - - name: Update /etc/hosts to reflect hostname change - lineinfile: - state: present - dest: /etc/hosts - regexp: "^(127.0.1.1).*$" - line: "127.0.1.1\t{{ inventory_hostname_short }}\t{{ inventory_hostname }}" - register: etc_hosts_result - - - name: Restart pf9-hostagent on hostname change - service: - name: pf9-hostagent - state: restarted - when: hostname_result|changed or etc_hosts_result|changed - when: (ansible_os_family == "Debian" or ansible_os_family == "RedHat") and - manage_hostname|bool == True - - - block: - - name: Modify devpts mount point - mount: - state: present - name: /dev/pts - src: devpts - fstype: devpts - opts: gid=5,mode=620 - dump: 0 - passno: 0 - register: devpts_result - - - name: Remount devpts mount point - command: mount -o remount devpts - when: devpts_result|changed - - when: ansible_os_family == "RedHat" +- hosts: hypervisors roles: - - ntp - - pf9-hostagent + - neutron-prerequisites -- hosts: image_libraries +- hosts: image_storage roles: - glance-host