system-config/playbooks/zuul/run-base.yaml
Ian Wienand 0c90c128d7
Reference bastion through prod_bastion group
In thinking harder about the bootstrap process, it struck me that the
"bastion" group we have is two separate ideas that become a bit
confusing because they share a name.

We have the testing and production paths that need to find a single
bridge node so they can run their nested Ansible.  We've recently
merged changes to the setup playbooks to not hard-code the bridge node
and they now use groups["bastion"][0] to find the bastion host -- but
this group is actually orthogonal to the group of the same name
defined in inventory/service/groups.yaml.

The testing and production paths are running on the executor, and, as
mentioned, need to know the bridge node to log into.  For the testing
path this is happening via the group created in the job definition
from zuul.d/system-config-run.yaml.  For the production jobs, this
group is populated via the add-bastion-host role which dynamically
adds the bridge host and group.

Only the *nested* Ansible running on the bastion host reads
s-c:inventory/service/groups.yaml.  None of the nested-ansible
playbooks need to target only the currently active bastion host.  For
example, we can define as many bridge nodes as we like in the
inventory and run service-bridge.yaml against them.  It won't matter
because the production jobs know the host that is the currently active
bridge as described above.

So, instead of using the same group name in two contexts, rename the
testing/production group "prod_bastion".  groups["prod_bastion"][0]
will be the host that the testing/production jobs use as the bastion
host -- references are updated in this change (i.e. the two places
this group is defined -- the group name in the system-config-run jobs,
and add-bastion-host for production).

We then can return the "bastion" group match to bridge*.opendev.org in
inventory/service/groups.yaml.

This fixes a bootstrapping problem -- if you launch, say,
bridge03.opendev.org the launch node script will now apply the
base.yaml playbook against it, and correctly apply all variables from
the "bastion" group which now matches this new host.  This is what we
want to ensure, e.g. the zuul user and keys are correctly populated.

The other thing we can do here is change the testing path
"prod_bastion" hostname to "bridge99.opendev.org".  By doing this we
ensure we're not hard-coding for the production bridge host in any way
(since if both testing and production are called bridge01.opendev.org
we can hide problems).  This is a big advantage when we want to rotate
the production bridge host, as we can be certain there's no hidden
dependencies.

Change-Id: I137ab824b9a09ccb067b8d5f0bb2896192291883
2022-11-04 09:18:35 +11:00

244 lines
8.8 KiB
YAML

