diff --git a/docker/placement-api/Dockerfile.j2 b/docker/placement-api/Dockerfile.j2
new file mode 100644
index 0000000..baca8bc
--- /dev/null
+++ b/docker/placement-api/Dockerfile.j2
@@ -0,0 +1,12 @@
+FROM {{ image_spec("nova-base") }}
+MAINTAINER {{ maintainer }}
+
+COPY daemon.sh /usr/local/bin/daemon.sh
+
+RUN apt-get install -y --no-install-recommends \
+ apache2 \
+ libapache2-mod-wsgi \
+ && apt-get clean \
+ && chmod 755 /usr/local/bin/daemon.sh \
+ && usermod -aG www-data nova \
+ && echo > /etc/apache2/ports.conf
diff --git a/docker/placement-api/daemon.sh b/docker/placement-api/daemon.sh
new file mode 100644
index 0000000..ead747d
--- /dev/null
+++ b/docker/placement-api/daemon.sh
@@ -0,0 +1,4 @@
+#!/bin/bash -ex
+
+source /etc/apache2/envvars
+/usr/sbin/apache2 -DNO_DETACH
diff --git a/service/files/apache-placement-api.conf.j2 b/service/files/apache-placement-api.conf.j2
new file mode 100644
index 0000000..1a91741
--- /dev/null
+++ b/service/files/apache-placement-api.conf.j2
@@ -0,0 +1,25 @@
+Listen {{ placement.port.cont }}
+
+ WSGIDaemonProcess placement-api processes={{ placement.wsgi.processes }} threads={{ placement.wsgi.threads }} user=nova display-name=%{GROUP} python-path=/var/lib/microservices/venv/lib/python2.7/site-packages
+ WSGIProcessGroup placement-api
+ WSGIScriptAlias / /var/lib/microservices/venv/bin/nova-placement-api
+ WSGIApplicationGroup %{GLOBAL}
+ WSGIPassAuthorization On
+ = 2.4>
+ ErrorLogFormat "%M"
+
+
+ Order allow,deny
+ Allow from all
+ Require all granted
+
+
+
+Alias /placement /var/lib/microservices/venv/bin/nova-placement-api
+
+ SetHandler wsgi-script
+ Options +ExecCGI
+ WSGIProcessGroup placement-api
+ WSGIApplicationGroup %{GLOBAL}
+ WSGIPassAuthorization On
+
diff --git a/service/files/defaults.yaml b/service/files/defaults.yaml
index 2dce4b9..33c97f8 100644
--- a/service/files/defaults.yaml
+++ b/service/files/defaults.yaml
@@ -214,10 +214,24 @@ configs:
ram: 16384
disk: 160
vcpus: 8
+ placement:
+ enabled: true
+ port:
+ cont: 8780
+ ingress: placement
+ wsgi:
+ processes: 4
+ threads: 4
versions:
novnc_version: "0.6.1"
+secret_configs:
+ placement:
+ account:
+ username: placement
+ password: password
+
sources:
openstack/nova:
git_url: https://git.openstack.org/openstack/nova.git
diff --git a/service/files/nova.conf.j2 b/service/files/nova.conf.j2
index 19b7255..aa9dd71 100644
--- a/service/files/nova.conf.j2
+++ b/service/files/nova.conf.j2
@@ -196,6 +196,20 @@ driver = {{ searchlight.notification_driver }}
notify_on_state_change = vm_and_task_state
{% endif %}
+{% if placement.enabled %}
+[placement]
+auth_uri = {{ address("keystone", keystone.public_port, with_scheme=True) }}
+auth_url = {{ address("keystone", keystone.admin_port, with_scheme=True) }}
+auth_type = password
+project_domain_name = {{ service_account.domain }}
+user_domain_name = {{ service_account.domain }}
+project_name = {{ service_account.project }}
+username = {{ placement.account.username }}
+password = {{ placement.account.password }}
+memcached_servers = {{ address("memcached", memcached.port) }}
+os_region_name = RegionOne
+{% endif %}
+
{# messaging macros templates #}
{{ oslo_messaging[messaging.backend.notifications]('notifications_config') }}
{{ oslo_messaging[messaging.backend.rpc]('rpc_config') }}
diff --git a/service/placement-api.yaml b/service/placement-api.yaml
new file mode 100644
index 0000000..b2bd565
--- /dev/null
+++ b/service/placement-api.yaml
@@ -0,0 +1,59 @@
+dsl_version: 0.4.0
+service:
+ name: placement-api
+ ports:
+ - {{ placement.port }}
+ annotations:
+ service:
+ prometheus.io/probe: "true"
+ containers:
+ - name: placement-api
+ image: placement-api
+ pre:
+ - name: placement-user-create
+ type: single
+ command: openstack user create --domain {{ service_account.domain }} --password {{ placement.account.password }} {{ placement.account.username }}
+ dependencies:
+ - keystone-create-domain
+ - name: placement-role-add
+ dependencies:
+ - keystone-create-project
+ - placement-user-create
+ type: single
+ command: openstack role add --project {{ service_account.project }} --user {{ placement.account.username }} admin
+ - name: placement-service-create
+ dependencies:
+ - keystone
+ type: single
+ command: openstack service create --name nova --description "Placement Service" placement
+ - name: placement-public-endpoint-create
+ dependencies:
+ - placement-service-create
+ type: single
+ command: openstack endpoint create --region RegionOne placement public {{ address('placement-api', placement.port, external=True, with_scheme=True) }}/placement
+ - name: placement-internal-endpoint-create
+ dependencies:
+ - placement-service-create
+ type: single
+ command: openstack endpoint create --region RegionOne placement internal {{ address('placement-api', placement.port, with_scheme=True) }}/placement
+ - name: placement-admin-endpoint-create
+ dependencies:
+ - placement-service-create
+ type: single
+ command: openstack endpoint create --region RegionOne placement admin {{ address('placement-api', placement.port, with_scheme=True) }}/placement
+
+ daemon:
+ command: daemon.sh
+ files:
+ - nova.conf
+ - apache-placement-api.conf
+
+files:
+ nova.conf:
+ path: /etc/nova/nova.conf
+ content: nova.conf.j2
+ perm: "0644"
+ apache-placement-api.conf:
+ path: /etc/apache2/conf-enabled/nova-placement-api.conf
+ content: apache-placement-api.conf.j2
+ perm: "0600"