Skip to content

Commit c6b10a1

Browse files
authored
Merge pull request #1471 from stackhpc/add-gitlab-kayobe-automation
Add GitLab based Kayobe-Automation
2 parents 264ff7c + 2e27317 commit c6b10a1

File tree

8 files changed

+356
-2
lines changed

8 files changed

+356
-2
lines changed

doc/source/configuration/ci-cd.rst

Lines changed: 212 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,21 @@ CI/CD
55
Concepts
66
========
77

8-
The CI/CD system developed for managing Kayobe based OpenStack clouds is composed of three main components; workflows, runners and kayobe automation.
8+
The CI/CD system developed for managing Kayobe based OpenStack clouds is composed of four main components; workflows, runners, OpenBao and kayobe automation.
9+
910
Firstly, the workflows are files which describe a series of tasks to be performed in relation to the deployed cloud.
1011
These workflows are executed on request, on schedule or in response to an event such as a pull request being opened.
12+
1113
The workflows are designed to carry out various day-to-day activites such as; running Tempest tests, configuring running services or displaying the change to configuration files if a pull request is merged.
1214
Secondly, in order for the workflows to run against a cloud we would need private runners present within the cloud positioned in such a way they can reach the internal network and public API.
1315
Deployment of private runners is supported by all major providers with the use of community developed Ansible roles.
16+
17+
Thirdly, OpenBao is used to store secrets on the same virtual machine the runners are hosted within.
18+
This provides a secure way of storing secrets and variables which can be accessed by the runners when executing workflows and ensures that secrets never have to leave the cloud.
19+
1420
Finally, due to the requirement that we support various different platforms tooling in the form of `Kayobe automation <https://github.com/stackhpc/kayobe-automation/>`__ was developed.
1521
This tooling is not tied to any single CI/CD platform as all tasks are a series of shell script and Ansible playbooks which are designed to run in a purpose build kayobe container.
22+
1623
This is complemented by the use of an Ansible collection known as `stackhpc.kayobe_workflows <https://github.com/stackhpc/ansible-collection-kayobe-workflows/>`__ which aims to provide users with a quick and easy way of customising all workflows to fit within a customer's cloud.
1724

1825
Currently we support the creation and deployment of workflows for GitHub with Gitlab support being actively worked upon.
@@ -42,6 +49,12 @@ These services will listen for jobs which have been tagged appropriately and dis
4249
The runners will need to be deployed using existing roles and playbooks whereby the binary/package is downloaded and registered using a special token.
4350
In some deployments runner hosts can be shared between environments however this is not always true and dedicated hosts will need to be used for each environment you intend to deploy kayobe automation within.
4451

52+
OpenBao
53+
-------
54+
55+
OpenBao is recommended when deploying kayobe automation to achieve a simple and secure way of storing secrets.
56+
OpenBao can easily be configured to hold the secrets for all environments and only permit access to the runners which require them utilising different authorisation mechanisms such as GitLab's JWT (JSON Web Token).
57+
4558
GitHub Actions
4659
=================
4760

