diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 85ce6e3426aee3d6c8c8ac3c4ae7726096c5d71e..f12a535452b3040f0bd8c0efc2ccf8dc5313c758 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,3 +1,7 @@ +workflow: + rules: + - if: $CLOUDSTACK_API_KEY + variables: CI_TEMPLATE_REGISTRY_HOST: registry.gitlab.inria.fr TF_STATE_NAME: default @@ -10,6 +14,10 @@ stages: - build - deploy - execute + - cleanup + +before_script: + - cp $SSH_PRIVATE_KEY id_rsa fmt: tags: @@ -22,8 +30,6 @@ validate: - linux - small extends: .terraform:validate - before_script: - - cp $SSH_PRIVATE_KEY id_rsa build: tags: @@ -32,8 +38,6 @@ build: extends: .terraform:build environment: name: $TF_STATE_NAME - before_script: - - cp $SSH_PRIVATE_KEY id_rsa deploy: tags: @@ -42,6 +46,8 @@ deploy: extends: .terraform:deploy dependencies: - build + rules: + - when: manual execute: stage: execute @@ -49,7 +55,11 @@ execute: tags: - terraform - docker - rules: - - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH script: - echo Greetings from runner! + +destroy: + tags: + - linux + - small + extends: .terraform:destroy diff --git a/CHANGES.md b/CHANGES.md index bbb7eb032b0a36b9863bca4e6c2f1a29fe7f8fbc..9593c7a4517ba08f3a5d16231fb4922f8f8a0bd2 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,7 @@ +# 2023-02-22 + +- !3 Use cloud-init configuration file instead of shell script + # 2023-02-13 - !1 Unregister gitlab runner on VM destruction diff --git a/README.md b/README.md index aa3d0325d1c677b89f366a1dda5335f439f956fe..759da1c8fec83f60d5f6c6c1b6582b19d6c5d8df 100644 --- a/README.md +++ b/README.md @@ -181,7 +181,7 @@ resource "cloudstack_instance" "custom_instance" { memory = 2048 } expunge = true - user_data = templatefile("cloud-init.sh.tftpl", { + user_data = templatefile("cloud-init.yaml.tftpl", { REGISTRATION_TOKEN = var.REGISTRATION_TOKEN SSH_PUBLIC_KEY = var.SSH_PUBLIC_KEY }) @@ -226,8 +226,8 @@ resource "cloudstack_instance" "custom_instance" { - `user_data` contains a script which is passed to [`cloud-init`](https://cloud-init.io/) to be run at the first boot of the virtual machine. The `templatefile` - is used to read the script from file - [`cloud-init.sh.tftpl`](cloud-init.sh.tftpl) + is used to read the cloud-init configuration file from file + [`cloud-init.yaml.tftpl`](cloud-init.yaml.tftpl) by substituting `${REGISTRATION_TOKEN}` with the value of the variable passed to Terraform. - We pass also the `SSH_PUBLIC_KEY` to the template file to have its @@ -244,10 +244,23 @@ resource "cloudstack_instance" "custom_instance" { in case of the `gitlab-runner` command was not yet installed when destroying occurs. -The script [`cloud-init.sh.tftpl`](cloud-init.sh.tftpl) registers -the SSH public key in `~ci/.ssh/authorized_keys`, -installs `gitlab-runner` and `docker.io` on the virtual machine, -and registers the runner. +## The cloud-init configuration file [`cloud-init.yaml.tftpl`](cloud-init.yaml.tftpl) + +The cloud-init configuration file +[`cloud-init.yaml.tftpl`](cloud-init.yaml.tftpl) sets up the following: +- the user `ci` can execute `sudo` without password, so that the destroy +provisioner be able to unregister the runners; +- the SSH public key is registed as authorized key for `ci`, +- by default, password authentication is disabled for `ci` + (you may add `lock_passwd: false` to enable it again, + [documentation](https://cloudinit.readthedocs.io/en/latest/reference/modules.html#users-and-groups)); +- `gitlab-runner` and `docker.io` is installed on the virtual machine, + the runner is registered on gitlab.inria.fr. +The configuration file should begin with the following line. +```yaml +#cloud-config +``` +You may provide a shell script with the according shebang (`#!/bin/sh`) instead. ## The pipeline specification file [`.gitlab-ci.yml`](.gitlab-ci.yml) @@ -298,16 +311,13 @@ stages: Every job that will use the Terraform configuration file needs to copy the file referred by `SSH_PRIVATE_KEY` into the file `id_rsa`. To copy the file without overriding all the script, -we use the `before_script` key. For instance, in the job `validate`: +we use the `before_script` key: +defining the `before_script` key at top-level, outside any job, +makes the file be copied before every job. ```yaml -validate: - tags: - - linux - - small - extends: .terraform:validate - before_script: - - cp $SSH_PRIVATE_KEY id_rsa +before_script: + - cp $SSH_PRIVATE_KEY id_rsa ``` ## Ignored files in [`.gitignore`](.gitignore) diff --git a/cloud-init.sh.tftpl b/cloud-init.sh.tftpl deleted file mode 100644 index fdcee37708eebf34dfa2458efbcb0749a7699a3b..0000000000000000000000000000000000000000 --- a/cloud-init.sh.tftpl +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash -# Standard output and errors are redirected to /root/log.txt to ease -# debugging. -( - # To be able to run `sudo gitlab-runner unregister --all-runners` on - # VM destruction. - echo 'ci ALL=(ALL) NOPASSWD:ALL' >/etc/sudoers.d/90-ci - mkdir -p -m 700 ~ci/.ssh - echo ${SSH_PUBLIC_KEY} >>~ci/.ssh/authorized_keys - chown -R ci:ci ~ci/.ssh - # GitLab needs a recent version of `gitlab-runner` to be compatible with - # the instance running on gitlab.inria.fr. The version packaged by default - # on Ubuntu is regularly out of date. - curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh" | sudo bash - # apt-get update performed by the script above - # We install docker.io to be able to register a docker executor - apt-get install --yes gitlab-runner docker.io - gitlab-runner register --non-interactive --tag-list terraform,docker \ - --executor docker --docker-image alpine --url https://gitlab.inria.fr \ - --registration-token ${REGISTRATION_TOKEN} -) >>/root/log.txt 2>&1 diff --git a/cloud-init.yaml.tftpl b/cloud-init.yaml.tftpl new file mode 100644 index 0000000000000000000000000000000000000000..f12418a0b520a20715b5a782b0845153eecdac30 --- /dev/null +++ b/cloud-init.yaml.tftpl @@ -0,0 +1,14 @@ +#cloud-config +users: + - name: ci + sudo: ALL=(ALL) NOPASSWD:ALL + ssh_authorized_keys: + - ${SSH_PUBLIC_KEY} + +runcmd: + - curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh" | sudo bash + - apt-get install --yes gitlab-runner docker.io + - | + gitlab-runner register --non-interactive --tag-list terraform,docker \ + --executor docker --docker-image alpine --url https://gitlab.inria.fr \ + --registration-token ${REGISTRATION_TOKEN} diff --git a/main.tf b/main.tf index dca84281a5193fdad2c9f5115c55a13d2a1d7da1..ff8aecfba8a1918702c614aa51bda89845d39c1d 100644 --- a/main.tf +++ b/main.tf @@ -36,7 +36,7 @@ resource "cloudstack_instance" "custom_instance" { memory = 2048 } expunge = true - user_data = templatefile("cloud-init.sh.tftpl", { + user_data = templatefile("cloud-init.yaml.tftpl", { REGISTRATION_TOKEN = var.REGISTRATION_TOKEN SSH_PUBLIC_KEY = var.SSH_PUBLIC_KEY })