From 677fd46cf37cab5f995170b3567939d784ebb07a Mon Sep 17 00:00:00 2001 From: Bogdan Dobrelya Date: Wed, 5 Jul 2017 12:46:57 +0200 Subject: Add bastion and ssh config for the static inventory role * Autogenerate SSH config for static inventory and bastion. * When using bastion, use FQDN for inventory's ansible_host and SSH config's Hostname. Simplifies accessing nodes by names instead of private IPs. Signed-off-by: Bogdan Dobrelya --- roles/static_inventory/defaults/main.yml | 13 +++++++++++ roles/static_inventory/tasks/main.yml | 4 ++++ roles/static_inventory/tasks/openstack.yml | 25 ++++++++++++++++++++-- roles/static_inventory/tasks/sshconfig.yml | 13 +++++++++++ roles/static_inventory/templates/inventory.j2 | 4 ++++ .../templates/openstack_ssh_config.j2 | 21 ++++++++++++++++++ 6 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 roles/static_inventory/tasks/sshconfig.yml create mode 100644 roles/static_inventory/templates/openstack_ssh_config.j2 (limited to 'roles/static_inventory') diff --git a/roles/static_inventory/defaults/main.yml b/roles/static_inventory/defaults/main.yml index 315965cde..63de45646 100644 --- a/roles/static_inventory/defaults/main.yml +++ b/roles/static_inventory/defaults/main.yml @@ -4,5 +4,18 @@ refresh_inventory: True inventory: static inventory_path: ~/openstack-inventory +# Either to configure bastion +use_bastion: true + +# SSH user/key/options to access hosts via bastion +ssh_user: openshift +ssh_options: >- + -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no + -o ConnectTimeout=90 -o ControlMaster=auto -o ControlPersist=270s + -o ServerAliveInterval=30 -o GSSAPIAuthentication=no + # SSH key to access nodes private_ssh_key: ~/.ssh/openshift + +# The patch to store the generated config to access bastion/hosts +ssh_config_path: /tmp/ssh.config.ansible diff --git a/roles/static_inventory/tasks/main.yml b/roles/static_inventory/tasks/main.yml index 15c81690e..b58866017 100644 --- a/roles/static_inventory/tasks/main.yml +++ b/roles/static_inventory/tasks/main.yml @@ -4,3 +4,7 @@ - name: Checkpoint in-memory data into a static inventory include: checkpoint.yml + +- name: Generate SSH config for accessing hosts via bastion + include: sshconfig.yml + when: use_bastion|bool diff --git a/roles/static_inventory/tasks/openstack.yml b/roles/static_inventory/tasks/openstack.yml index a25502835..95d0d172f 100644 --- a/roles/static_inventory/tasks/openstack.yml +++ b/roles/static_inventory/tasks/openstack.yml @@ -16,12 +16,14 @@ - name: set_fact for openstack inventory nodes set_fact: + registered_bastion_nodes: "{{ (registered_nodes_output.stdout | from_json) | json_query(q) }}" registered_nodes_floating: "{{ (registered_nodes_output.stdout | from_json) | json_query(q2) }}" vars: q: "[] | [?metadata.group=='infra.{{stack_name}}']" q2: "[] | [?metadata.clusterid=='{{stack_name}}'] | [?public_v4!='']" when: - refresh_inventory|bool + - use_bastion|bool - name: Add cluster nodes w/o floating IPs to inventory with_items: "{{ registered_nodes }}" @@ -29,9 +31,11 @@ add_host: name: '{{ item.name }}' groups: '{{ item.metadata.group }}' - ansible_host: '{{ item.private_v4 }}' + ansible_host: "{% if use_bastion|bool %}{{ item.name }}{% else %}{{ item.private_v4 }}{% endif %}" ansible_fqdn: '{{ item.name }}' + ansible_user: '{{ ssh_user }}' ansible_private_key_file: '{{ private_ssh_key }}' + ansible_ssh_extra_args: '-F {{ ssh_config_path }}' private_v4: '{{ item.private_v4 }}' - name: Add cluster nodes with floating IPs to inventory @@ -40,8 +44,25 @@ add_host: name: '{{ item.name }}' groups: '{{ item.metadata.group }}' - ansible_host: '{{ item.public_v4 }}' + ansible_host: "{% if use_bastion|bool %}{{ item.name }}{% else %}{{ item.private_v4 }}{% endif %}" ansible_fqdn: '{{ item.name }}' + ansible_user: '{{ ssh_user }}' ansible_private_key_file: '{{ private_ssh_key }}' + ansible_ssh_extra_args: '-F {{ ssh_config_path }}' private_v4: '{{ item.private_v4 }}' public_v4: '{{ item.public_v4 }}' + + - name: Add bastion node to inventory + add_host: + name: bastion + groups: bastions + ansible_host: '{{ registered_bastion_nodes[0].public_v4 }}' + ansible_fqdn: '{{ registered_bastion_nodes[0].name }}' + ansible_user: '{{ ssh_user }}' + ansible_private_key_file: '{{ private_ssh_key }}' + ansible_ssh_extra_args: '-F {{ ssh_config_path }}' + private_v4: '{{ registered_bastion_nodes[0].private_v4 }}' + public_v4: '{{ registered_bastion_nodes[0].public_v4 }}' + when: + - registered_bastion_nodes is defined + - use_bastion|bool diff --git a/roles/static_inventory/tasks/sshconfig.yml b/roles/static_inventory/tasks/sshconfig.yml new file mode 100644 index 000000000..7119fe6ff --- /dev/null +++ b/roles/static_inventory/tasks/sshconfig.yml @@ -0,0 +1,13 @@ +--- +- name: set ssh proxy command prefix for accessing nodes via bastion + set_fact: + ssh_proxy_command: >- + ssh {{ ssh_options }} + -i {{ private_ssh_key }} + {{ ssh_user }}@{{ hostvars['bastion'].ansible_host }} + +- name: regenerate ssh config + template: + src: openstack_ssh_config.j2 + dest: "{{ ssh_config_path }}" + mode: 0644 diff --git a/roles/static_inventory/templates/inventory.j2 b/roles/static_inventory/templates/inventory.j2 index 464726a0b..ac74db35c 100644 --- a/roles/static_inventory/templates/inventory.j2 +++ b/roles/static_inventory/templates/inventory.j2 @@ -10,8 +10,12 @@ %} private_v4={{ hostvars[host]['private_v4'] }}{% endif %} {% if 'public_v4' in hostvars[host] %} public_v4={{ hostvars[host]['public_v4'] }}{% endif %} +{% if 'ansible_user' in hostvars[host] +%} ansible_user={{ hostvars[host]['ansible_user'] }}{% endif %} {% if 'ansible_private_key_file' in hostvars[host] %} ansible_private_key_file={{ hostvars[host]['ansible_private_key_file'] }}{% endif %} +{% if 'ansible_ssh_extra_args' in hostvars[host] +%} ansible_ssh_extra_args={{ hostvars[host]['ansible_ssh_extra_args']|quote }}{% endif %} openshift_hostname={{ host }} {% endif %} diff --git a/roles/static_inventory/templates/openstack_ssh_config.j2 b/roles/static_inventory/templates/openstack_ssh_config.j2 new file mode 100644 index 000000000..ad5d1253a --- /dev/null +++ b/roles/static_inventory/templates/openstack_ssh_config.j2 @@ -0,0 +1,21 @@ +Host * + IdentitiesOnly yes + +Host bastion + Hostname {{ hostvars['bastion'].ansible_host }} + IdentityFile {{ hostvars['bastion'].ansible_private_key_file }} + User {{ ssh_user }} + StrictHostKeyChecking no + UserKnownHostsFile=/dev/null + +{% for host in groups['all'] | difference(groups['bastions'][0]) %} + +Host {{ host }} + Hostname {{ hostvars[host].ansible_host }} + ProxyCommand {{ ssh_proxy_command }} -W {{ hostvars[host].private_v4 }}:22 + IdentityFile {{ hostvars[host].ansible_private_key_file }} + User {{ ssh_user }} + StrictHostKeyChecking no + UserKnownHostsFile=/dev/null + +{% endfor %} -- cgit v1.2.3 From df8f5f0e251a014ab30dabd62c17e151b7fe36e8 Mon Sep 17 00:00:00 2001 From: Bogdan Dobrelya Date: Wed, 12 Jul 2017 13:09:45 +0200 Subject: Options for bastion, SSH config, static inventory autogeneration * At the provisioning stage, allow users to auto-generate SSH config, when using a static inventory. * Run playbooks to provsion and post-provision as a separate, when using a bastion. This re-applies the SSH config, which ansible can't do on the fly. * Support a pre-installed bastion node, colocated with the 1st infra node. * With a bastion enabled, reduce floating IP footprint to infra and dns nodes only, effectively isolating a cluster in a private network. Signed-off-by: Bogdan Dobrelya --- playbooks/provisioning/openstack/README.md | 31 ++++- .../openstack/openstack_dns_records.yml | 2 + .../openstack/post-provision-openstack.yml | 6 +- .../provisioning/openstack/provision-openstack.yml | 11 +- .../openstack/sample-inventory/group_vars/all.yml | 7 + playbooks/provisioning/openstack/stack_params.yaml | 1 + roles/openstack-stack/defaults/main.yml | 2 + roles/openstack-stack/tasks/main.yml | 9 +- roles/openstack-stack/templates/heat_stack.yaml.j2 | 25 ++++ .../templates/heat_stack_server_nofloating.yaml.j2 | 149 +++++++++++++++++++++ roles/static_inventory/tasks/openstack.yml | 7 +- roles/static_inventory/templates/inventory.j2 | 5 +- 12 files changed, 238 insertions(+), 17 deletions(-) create mode 100644 roles/openstack-stack/templates/heat_stack_server_nofloating.yaml.j2 (limited to 'roles/static_inventory') diff --git a/playbooks/provisioning/openstack/README.md b/playbooks/provisioning/openstack/README.md index 1ff586b49..6b9e5a3a9 100644 --- a/playbooks/provisioning/openstack/README.md +++ b/playbooks/provisioning/openstack/README.md @@ -40,7 +40,7 @@ Alternatively you can install directly from github: -p openshift-ansible-contrib/roles Notes: -* This assumes we're in the directory that contains the clonned +* This assumes we're in the directory that contains the clonned openshift-ansible-contrib repo in its root path. * When trying to install a different version, the previous one must be removed first (`infra-ansible` directory from [roles](https://github.com/openshift/openshift-ansible-contrib/tree/master/roles)). @@ -177,16 +177,30 @@ variables for the `inventory/group_vars/OSEv3.yml`, `all.yml`: origin_release: 1.5.1 openshift_deployment_type: "{{ deployment_type }}" -### Configure static inventory +### Configure static inventory and access via a bastion node Example inventory variables: + openstack_use_bastion: true + bastion_ingress_cidr: "{{openstack_subnet_prefix}}.0/24" openstack_private_ssh_key: ~/.ssh/openshift openstack_inventory: static openstack_inventory_path: ../../../../inventory + openstack_ssh_config_path: /tmp/ssh.config.openshift.ansible.openshift.example.com +The `openstack_subnet_prefix` is the openstack private network for your cluster. +And the `bastion_ingress_cidr` defines accepted range for SSH connections to nodes +additionally to the `ssh_ingress_cidr`` (see the security notes above). -In this guide, the latter points to the current directory, where you run ansible commands +The SSH config will be stored on the ansible control node by the +gitven path. Ansible uses it automatically. To access the cluster nodes with +that ssh config, use the `-F` prefix, f.e.: + + ssh -F /tmp/ssh.config.openshift.ansible.openshift.example.com master-0.openshift.example.com echo OK + +Note, relative paths will not work for the `openstack_ssh_config_path`, but it +works for the `openstack_private_ssh_key` and `openstack_inventory_path`. In this +guide, the latter points to the current directory, where you run ansible commands from. To verify nodes connectivity, use the command: @@ -194,7 +208,7 @@ To verify nodes connectivity, use the command: ansible -v -i inventory/hosts -m ping all If something is broken, double-check the inventory variables, paths and the -generated `/hosts` file. +generated `/hosts` and `openstack_ssh_config_path` files. The `inventory: dynamic` can be used instead to access cluster nodes directly via floating IPs. In this mode you can not use a bastion node and should specify @@ -213,6 +227,15 @@ this is how you stat the provisioning process from your ansible control node: Note, here you start with an empty inventory. The static inventory will be populated with data so you can omit providing additional arguments for future ansible commands. +If bastion enabled, the generates SSH config must be applied for ansible. +Otherwise, it is auto included by the previous step. In order to execute it +as a separate playbook, use the following command: + + ansible-playbook openshift-ansible-contrib/playbooks/provisioning/openstack/post-provision-openstack.yml + +The first infra node then becomes a bastion node as well and proxies access +for future ansible commands. The post-provision step also configures Satellite, +if requested, and DNS server, and ensures other OpenShift requirements to be met. ### Install OpenShift diff --git a/playbooks/provisioning/openstack/openstack_dns_records.yml b/playbooks/provisioning/openstack/openstack_dns_records.yml index b5f0840c5..980221ed6 100644 --- a/playbooks/provisioning/openstack/openstack_dns_records.yml +++ b/playbooks/provisioning/openstack/openstack_dns_records.yml @@ -36,11 +36,13 @@ set_fact: public_records: "{{ public_records | default([]) + [ { 'type': 'A', 'hostname': hostvars[item]['ansible_hostname'], 'ip': hostvars[item]['public_v4'] } ] }}" with_items: "{{ groups['cluster_hosts'] }}" + when: hostvars[item]['public_v4'] is defined - name: "Add wildcard records to the public A records" set_fact: public_records: "{{ public_records | default([]) + [ { 'type': 'A', 'hostname': '*.' + openshift_app_domain, 'ip': hostvars[item]['public_v4'] } ] }}" with_items: "{{ groups['infra_hosts'] }}" + when: hostvars[item]['public_v4'] is defined - name: "Set the public DNS server details to use the external value (if provided)" set_fact: diff --git a/playbooks/provisioning/openstack/post-provision-openstack.yml b/playbooks/provisioning/openstack/post-provision-openstack.yml index a807c4d2f..c7df74a87 100644 --- a/playbooks/provisioning/openstack/post-provision-openstack.yml +++ b/playbooks/provisioning/openstack/post-provision-openstack.yml @@ -4,7 +4,11 @@ become: False gather_facts: False tasks: - - wait_for_connection: + - when: not openstack_use_bastion|default(False)|bool + wait_for_connection: + - when: openstack_use_bastion|default(False)|bool + delegate_to: bastion + wait_for_connection: - hosts: cluster_hosts gather_facts: True diff --git a/playbooks/provisioning/openstack/provision-openstack.yml b/playbooks/provisioning/openstack/provision-openstack.yml index 0cac37aaf..6ec944d56 100644 --- a/playbooks/provisioning/openstack/provision-openstack.yml +++ b/playbooks/provisioning/openstack/provision-openstack.yml @@ -12,13 +12,20 @@ when: openstack_inventory|default('static') == 'static' inventory_path: "{{ openstack_inventory_path|default(inventory_dir) }}" private_ssh_key: "{{ openstack_private_ssh_key|default('~/.ssh/id_rsa') }}" + ssh_config_path: "{{ openstack_ssh_config_path|default('/tmp/ssh.config.openshift.ansible' + '.' + stack_name) }}" + ssh_user: "{{ ansible_user }}" -- name: Refresh Server inventory +- name: Refresh Server inventory or exit to apply SSH config hosts: localhost connection: local become: False gather_facts: False tasks: - - meta: refresh_inventory + - name: Exit to apply SSH config for a bastion + meta: end_play + when: openstack_use_bastion|default(False)|bool + - name: Refresh Server inventory + meta: refresh_inventory - include: post-provision-openstack.yml + when: not openstack_use_bastion|default(False)|bool diff --git a/playbooks/provisioning/openstack/sample-inventory/group_vars/all.yml b/playbooks/provisioning/openstack/sample-inventory/group_vars/all.yml index 9eb36ab13..6d07f9b56 100644 --- a/playbooks/provisioning/openstack/sample-inventory/group_vars/all.yml +++ b/playbooks/provisioning/openstack/sample-inventory/group_vars/all.yml @@ -69,5 +69,12 @@ ansible_user: openshift # # The path to checkpoint the static inventory from the in-memory one #openstack_inventory_path: ../../../../inventory +# # Use bastion node to access cluster nodes (Defaults to False). +# # Requires a static inventory. +#openstack_use_bastion: False +#bastion_ingress_cidr: "{{openstack_subnet_prefix}}.0/24" +# # # The Nova key-pair's private SSH key to access inventory nodes #openstack_private_ssh_key: ~/.ssh/openshift +# # The path for the SSH config to access all nodes +#openstack_ssh_config_path: /tmp/ssh.config.openshift.ansible.{{ env_id }}.{{ public_dns_domain }} diff --git a/playbooks/provisioning/openstack/stack_params.yaml b/playbooks/provisioning/openstack/stack_params.yaml index 9c0b09b45..c3a42ab06 100644 --- a/playbooks/provisioning/openstack/stack_params.yaml +++ b/playbooks/provisioning/openstack/stack_params.yaml @@ -21,3 +21,4 @@ master_volume_size: "{{ docker_volume_size }}" app_volume_size: "{{ docker_volume_size }}" infra_volume_size: "{{ docker_volume_size }}" nodes_to_remove: "{{ openstack_nodes_to_remove | default([]) | to_yaml }}" +use_bastion: "{{ openstack_use_bastion|default(False) }}" diff --git a/roles/openstack-stack/defaults/main.yml b/roles/openstack-stack/defaults/main.yml index 4831d6bc4..803a96389 100644 --- a/roles/openstack-stack/defaults/main.yml +++ b/roles/openstack-stack/defaults/main.yml @@ -4,6 +4,7 @@ ssh_ingress_cidr: 0.0.0.0/0 node_ingress_cidr: 0.0.0.0/0 master_ingress_cidr: 0.0.0.0/0 lb_ingress_cidr: 0.0.0.0/0 +bastion_ingress_cidr: 0.0.0.0/0 num_etcd: 0 num_masters: 1 num_nodes: 1 @@ -11,3 +12,4 @@ num_dns: 1 num_infra: 1 nodes_to_remove: [] etcd_volume_size: 2 +use_bastion: False diff --git a/roles/openstack-stack/tasks/main.yml b/roles/openstack-stack/tasks/main.yml index a53e6350b..9b4855294 100644 --- a/roles/openstack-stack/tasks/main.yml +++ b/roles/openstack-stack/tasks/main.yml @@ -8,7 +8,6 @@ - name: set template paths set_fact: stack_template_path: "{{ stack_template_pre.path }}/stack.yaml" - server_template_path: "{{ stack_template_pre.path }}/server.yaml" user_data_template_path: "{{ stack_template_pre.path }}/user-data" - name: generate HOT stack template from jinja2 template @@ -19,7 +18,13 @@ - name: generate HOT server template from jinja2 template template: src: heat_stack_server.yaml.j2 - dest: "{{ server_template_path }}" + dest: "{{ stack_template_pre.path }}/server.yaml" + +- name: generate HOT server w/o floating IPs template from jinja2 template + template: + src: heat_stack_server_nofloating.yaml.j2 + dest: "{{ stack_template_pre.path }}/server_nofloating.yaml" + when: use_bastion|bool - name: generate user_data from jinja2 template template: diff --git a/roles/openstack-stack/templates/heat_stack.yaml.j2 b/roles/openstack-stack/templates/heat_stack.yaml.j2 index 54941db06..524f466ff 100644 --- a/roles/openstack-stack/templates/heat_stack.yaml.j2 +++ b/roles/openstack-stack/templates/heat_stack.yaml.j2 @@ -156,6 +156,13 @@ resources: port_range_min: 22 port_range_max: 22 remote_ip_prefix: {{ ssh_ingress_cidr }} +{% if use_bastion|bool %} + - direction: ingress + protocol: tcp + port_range_min: 22 + port_range_max: 22 + remote_ip_prefix: {{ bastion_ingress_cidr }} +{% endif %} - direction: ingress protocol: icmp remote_ip_prefix: {{ ssh_ingress_cidr }} @@ -458,7 +465,11 @@ resources: properties: count: {{ num_etcd }} resource_def: +{% if use_bastion|bool %} + type: server_nofloating.yaml +{% else %} type: server.yaml +{% endif %} properties: name: str_replace: @@ -483,7 +494,9 @@ resources: secgrp: - { get_resource: {% if openstack_flat_secgrp|default(False)|bool %}flat-secgrp{% else %}etcd-secgrp{% endif %} } - { get_resource: common-secgrp } +{% if not use_bastion|bool %} floating_network: {{ external_network }} +{% endif %} net_name: str_replace: template: openshift-ansible-cluster_id-net @@ -540,7 +553,11 @@ resources: properties: count: {{ num_masters }} resource_def: +{% if use_bastion|bool %} + type: server_nofloating.yaml +{% else %} type: server.yaml +{% endif %} properties: name: str_replace: @@ -573,7 +590,9 @@ resources: {% endif %} {% endif %} - { get_resource: common-secgrp } +{% if not use_bastion|bool %} floating_network: {{ external_network }} +{% endif %} net_name: str_replace: template: openshift-ansible-cluster_id-net @@ -590,7 +609,11 @@ resources: removal_policies: - resource_list: {{ nodes_to_remove }} resource_def: +{% if use_bastion|bool %} + type: server_nofloating.yaml +{% else %} type: server.yaml +{% endif %} properties: name: str_replace: @@ -621,7 +644,9 @@ resources: secgrp: - { get_resource: {% if openstack_flat_secgrp|default(False)|bool %}flat-secgrp{% else %}node-secgrp{% endif %} } - { get_resource: common-secgrp } +{% if not use_bastion|bool %} floating_network: {{ external_network }} +{% endif %} net_name: str_replace: template: openshift-ansible-cluster_id-net diff --git a/roles/openstack-stack/templates/heat_stack_server_nofloating.yaml.j2 b/roles/openstack-stack/templates/heat_stack_server_nofloating.yaml.j2 new file mode 100644 index 000000000..792a8b90c --- /dev/null +++ b/roles/openstack-stack/templates/heat_stack_server_nofloating.yaml.j2 @@ -0,0 +1,149 @@ +heat_template_version: 2016-10-14 + +description: OpenShift cluster server w/o floating IP + +parameters: + + name: + type: string + label: Name + description: Name + + group: + type: string + label: Host Group + description: The Primary Ansible Host Group + default: host + + 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 + + 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. + + node_labels: + type: json + description: OpenShift Node Labels + default: {"region": "default" } + +outputs: + + name: + description: Name of the server + value: { get_attr: [ server_nofloating, name ] } + + private_ip: + description: Private IP of the server + value: + get_attr: + - server_nofloating + - addresses + - { get_param: net_name } + - 0 + - addr + +resources: + + server_nofloating: + 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: + group: { get_param: group } + environment: { get_param: cluster_env } + clusterid: { get_param: cluster_id } + host-type: { get_param: type } + sub-host-type: { get_param: subtype } + node_labels: { get_param: node_labels } + + port: + type: OS::Neutron::Port + properties: + network: { get_param: net } + fixed_ips: + - subnet: { get_param: subnet } + security_groups: { get_param: secgrp } + + 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_nofloating } + mountpoint: /dev/sdb diff --git a/roles/static_inventory/tasks/openstack.yml b/roles/static_inventory/tasks/openstack.yml index 95d0d172f..499adf08c 100644 --- a/roles/static_inventory/tasks/openstack.yml +++ b/roles/static_inventory/tasks/openstack.yml @@ -23,11 +23,9 @@ q2: "[] | [?metadata.clusterid=='{{stack_name}}'] | [?public_v4!='']" when: - refresh_inventory|bool - - use_bastion|bool - name: Add cluster nodes w/o floating IPs to inventory - with_items: "{{ registered_nodes }}" - when: not item in registered_nodes_floating + with_items: "{{ registered_nodes|difference(registered_nodes_floating) }}" add_host: name: '{{ item.name }}' groups: '{{ item.metadata.group }}' @@ -40,11 +38,10 @@ - name: Add cluster nodes with floating IPs to inventory with_items: "{{ registered_nodes_floating }}" - when: item in registered_nodes_floating add_host: name: '{{ item.name }}' groups: '{{ item.metadata.group }}' - ansible_host: "{% if use_bastion|bool %}{{ item.name }}{% else %}{{ item.private_v4 }}{% endif %}" + ansible_host: "{% if use_bastion|bool %}{{ item.name }}{% else %}{{ item.public_v4 }}{% endif %}" ansible_fqdn: '{{ item.name }}' ansible_user: '{{ ssh_user }}' ansible_private_key_file: '{{ private_ssh_key }}' diff --git a/roles/static_inventory/templates/inventory.j2 b/roles/static_inventory/templates/inventory.j2 index ac74db35c..24dc9d4a8 100644 --- a/roles/static_inventory/templates/inventory.j2 +++ b/roles/static_inventory/templates/inventory.j2 @@ -14,9 +14,8 @@ %} ansible_user={{ hostvars[host]['ansible_user'] }}{% endif %} {% if 'ansible_private_key_file' in hostvars[host] %} ansible_private_key_file={{ hostvars[host]['ansible_private_key_file'] }}{% endif %} -{% if 'ansible_ssh_extra_args' in hostvars[host] -%} ansible_ssh_extra_args={{ hostvars[host]['ansible_ssh_extra_args']|quote }}{% endif %} - openshift_hostname={{ host }} +{% if use_bastion|bool and 'ansible_ssh_extra_args' in hostvars[host] +%} ansible_ssh_extra_args={{ hostvars[host]['ansible_ssh_extra_args']|quote }}{% endif %} openshift_hostname={{ host }} {% endif %} {% endfor %} -- cgit v1.2.3 From 784443b0d88597b988c3d5c58bc6358f5c73675e Mon Sep 17 00:00:00 2001 From: Bogdan Dobrelya Date: Tue, 15 Aug 2017 17:48:58 +0200 Subject: Support multiple private networks for static inventory (#604) Add openstack_private_network_name to filter by a wanted private network. Signed-off-by: Bogdan Dobrelya --- playbooks/provisioning/openstack/README.md | 4 ++++ .../openstack/sample-inventory/group_vars/all.yml | 1 + playbooks/provisioning/openstack/stack_params.yaml | 1 + roles/static_inventory/defaults/main.yml | 2 ++ roles/static_inventory/tasks/openstack.yml | 20 ++++++++++++++++---- 5 files changed, 24 insertions(+), 4 deletions(-) (limited to 'roles/static_inventory') diff --git a/playbooks/provisioning/openstack/README.md b/playbooks/provisioning/openstack/README.md index c7b2ea975..98c847d88 100644 --- a/playbooks/provisioning/openstack/README.md +++ b/playbooks/provisioning/openstack/README.md @@ -110,6 +110,10 @@ providing external connectivity. It is often called `public`, `external` or `ext-net`. You can see your networks with `openstack network list`. +`openstack_private_network_name` is the name of the private Neutron network +providing admin/control access for ansible. It can be merged with other +cluster networks, there are no special requirements for networking. + The `openstack_num_masters`, `openstack_num_infra` and `openstack_num_nodes` values specify the number of Master, Infra and App nodes to create. diff --git a/playbooks/provisioning/openstack/sample-inventory/group_vars/all.yml b/playbooks/provisioning/openstack/sample-inventory/group_vars/all.yml index 8f337546c..210caee16 100644 --- a/playbooks/provisioning/openstack/sample-inventory/group_vars/all.yml +++ b/playbooks/provisioning/openstack/sample-inventory/group_vars/all.yml @@ -7,6 +7,7 @@ openstack_ssh_public_key: "openshift" openstack_default_image_name: "centos7" openstack_default_flavor: "m1.medium" openstack_external_network_name: "public" +#openstack_private_network_name: "openshift-ansible-{{ stack_name }}-net" openstack_num_masters: 1 openstack_num_infra: 1 diff --git a/playbooks/provisioning/openstack/stack_params.yaml b/playbooks/provisioning/openstack/stack_params.yaml index c3a42ab06..e8434861b 100644 --- a/playbooks/provisioning/openstack/stack_params.yaml +++ b/playbooks/provisioning/openstack/stack_params.yaml @@ -5,6 +5,7 @@ dns_nameservers: "{{ public_dns_nameservers }}" subnet_prefix: "{{ openstack_subnet_prefix }}" ssh_public_key: "{{ openstack_ssh_public_key }}" openstack_image: "{{ openstack_default_image_name }}" +openstack_private_network: "{{ openstack_private_network_name | default ('openshift-ansible-' + stack_name + '-net') }}" lb_flavor: "{{ openstack_default_flavor | default('m1.small') }}" etcd_flavor: "{{ openstack_default_flavor | default('m1.small') }}" master_flavor: "{{ openstack_default_flavor | default('m1.medium') }}" diff --git a/roles/static_inventory/defaults/main.yml b/roles/static_inventory/defaults/main.yml index 63de45646..5b8aacf5c 100644 --- a/roles/static_inventory/defaults/main.yml +++ b/roles/static_inventory/defaults/main.yml @@ -19,3 +19,5 @@ private_ssh_key: ~/.ssh/openshift # The patch to store the generated config to access bastion/hosts ssh_config_path: /tmp/ssh.config.ansible + +openstack_private_network: private diff --git a/roles/static_inventory/tasks/openstack.yml b/roles/static_inventory/tasks/openstack.yml index 499adf08c..75d0ee6d5 100644 --- a/roles/static_inventory/tasks/openstack.yml +++ b/roles/static_inventory/tasks/openstack.yml @@ -29,12 +29,20 @@ add_host: name: '{{ item.name }}' groups: '{{ item.metadata.group }}' - ansible_host: "{% if use_bastion|bool %}{{ item.name }}{% else %}{{ item.private_v4 }}{% endif %}" + ansible_host: >- + {% if use_bastion|bool -%} + {{ item.name }} + {%- else -%} + {%- set node = registered_nodes | json_query("[?name=='" + item.name + "']") -%} + {{ node[0].addresses[openstack_private_network|quote][0].addr }} + {%- endif %} ansible_fqdn: '{{ item.name }}' ansible_user: '{{ ssh_user }}' ansible_private_key_file: '{{ private_ssh_key }}' ansible_ssh_extra_args: '-F {{ ssh_config_path }}' - private_v4: '{{ item.private_v4 }}' + private_v4: >- + {% set node = registered_nodes | json_query("[?name=='" + item.name + "']") -%} + {{ node[0].addresses[openstack_private_network|quote][0].addr }} - name: Add cluster nodes with floating IPs to inventory with_items: "{{ registered_nodes_floating }}" @@ -46,7 +54,9 @@ ansible_user: '{{ ssh_user }}' ansible_private_key_file: '{{ private_ssh_key }}' ansible_ssh_extra_args: '-F {{ ssh_config_path }}' - private_v4: '{{ item.private_v4 }}' + private_v4: >- + {% set node = registered_nodes | json_query("[?name=='" + item.name + "']") -%} + {{ node[0].addresses[openstack_private_network|quote][0].addr }} public_v4: '{{ item.public_v4 }}' - name: Add bastion node to inventory @@ -58,7 +68,9 @@ ansible_user: '{{ ssh_user }}' ansible_private_key_file: '{{ private_ssh_key }}' ansible_ssh_extra_args: '-F {{ ssh_config_path }}' - private_v4: '{{ registered_bastion_nodes[0].private_v4 }}' + private_v4: >- + {% set node = registered_nodes | json_query("[?name=='" + registered_bastion_nodes[0].name + "']") -%} + {{ node[0].addresses[openstack_private_network|quote][0].addr }} public_v4: '{{ registered_bastion_nodes[0].public_v4 }}' when: - registered_bastion_nodes is defined -- cgit v1.2.3 From 6ebad037254b0c254638f6e6dfbd48e451a1ceeb Mon Sep 17 00:00:00 2001 From: Bogdan Dobrelya Date: Wed, 16 Aug 2017 09:14:06 +0200 Subject: Access UI via a bastion node (#596) When using a bastion and a single master, use the lb-secgrp to access UI port allowed from the ingress bastion node cidr. For HA (masters>1), UI still should be accessed via the LB node's ingress cidr, omitting the bastion. Signed-off-by: Bogdan Dobrelya --- playbooks/provisioning/openstack/README.md | 18 ++++++++++++++++++ playbooks/provisioning/openstack/stack_params.yaml | 1 + roles/openstack-stack/defaults/main.yml | 1 + roles/openstack-stack/templates/heat_stack.yaml.j2 | 20 +++++++++++++++----- roles/static_inventory/defaults/main.yml | 6 ++++++ roles/static_inventory/tasks/main.yml | 7 +++++++ roles/static_inventory/tasks/sshtun.yml | 15 +++++++++++++++ .../static_inventory/templates/ssh-tunnel.service.j2 | 20 ++++++++++++++++++++ 8 files changed, 83 insertions(+), 5 deletions(-) create mode 100644 roles/static_inventory/tasks/sshtun.yml create mode 100644 roles/static_inventory/templates/ssh-tunnel.service.j2 (limited to 'roles/static_inventory') diff --git a/playbooks/provisioning/openstack/README.md b/playbooks/provisioning/openstack/README.md index 79e153fe1..d7fa76b0f 100644 --- a/playbooks/provisioning/openstack/README.md +++ b/playbooks/provisioning/openstack/README.md @@ -251,6 +251,24 @@ Once it succeeds, you can install openshift by running: ansible-playbook openshift-ansible/playbooks/byo/config.yml +### Access UI + +OpenShift UI may be accessed via the 1st master node FQDN, port 8443. + +When using a bastion, you may want to make an SSH tunnel from your control node +to access UI on the `https://localhost:8443`, with this inventory variable: + + openshift_ui_ssh_tunnel: True + +Note, this requires sudo rights on the ansible control node and an absolute path +for the `openstack_private_ssh_key`. You should also update the control node's +`/etc/hosts`: + + 127.0.0.1 master-0.openshift.example.com + +In order to access UI, the ssh-tunnel service will be created and started on the +control node. Make sure to remove these changes and the service manually, when not +needed anymore. ## License diff --git a/playbooks/provisioning/openstack/stack_params.yaml b/playbooks/provisioning/openstack/stack_params.yaml index 6c920d2a2..8f36d5c4f 100644 --- a/playbooks/provisioning/openstack/stack_params.yaml +++ b/playbooks/provisioning/openstack/stack_params.yaml @@ -29,3 +29,4 @@ app_volume_size: "{{ docker_volume_size }}" infra_volume_size: "{{ docker_volume_size }}" nodes_to_remove: "{{ openstack_nodes_to_remove | default([]) | to_yaml }}" use_bastion: "{{ openstack_use_bastion|default(False) }}" +ui_ssh_tunnel: "{{ openshift_ui_ssh_tunnel|default(False) }}" diff --git a/roles/openstack-stack/defaults/main.yml b/roles/openstack-stack/defaults/main.yml index 803a96389..c8529612e 100644 --- a/roles/openstack-stack/defaults/main.yml +++ b/roles/openstack-stack/defaults/main.yml @@ -13,3 +13,4 @@ num_infra: 1 nodes_to_remove: [] etcd_volume_size: 2 use_bastion: False +ui_ssh_tunnel: False diff --git a/roles/openstack-stack/templates/heat_stack.yaml.j2 b/roles/openstack-stack/templates/heat_stack.yaml.j2 index c41bf15be..a670ff0e3 100644 --- a/roles/openstack-stack/templates/heat_stack.yaml.j2 +++ b/roles/openstack-stack/templates/heat_stack.yaml.j2 @@ -439,7 +439,7 @@ resources: port_range_min: 53 port_range_max: 53 remote_ip_prefix: "{{ openstack_subnet_prefix }}.0/24" -{% if num_masters > 1 %} +{% if num_masters > 1 or ui_ssh_tunnel|bool %} lb-secgrp: type: OS::Neutron::SecurityGroup properties: @@ -450,14 +450,21 @@ resources: protocol: tcp port_range_min: {{ openshift_master_api_port | default(8443) }} port_range_max: {{ openshift_master_api_port | default(8443) }} - remote_ip_prefix: {{ lb_ingress_cidr }} - {% if openshift_master_console_port is defined and openshift_master_console_port != openshift_master_api_port %} + remote_ip_prefix: {{ lb_ingress_cidr | default(bastion_ingress_cidr) }} +{% if ui_ssh_tunnel|bool %} + - direction: ingress + protocol: tcp + port_range_min: {{ openshift_master_api_port | default(8443) }} + port_range_max: {{ openshift_master_api_port | default(8443) }} + remote_ip_prefix: {{ ssh_ingress_cidr }} +{% endif %} +{% if openshift_master_console_port is defined and openshift_master_console_port != openshift_master_api_port %} - direction: ingress protocol: tcp port_range_min: {{ openshift_master_console_port | default(8443) }} port_range_max: {{ openshift_master_console_port | default(8443) }} - remote_ip_prefix: {{ lb_ingress_cidr }} - {% endif %} + remote_ip_prefix: {{ lb_ingress_cidr | default(bastion_ingress_cidr) }} +{% endif %} {% endif %} etcd: @@ -695,6 +702,9 @@ resources: - { get_resource: flat-secgrp } {% else %} - { get_resource: node-secgrp } +{% endif %} +{% if ui_ssh_tunnel|bool and num_masters < 2 %} + - { get_resource: lb-secgrp } {% endif %} - { get_resource: infra-secgrp } - { get_resource: common-secgrp } diff --git a/roles/static_inventory/defaults/main.yml b/roles/static_inventory/defaults/main.yml index 5b8aacf5c..871700f8c 100644 --- a/roles/static_inventory/defaults/main.yml +++ b/roles/static_inventory/defaults/main.yml @@ -20,4 +20,10 @@ private_ssh_key: ~/.ssh/openshift # The patch to store the generated config to access bastion/hosts ssh_config_path: /tmp/ssh.config.ansible +# The IP:port to make an SSH tunnel to access UI on the 1st master +# via bastion node (requires sudo on the ansible control node) +ui_ssh_tunnel: False +ui_port: "{{ openshift_master_api_port | default(8443) }}" +target_ip: "{{ hostvars[groups['masters.' + stack_name|quote][0]].private_v4 }}" + openstack_private_network: private diff --git a/roles/static_inventory/tasks/main.yml b/roles/static_inventory/tasks/main.yml index b58866017..24e11beb6 100644 --- a/roles/static_inventory/tasks/main.yml +++ b/roles/static_inventory/tasks/main.yml @@ -8,3 +8,10 @@ - name: Generate SSH config for accessing hosts via bastion include: sshconfig.yml when: use_bastion|bool + +- name: Configure SSH tunneling to access UI + include: sshtun.yml + become: true + when: + - use_bastion|bool + - ui_ssh_tunnel|bool diff --git a/roles/static_inventory/tasks/sshtun.yml b/roles/static_inventory/tasks/sshtun.yml new file mode 100644 index 000000000..b0e4c832c --- /dev/null +++ b/roles/static_inventory/tasks/sshtun.yml @@ -0,0 +1,15 @@ +--- +- name: Create ssh tunnel systemd service + template: + src: ssh-tunnel.service.j2 + dest: /etc/systemd/system/ssh-tunnel.service + mode: 0644 + +- name: reload the systemctl daemon after file update + command: systemctl daemon-reload + +- name: Enable ssh tunnel service + service: + name: ssh-tunnel + enabled: true + state: restarted diff --git a/roles/static_inventory/templates/ssh-tunnel.service.j2 b/roles/static_inventory/templates/ssh-tunnel.service.j2 new file mode 100644 index 000000000..0d1cf8f79 --- /dev/null +++ b/roles/static_inventory/templates/ssh-tunnel.service.j2 @@ -0,0 +1,20 @@ +[Unit] +Description=Set up ssh tunneling for OpenShift cluster UI +After=network.target + +[Service] +ExecStart=/usr/bin/ssh -NT -o \ + ServerAliveInterval=60 -o \ + UserKnownHostsFile=/dev/null -o \ + StrictHostKeyChecking=no -o \ + ExitOnForwardFailure=no -i \ + {{ private_ssh_key }} {{ ssh_user }}@{{ hostvars['bastion'].ansible_host }} \ + -L 0.0.0.0:{{ ui_port }}:{{ target_ip }}:{{ ui_port }} + + +# Restart every >2 seconds to avoid StartLimitInterval failure +RestartSec=5 +Restart=always + +[Install] +WantedBy=multi-user.target -- cgit v1.2.3 From f4b584fcef4fad12be931631e0c95ac677799ee7 Mon Sep 17 00:00:00 2001 From: Bogdan Dobrelya Date: Wed, 16 Aug 2017 11:04:27 +0200 Subject: Add docs and defaults for multi-master setup Additionally, add the lb group to contain lb nodes to the static inventory template. Include the lb group into the OSEv3 group, in order to apply the cluster group vars to it. Signed-off-by: Bogdan Dobrelya --- playbooks/provisioning/openstack/README.md | 13 +++++++++++++ .../openstack/sample-inventory/group_vars/OSEv3.yml | 4 ++++ roles/static_inventory/templates/inventory.j2 | 5 +++++ 3 files changed, 22 insertions(+) (limited to 'roles/static_inventory') diff --git a/playbooks/provisioning/openstack/README.md b/playbooks/provisioning/openstack/README.md index 099b017bb..358ed182b 100644 --- a/playbooks/provisioning/openstack/README.md +++ b/playbooks/provisioning/openstack/README.md @@ -162,6 +162,19 @@ The `openstack_inventory_path` points the directory to host the generated static It should point to the copied example inventory directory, otherwise ti creates a new one for you. +#### Multi-master configuration + +Please refer to the official documentation for the +[multi-master setup](https://docs.openshift.com/container-platform/3.6/install_config/install/advanced_install.html#multiple-masters) +and define the corresponding [inventory +variables](https://docs.openshift.com/container-platform/3.6/install_config/install/advanced_install.html#configuring-cluster-variables) +in `inventory/group_vars/OSEv3.yml`. For example, given a load balancer node +under the ansible group named `ext_lb`: + + openshift_master_cluster_method: native + openshift_master_cluster_hostname: "{{ groups.ext_lb.0 }}" + openshift_master_cluster_public_hostname: "{{ groups.ext_lb.0 }}" + #### Security notes Configure required `*_ingress_cidr` variables to restrict public access diff --git a/playbooks/provisioning/openstack/sample-inventory/group_vars/OSEv3.yml b/playbooks/provisioning/openstack/sample-inventory/group_vars/OSEv3.yml index 6ceeff827..9d47815ec 100644 --- a/playbooks/provisioning/openstack/sample-inventory/group_vars/OSEv3.yml +++ b/playbooks/provisioning/openstack/sample-inventory/group_vars/OSEv3.yml @@ -4,6 +4,10 @@ openshift_deployment_type: origin #openshift_release: v3.5 openshift_master_default_subdomain: "apps.{{ env_id }}.{{ public_dns_domain }}" +openshift_master_cluster_method: native +openshift_master_cluster_hostname: "{{ groups.lb.0|default(groups.masters.0) }}" +openshift_master_cluster_public_hostname: "{{ groups.lb.0|default(groups.masters.0) }}" + #openshift_cluster_node_labels: # app: # region: primary diff --git a/roles/static_inventory/templates/inventory.j2 b/roles/static_inventory/templates/inventory.j2 index 24dc9d4a8..987c98ec6 100644 --- a/roles/static_inventory/templates/inventory.j2 +++ b/roles/static_inventory/templates/inventory.j2 @@ -39,6 +39,7 @@ dns [OSEv3:children] nodes etcd +lb # Set variables common for all OSEv3 hosts #[OSEv3:vars] @@ -68,6 +69,9 @@ nodes.{{ stack_name }} [dns:children] dns.{{ stack_name }} +[lb:children] +lb.{{ stack_name }} + # Empty placeholders for all groups of the cluster nodes [masters.{{ stack_name }}] [etcd.{{ stack_name }}] @@ -75,6 +79,7 @@ dns.{{ stack_name }} [nodes.{{ stack_name }}] [app.{{ stack_name }}] [dns.{{ stack_name }}] +[lb.{{ stack_name }}] # BEGIN Autogenerated groups {% for group in groups %} -- cgit v1.2.3 From daa0b91119d2c16860a19b4ead2d0d128f8bc5ce Mon Sep 17 00:00:00 2001 From: Tomas Sedovic Date: Wed, 6 Sep 2017 10:24:16 +0200 Subject: Allow using a provider network (#701) * Allow using a provider network This adds a new option `openstack_provider_network_name` which will take a name of an existing network and put the servers there. It will also prevent creating floating IP addresses as the provider network's IPs should already be accessible without any additional routing required. Fixes #622 * Requested changes Don't fail on external/private networks and use role defaults for the provider network. * Add missing endif --- playbooks/provisioning/openstack/README.md | 18 ++++ playbooks/provisioning/openstack/prerequisites.yml | 2 + .../openstack/sample-inventory/group_vars/all.yml | 6 ++ playbooks/provisioning/openstack/stack_params.yaml | 10 +- roles/openstack-stack/defaults/main.yml | 1 + .../tasks/subnet_update_dns_servers.yaml | 1 + roles/openstack-stack/templates/heat_stack.yaml.j2 | 113 +++++++++++++++------ .../templates/heat_stack_server.yaml.j2 | 12 +++ roles/static_inventory/tasks/openstack.yml | 25 ++++- 9 files changed, 153 insertions(+), 35 deletions(-) (limited to 'roles/static_inventory') diff --git a/playbooks/provisioning/openstack/README.md b/playbooks/provisioning/openstack/README.md index b898351e6..4e74627dc 100644 --- a/playbooks/provisioning/openstack/README.md +++ b/playbooks/provisioning/openstack/README.md @@ -229,6 +229,24 @@ under the ansible group named `ext_lb`: openshift_master_cluster_hostname: "{{ groups.ext_lb.0 }}" openshift_master_cluster_public_hostname: "{{ groups.ext_lb.0 }}" +#### Provider Network + +Normally, the playbooks create a new Neutron network and subnet and attach +floating IP addresses to each node. If you have a provider network set up, this +is all unnecessary as you can just access servers that are placed in the +provider network directly. + +To use a provider network, set its name in `openstack_provider_network_name` in +`inventory/group_vars/all.yml`. + +If you set the provider network name, the `openstack_external_network_name` and +`openstack_private_network_name` fields will be ignored. + +**NOTE**: this will not update the nodes' DNS, so running openshift-ansible +right after provisioning will fail (unless you're using an external DNS server +your provider network knows about). You must make sure your nodes are able to +resolve each other by name. + #### Security notes Configure required `*_ingress_cidr` variables to restrict public access diff --git a/playbooks/provisioning/openstack/prerequisites.yml b/playbooks/provisioning/openstack/prerequisites.yml index a87c06705..f2f720f8b 100644 --- a/playbooks/provisioning/openstack/prerequisites.yml +++ b/playbooks/provisioning/openstack/prerequisites.yml @@ -65,10 +65,12 @@ os_networks_facts: name: "{{ openstack_external_network_name }}" register: network_result + when: not openstack_provider_network_name|default(None) - name: Check that network is available assert: that: "network_result.ansible_facts.openstack_networks" msg: "Network {{ openstack_external_network_name }} is not available" + when: not openstack_provider_network_name|default(None) # Check keypair # TODO kpilatov: there is no Ansible module for getting OS keypairs diff --git a/playbooks/provisioning/openstack/sample-inventory/group_vars/all.yml b/playbooks/provisioning/openstack/sample-inventory/group_vars/all.yml index 5028141d2..0e198342c 100644 --- a/playbooks/provisioning/openstack/sample-inventory/group_vars/all.yml +++ b/playbooks/provisioning/openstack/sample-inventory/group_vars/all.yml @@ -16,6 +16,12 @@ openstack_ssh_public_key: "openshift" openstack_external_network_name: "public" #openstack_private_network_name: "openshift-ansible-{{ stack_name }}-net" +## If you want to use a provider network, set its name here. +## NOTE: the `openstack_external_network_name` and +## `openstack_private_network_name` options will be ignored when using a +## provider network. +#openstack_provider_network_name: "provider" + # # Used Images # # - set specific images for roles by uncommenting corresponding lines # # - note: do not remove openstack_default_image_name definition diff --git a/playbooks/provisioning/openstack/stack_params.yaml b/playbooks/provisioning/openstack/stack_params.yaml index 60e9bcf45..484c06889 100644 --- a/playbooks/provisioning/openstack/stack_params.yaml +++ b/playbooks/provisioning/openstack/stack_params.yaml @@ -23,8 +23,14 @@ openstack_node_image: "{{ openstack_node_image_name | default(openstack_default_ openstack_lb_image: "{{ openstack_lb_image_name | default(openstack_default_image_name) }}" openstack_etcd_image: "{{ openstack_etcd_image_name | default(openstack_default_image_name) }}" openstack_dns_image: "{{ openstack_dns_image_name | default(openstack_default_image_name) }}" -openstack_private_network: "{{ openstack_private_network_name | default ('openshift-ansible-' + stack_name + '-net') }}" -external_network: "{{ openstack_external_network_name }}" +openstack_private_network: >- + {% if openstack_provider_network_name | default(None) -%} + {{ openstack_provider_network_name }} + {%- else -%} + {{ openstack_private_network_name | default ('openshift-ansible-' + stack_name + '-net') }} + {%- endif -%} +provider_network: "{{ openstack_provider_network_name | default(None) }}" +external_network: "{{ openstack_external_network_name | default(None) }}" num_etcd: "{{ openstack_num_etcd | default(0) }}" num_masters: "{{ openstack_num_masters }}" num_nodes: "{{ openstack_num_nodes }}" diff --git a/roles/openstack-stack/defaults/main.yml b/roles/openstack-stack/defaults/main.yml index fbca0bdf6..c16b5dc00 100644 --- a/roles/openstack-stack/defaults/main.yml +++ b/roles/openstack-stack/defaults/main.yml @@ -15,3 +15,4 @@ dns_volume_size: 1 lb_volume_size: 5 use_bastion: False ui_ssh_tunnel: False +provider_network: None diff --git a/roles/openstack-stack/tasks/subnet_update_dns_servers.yaml b/roles/openstack-stack/tasks/subnet_update_dns_servers.yaml index be4f07b97..af28fc98f 100644 --- a/roles/openstack-stack/tasks/subnet_update_dns_servers.yaml +++ b/roles/openstack-stack/tasks/subnet_update_dns_servers.yaml @@ -6,3 +6,4 @@ state: present use_default_subnetpool: yes dns_nameservers: "{{ [private_dns_server|default(public_dns_nameservers[0])]|union(public_dns_nameservers)|unique }}" + when: not provider_network diff --git a/roles/openstack-stack/templates/heat_stack.yaml.j2 b/roles/openstack-stack/templates/heat_stack.yaml.j2 index ea2742a2c..b6b5e3613 100644 --- a/roles/openstack-stack/templates/heat_stack.yaml.j2 +++ b/roles/openstack-stack/templates/heat_stack.yaml.j2 @@ -73,6 +73,7 @@ outputs: resources: +{% if not provider_network %} net: type: OS::Neutron::Net properties: @@ -129,6 +130,8 @@ resources: router_id: { get_resource: router } subnet_id: { get_resource: subnet } +{% endif %} + # keypair: # type: OS::Nova::KeyPair # properties: @@ -501,22 +504,29 @@ resources: image: {{ openstack_etcd_image }} flavor: {{ etcd_flavor }} key_name: {{ ssh_public_key }} +{% if provider_network %} + net: {{ provider_network }} + net_name: {{ provider_network }} +{% else %} net: { get_resource: net } subnet: { get_resource: subnet } - secgrp: - - { get_resource: {% if openstack_flat_secgrp|default(False)|bool %}flat-secgrp{% else %}etcd-secgrp{% endif %} } - - { get_resource: common-secgrp } -{% if not use_bastion|bool %} - floating_network: {{ external_network }} -{% endif %} net_name: str_replace: template: openshift-ansible-cluster_id-net params: cluster_id: {{ stack_name }} +{% endif %} + secgrp: + - { get_resource: {% if openstack_flat_secgrp|default(False)|bool %}flat-secgrp{% else %}etcd-secgrp{% endif %} } + - { get_resource: common-secgrp } +{% if not use_bastion|bool and not provider_network %} + floating_network: {{ external_network }} +{% endif %} volume_size: {{ etcd_volume_size }} +{% if not provider_network %} depends_on: - interface +{% endif %} {% if num_masters|int > 1 %} loadbalancer: @@ -544,20 +554,29 @@ resources: image: {{ openstack_lb_image }} flavor: {{ lb_flavor }} key_name: {{ ssh_public_key }} +{% if provider_network %} + net: {{ provider_network }} + net_name: {{ provider_network }} +{% else %} net: { get_resource: net } subnet: { get_resource: subnet } - secgrp: - - { get_resource: lb-secgrp } - - { get_resource: common-secgrp } - floating_network: {{ external_network }} net_name: str_replace: template: openshift-ansible-cluster_id-net params: cluster_id: {{ stack_name }} +{% endif %} + secgrp: + - { get_resource: lb-secgrp } + - { get_resource: common-secgrp } + {% if not provider_network %} + floating_network: {{ external_network }} + {% endif %} volume_size: {{ lb_volume_size }} + {% if not provider_network %} depends_on: - interface + {% endif %} {% endif %} masters: @@ -589,8 +608,18 @@ resources: image: {{ openstack_master_image }} flavor: {{ master_flavor }} key_name: {{ ssh_public_key }} +{% if provider_network %} + net: {{ provider_network }} + net_name: {{ provider_network }} +{% else %} net: { get_resource: net } subnet: { get_resource: subnet } + net_name: + str_replace: + template: openshift-ansible-cluster_id-net + params: + cluster_id: {{ stack_name }} +{% endif %} secgrp: {% if openstack_flat_secgrp|default(False)|bool %} - { get_resource: flat-secgrp } @@ -602,17 +631,14 @@ resources: {% endif %} {% endif %} - { get_resource: common-secgrp } -{% if not use_bastion|bool %} +{% if not use_bastion|bool and not provider_network %} floating_network: {{ external_network }} {% endif %} - net_name: - str_replace: - template: openshift-ansible-cluster_id-net - params: - cluster_id: {{ stack_name }} volume_size: {{ master_volume_size }} +{% if not provider_network %} depends_on: - interface +{% endif %} compute_nodes: type: OS::Heat::ResourceGroup @@ -650,22 +676,29 @@ resources: image: {{ openstack_node_image }} flavor: {{ node_flavor }} key_name: {{ ssh_public_key }} +{% if provider_network %} + net: {{ provider_network }} + net_name: {{ provider_network }} +{% else %} net: { get_resource: net } subnet: { get_resource: subnet } - secgrp: - - { get_resource: {% if openstack_flat_secgrp|default(False)|bool %}flat-secgrp{% else %}node-secgrp{% endif %} } - - { get_resource: common-secgrp } -{% if not use_bastion|bool %} - floating_network: {{ external_network }} -{% endif %} net_name: str_replace: template: openshift-ansible-cluster_id-net params: cluster_id: {{ stack_name }} +{% endif %} + secgrp: + - { get_resource: {% if openstack_flat_secgrp|default(False)|bool %}flat-secgrp{% else %}node-secgrp{% endif %} } + - { get_resource: common-secgrp } +{% if not use_bastion|bool and not provider_network %} + floating_network: {{ external_network }} +{% endif %} volume_size: {{ node_volume_size }} +{% if not provider_network %} depends_on: - interface +{% endif %} infra_nodes: type: OS::Heat::ResourceGroup @@ -697,8 +730,18 @@ resources: image: {{ openstack_infra_image }} flavor: {{ infra_flavor }} key_name: {{ ssh_public_key }} +{% if provider_network %} + net: {{ provider_network }} + net_name: {{ provider_network }} +{% else %} net: { get_resource: net } subnet: { get_resource: subnet } + net_name: + str_replace: + template: openshift-ansible-cluster_id-net + params: + cluster_id: {{ stack_name }} +{% endif %} secgrp: # TODO(bogdando) filter only required node rules into infra-secgrp {% if openstack_flat_secgrp|default(False)|bool %} @@ -711,15 +754,14 @@ resources: {% endif %} - { get_resource: infra-secgrp } - { get_resource: common-secgrp } +{% if not provider_network %} floating_network: {{ external_network }} - net_name: - str_replace: - template: openshift-ansible-cluster_id-net - params: - cluster_id: {{ stack_name }} +{% endif %} volume_size: {{ infra_volume_size }} +{% if not provider_network %} depends_on: - interface +{% endif %} {% if num_dns|int > 0 %} dns: @@ -747,18 +789,27 @@ resources: image: {{ openstack_dns_image }} flavor: {{ dns_flavor }} key_name: {{ ssh_public_key }} +{% if provider_network %} + net: {{ provider_network }} + net_name: {{ provider_network }} +{% else %} net: { get_resource: net } subnet: { get_resource: subnet } - secgrp: - - { get_resource: dns-secgrp } - - { get_resource: common-secgrp } - floating_network: {{ external_network }} net_name: str_replace: template: openshift-ansible-cluster_id-net params: cluster_id: {{ stack_name }} +{% endif %} + secgrp: + - { get_resource: dns-secgrp } + - { get_resource: common-secgrp } +{% if not provider_network %} + floating_network: {{ external_network }} +{% endif %} volume_size: {{ dns_volume_size }} +{% if not provider_network %} depends_on: - interface {% endif %} +{% endif %} diff --git a/roles/openstack-stack/templates/heat_stack_server.yaml.j2 b/roles/openstack-stack/templates/heat_stack_server.yaml.j2 index 32fb166f6..a520a8fe2 100644 --- a/roles/openstack-stack/templates/heat_stack_server.yaml.j2 +++ b/roles/openstack-stack/templates/heat_stack_server.yaml.j2 @@ -61,20 +61,24 @@ parameters: label: Net name description: Net name +{% if not provider_network %} subnet: type: string label: Subnet ID description: Subnet resource +{% endif %} secgrp: type: comma_delimited_list label: Security groups description: Security group resources +{% if not provider_network %} floating_network: type: string label: Floating network description: Network to allocate floating IP from +{% endif %} availability_zone: type: string @@ -117,7 +121,11 @@ outputs: - server - addresses - { get_param: net_name } +{% if provider_network %} + - 0 +{% else %} - 1 +{% endif %} - addr resources: @@ -147,15 +155,19 @@ resources: type: OS::Neutron::Port properties: network: { get_param: net } +{% if not provider_network %} fixed_ips: - subnet: { get_param: subnet } +{% endif %} security_groups: { get_param: secgrp } +{% if not provider_network %} floating-ip: type: OS::Neutron::FloatingIP properties: floating_network: { get_param: floating_network } port_id: { get_resource: port } +{% endif %} {% if not ephemeral_volumes|default(false)|bool %} cinder_volume: diff --git a/roles/static_inventory/tasks/openstack.yml b/roles/static_inventory/tasks/openstack.yml index 75d0ee6d5..e36974d93 100644 --- a/roles/static_inventory/tasks/openstack.yml +++ b/roles/static_inventory/tasks/openstack.yml @@ -24,6 +24,15 @@ when: - refresh_inventory|bool + - name: set_fact for openstack inventory nodes with provider network + set_fact: + registered_nodes_floating: "{{ (registered_nodes_output.stdout | from_json) | json_query(q) }}" + vars: + q: "[] | [?metadata.clusterid=='{{stack_name}}'] | [?public_v4=='']" + when: + - refresh_inventory|bool + - openstack_provider_network_name|default(None) + - name: Add cluster nodes w/o floating IPs to inventory with_items: "{{ registered_nodes|difference(registered_nodes_floating) }}" add_host: @@ -49,7 +58,14 @@ add_host: name: '{{ item.name }}' groups: '{{ item.metadata.group }}' - ansible_host: "{% if use_bastion|bool %}{{ item.name }}{% else %}{{ item.public_v4 }}{% endif %}" + ansible_host: >- + {% if use_bastion|bool -%} + {{ item.name }} + {%- elif openstack_provider_network_name|default(None) -%} + {{ item.private_v4 }} + {%- else -%} + {{ item.public_v4 }} + {%- endif %} ansible_fqdn: '{{ item.name }}' ansible_user: '{{ ssh_user }}' ansible_private_key_file: '{{ private_ssh_key }}' @@ -57,7 +73,12 @@ private_v4: >- {% set node = registered_nodes | json_query("[?name=='" + item.name + "']") -%} {{ node[0].addresses[openstack_private_network|quote][0].addr }} - public_v4: '{{ item.public_v4 }}' + public_v4: >- + {% if openstack_provider_network_name|default(None) -%} + {{ item.private_v4 }} + {%- else -%} + {{ item.public_v4 }} + {%- endif %} - name: Add bastion node to inventory add_host: -- cgit v1.2.3