@@ -181,3 +194,201 @@ Sometimes the kayobe docker image must be rebuilt the reasons for this include b
181194
* Update kolla-ansible
182195
* UID/GID collision when deploying workflows to a new environment
183196
* Prior to deployment of new a OpenStack release
197+
198+
GitLab Pipelines
199+
================
200+
201+
To enable CI/CD where GitLab Pipelines is used please follow the steps described below starting with the deployment of the runners.
202+
203+
Runner Deployment
204+
-----------------
205+
206+
1. Identify a suitable host for hosting the runners.
207+
Ideally an infra-vm would be deployed to allow for easily compartmentalising the runners from the rest of the environment.
208+
8 VCPUs and 16GB of RAM is recommended for the guest machine however this may need to be adjusted for larger deployments.
209+
Whether the host is in an infra-vm or not it will need access to the :code:`admin_network` or :code:`provision_oc_network`, :code:`public_network` and the :code:`pulp registry` on the seed.
210+
The steps will assume that an infra-vm will be used for the purpose of hosting the runners.
211+
212+
2. Edit the environment's :code:`${KAYOBE_CONFIG_PATH}/environments/${KAYOBE_ENVIRONMENT}/inventory/hosts` to define the host(s) that will host the runners.
213+
214+
.. code-block:: ini
215+
216+
[gitlab-runners]
217+
gitlab-runner-01
218+
219+
4. Provide all the relevant Kayobe :code:`group_vars` for :code:`gitlab-runners` under :code:`${KAYOBE_CONFIG_PATH}/environments/${KAYOBE_ENVIRONMENT}/inventory/group_vars/gitlab-runners`
220+
* `infra-vms` ensuring all required `infra_vm_extra_network_interfaces` are defined
221+
* `network-interfaces`
222+
* `allocated IPs`
223+
224+
5. Edit the ``${KAYOBE_CONFIG_PATH}/inventory/group_vars/gitlab-runners/runners.yml`` file which will contain the variables required to deploy a series of runners.
225+
Below is an example of how GitLab runners can be configured for deployment.
226+
In this example we have two runners, one for production and one for staging and will both be deployed on the same host.
227+
This might not be possible for all deployments as multiple environments may require different runners as no single runner can serve all environments.
228+
Note a GitLab runner can run multiple jobs concurrently so deploying a single runner per environment is recommended.
229+
230+
.. code-block:: yaml
231+
232+
---
233+
gitlab_runner_coordinator_url: "https://gitlab.example.com"
234+
gitlab_runner_runners:
235+
- name: "Kayobe Automation Runner [Production] #1"
236+
executor: docker
237+
docker_image: 'alpine'
238+
token: "{{ secrets_gitlab_production_runner_token }}"
239+
env_vars:
240+
- "GIT_CONFIG_COUNT=1"
241+
- "GIT_CONFIG_KEY_0=safe.directory"
242+
- "GIT_CONFIG_VALUE_0=*"
243+
tags:
244+
- kayobe
245+
- openstack
246+
- production
247+
docker_volumes:
248+
- "/var/run/docker.sock:/var/run/docker.sock"
249+
- "/opt/.docker/config.json:/root/.docker/config.json:ro"
250+
- "/cache"
251+
extra_configs:
252+
runners.docker:
253+
network_mode: host
254+
- name: "Kayobe Automation Runner [Staging] #1"
255+
executor: docker
256+
docker_image: 'alpine'
257+
token: "{{ secrets_gitlab_staging_runner_token }}"
258+
env_vars:
259+
- "GIT_CONFIG_COUNT=1"
260+
- "GIT_CONFIG_KEY_0=safe.directory"
261+
- "GIT_CONFIG_VALUE_0=*"
262+
tags:
263+
- kayobe
264+
- openstack
265+
- staging
266+
docker_volumes:
267+
- "/var/run/docker.sock:/var/run/docker.sock"
268+
- "/opt/.docker/config.json:/root/.docker/config.json:ro"
269+
- "/cache"
270+
extra_configs:
271+
runners.docker:
272+
network_mode: host
273+
274+
6. Obtain a runner token for each runner that is required for deployment.
275+
This token can be obtained by visiting the GitLab project -> Settings -> CI/CD -> Runners -> New project runner -> Complete the form including any tags used by the runners such as kayobe, openstack and environment_name.
276+
Once the token has been obtained, add it to :code:`secrets.yml` under :code:`secrets_gitlab_production_runner_token` and :code:`secrets_gitlab_staging_runner_token`
277+
278+
7. Deploy the infra-vm
279+
280+
.. code-block:: bash
281+
282+
kayobe infra vm provision --limit gitlab-runner-01
283+
284+
8. Perform a host configure against the infra-vm
285+
286+
.. code-block:: bash
287+
288+
kayobe infra vm host configure --limit gitlab-runner-01
289+
290+
9. Run :code:`kayobe playbook run ${KAYOBE_CONFIG_PATH}/ansible/deploy-gitlab-runner.yml`
291+
292+
10. Check runners have registered properly by visiting the repository's :code:`CI/CD` tab -> :code:`Runners`
293+
294+
11. The contents of :code:`/opt/.docker/config.json` on the runner should be added to GitLab CI/CD settings as a sercret variable if GitLab version permits otherwise variable is fine.
295+
This is required to allow the runners to pull images from the registry.
296+
Visit the GitLab project -> Settings -> CI/CD -> Variables -> Add a new variable with the key :code:`DOCKER_AUTH_CONFIG` and the value of the contents of :code:`/opt/.docker/config.json`
297+
298+
OpenBao Deployment
299+
------------------
300+
301+
OpenBao must be installed on the same host as the runners.
302+
If you have multiple environments that each have the own runners then OpenBao must be installed on each host.
303+
However, if you have a single host that is shared between environments then OpenBao only needs to be installed once and can be achieved by running the following playbook.
304+
305+
.. code-block:: bash
306+
307+
kayobe playbook run ${KAYOBE_CONFIG_PATH}/ansible/deploy-openbao-kayobe-automation.yml
308+
309+
.. note::
310+
311+
If you are sharing OpenBao between environments then you will need to rerun the playbook under each environment to ensure that the correct secrets are available to the runners.
312+
You may use :code:`--tags add_secrets` to skip the deployment within other environments.
313+
For this to work you will need to copy :code:`vault/kayobe-automation-keys.json` from the first environment to the other environments in addition to copying the host definition of the gitlab runner add network IP.
314+
315+
Once the above playbook has been applied you need to grab the root token from :code:`vault/kayobe-automation-keys.json` as you will need this to enable JWT support.
316+
This would also be an opportune time to encrypt the :code:`vault/kayobe-automation-keys.json` to protect the contents.
317+
318+
.. code-block:: bash
319+
320+
ansible-vault encrypt vault/kayobe-automation-keys.json --vault-password-file ~/.vault.password
321+
322+
In order to enable JWT support the following steps must be carried out within the openbao container on the runner host.
323+
324+
1. SSH into the runner host
325+
326+
2. Run :code:`sudo docker exec -it bao sh`
327+
328+
3. Run :code:`export BAO_ADDR=http://127.0.0.1:8200`
329+
330+
4. Run :code:`bao login` and use root token
331+
332+
5. Run the following to enable and configure JWT support
333+
334+
.. note::
335+
336+
The following steps are an example and should be adapted to suit your deployment.
337+
For example project_id within the gitlab role will need ID of the project that the runners are registered against.
338+
This can acquired by visiting the project -> Settings -> General -> General project settings -> Project ID.
339+
340+
.. code-block:: bash
341+
342+
bao auth enable jwt
343+
bao policy write kayobe-automation - <<EOF
344+
path "kayobe-automation/*" {
345+
capabilities = [ "read" ]
346+
}
347+
EOF
348+
bao write auth/jwt/role/gitlab - <<EOF
349+
{
350+
"role_type": "jwt",
351+
"token_explicit_max_ttl": 60,
352+
"user_claim": "user_email",
353+
"bound_audiences": "http://127.0.0.1:8200",
354+
"bound_claims": {
355+
"project_id": "ADD_PROJECT_ID_HERE"
356+
},
357+
"policies": ["kayobe-automation"]
358+
}
359+
EOF
360+
bao write auth/jwt/config \
361+
jwks_url="https://gitlab.example.com/oauth/discovery/keys" \
362+
bound_issuer="https://gitlab.example.com"
363+
364+
GitLab Pipelines
365+
----------------
366+
367+
1. Edit :code:`${KAYOBE_CONFIG_PATH}/inventory/group_vars/gitlab-writer/writer.yml` or environment equivalent the appropriate changes to your deployments specific needs.
368+
See documentation for `stackhpc.kayobe_workflows.gitlab <https://github.com/stackhpc/ansible-collection-kayobe-workflows/tree/main/roles/gitlab>`__.
369+
Following the instructions in the documentation will allow you to customise the workflows to fit within your deployment.
370+
If using multiple environments ensure that :code:`gitlab_kayobe_environments` is updated to reflect all environments present in the deployment.
371+
Also consider the impact runbooks might have as the runbooks are designed with a particular cloud in mind and may not be suitable for all deployments such as hyperconverged deployments with Ceph on hypervisors.
372+
373+
2. Run :code:`kayobe playbook run ${KAYOBE_CONFIG_PATH}/ansible/write-gitlab-pipelines.yml`
374+
375+
3. Commit and push all newly generated pipelines found under root of the repository.
376+
377+
Things to consider
378+
==================
379+
380+
- Adjust General Pipeline settings by visiting the project -> Settings -> CI/CD -> General pipelines
381+
- Disable :code:`Public Pipelines`
382+
- Disable :code:`Auto-cancel redundant pipelines`
383+
- Disable :code:`Prevent outdated deployment jobs`
384+
- Increase :code:`Timeout` to :code:`12h`
385+
386+
- Disable Auto DevOps in the GitLab project settings by visiting the project -> Settings -> CI/CD -> Auto DevOps -> Disable Auto DevOps
387+
388+
Sometimes the kayobe docker image must be rebuilt. The reasons for this include but are not limited to the following;
389+
390+
* Change :code:`$KAYOBE_CONFIG_PATH/ansible/requirements.yml`
391+
* Change to requirements.txt
392+
* Update Kayobe
393+
* Update kolla-ansible
394+
* Prior to deployment of new a OpenStack release
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
---
2+
- name: Deploy GitLab runners
3+
hosts: gitlab-runners
4+
become: true
5+
pre_tasks:
6+
- name: Ensure /opt/.docker folder exists
7+
ansible.builtin.file:
8+
path: /opt/.docker
9+
state: directory
10+
11+
- name: Ensure docker/config.json exists for runner
12+
ansible.builtin.copy:
13+
content: |
14+
{
15+
"auths": {
16+
"{{ pulp_url | regex_replace('^https?://|^http?://', '') }}": {
17+
"auth": "{{ (pulp_username + ':' + pulp_password) | b64encode }}"
18+
}
19+
}
20+
}
21+
dest: /opt/.docker/config.json
22+
mode: "0600"
23+
roles:
24+
- role: riemers.gitlab-runner
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
---
2+
- name: Deploy OpenBao on the runners
3+
any_errors_fatal: true
4+
gather_facts: true
5+
hosts: github-runners,gitlab-runners
6+
tasks:
7+
- name: Set a fact about the virtualenv on the remote system
8+
ansible.builtin.set_fact:
9+
virtualenv: "{{ ansible_python_interpreter | dirname | dirname }}"
10+
when:
11+
- ansible_python_interpreter is defined
12+
- not ansible_python_interpreter.startswith('/bin/')
13+
- not ansible_python_interpreter.startswith('/usr/bin/')
14+
15+
- name: Ensure Python hvac module is installed
16+
ansible.builtin.pip:
17+
name: hvac
18+
state: latest
19+
extra_args: "{% if pip_upper_constraints_file %}-c {{ pip_upper_constraints_file }}{% endif %}"
20+
virtualenv: "{{ virtualenv is defined | ternary(virtualenv, omit) }}"
21+
become: "{{ virtualenv is not defined }}"
22+
23+
- name: Ensure /opt/kayobe/vault exists
24+
ansible.builtin.file:
25+
path: /opt/kayobe/vault
26+
state: directory
27+
become: true
28+
29+
- name: Ensure vault directory exists in environment
30+
ansible.builtin.file:
31+
path: "{{ kayobe_env_config_path }}/vault"
32+
state: directory
33+
become: true
34+
35+
- name: Import OpenBao role
36+
ansible.builtin.import_role:
37+
name: stackhpc.hashicorp.openbao
38+
vars:
39+
openbao_config_dir: "/opt/kayobe/vault"
40+
openbao_cluster_name: "kayobe-automation"
41+
copy_self_signed_ca: false
42+
openbao_write_keys_file: true
43+
openbao_write_keys_file_path: "{{ kayobe_env_config_path }}/vault/kayobe-automation-keys.json"
44+
45+
- name: Include OpenBao keys
46+
ansible.builtin.include_vars:
47+
file: "{{ kayobe_env_config_path }}/vault/kayobe-automation-keys.json"
48+
name: openbao_keys
49+
tags: always
50+
51+
- name: Import Vault unseal role
52+
ansible.builtin.import_role:
53+
name: stackhpc.hashicorp.vault_unseal
54+
vars:
55+
vault_api_addr: "{{ openbao_api_addr }}"
56+
vault_unseal_token: "{{ openbao_keys.root_token }}"
57+
vault_unseal_keys: "{{ openbao_keys.keys_base64 }}"
58+
vault_unseal_verify: false
59+
environment:
60+
https_proxy: ''
61+
62+
- name: Create secret store
63+
ansible.legacy.hashivault_secret_engine:
64+
name: kayobe-automation
65+
backend: kv
66+
url: "{{ openbao_api_addr }}"
67+
token: "{{ openbao_keys.root_token }}"
68+
69+
- name: Ensure secret store is present
70+
community.hashi_vault.vault_write:
71+
url: "{{ openbao_api_addr }}"
72+
token: "{{ openbao_keys.root_token }}"
73+
path: kayobe-automation/{{ kayobe_environment }}
74+
data:
75+
kayobe_vault_password: "{{ kolla_ansible_vault_password }}"
76+
kayobe_automation_ssh_private_key: "{{ lookup('ansible.builtin.file', '{{ ssh_private_key_path }}') }}"
77+
kayobe_public_openrc: "{{ lookup('ansible.builtin.file', '{{ kolla_config_path }}/public-openrc.sh') }}"
78+
tags: add_secrets

