aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2015-08-06 18:45:28 +0000
committerGerrit Code Review <review@openstack.org>2015-08-06 18:45:28 +0000
commit97be8d12148bd61e6d85a8001a13a871b1be31d8 (patch)
tree23210dbfdb27647682d632252d69160b8e454154
parenta5fa276c3a8f30a25e009d69ee93a80635337caa (diff)
parent98a379b0fd0c24da6bfc5b9828aa5e734788c9bc (diff)
downloadkolla-97be8d12148bd61e6d85a8001a13a871b1be31d8.tar.gz
kolla-97be8d12148bd61e6d85a8001a13a871b1be31d8.zip
Merge "Reduce dependencies on the dest nodes"
-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