aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Yaple <sam@yaple.net>2015-08-03 07:50:01 +0000
committerSam Yaple <sam@yaple.net>2015-08-06 01:32:05 +0000
commit98a379b0fd0c24da6bfc5b9828aa5e734788c9bc (patch)
treecc1fa705cf662e96af031756f03744206e122f75
parent12b70241badd498ed3bfda3788ea5597898e99cb (diff)
downloadkolla-98a379b0fd0c24da6bfc5b9828aa5e734788c9bc.tar.gz
kolla-98a379b0fd0c24da6bfc5b9828aa5e734788c9bc.zip
Reduce dependencies on the dest nodes
Currently we require a slew of deps on each destination node, this includes a gcc compiler and installing things via pip. We can remove these dependencies by containerizing them and running and Ansible inside the container itself. The container would then report back facts about idempotency. DocImpact Closes-Bug: #1481495 Implements: blueprint containerize-dependencies Change-Id: I3dfccbf9fafc06ffc36e78f3006fe5d3367891df
-rw-r--r--ansible/roles/bootstrap.yml41
-rw-r--r--ansible/roles/common/defaults/main.yml13
-rw-r--r--ansible/roles/common/tasks/main.yml2
-rw-r--r--ansible/roles/common/tasks/start.yml9
-rw-r--r--ansible/roles/glance/defaults/main.yml2
-rw-r--r--ansible/roles/glance/meta/main.yml3
-rw-r--r--ansible/roles/glance/tasks/register.yml48
-rw-r--r--ansible/roles/haproxy/meta/main.yml3
-rw-r--r--ansible/roles/keystone/meta/main.yml3
-rw-r--r--ansible/roles/mariadb/meta/main.yml3
-rw-r--r--ansible/roles/mariadb/tasks/register.yml36
-rw-r--r--ansible/roles/neutron/defaults/main.yml2
-rw-r--r--ansible/roles/neutron/meta/main.yml3
-rw-r--r--ansible/roles/neutron/tasks/register.yml48
-rw-r--r--ansible/roles/nova/defaults/main.yml2
-rw-r--r--ansible/roles/nova/meta/main.yml3
-rw-r--r--ansible/roles/nova/tasks/register.yml49
-rw-r--r--ansible/roles/rabbitmq/meta/main.yml3
-rw-r--r--ansible/roles/start.yml4
-rw-r--r--docker/centos/binary/kolla-ansible/Dockerfile27
l---------docker/centos/binary/kolla-ansible/build1
-rw-r--r--docker/centos/binary/kolla-ansible/kolla_keystone_service.py (renamed from ansible/library/kolla_keystone_service.py)0
-rw-r--r--docker/centos/binary/kolla-ansible/kolla_keystone_user.py (renamed from ansible/library/kolla_keystone_user.py)0
-rw-r--r--docs/minimal-environment-vars.md4
-rw-r--r--tox.ini2
25 files changed, 230 insertions, 81 deletions
diff --git a/ansible/roles/bootstrap.yml b/ansible/roles/bootstrap.yml
index 4b1aa5662..84799d7d8 100644
--- a/ansible/roles/bootstrap.yml
+++ b/ansible/roles/bootstrap.yml
@@ -1,38 +1,45 @@
---
- name: Creating database
- mysql_db:
- login_host: "{{ database_address }}"
- login_user: "{{ database_user }}"
- login_password: "{{ database_password }}"
- name: "{{ service_database_name }}"
+ command: docker exec -t kolla_ansible /usr/bin/ansible localhost
+ -m mysql_db
+ -a "login_host='{{ database_address }}'
+ login_user='{{ database_user }}'
+ login_password='{{ database_password }}'
+ name='{{ service_database_name }}'"
register: database
+ changed_when: "{{ database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed }}"
+ failed_when: database.stdout.split()[2] != 'SUCCESS'
run_once: True
- name: Creating database user and setting permissions
- mysql_user:
- login_host: "{{ database_address }}"
- login_user: "{{ database_user }}"
- login_password: "{{ database_password }}"
- name: "{{ service_database_name }}"
- password: "{{ service_database_password }}"
- host: "%"
- priv: "{{ service_database_name }}.*:ALL"
- append_privs: "yes"
+ command: docker exec -t kolla_ansible /usr/bin/ansible localhost
+ -m mysql_user
+ -a "login_host='{{ database_address }}'
+ login_user='{{ database_user }}'
+ login_password='{{ database_password }}'
+ name='{{ service_database_name }}'
+ password='{{ service_database_password }}'
+ host='%'
+ priv='{{ service_database_name }}.*:ALL'
+ append_privs='yes'"
+ register: database_user
+ changed_when: "{{ database.stdout.find('localhost | SUCCESS => ') != -1 and (database_user.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed }}"
+ failed_when: database_user.stdout.split()[2] != 'SUCCESS'
run_once: True
- include: start.yml
vars:
run_once: True
- when: database|changed
+ when: database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed
# https://github.com/ansible/ansible-modules-core/pull/1031
- name: Waiting for bootstrap container to exit
command: docker wait "{{ container_name }}"
- when: database|changed
+ when: database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed
- name: Cleaning up boostrap container
docker:
name: "{{ container_name }}"
image: "{{ container_image }}"
state: "absent"
- when: database|changed
+ when: database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed
diff --git a/ansible/roles/common/defaults/main.yml b/ansible/roles/common/defaults/main.yml
new file mode 100644
index 000000000..e6a59a4fe
--- /dev/null
+++ b/ansible/roles/common/defaults/main.yml
@@ -0,0 +1,13 @@
+---
+####################
+# Docker
+####################
+docker_ansible_registry: "{{ docker_registry ~ '/' if docker_registry else '' }}"
+docker_ansible_namespace: "{{ docker_namespace }}"
+kolla_ansible_base_distro: "{{ kolla_base_distro }}"
+kolla_ansible_install_type: "{{ kolla_install_type }}"
+kolla_ansible_container_name: "kolla-ansible"
+
+docker_ansible_image: "{{ docker_ansible_registry }}{{ docker_ansible_namespace }}/{{ kolla_ansible_base_distro }}-{{ kolla_ansible_install_type }}-{{ kolla_ansible_container_name }}"
+docker_ansible_tag: "{{ openstack_release }}"
+docker_ansible_image_full: "{{ docker_ansible_image }}:{{ docker_ansible_tag }}"
diff --git a/ansible/roles/common/tasks/main.yml b/ansible/roles/common/tasks/main.yml
new file mode 100644
index 000000000..50662fbc5
--- /dev/null
+++ b/ansible/roles/common/tasks/main.yml
@@ -0,0 +1,2 @@
+---
+- include: start.yml
diff --git a/ansible/roles/common/tasks/start.yml b/ansible/roles/common/tasks/start.yml
new file mode 100644
index 000000000..b63722b97
--- /dev/null
+++ b/ansible/roles/common/tasks/start.yml
@@ -0,0 +1,9 @@
+---
+- include: ../../start.yml
+ vars:
+ container_command: "/bin/sleep infinity"
+ container_environment:
+ ANSIBLE_NOCOLOR: "1"
+ ANSIBLE_LIBRARY: "/usr/share/ansible"
+ container_image: "{{ docker_ansible_image_full }}"
+ container_name: "kolla_ansible"
diff --git a/ansible/roles/glance/defaults/main.yml b/ansible/roles/glance/defaults/main.yml
index 8c33f9d75..60b404ac0 100644
--- a/ansible/roles/glance/defaults/main.yml
+++ b/ansible/roles/glance/defaults/main.yml
@@ -44,3 +44,5 @@ glance_logging_verbose: "{{ openstack_logging_verbose }}"
glance_logging_debug: "{{ openstack_logging_debug }}"
glance_keystone_user: "glance"
+
+openstack_glance_auth: "{'auth_url':'{{ openstack_auth_v2.auth_url }}','username':'{{ openstack_auth_v2.username }}','password':'{{ openstack_auth_v2.password }}','project_name':'{{ openstack_auth_v2.project_name }}'}"
diff --git a/ansible/roles/glance/meta/main.yml b/ansible/roles/glance/meta/main.yml
new file mode 100644
index 000000000..6b4fff8fe
--- /dev/null
+++ b/ansible/roles/glance/meta/main.yml
@@ -0,0 +1,3 @@
+---
+dependencies:
+ - { role: common }
diff --git a/ansible/roles/glance/tasks/register.yml b/ansible/roles/glance/tasks/register.yml
index cda1ff182..f5655e63e 100644
--- a/ansible/roles/glance/tasks/register.yml
+++ b/ansible/roles/glance/tasks/register.yml
@@ -1,23 +1,37 @@
---
- name: Creating the Glance service and endpoint
- kolla_keystone_service:
- service_name: "glance"
- service_type: "image"
- description: "Openstack Image"
- endpoint_region: "{{ openstack_region_name }}"
- admin_url: "http://{{ kolla_internal_address }}:{{ glance_api_port }}"
- internal_url: "http://{{ kolla_internal_address }}:{{ glance_api_port }}"
- public_url: "http://{{ kolla_external_address }}:{{ glance_api_port }}"
- auth: "{{ openstack_auth_v2 }}"
- region_name: "{{ openstack_region_name }}"
+ command: docker exec -t kolla_ansible /usr/bin/ansible localhost
+ -m kolla_keystone_service
+ -a "service_name=glance
+ service_type=image
+ description='Openstack Image'
+ endpoint_region={{ openstack_region_name }}
+ admin_url='http://{{ kolla_internal_address }}:{{ glance_api_port }}'
+ internal_url='http://{{ kolla_internal_address }}:{{ glance_api_port }}'
+ public_url='http://{{ kolla_external_address }}:{{ glance_api_port }}'
+ region_name={{ openstack_region_name }}
+ auth={{ '{{ openstack_glance_auth }}' }}"
+ -e "{'openstack_glance_auth':{{ openstack_glance_auth }}}"
+ register: glance_endpoint
+ changed_when: "{{ glance_endpoint.stdout.find('localhost | SUCCESS => ') != -1 and (glance_endpoint.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed }}"
+ until: glance_endpoint.stdout.split()[2] == 'SUCCESS'
+ retries: 10
+ delay: 5
run_once: True
- name: Creating the Glance project, user, and role
- kolla_keystone_user:
- project: "service"
- user: "glance"
- password: "{{ glance_keystone_password }}"
- role: "admin"
- auth: "{{ openstack_auth_v2 }}"
- region_name: "{{ openstack_region_name }}"
+ command: docker exec -t kolla_ansible /usr/bin/ansible localhost
+ -m kolla_keystone_user
+ -a "project=service
+ user=glance
+ password={{ glance_keystone_password }}
+ role=admin
+ region_name={{ openstack_region_name }}
+ auth={{ '{{ openstack_glance_auth }}' }}"
+ -e "{'openstack_glance_auth':{{ openstack_glance_auth }}}"
+ register: glance_user
+ changed_when: "{{ glance_user.stdout.find('localhost | SUCCESS => ') != -1 and (glance_user.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed }}"
+ until: glance_user.stdout.split()[2] == 'SUCCESS'
+ retries: 10
+ delay: 5
run_once: True
diff --git a/ansible/roles/haproxy/meta/main.yml b/ansible/roles/haproxy/meta/main.yml
new file mode 100644
index 000000000..6b4fff8fe
--- /dev/null
+++ b/ansible/roles/haproxy/meta/main.yml
@@ -0,0 +1,3 @@
+---
+dependencies:
+ - { role: common }
diff --git a/ansible/roles/keystone/meta/main.yml b/ansible/roles/keystone/meta/main.yml
new file mode 100644
index 000000000..6b4fff8fe
--- /dev/null
+++ b/ansible/roles/keystone/meta/main.yml
@@ -0,0 +1,3 @@
+---
+dependencies:
+ - { role: common }
diff --git a/ansible/roles/mariadb/meta/main.yml b/ansible/roles/mariadb/meta/main.yml
new file mode 100644
index 000000000..6b4fff8fe
--- /dev/null
+++ b/ansible/roles/mariadb/meta/main.yml
@@ -0,0 +1,3 @@
+---
+dependencies:
+ - { role: common }
diff --git a/ansible/roles/mariadb/tasks/register.yml b/ansible/roles/mariadb/tasks/register.yml
index c7382ff88..5462aa4ce 100644
--- a/ansible/roles/mariadb/tasks/register.yml
+++ b/ansible/roles/mariadb/tasks/register.yml
@@ -1,15 +1,31 @@
---
+- include: ../../start.yml
+ vars:
+ container_environment:
+ KOLLA_BOOTSTRAP:
+ KOLLA_CONFIG_STRATEGY: "{{ config_strategy }}"
+ DB_ROOT_PASSWORD: "{{ database_password }}"
+ container_image: "{{ docker_database_image_full }}"
+ container_name: "mariadb"
+ container_restart_policy: "no"
+ container_volumes:
+ - "{{ node_config_directory }}/mariadb/:/opt/kolla/mariadb/:ro"
+ container_volumes_from:
+ - "mariadb_data"
+ when: delegate_host == 'None' and inventory_hostname == groups['mariadb'][0]
+
- name: Creating haproxy mysql user
- mysql_user:
- login_host: "{{ hostvars[inventory_hostname]['ansible_' + api_interface]['ipv4']['address'] }}"
- login_user: "{{ database_user }}"
- login_password: "{{ database_password }}"
- name: "haproxy"
- password: ""
- host: "%"
- priv: "*.*:USAGE"
- register: status
- until: status|success
+ command: docker exec -t kolla_ansible /usr/bin/ansible localhost
+ -m mysql_user
+ -a "login_host='{{ hostvars[inventory_hostname]['ansible_' + api_interface]['ipv4']['address'] }}'
+ login_user='{{ database_user }}'
+ login_password='{{ database_password }}'
+ name='haproxy'
+ password=''
+ host='%'"
+ register: haproxy_user
+ changed_when: "{{ (haproxy_user.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed }}"
+ until: haproxy_user.stdout.split()[2] == 'SUCCESS'
retries: 10
delay: 5
diff --git a/ansible/roles/neutron/defaults/main.yml b/ansible/roles/neutron/defaults/main.yml
index 432eaee34..22475f205 100644
--- a/ansible/roles/neutron/defaults/main.yml
+++ b/ansible/roles/neutron/defaults/main.yml
@@ -66,3 +66,5 @@ neutron_logging_debug: "{{ openstack_logging_debug }}"
neutron_keystone_user: "neutron"
neutron_bridge_name: "br-ex"
+
+openstack_neutron_auth: "{'auth_url':'{{ openstack_auth_v2.auth_url }}','username':'{{ openstack_auth_v2.username }}','password':'{{ openstack_auth_v2.password }}','project_name':'{{ openstack_auth_v2.project_name }}'}"
diff --git a/ansible/roles/neutron/meta/main.yml b/ansible/roles/neutron/meta/main.yml
new file mode 100644
index 000000000..6b4fff8fe
--- /dev/null
+++ b/ansible/roles/neutron/meta/main.yml
@@ -0,0 +1,3 @@
+---
+dependencies:
+ - { role: common }
diff --git a/ansible/roles/neutron/tasks/register.yml b/ansible/roles/neutron/tasks/register.yml
index 9f1d35a40..0f552638c 100644
--- a/ansible/roles/neutron/tasks/register.yml
+++ b/ansible/roles/neutron/tasks/register.yml
@@ -1,23 +1,37 @@
---
- name: Creating the Neutron service and endpoint
- kolla_keystone_service:
- service_name: "neutron"
- service_type: "network"
- description: "OpenStack Networking"
- endpoint_region: "{{ openstack_region_name }}"
- admin_url: "http://{{ kolla_internal_address }}:{{ neutron_server_port }}"
- internal_url: "http://{{ kolla_internal_address }}:{{ neutron_server_port }}"
- public_url: "http://{{ kolla_external_address }}:{{ neutron_server_port }}"
- auth: "{{ openstack_auth_v2 }}"
- region_name: "{{ openstack_region_name }}"
+ command: docker exec -t kolla_ansible /usr/bin/ansible localhost
+ -m kolla_keystone_service
+ -a "service_name=neutron
+ service_type=image
+ description='Openstack Networking'
+ endpoint_region={{ openstack_region_name }}
+ admin_url='http://{{ kolla_internal_address }}:{{ neutron_server_port }}'
+ internal_url='http://{{ kolla_internal_address }}:{{ neutron_server_port }}'
+ public_url='http://{{ kolla_external_address }}:{{ neutron_server_port }}'
+ region_name={{ openstack_region_name }}
+ auth={{ '{{ openstack_neutron_auth }}' }}"
+ -e "{'openstack_neutron_auth':{{ openstack_neutron_auth }}}"
+ register: neutron_endpoint
+ changed_when: "{{ neutron_endpoint.stdout.find('localhost | SUCCESS => ') != -1 and (neutron_endpoint.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed }}"
+ until: neutron_endpoint.stdout.split()[2] == 'SUCCESS'
+ retries: 10
+ delay: 5
run_once: True
- name: Creating the Neutron project, user, and role
- kolla_keystone_user:
- project: "service"
- user: "neutron"
- password: "{{ neutron_keystone_password }}"
- role: "admin"
- auth: "{{ openstack_auth_v2 }}"
- region_name: "{{ openstack_region_name }}"
+ command: docker exec -t kolla_ansible /usr/bin/ansible localhost
+ -m kolla_keystone_user
+ -a "project=service
+ user=neutron
+ password={{ neutron_keystone_password }}
+ role=admin
+ region_name={{ openstack_region_name }}
+ auth={{ '{{ openstack_neutron_auth }}' }}"
+ -e "{'openstack_neutron_auth':{{ openstack_neutron_auth }}}"
+ register: neutron_user
+ changed_when: "{{ neutron_user.stdout.find('localhost | SUCCESS => ') != -1 and (neutron_user.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed }}"
+ until: neutron_user.stdout.split()[2] == 'SUCCESS'
+ retries: 10
+ delay: 5
run_once: True
diff --git a/ansible/roles/nova/defaults/main.yml b/ansible/roles/nova/defaults/main.yml
index 9f3284f1c..7dbdc6b59 100644
--- a/ansible/roles/nova/defaults/main.yml
+++ b/ansible/roles/nova/defaults/main.yml
@@ -69,3 +69,5 @@ nova_logging_verbose: "{{ openstack_logging_verbose }}"
nova_logging_debug: "{{ openstack_logging_debug }}"
nova_keystone_user: "nova"
+
+openstack_nova_auth: "{'auth_url':'{{ openstack_auth_v2.auth_url }}','username':'{{ openstack_auth_v2.username }}','password':'{{ openstack_auth_v2.password }}','project_name':'{{ openstack_auth_v2.project_name }}'}"
diff --git a/ansible/roles/nova/meta/main.yml b/ansible/roles/nova/meta/main.yml
new file mode 100644
index 000000000..6b4fff8fe
--- /dev/null
+++ b/ansible/roles/nova/meta/main.yml
@@ -0,0 +1,3 @@
+---
+dependencies:
+ - { role: common }
diff --git a/ansible/roles/nova/tasks/register.yml b/ansible/roles/nova/tasks/register.yml
index 0b976c8c8..8a82319f2 100644
--- a/ansible/roles/nova/tasks/register.yml
+++ b/ansible/roles/nova/tasks/register.yml
@@ -1,23 +1,38 @@
---
- name: Creating the Nova service and endpoint
- kolla_keystone_service:
- service_name: "nova"
- service_type: "compute"
- description: "Openstack Compute"
- endpoint_region: "{{ openstack_region_name }}"
- admin_url: "http://{{ kolla_internal_address }}:{{ nova_api_port }}/v2/%(tenant_id)s"
- internal_url: "http://{{ kolla_internal_address }}:{{ nova_api_port }}/v2/%(tenant_id)s"
- public_url: "http://{{ kolla_external_address }}:{{ nova_api_port }}/v2/%(tenant_id)s"
- auth: "{{ openstack_auth_v2 }}"
- region_name: "{{ openstack_region_name }}"
+ command: docker exec -t kolla_ansible /usr/bin/ansible localhost
+ -m kolla_keystone_service
+ -a "service_name=nova
+ service_type=compute
+ description='Openstack Compute'
+ endpoint_region={{ openstack_region_name }}
+ admin_url='http://{{ kolla_internal_address }}:{{ nova_api_port }}/v2/%(tenant_id)s'
+ internal_url='http://{{ kolla_internal_address }}:{{ nova_api_port }}/v2/%(tenant_id)s'
+ public_url='http://{{ kolla_external_address }}:{{ nova_api_port }}/v2/%(tenant_id)s'
+ region_name={{ openstack_region_name }}
+ auth={{ '{{ openstack_nova_auth }}' }}"
+ -e "{'openstack_nova_auth':{{ openstack_nova_auth }}}"
+ register: nova_endpoint
+ changed_when: "{{ nova_endpoint.stdout.find('localhost | SUCCESS => ') != -1 and (nova_endpoint.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed }}"
+ until: nova_endpoint.stdout.split()[2] == 'SUCCESS'
+ retries: 10
+ delay: 5
run_once: True
+
- name: Creating the Nova project, user, and role
- kolla_keystone_user:
- project: "service"
- user: "nova"
- password: "{{ nova_keystone_password }}"
- role: "admin"
- auth: "{{ openstack_auth_v2 }}"
- region_name: "{{ openstack_region_name }}"
+ command: docker exec -t kolla_ansible /usr/bin/ansible localhost
+ -m kolla_keystone_user
+ -a "project=service
+ user=nova
+ password={{ nova_keystone_password }}
+ role=admin
+ region_name={{ openstack_region_name }}
+ auth={{ '{{ openstack_nova_auth }}' }}"
+ -e "{'openstack_nova_auth':{{ openstack_nova_auth }}}"
+ register: nova_user
+ changed_when: "{{ nova_user.stdout.find('localhost | SUCCESS => ') != -1 and (nova_user.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed }}"
+ until: nova_user.stdout.split()[2] == 'SUCCESS'
+ retries: 10
+ delay: 5
run_once: True
diff --git a/ansible/roles/rabbitmq/meta/main.yml b/ansible/roles/rabbitmq/meta/main.yml
new file mode 100644
index 000000000..6b4fff8fe
--- /dev/null
+++ b/ansible/roles/rabbitmq/meta/main.yml
@@ -0,0 +1,3 @@
+---
+dependencies:
+ - { role: common }
diff --git a/ansible/roles/start.yml b/ansible/roles/start.yml
index 26262bd3d..cdad31d4d 100644
--- a/ansible/roles/start.yml
+++ b/ansible/roles/start.yml
@@ -27,7 +27,7 @@
restart_policy_retry: "{{ docker_restart_policy_retry }}"
state: "reloaded"
username: "{{ docker_registry_username }}"
- volumes: "{{ container_volumes }}"
+ volumes: "{{ container_volumes | default([]) }}"
volumes_from: "{{ container_volumes_from | default([]) }}"
run_once: "{{ run_once | default('False') }}"
when: not container_pid|default(False)
@@ -51,7 +51,7 @@
restart_policy_retry: "{{ docker_restart_policy_retry }}"
state: "reloaded"
username: "{{ docker_registry_username }}"
- volumes: "{{ container_volumes }}"
+ volumes: "{{ container_volumes | default([]) }}"
volumes_from: "{{ container_volumes_from | default([]) }}"
run_once: "{{ run_once | default('False') }}"
when: container_pid|default(False)
diff --git a/docker/centos/binary/kolla-ansible/Dockerfile b/docker/centos/binary/kolla-ansible/Dockerfile
new file mode 100644
index 000000000..9368eb786
--- /dev/null
+++ b/docker/centos/binary/kolla-ansible/Dockerfile
@@ -0,0 +1,27 @@
+FROM %%KOLLA_NAMESPACE%%/%%KOLLA_PREFIX%%base:%%KOLLA_TAG%%
+MAINTAINER Kolla Project (https://launchpad.net/kolla)
+
+RUN yum -y install \
+ git \
+ gcc \
+ libffi-devel \
+ libxml2-devel \
+ libxslt-devel \
+ MySQL-python \
+ openssl-devel \
+ python-devel \
+ openssh-clients \
+ && yum clean all
+
+RUN pip install -U pip wheel \
+ && pip install python-openstackclient shade
+
+RUN git clone https://github.com/ansible/ansible.git \
+ && cd ansible \
+ && git submodule update --init --recursive \
+ && pip install .
+
+RUN mkdir -p /etc/ansible /usr/share/ansible \
+ && echo 'localhost ansible_connection=local' > /etc/ansible/hosts
+
+COPY kolla_keystone_service.py kolla_keystone_user.py /usr/share/ansible/
diff --git a/docker/centos/binary/kolla-ansible/build b/docker/centos/binary/kolla-ansible/build
new file mode 120000
index 000000000..8d652f7ee
--- /dev/null
+++ b/docker/centos/binary/kolla-ansible/build
@@ -0,0 +1 @@
+../../../../tools/build-docker-image \ No newline at end of file
diff --git a/ansible/library/kolla_keystone_service.py b/docker/centos/binary/kolla-ansible/kolla_keystone_service.py
index 455aaf578..455aaf578 100644
--- a/ansible/library/kolla_keystone_service.py
+++ b/docker/centos/binary/kolla-ansible/kolla_keystone_service.py
diff --git a/ansible/library/kolla_keystone_user.py b/docker/centos/binary/kolla-ansible/kolla_keystone_user.py
index 5d295c1e2..5d295c1e2 100644
--- a/ansible/library/kolla_keystone_user.py
+++ b/docker/centos/binary/kolla-ansible/kolla_keystone_user.py
diff --git a/docs/minimal-environment-vars.md b/docs/minimal-environment-vars.md
index d9d41c481..f33e5a3c4 100644
--- a/docs/minimal-environment-vars.md
+++ b/docs/minimal-environment-vars.md
@@ -329,6 +329,10 @@ In order for each service to function, there is a minimum set of required variab
KEYSTONE_PUBLIC_SERVICE_HOST
PUBLIC_IP
+# Kolla-ansible
+
+ None
+
# Magnum-api
ADMIN_TENANT_NAME
diff --git a/tox.ini b/tox.ini
index 76b006c31..8f753782a 100644
--- a/tox.ini
+++ b/tox.ini
@@ -58,4 +58,4 @@ commands =
[flake8]
show-source = True
-exclude=.git,.tox,doc,ansible/library
+exclude=.git,.tox,doc,ansible/library,docker/centos/binary/kolla-ansible