- import_playbook: ../bootstrap-bridge.yaml
vars:
root_rsa_key: "{{ lookup('file', zuul.executor.work_root + '/' + zuul.build + '_id_rsa', rstrip=False) }}"
ansible_cron_disable_job: true
cloud_launcher_disable_job: true
# setup opendev CA
- hosts: prod_bastion[0]
become: true
tasks:
- name: Make temporary dir for CA generation
tempfile:
state: directory
register: _ca_tempdir
- name: Create CA PEM/crt
shell: |
set -x
# Generate a CA key
openssl genrsa -out ca.key 2048
# Create fake CA root certificate
openssl req -x509 -new -nodes -key ca.key -sha256 -days 30 -subj "/C=US/ST=CA/O=OpenDev Infra" -out ca.crt
args:
chdir: '{{ _ca_tempdir.path }}'
executable: /bin/bash
- name: Save key
slurp:
src: '{{ _ca_tempdir.path }}/ca.key'
register: _opendev_ca_key
- name: Save certificate
slurp:
src: '{{ _ca_tempdir.path }}//ca.crt'
register: _opendev_ca_certificate
- name: Cleanup tempdir
file:
path: '{{ _ca_tempdir.path }}'
state: absent
when: _ca_tempdir.path is defined
- hosts: all
become: true
tasks:
- name: Make CA directory
file:
path: '/etc/opendev-ca'
state: directory
owner: root
group: root
mode: 0600
- name: Import files
shell: 'echo "{{ item.content }}" | base64 -d > {{ item.file }}'
args:
creates: '{{ item.file }}'
loop:
- file: '/etc/opendev-ca/ca.key'
content: '{{ hostvars[groups["prod_bastion"][0]]["_opendev_ca_key"]["content"] }}'
- file: '/etc/opendev-ca/ca.crt'
content: '{{ hostvars[groups["prod_bastion"][0]]["_opendev_ca_certificate"]["content"] }}'
- name: Install and trust certificate
shell:
cmd: |
cp /etc/opendev-ca/ca.crt /usr/local/share/ca-certificates/opendev-infra-ca.crt
update-ca-certificates
- hosts: prod_bastion[0]
become: true
tasks:
- name: Write inventory on bridge
include_role:
name: write-inventory
vars:
write_inventory_dest: /home/zuul/src/opendev.org/opendev/system-config/inventory/base/gate-hosts.yaml
write_inventory_exclude_hostvars:
- ansible_user
- ansible_python_interpreter
write_inventory_additional_hostvars:
public_v4: nodepool.private_ipv4
public_v6: nodepool.public_ipv6
- name: Add groups config for test nodes
template:
src: "templates/gate-groups.yaml.j2"
dest: "/etc/ansible/hosts/gate-groups.yaml"
- name: Update ansible.cfg to use job inventory
ini_file:
path: /etc/ansible/ansible.cfg
section: defaults
option: inventory
value: /home/zuul/src/opendev.org/opendev/system-config/inventory/base/gate-hosts.yaml,/home/zuul/src/opendev.org/opendev/system-config/inventory/service/groups.yaml,/etc/ansible/hosts/gate-groups.yaml
- name: Make host_vars directory
file:
path: "/etc/ansible/hosts/host_vars"
state: directory
- name: Make group_vars directory
file:
path: "/etc/ansible/hosts/group_vars"
state: directory
- name: Write hostvars files
vars:
bastion_ipv4: "{{ nodepool['public_ipv4'] }}"
bastion_ipv6: "{{ nodepool['public_ipv6'] }}"
bastion_public_key: "{{ lookup('file', zuul.executor.work_root + '/' + zuul.build + '_id_rsa.pub') }}"
iptables_test_public_tcp_ports:
# Zuul web console
- 19885
# selenium
- 4444
template:
src: "templates/{{ item }}.j2"
dest: "/etc/ansible/hosts/{{ item }}"
loop:
- group_vars/all.yaml
- group_vars/adns.yaml
- group_vars/bastion.yaml
- group_vars/eavesdrop.yaml
- group_vars/nodepool.yaml
- group_vars/ns.yaml
- group_vars/registry.yaml
- group_vars/gitea.yaml
- group_vars/gitea-lb.yaml
- group_vars/kerberos-kdc.yaml
- group_vars/keycloak.yaml
- group_vars/letsencrypt.yaml
- group_vars/meetpad.yaml
- group_vars/jvb.yaml
- group_vars/refstack.yaml
- group_vars/registry.yaml
- group_vars/control-plane-clouds.yaml
- group_vars/afs-client.yaml
- group_vars/zuul-lb.yaml
- group_vars/zuul.yaml
- group_vars/zuul-executor.yaml
- group_vars/zuul-merger.yaml
- group_vars/zuul-scheduler.yaml
- group_vars/zuul-web.yaml
- host_vars/codesearch01.opendev.org.yaml
- host_vars/etherpad01.opendev.org.yaml
- host_vars/letsencrypt01.opendev.org.yaml
- host_vars/letsencrypt02.opendev.org.yaml
- host_vars/lists.openstack.org.yaml
- host_vars/lists.katacontainers.io.yaml
- host_vars/gitea99.opendev.org.yaml
- host_vars/grafana01.opendev.org.yaml
- host_vars/mirror01.openafs.provider.opendev.org.yaml
- host_vars/mirror02.openafs.provider.opendev.org.yaml
- host_vars/mirror-update99.opendev.org.yaml
- host_vars/paste99.opendev.org.yaml
- host_vars/refstack01.openstack.org.yaml
- host_vars/review99.opendev.org.yaml
- name: Display group membership
command: ansible localhost -m debug -a 'var=groups'
- name: Run base.yaml
shell: 'set -o pipefail && ansible-playbook -f 50 -v /home/zuul/src/opendev.org/opendev/system-config/playbooks/base.yaml 2>&1 | tee /var/log/ansible/base.yaml.log'
args:
executable: /bin/bash
- name: Run bridge service playbook
shell: 'set -o pipefail && ansible-playbook -v /home/zuul/src/opendev.org/opendev/system-config/playbooks/service-bridge.yaml 2>&1 | tee /var/log/ansible/service-bridge.yaml.log'
args:
executable: /bin/bash
- name: Run dstat logger playbook
shell: 'set -o pipefail && ansible-playbook -v /home/zuul/src/opendev.org/opendev/system-config/playbooks/service-dstatlogger.yaml 2>&1 | tee /var/log/ansible/service-dstatlogger.yaml.log'
args:
executable: /bin/bash
- name: Run playbook
when: run_playbooks is defined
loop: "{{ run_playbooks }}"
shell: "set -o pipefail && ansible-playbook -f 50 -v /home/zuul/src/opendev.org/opendev/system-config/{{ item }} 2>&1 | tee /var/log/ansible/{{ item | basename }}.log"
args:
executable: /bin/bash
- name: Build list of playbook logs
find:
paths: '/var/log/ansible'
patterns: '*.yaml.log'
register: _run_playbooks_logs
- name: Encrypt playbook logs
when: run_playbooks is defined
include_role:
name: encrypt-logs
vars:
encrypt_logs_files: '{{ _run_playbooks_logs.files | map(attribute="path") | list }}'
encrypt_logs_artifact_path: '{{ groups["prod_bastion"][0] }}/ansible'
encrypt_logs_download_script_path: '/var/log/ansible'
- name: Run test playbook
when: run_test_playbook is defined
shell: "set -o pipefail && ANSIBLE_ROLES_PATH=/home/zuul/src/opendev.org/opendev/system-config/playbooks/roles ansible-playbook -v /home/zuul/src/opendev.org/opendev/system-config/{{ run_test_playbook }} 2>&1 | tee /var/log/ansible/{{ run_test_playbook | basename }}.log"
args:
executable: /bin/bash
- name: Generate testinfra extra data fixture
set_fact:
testinfra_extra_data:
zuul_job: '{{ zuul.job }}'
zuul: '{{ zuul }}'
- name: Write out testinfra extra data fixture
copy:
content: '{{ testinfra_extra_data | to_nice_yaml(indent=2) }}'
dest: '/home/zuul/testinfra_extra_data_fixture.yaml'
- name: Make screenshots directory
file:
path: '/var/log/screenshots'
state: directory
- name: Return screenshots artifact
zuul_return:
data:
zuul:
artifacts:
- name: Screenshots
url: '{{ groups["prod_bastion"][0] }}/screenshots'
- name: Allow PBR's git calls to operate in system-config, despite not owning it
command: git config --global safe.directory /home/zuul/src/opendev.org/opendev/system-config
- name: Run and collect testinfra
block:
- name: Run testinfra to validate configuration
include_role:
name: tox
vars:
tox_envlist: testinfra
# This allows us to run from external projects (like testinfra
# itself)
tox_environment:
TESTINFRA_EXTRA_DATA: '/home/zuul/testinfra_extra_data_fixture.yaml'
zuul_work_dir: src/opendev.org/opendev/system-config
always:
- name: Return testinfra report artifact
zuul_return:
data:
zuul:
artifacts:
- name: testinfra results
url: '{{ groups["prod_bastion"][0] }}/test-results.html'