# Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. --- # NOTE(TheJulia): There is significant commonality between this playbook # and the bifrost bootstrap process. - name: "Get uwsgi install location" shell: echo $(dirname $(which uwsgi)) register: uwsgi_install_prefix environment: "{{ bifrost_venv_env }}" - name: "Get keystone-wsgi-admin location" shell: echo $(dirname $(which keystone-wsgi-admin)) register: keystone_install_prefix environment: "{{ bifrost_venv_env }}" # NOTE(sean-k-mooney) only the MySQL db is started during bootstrapping. # all other services are started in the Start phase. - name: "Start database service" service: name={{ mysql_service_name }} state=started enabled=yes - name: "Set mysql_username if environment variable mysql_user is set" set_fact: mysql_username: "{{ lookup('env', 'mysql_user') }}" when: lookup('env', 'mysql_user') | length > 0 no_log: true - name: "Set mysql_password if environment variable mysql_pass is set" set_fact: mysql_password: "{{ lookup('env', 'mysql_pass') }}" when: lookup('env', 'mysql_pass') | length > 0 no_log: true - name: "Set MySQL socket fact for Red Hat family" set_fact: mysql_socket_path: "/var/lib/mysql/mysql.sock" when: ansible_os_family | lower == 'redhat' - name: "Set MySQL socket fact for Debian family" set_fact: mysql_socket_path: "/var/run/mysqld/mysqld.sock" when: ansible_os_family | lower == 'debian' - name: "Set MySQL socket fact for other systems" set_fact: mysql_socket_path: "/var/run/mysql/mysql.sock" when: (ansible_os_family | lower) not in ['redhat', 'debian'] - name: "MySQL - Creating DB" mysql_db: login_unix_socket: "{{ mysql_socket_path | default(omit) }}" name: "{{ keystone.database.name }}" state: present encoding: utf8 login_user: "{{ mysql_username | default(None) }}" login_password: "{{ mysql_password | default(None) }}" register: test_created_keystone_db when: keystone.database.host == 'localhost' - name: "MySQL - Creating user for keystone" mysql_user: login_unix_socket: "{{ mysql_socket_path | default(omit) }}" name: "{{ keystone.database.username }}" password: "{{ keystone.database.password }}" priv: "{{ keystone.database.name }}.*:ALL" state: present login_user: "{{ mysql_username | default(None) }}" login_password: "{{ mysql_password | default(None) }}" when: keystone.database.host == 'localhost' - name: "Create an keystone service group" group: name: "keystone" - name: "Create an keystone service user" user: name: "keystone" group: "keystone" - name: "Ensure /etc/keystone exists" file: name: "/etc/keystone" state: directory owner: "keystone" group: "keystone" mode: 0755 - name: "Write keystone configuration from template" template: src: keystone.conf.j2 dest: "/etc/keystone/keystone.conf" owner: "keystone" group: "keystone" mode: 0755 - name: "Apply/Update keystone DB Schema" command: keystone-manage db_sync environment: "{{ bifrost_venv_env }}" - name: "Setup Fernet key repositories" command: > keystone-manage fernet_setup --keystone-user="{{ nginx_user }}" --keystone-group="{{ nginx_user }}" environment: "{{ bifrost_venv_env }}" - name: "Setup Keystone Credentials" command: > keystone-manage credential_setup --keystone-user="{{ nginx_user }}" --keystone-group="{{ nginx_user }}" environment: "{{ bifrost_venv_env }}" - name: "Setting external Keystone public URL" set_fact: keystone_public_url: "{{ api_protocol }}://{{ public_ip }}:5000/v3" when: public_ip is defined - name: "Setting internal Keystone URL" set_fact: keystone_private_url: "{{ api_protocol }}://{{ private_ip }}:5000/v3" when: private_ip is defined and private_ip | length > 0 - name: "Bootstrap Keystone Database" command: > keystone-manage bootstrap --bootstrap-username="{{ keystone.bootstrap.username }}" --bootstrap-password="{{ keystone.bootstrap.password }}" --bootstrap-project-name="{{ keystone.bootstrap.project_name }}" --bootstrap-service-name="keystone" --bootstrap-admin-url="{{ keystone.bootstrap.admin_url | default(keystone_api_url) }}" --bootstrap-public-url="{{ keystone.bootstrap.public_url | default(keystone_public_url) | default(keystone_api_url) }}" --bootstrap-internal-url="{{ keystone.bootstrap.internal_url | default(keystone_private_url) | default(keystone_api_url) }}" --bootstrap-region-id="{{ keystone.bootstrap.region_name }}" environment: "{{ bifrost_venv_env }}" when: - test_created_keystone_db.changed - keystone.bootstrap.enabled | bool - keystone.database.host == 'localhost' - name: "Reserve keystone admin port" sysctl: name: "net.ipv4.ip_local_reserved_ports" value: 35357 sysctl_set: yes state: present reload: yes - name: "Ensure /var/www/keystone exists" file: name: "/var/www/keystone" state: directory owner: "keystone" group: "{{ nginx_user }}" # TODO(TheJulia): Split webserver user/group. mode: 0755 - name: "Add keystone to web server group" user: name: "keystone" append: yes groups: "{{ nginx_user }}" # TODO(TheJulia): Split webserver user/group. - name: "Make folder for keystone logs" file: name: "/var/log/nginx/keystone" state: directory owner: "{{ nginx_user }}" group: "{{ nginx_user }}" # TODO(TheJulia): Split webserver user/group. mode: 0755 # Note(ashestakov): "copy" module in ansible doesn't support recursive # copying on remote host. "cp" command used instead. - name: "Copy keystone-wsgi-public to /var/www/keystone/public" command: cp -r "{{ keystone_install_prefix.stdout }}/keystone-wsgi-public" /var/www/keystone/public - name: "Ensure owner and mode of keystone-wsgi-public" file: path: /var/www/keystone/public owner: "keystone" group: "{{ nginx_user }}" mode: 0754 # Note(ashestakov): "copy" module in ansible doesn't support recursive # copying on remote host. "cp" command used instead. - name: "Copy keystone-wsgi-admin to /var/www/keystone/admin" command: cp -r "{{ keystone_install_prefix.stdout }}/keystone-wsgi-admin" /var/www/keystone/admin - name: "Ensure owner and mode of keystone-wsgi-admin" file: path: /var/www/keystone/admin owner: "keystone" group: "{{ nginx_user }}" mode: 0754 - name: "Ensure /etc/uwsgi exists" file: name: "/etc/uwsgi" state: directory owner: "{{ nginx_user }}" group: "{{ nginx_user }}" # TODO(TheJulia): Split webserver user/group. mode: 0755 - name: "Ensure /etc/uwsgi/apps-available exists" file: name: "/etc/uwsgi/apps-available" state: directory owner: "{{ nginx_user }}" group: "{{ nginx_user }}" # TODO(TheJulia): Split webserver user/group. mode: 0755 - name: "Ensure /etc/uwsgi/apps-enabled exists" file: name: "/etc/uwsgi/apps-enabled" state: directory owner: "{{ nginx_user }}" group: "{{ nginx_user }}" # TODO(TheJulia): Split webserver user/group. mode: 0755 - name: "Place keystone public uwsgi config" template: src: keystone-public.ini.j2 dest: /etc/uwsgi/apps-available/keystone-public.ini owner: "{{ nginx_user }}" group: "{{ nginx_user }}" # TODO(TheJulia): Split webserver user/group. mode: 0755 - name: "Place keystone admin uwsgi config" template: src: keystone-admin.ini.j2 dest: /etc/uwsgi/apps-available/keystone-admin.ini owner: "{{ nginx_user }}" group: "{{ nginx_user }}" # TODO(TheJulia): Split webserver user/group. mode: 0755 - name: "Enable keystone-public in uwsgi" file: src: "/etc/uwsgi/apps-available/keystone-public.ini" dest: "/etc/uwsgi/apps-enabled/keystone-public.ini" state: link - name: "Enable keystone-admin in uwsgi" file: src: "/etc/uwsgi/apps-available/keystone-admin.ini" dest: "/etc/uwsgi/apps-enabled/keystone-admin.ini" state: link - name: "Place nginx core configuration" # TODO(TheJulia): Refactor this out so we don't have anything related to # bifrost it's self in the main config file. template: src: nginx.conf.j2 dest: /etc/nginx/nginx.conf owner: "{{ nginx_user }}" group: "{{ nginx_user }}" # TODO(TheJulia): Split webserver user/group. mode: 0755 - name: "Place nginx configuration for keystone" # TODO(TheJulia): Refactor this so we use sites-enabled, but bifrost's # handling of co-existence needs to be cleaned up first. template: src: nginx_conf.d_bifrost-keystone.conf.j2 dest: /etc/nginx/conf.d/bifrost-keystone.conf owner: "{{ nginx_user }}" group: "{{ nginx_user }}" # TODO(TheJulia): Split webserver user/group. mode: 0755 - name: "Place uwsgi services" template: src: systemd_template.j2 dest: "{{ init_dest_dir }}{{ item.service_name }}.service" owner: "root" group: "root" loop: - { service_path: "{{ uwsgi_install_prefix.stdout | default('') }}", service_name: 'uwsgi', username: "{{ nginx_user }}", exec_start_pre: "/usr/bin/install -m 755 -o {{ nginx_user }} -g {{ nginx_user }} -d /run/uwsgi", args: '--master --emperor /etc/uwsgi/apps-enabled'} # TODO(TheJulia): Split webserver user/group. - block: - name: "Explicitly allow keystone port (TCP) on selinux" seport: ports: "5000" proto: tcp setype: http_port_t state: present - name: Copy keystone policy file to temporary directory copy: src: keystone_policy.te dest: /tmp/keystone_policy.te - name: Check keystone policy module command: checkmodule -M -m -o /tmp/keystone_policy.mod /tmp/keystone_policy.te - name: Package keystone policy module command: semodule_package -m /tmp/keystone_policy.mod -o /tmp/keystone_policy.pp - name: Include keystone policy module command: semodule -i /tmp/keystone_policy.pp - name: Enable keystone policy module command: semodule -e keystone_policy when: (ansible_os_family == 'RedHat' or ansible_os_family == 'Suse') and ansible_selinux.status == 'enabled' and ansible_selinux.mode == "enforcing"