diff options
author | Eric Sauer <etsauer@gmail.com> | 2016-12-21 10:37:40 -0500 |
---|---|---|
committer | Øystein Bedin <oybed@users.noreply.github.com> | 2016-12-21 08:37:40 -0700 |
commit | 11b48fe4e237950f9d9e9a0e66d8b15f48be1ea0 (patch) | |
tree | 37465841228605d501ef1761578856df90e45a22 /roles/openstack-stack | |
parent | 953e8a7403f49640c04175386eadda329e9fd4b0 (diff) | |
download | openshift-11b48fe4e237950f9d9e9a0e66d8b15f48be1ea0.tar.gz openshift-11b48fe4e237950f9d9e9a0e66d8b15f48be1ea0.tar.bz2 openshift-11b48fe4e237950f9d9e9a0e66d8b15f48be1ea0.tar.xz openshift-11b48fe4e237950f9d9e9a0e66d8b15f48be1ea0.zip |
Openstack heat (#2)
* Adding a role to invoke openstack heat
* Adding readme
* Pulling parameters out to inventory file
* start of end-to-end playbook
* More enhancements and refactoring to make dynamic inventory the driver for an openshift install
* Switching to variable substituted path to config.yaml playbook
* Changes to allow defining of number of nodes/infranodes.
* Added labels to inventory
* Start of end-to-end functionality
* Enhancements to support openstack heat provisioning
* Updating inventory sample to remove some deprecation warnings
* Working towards making the secure-registry role 'become' aware
* Fixing node labels and removing secure-registry as it's no longer needed
* No longer need insecure registry line, as installer will secure our registry
* Adjusted dynamic inventory to filter by clusterid
* Minor updates to dynamic inventory bug
* Adding a refactored sample inventory directory
* Refactoring playbooks for better directory structure, and to narrow down host groups
* Adding volume mounts to heat template
* Moving dns playbooks back to original location
* Fixing incorrect file path
* Cleaning up inventory samples
* One more hostname to clean up
* Changing var name
* changed openshift-provision to openshift-prep
* Adjusting current provision script to avoid breakage by new openstack-heat code
Diffstat (limited to 'roles/openstack-stack')
-rw-r--r-- | roles/openstack-stack/README.md | 9 | ||||
-rw-r--r-- | roles/openstack-stack/files/heat_stack.yaml | 684 | ||||
-rw-r--r-- | roles/openstack-stack/files/heat_stack_server.yaml | 156 | ||||
-rw-r--r-- | roles/openstack-stack/files/user-data | 13 | ||||
-rw-r--r-- | roles/openstack-stack/tasks/main.yml | 31 | ||||
l--------- | roles/openstack-stack/test/roles | 1 | ||||
-rw-r--r-- | roles/openstack-stack/test/stack-create-test.yml | 17 |
7 files changed, 911 insertions, 0 deletions
diff --git a/roles/openstack-stack/README.md b/roles/openstack-stack/README.md new file mode 100644 index 000000000..509c9de6c --- /dev/null +++ b/roles/openstack-stack/README.md @@ -0,0 +1,9 @@ +# Role openstack-stack + +Role for spinning up instances using OpenStack Heat. + +## To Test + +``` +ansible-playbook casl-ansible/roles/openstack-stack/test/stack-create-test.yml +``` diff --git a/roles/openstack-stack/files/heat_stack.yaml b/roles/openstack-stack/files/heat_stack.yaml new file mode 100644 index 000000000..058f7a7ad --- /dev/null +++ b/roles/openstack-stack/files/heat_stack.yaml @@ -0,0 +1,684 @@ +heat_template_version: 2014-10-16 + +description: OpenShift cluster + +parameters: + + cluster_env: + type: string + label: Cluster environment + description: Environment of the cluster + + cluster_id: + type: string + label: Cluster ID + description: Identifier of the cluster + + subnet_24_prefix: + type: string + label: subnet /24 prefix + description: /24 subnet prefix of the network of the cluster (dot separated number triplet) + + dns_nameservers: + type: comma_delimited_list + label: DNS nameservers list + description: List of DNS nameservers + + external_net: + type: string + label: External network + description: Name of the external network + default: external + + ssh_public_key: + type: string + label: SSH public key + description: SSH public key + hidden: true + + ssh_incoming: + type: string + label: Source of ssh connections + description: Source of legitimate ssh connections + default: 0.0.0.0/0 + + node_port_incoming: + type: string + label: Source of node port connections + description: Authorized sources targetting node ports + default: 0.0.0.0/0 + + num_etcd: + type: number + label: Number of etcd nodes + description: Number of etcd nodes + + num_masters: + type: number + label: Number of masters + description: Number of masters + + num_nodes: + type: number + label: Number of compute nodes + description: Number of compute nodes + + num_infra: + type: number + label: Number of infrastructure nodes + description: Number of infrastructure nodes + + num_dns: + type: number + label: Number of dns servers + description: Number of dns servers + + etcd_image: + type: string + label: Etcd image + description: Name of the image for the etcd servers + + master_image: + type: string + label: Master image + description: Name of the image for the master servers + + node_image: + type: string + label: Node image + description: Name of the image for the compute node servers + + infra_image: + type: string + label: Infra image + description: Name of the image for the infra node servers + + dns_image: + type: string + label: DNS image + description: Name of the image for the DNS server + + etcd_flavor: + type: string + label: Etcd flavor + description: Flavor of the etcd servers + + master_flavor: + type: string + label: Master flavor + description: Flavor of the master servers + + node_flavor: + type: string + label: Node flavor + description: Flavor of the compute node servers + + infra_flavor: + type: string + label: Infra flavor + description: Flavor of the infra node servers + + dns_flavor: + type: string + label: DNS flavor + description: Flavor of the DNS server + + master_volume_size: + type: number + description: Size of the volume to be created. + default: 5 + constraints: + - range: { min: 1, max: 1024 } + description: must be between 1 and 1024 Gb. + + app_volume_size: + type: number + description: Size of the volume to be created. + default: 5 + constraints: + - range: { min: 1, max: 1024 } + description: must be between 1 and 1024 Gb. + + infra_volume_size: + type: number + description: Size of the volume to be created. + default: 5 + constraints: + - range: { min: 1, max: 1024 } + description: must be between 1 and 1024 Gb. + + dns_volume_size: + type: number + description: Size of the volume to be created. + default: 5 + constraints: + - range: { min: 1, max: 1024 } + description: must be between 1 and 1024 Gb. + + etcd_volume_size: + type: number + description: Size of the volume to be created. + default: 5 + constraints: + - range: { min: 1, max: 1024 } + description: must be between 1 and 1024 Gb. + +outputs: + + etcd_names: + description: Name of the etcds + value: { get_attr: [ etcd, name ] } + + etcd_ips: + description: IPs of the etcds + value: { get_attr: [ etcd, private_ip ] } + + etcd_floating_ips: + description: Floating IPs of the etcds + value: { get_attr: [ etcd, floating_ip ] } + + master_names: + description: Name of the masters + value: { get_attr: [ masters, name ] } + + master_ips: + description: IPs of the masters + value: { get_attr: [ masters, private_ip ] } + + master_floating_ips: + description: Floating IPs of the masters + value: { get_attr: [ masters, floating_ip ] } + + node_names: + description: Name of the nodes + value: { get_attr: [ compute_nodes, name ] } + + node_ips: + description: IPs of the nodes + value: { get_attr: [ compute_nodes, private_ip ] } + + node_floating_ips: + description: Floating IPs of the nodes + value: { get_attr: [ compute_nodes, floating_ip ] } + + infra_names: + description: Name of the nodes + value: { get_attr: [ infra_nodes, name ] } + + infra_ips: + description: IPs of the nodes + value: { get_attr: [ infra_nodes, private_ip ] } + + infra_floating_ips: + description: Floating IPs of the nodes + value: { get_attr: [ infra_nodes, floating_ip ] } + + dns_name: + description: Name of the DNS + value: + get_attr: + - dns + - name + + dns_floating_ip: + description: Floating IP of the DNS + value: + get_attr: + - dns + - addresses + - str_replace: + template: openshift-ansible-cluster_id-net + params: + cluster_id: { get_param: cluster_id } + - 1 + - addr + +resources: + + net: + type: OS::Neutron::Net + properties: + name: + str_replace: + template: openshift-ansible-cluster_id-net + params: + cluster_id: { get_param: cluster_id } + + subnet: + type: OS::Neutron::Subnet + properties: + name: + str_replace: + template: openshift-ansible-cluster_id-subnet + params: + cluster_id: { get_param: cluster_id } + network: { get_resource: net } + cidr: + str_replace: + template: subnet_24_prefix.0/24 + params: + subnet_24_prefix: { get_param: subnet_24_prefix } + allocation_pools: + - start: + str_replace: + template: subnet_24_prefix.3 + params: + subnet_24_prefix: { get_param: subnet_24_prefix } + end: + str_replace: + template: subnet_24_prefix.254 + params: + subnet_24_prefix: { get_param: subnet_24_prefix } + dns_nameservers: + - 10.9.48.31 +# - { get_param: dns_nameservers } +# repeat: +# for_each: +# <%nameserver%>: { get_param: dns_nameservers } +# template: <%nameserver%> + + router: + type: OS::Neutron::Router + properties: + name: + str_replace: + template: openshift-ansible-cluster_id-router + params: + cluster_id: { get_param: cluster_id } + external_gateway_info: + network: { get_param: external_net } + + interface: + type: OS::Neutron::RouterInterface + properties: + router_id: { get_resource: router } + subnet_id: { get_resource: subnet } + +# keypair: +# type: OS::Nova::KeyPair +# properties: +# name: +# str_replace: +# template: openshift-ansible-cluster_id-keypair +# params: +# cluster_id: { get_param: cluster_id } +# public_key: { get_param: ssh_public_key } + + master-secgrp: + type: OS::Neutron::SecurityGroup + properties: + name: + str_replace: + template: openshift-ansible-cluster_id-master-secgrp + params: + cluster_id: { get_param: cluster_id } + description: + str_replace: + template: Security group for cluster_id OpenShift cluster master + params: + cluster_id: { get_param: cluster_id } + rules: + - direction: ingress + protocol: tcp + port_range_min: 22 + port_range_max: 22 + remote_ip_prefix: { get_param: ssh_incoming } + - direction: ingress + protocol: tcp + port_range_min: 4001 + port_range_max: 4001 + - direction: ingress + protocol: tcp + port_range_min: 8443 + port_range_max: 8443 + - direction: ingress + protocol: tcp + port_range_min: 8444 + port_range_max: 8444 + - direction: ingress + protocol: tcp + port_range_min: 53 + port_range_max: 53 + - direction: ingress + protocol: udp + port_range_min: 53 + port_range_max: 53 + - direction: ingress + protocol: tcp + port_range_min: 8053 + port_range_max: 8053 + - direction: ingress + protocol: udp + port_range_min: 8053 + port_range_max: 8053 + - direction: ingress + protocol: tcp + port_range_min: 24224 + port_range_max: 24224 + - direction: ingress + protocol: udp + port_range_min: 24224 + port_range_max: 24224 + - direction: ingress + protocol: tcp + port_range_min: 2224 + port_range_max: 2224 + - direction: ingress + protocol: udp + port_range_min: 5404 + port_range_max: 5404 + - direction: ingress + protocol: udp + port_range_min: 5405 + port_range_max: 5405 + - direction: ingress + protocol: tcp + port_range_min: 9090 + port_range_max: 9090 + + etcd-secgrp: + type: OS::Neutron::SecurityGroup + properties: + name: + str_replace: + template: openshift-ansible-cluster_id-etcd-secgrp + params: + cluster_id: { get_param: cluster_id } + description: + str_replace: + template: Security group for cluster_id etcd cluster + params: + cluster_id: { get_param: cluster_id } + rules: + - direction: ingress + protocol: tcp + port_range_min: 22 + port_range_max: 22 + remote_ip_prefix: { get_param: ssh_incoming } + - direction: ingress + protocol: tcp + port_range_min: 2379 + port_range_max: 2379 + remote_mode: remote_group_id + remote_group_id: { get_resource: master-secgrp } + - direction: ingress + protocol: tcp + port_range_min: 2380 + port_range_max: 2380 + remote_mode: remote_group_id + + node-secgrp: + type: OS::Neutron::SecurityGroup + properties: + name: + str_replace: + template: openshift-ansible-cluster_id-node-secgrp + params: + cluster_id: { get_param: cluster_id } + description: + str_replace: + template: Security group for cluster_id OpenShift cluster nodes + params: + cluster_id: { get_param: cluster_id } + rules: + - direction: ingress + protocol: tcp + port_range_min: 22 + port_range_max: 22 + remote_ip_prefix: { get_param: ssh_incoming } + - direction: ingress + protocol: tcp + port_range_min: 10250 + port_range_max: 10250 + remote_mode: remote_group_id + - direction: ingress + protocol: tcp + port_range_min: 10255 + port_range_max: 10255 + remote_mode: remote_group_id + - direction: ingress + protocol: udp + port_range_min: 10255 + port_range_max: 10255 + remote_mode: remote_group_id + - direction: ingress + protocol: udp + port_range_min: 4789 + port_range_max: 4789 + remote_mode: remote_group_id + - direction: ingress + protocol: tcp + port_range_min: 30000 + port_range_max: 32767 + remote_ip_prefix: { get_param: node_port_incoming } + + infra-secgrp: + type: OS::Neutron::SecurityGroup + properties: + name: + str_replace: + template: openshift-ansible-cluster_id-infra-secgrp + params: + cluster_id: { get_param: cluster_id } + description: + str_replace: + template: Security group for cluster_id OpenShift infrastructure cluster nodes + params: + cluster_id: { get_param: cluster_id } + rules: + - direction: ingress + protocol: tcp + port_range_min: 80 + port_range_max: 80 + - direction: ingress + protocol: tcp + port_range_min: 443 + port_range_max: 443 + + dns-secgrp: + type: OS::Neutron::SecurityGroup + properties: + name: + str_replace: + template: openshift-ansible-cluster_id-dns-secgrp + params: + cluster_id: { get_param: cluster_id } + description: + str_replace: + template: Security group for cluster_id cluster DNS + params: + cluster_id: { get_param: cluster_id } + rules: + - direction: ingress + protocol: tcp + port_range_min: 22 + port_range_max: 22 + remote_ip_prefix: { get_param: ssh_incoming } + - direction: ingress + protocol: udp + port_range_min: 53 + port_range_max: 53 + remote_ip_prefix: { get_param: node_port_incoming } + - direction: ingress + protocol: tcp + port_range_min: 53 + port_range_max: 53 + remote_ip_prefix: { get_param: node_port_incoming } + + etcd: + type: OS::Heat::ResourceGroup + properties: + count: { get_param: num_etcd } + resource_def: + type: heat_stack_server.yaml + properties: + name: + str_replace: + template: k8s_type-%index%.cluster_id.cluster_env + params: + cluster_id: { get_param: cluster_id } + k8s_type: etcd + cluster_env: { get_param: cluster_env } + cluster_env: { get_param: cluster_env } + cluster_id: { get_param: cluster_id } + type: etcd + image: { get_param: etcd_image } + flavor: { get_param: etcd_flavor } + key_name: { get_param: ssh_public_key } + net: { get_resource: net } + subnet: { get_resource: subnet } + secgrp: + - { get_resource: etcd-secgrp } + floating_network: { get_param: external_net } + net_name: + str_replace: + template: openshift-ansible-cluster_id-net + params: + cluster_id: { get_param: cluster_id } + volume_size: { get_param: etcd_volume_size } + depends_on: + - interface + + masters: + type: OS::Heat::ResourceGroup + properties: + count: { get_param: num_masters } + resource_def: + type: heat_stack_server.yaml + properties: + name: + str_replace: + template: k8s_type-%index%.cluster_id.cluster_env + params: + cluster_id: { get_param: cluster_id } + k8s_type: master + cluster_env: { get_param: cluster_env } + cluster_env: { get_param: cluster_env } + cluster_id: { get_param: cluster_id } + type: master + image: { get_param: master_image } + flavor: { get_param: master_flavor } + key_name: { get_param: ssh_public_key } + net: { get_resource: net } + subnet: { get_resource: subnet } + secgrp: + - { get_resource: master-secgrp } + - { get_resource: node-secgrp } + floating_network: { get_param: external_net } + net_name: + str_replace: + template: openshift-ansible-cluster_id-net + params: + cluster_id: { get_param: cluster_id } + volume_size: { get_param: master_volume_size } + depends_on: + - interface + + compute_nodes: + type: OS::Heat::ResourceGroup + properties: + count: { get_param: num_nodes } + resource_def: + type: heat_stack_server.yaml + properties: + name: + str_replace: + template: subtype-k8s_type-%index%.cluster_id.cluster_env + params: + cluster_id: { get_param: cluster_id } + k8s_type: node + subtype: app + cluster_env: { get_param: cluster_env } + cluster_env: { get_param: cluster_env } + cluster_id: { get_param: cluster_id } + type: node + subtype: app + image: { get_param: node_image } + flavor: { get_param: node_flavor } + key_name: { get_param: ssh_public_key } + net: { get_resource: net } + subnet: { get_resource: subnet } + secgrp: + - { get_resource: node-secgrp } + floating_network: { get_param: external_net } + net_name: + str_replace: + template: openshift-ansible-cluster_id-net + params: + cluster_id: { get_param: cluster_id } + volume_size: { get_param: app_volume_size } + depends_on: + - interface + + infra_nodes: + type: OS::Heat::ResourceGroup + properties: + count: { get_param: num_infra } + resource_def: + type: heat_stack_server.yaml + properties: + name: + str_replace: + template: subtypek8s_type-%index%.cluster_id.cluster_env + params: + cluster_id: { get_param: cluster_id } + k8s_type: node + subtype: infra + cluster_env: { get_param: cluster_env } + cluster_env: { get_param: cluster_env } + cluster_id: { get_param: cluster_id } + type: node + subtype: infra + image: { get_param: infra_image } + flavor: { get_param: infra_flavor } + key_name: { get_param: ssh_public_key } + net: { get_resource: net } + subnet: { get_resource: subnet } + secgrp: + - { get_resource: node-secgrp } + - { get_resource: infra-secgrp } + floating_network: { get_param: external_net } + net_name: + str_replace: + template: openshift-ansible-cluster_id-net + params: + cluster_id: { get_param: cluster_id } + volume_size: { get_param: infra_volume_size } + depends_on: + - interface + + dns: + type: OS::Heat::ResourceGroup + properties: + count: { get_param: num_dns } + resource_def: + type: heat_stack_server.yaml + properties: + name: + str_replace: + template: k8s_type-%index%.cluster_id.cluster_env + params: + cluster_id: { get_param: cluster_id } + k8s_type: dns + cluster_env: { get_param: cluster_env } + cluster_env: { get_param: cluster_env } + cluster_id: { get_param: cluster_id } + type: dns + image: { get_param: dns_image } + flavor: { get_param: dns_flavor } + key_name: { get_param: ssh_public_key } + net: { get_resource: net } + subnet: { get_resource: subnet } + secgrp: + - { get_resource: node-secgrp } + - { get_resource: dns-secgrp } + floating_network: { get_param: external_net } + net_name: + str_replace: + template: openshift-ansible-cluster_id-net + params: + cluster_id: { get_param: cluster_id } + volume_size: { get_param: dns_volume_size } + depends_on: + - interface + diff --git a/roles/openstack-stack/files/heat_stack_server.yaml b/roles/openstack-stack/files/heat_stack_server.yaml new file mode 100644 index 000000000..978da4f0b --- /dev/null +++ b/roles/openstack-stack/files/heat_stack_server.yaml @@ -0,0 +1,156 @@ +heat_template_version: 2014-10-16 + +description: OpenShift cluster server + +parameters: + + name: + type: string + label: Name + description: Name + + cluster_env: + type: string + label: Cluster environment + description: Environment of the cluster + + cluster_id: + type: string + label: Cluster ID + description: Identifier of the cluster + + type: + type: string + label: Type + description: Type master or node + + subtype: + type: string + label: Sub-type + description: Sub-type compute or infra for nodes, default otherwise + default: default + + key_name: + type: string + label: Key name + description: Key name of keypair + + image: + type: string + label: Image + description: Name of the image + + flavor: + type: string + label: Flavor + description: Name of the flavor + + net: + type: string + label: Net ID + description: Net resource + + net_name: + type: string + label: Net name + description: Net name + + subnet: + type: string + label: Subnet ID + description: Subnet resource + + secgrp: + type: comma_delimited_list + label: Security groups + description: Security group resources + + floating_network: + type: string + label: Floating network + description: Network to allocate floating IP from + + availability_zone: + type: string + description: The Availability Zone to launch the instance. + default: nova + + volume_size: + type: number + description: Size of the volume to be created. + default: 1 + constraints: + - range: { min: 1, max: 1024 } + description: must be between 1 and 1024 Gb. + +outputs: + + name: + description: Name of the server + value: { get_attr: [ server, name ] } + + private_ip: + description: Private IP of the server + value: + get_attr: + - server + - addresses + - { get_param: net_name } + - 0 + - addr + + floating_ip: + description: Floating IP of the server + value: + get_attr: + - server + - addresses + - { get_param: net_name } + - 1 + - addr + +resources: + + server: + type: OS::Nova::Server + properties: + name: { get_param: name } + key_name: { get_param: key_name } + image: { get_param: image } + flavor: { get_param: flavor } + networks: + - port: { get_resource: port } + user_data: { get_file: user-data } + user_data_format: RAW + metadata: + environment: { get_param: cluster_env } + clusterid: { get_param: cluster_id } + host-type: { get_param: type } + sub-host-type: { get_param: subtype } + + port: + type: OS::Neutron::Port + properties: + network: { get_param: net } + fixed_ips: + - subnet: { get_param: subnet } + security_groups: { get_param: secgrp } + + floating-ip: + type: OS::Neutron::FloatingIP + properties: + floating_network: { get_param: floating_network } + port_id: { get_resource: port } + + cinder_volume: + type: OS::Cinder::Volume + properties: + size: { get_param: volume_size } + availability_zone: { get_param: availability_zone } + + volume_attachment: + type: OS::Cinder::VolumeAttachment + properties: + volume_id: { get_resource: cinder_volume } + instance_uuid: { get_resource: server } + mountpoint: /dev/sdb diff --git a/roles/openstack-stack/files/user-data b/roles/openstack-stack/files/user-data new file mode 100644 index 000000000..eb65f7cec --- /dev/null +++ b/roles/openstack-stack/files/user-data @@ -0,0 +1,13 @@ +#cloud-config +disable_root: true + +system_info: + default_user: + name: openshift + sudo: ["ALL=(ALL) NOPASSWD: ALL"] + +write_files: + - path: /etc/sudoers.d/00-openshift-no-requiretty + permissions: 440 + content: | + Defaults:openshift !requiretty diff --git a/roles/openstack-stack/tasks/main.yml b/roles/openstack-stack/tasks/main.yml new file mode 100644 index 000000000..c953cb603 --- /dev/null +++ b/roles/openstack-stack/tasks/main.yml @@ -0,0 +1,31 @@ +--- +- name: create stack + ignore_errors: False + register: stack_create + os_stack: + name: "{{ stack_name }}" + state: present + template: 'roles/openstack-stack/files/heat_stack.yaml' + wait: yes + parameters: + cluster_env: "{{ dns_domain }}" + cluster_id: "{{ stack_name }}" + subnet_24_prefix: "{{ subnet_prefix }}" + dns_nameservers: "{{ dns_nameservers }}" + external_net: "{{ external_network }}" + ssh_public_key: "{{ ssh_public_key }}" + num_etcd: "{{ num_etcd }}" + num_masters: "{{ num_masters }}" + num_nodes: "{{ num_nodes }}" + num_infra: "{{ num_infra }}" + num_dns: "{{ num_dns }}" + etcd_image: "{{ openstack_image }}" + master_image: "{{ openstack_image }}" + node_image: "{{ openstack_image }}" + infra_image: "{{ openstack_image }}" + dns_image: "{{ openstack_image }}" + etcd_flavor: "{{ etcd_flavor }}" + master_flavor: "{{ master_flavor }}" + node_flavor: "{{ node_flavor }}" + infra_flavor: "{{ infra_flavor }}" + dns_flavor: "{{ dns_flavor }}" diff --git a/roles/openstack-stack/test/roles b/roles/openstack-stack/test/roles new file mode 120000 index 000000000..e2b799b9d --- /dev/null +++ b/roles/openstack-stack/test/roles @@ -0,0 +1 @@ +../../../roles/
\ No newline at end of file diff --git a/roles/openstack-stack/test/stack-create-test.yml b/roles/openstack-stack/test/stack-create-test.yml new file mode 100644 index 000000000..94e312ee3 --- /dev/null +++ b/roles/openstack-stack/test/stack-create-test.yml @@ -0,0 +1,17 @@ +--- +- hosts: localhost + roles: + - role: openstack-stack + stack_name: test-stack + dns_domain: "{{ openstack_dns_domain }}" + dns_nameservers: "{{ openstack_nameservers }}" + subnet_prefix: "{{ openstack_subnet_prefix }}" + ssh_public_key: "{{ openstack_ssh_public_key }}" + openstack_image: "{{ openstack_default_image_name }}" + etcd_flavor: "{{ openstack_default_flavor }}" + master_flavor: "{{ openstack_default_flavor }}" + node_flavor: "{{ openstack_default_flavor }}" + infra_flavor: "{{ openstack_default_flavor }}" + dns_flavor: "{{ openstack_default_flavor }}" + external_network: "{{ openstack_external_network_name }}" + |