etc/kayobe/ansible/requirements.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ collections:
1111
- name: stackhpc.hashicorp
1212
version: 2.7.1
1313
- name: stackhpc.kayobe_workflows
14-
version: 1.1.0
14+
version: 1.2.0
1515
roles:
1616
- src: stackhpc.vxlan
1717
version: 1.1.0
@@ -31,3 +31,7 @@ roles:
3131
- src: https://github.com/stackhpc/ansible-role-docker.git
3232
name: geerlingguy.docker
3333
version: stackhpc/7.0.1.1
34+
# (jackhodgkiss) Update once patch is merged and released upstream.
35+
- src: https://github.com/stackhpc/ansible-gitlab-runner
36+
name: riemers.gitlab-runner
37+
version: use-ansible-facts
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
- name: Write Kayobe Automation Pipeline for GitLab
3+
hosts: gitlab-writer
4+
vars:
5+
gitlab_output_directory: "{{ kayobe_config_path }}/../../"
6+
roles:
7+
- stackhpc.kayobe_workflows.gitlab
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
# Configuration of GitLab runners using riemers.gitlab-runner should go here.
3+
# See documentation for more information
4+
# https://github.com/riemers/ansible-gitlab-runner
5+
# https://stackhpc-kayobe-config.readthedocs.io/en/stackhpc-2024.1/configuration/ci-cd.html
6+
7+
###############################################################################
8+
# Dummy variable to allow Ansible to accept this file.
9+
workaround_ansible_issue_8743: yes
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
# Configuration of GitLab pipelines generated with stackhpc.kayobe_workflows.gitlab should go here.
3+
# See documentation for more information
4+
# https://github.com/stackhpc/ansible-collection-kayobe-workflows/blob/main/roles/gitlab/README.md
5+
6+
gitlab_output_directory: $KAYOBE_CONFIG_PATH/../../.gitlab/
7+
8+
gitlab_registry: "{{ pulp_url | regex_replace('^https?://|^http?://', '') }}"
9+
10+
gitlab_openstack_release: "{{ openstack_release }}"
11+
12+
###############################################################################
13+
# Dummy variable to allow Ansible to accept this file.
14+
workaround_ansible_issue_8743: yes

0 commit comments

Comments
 (0)