diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b8e8cad95f77c2d16a40b92b600dac0d708fc10c..8c8426af7637f8080a5d038ba161d5cb565589e7 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -57,10 +57,13 @@ stages: - release - cleanup -.opentofu-versions: +.image-matrix: parallel: matrix: - OPENTOFU_VERSION: !reference [.data, supported_versions] + GITLAB_OPENTOFU_BASE_IMAGE_OS: + - 'alpine' + - 'debian' variables: # OpenTofu variables @@ -68,9 +71,8 @@ variables: # OpenTofu image build variables: PLATFORMS: linux/amd64,linux/arm64 - BASE_IMAGE: "alpine:3.20.3" GITLAB_OPENTOFU_IMAGE_BASE: "$CI_REGISTRY_IMAGE/internal" - GITLAB_OPENTOFU_IMAGE_NAME: "$GITLAB_OPENTOFU_IMAGE_BASE/gitlab-opentofu:$CI_COMMIT_SHA-opentofu$OPENTOFU_VERSION" + GITLAB_OPENTOFU_IMAGE_NAME: "$GITLAB_OPENTOFU_IMAGE_BASE/gitlab-opentofu:$CI_COMMIT_SHA-opentofu$OPENTOFU_VERSION-$GITLAB_OPENTOFU_BASE_IMAGE_OS" check-semantic-version: stage: .pre @@ -83,17 +85,17 @@ check-semantic-version: - echo -n "$CI_COMMIT_TAG" | ./.gitlab/scripts/check-semantic-version.sh gitlab-opentofu-image:build: - extends: .opentofu-versions + extends: .image-matrix stage: build image: quay.io/containers/buildah:v1.37.1 before_script: - buildah login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY" script: + - echo "Building $GITLAB_OPENTOFU_IMAGE_NAME" - buildah build --platform "$PLATFORMS" - --build-arg BASE_IMAGE=$BASE_IMAGE --build-arg OPENTOFU_VERSION=$OPENTOFU_VERSION - --file Dockerfile + --file Dockerfile.$GITLAB_OPENTOFU_BASE_IMAGE_OS --jobs 2 --manifest "$GITLAB_OPENTOFU_IMAGE_NAME" . @@ -101,7 +103,7 @@ gitlab-opentofu-image:build: rules: - if: $CI_COMMIT_TAG - changes: - - Dockerfile + - Dockerfile* - .dockerignore - opentofu_versions.yaml - .gitlab-ci.yml @@ -163,26 +165,23 @@ shellcheck: # - if: $CI_COMMIT_TAG # - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH -gitlab-opentofu-image:deploy: +.gitlab-opentofu-image:deploy:base: stage: deploy image: name: gcr.io/go-containerregistry/crane:debug entrypoint: [""] + variables: + GITLAB_OPENTOFU_BASE_IMAGE_OS: $RELEASE_BASE_IMAGE_OS before_script: - crane auth login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY" - script: # OCI image tags are not compatible with semver, specifically the build metadata part # indicated with a `+` sign, see https://github.com/distribution/distribution/issues/1201 # We use a dash `-` here, instead of the `+`. # This may be problematic, because it indicates a semver prerelease. - export RELEASE_IMAGE_NAME="$CI_REGISTRY_IMAGE/gitlab-opentofu" - - export RELEASE_IMAGE="${RELEASE_IMAGE_NAME}:${RELEASE_VERSION}${RELEASE_OPENTOFU_VERSION:+-opentofu$RELEASE_OPENTOFU_VERSION}" + - export RELEASE_IMAGE="${RELEASE_IMAGE_NAME}:${RELEASE_VERSION}${RELEASE_OPENTOFU_VERSION:+-opentofu$RELEASE_OPENTOFU_VERSION}${RELEASE_BASE_IMAGE_OS:+-$RELEASE_BASE_IMAGE_OS}" + - 'echo "base image OS: $GITLAB_OPENTOFU_BASE_IMAGE_OS"' - echo "Deploying $GITLAB_OPENTOFU_IMAGE_NAME as $RELEASE_IMAGE" - - crane copy "$GITLAB_OPENTOFU_IMAGE_NAME" "$RELEASE_IMAGE" - - 'echo "- \`$RELEASE_IMAGE\` (digest: \`$(crane digest $RELEASE_IMAGE)\`)" > image$CI_JOB_ID.md' - artifacts: - paths: - - 'image*.md' parallel: # OPENTOFU_VERSION: opentofu version to release in the job (from gitlab-opentofu-image:build) # RELEASE_VERSION: Tag base for the release image @@ -192,16 +191,44 @@ gitlab-opentofu-image:deploy: OPENTOFU_VERSION: !reference [.data, supported_versions] RELEASE_VERSION: $CI_COMMIT_TAG RELEASE_OPENTOFU_VERSION: $OPENTOFU_VERSION + RELEASE_BASE_IMAGE_OS: ['alpine', 'debian'] - # :latest-opentofu{opentofu-version} OPENTOFU_VERSION: !reference [.data, supported_versions] RELEASE_VERSION: latest RELEASE_OPENTOFU_VERSION: $OPENTOFU_VERSION + RELEASE_BASE_IMAGE_OS: ['alpine', 'debian'] - # :{commit-tag|latest}{-opentofulatest|} OPENTOFU_VERSION: $LATEST_OPENTOFU_VERSION RELEASE_VERSION: ["${CI_COMMIT_TAG}", latest] RELEASE_OPENTOFU_VERSION: ["", latest] + RELEASE_BASE_IMAGE_OS: ['alpine', 'debian'] + +gitlab-opentofu-image:deploy: + extends: ['.gitlab-opentofu-image:deploy:base'] + script: + - crane copy "$GITLAB_OPENTOFU_IMAGE_NAME" "$RELEASE_IMAGE" + - export image_digest="$(crane digest $RELEASE_IMAGE)" + - 'echo "- \`$RELEASE_IMAGE\` (digest: \`$image_digest\`)" > image$CI_JOB_ID.md' + artifacts: + paths: + - 'image*.md' + rules: + - if: $CI_COMMIT_TAG + +gitlab-opentofu-image:deploy:dry-run: + extends: ['.gitlab-opentofu-image:deploy:base'] + needs: ['gitlab-opentofu-image:build'] + script: + - echo "dry run" rules: - if: $CI_COMMIT_TAG + when: never + - changes: + - Dockerfile* + - .dockerignore + - opentofu_versions.yaml + - .gitlab-ci.yml + - src/**/* # If the pipeline is for a new tag with a semantic version, and all previous jobs succeed, # create the release. diff --git a/.gitlab/README.md.template b/.gitlab/README.md.template index 849b65d35f593fc508ef7d840b22ca3c97292f0e..1fc866f7a796b51c175dc2601a35f4b05462e969 100644 --- a/.gitlab/README.md.template +++ b/.gitlab/README.md.template @@ -97,6 +97,20 @@ fmt: ... ``` +### OpenTofu Version + +The OpenTofu version can be specified with the `opentofu_version` input. +More details can be found [here](#available-opentofu-versions). + +### Base Image OS + +The GitLab OpenTofu images come in multiple base image variants: + +- `alpine` (default) +- `debian` + +The base image OS can be specified with the `base_os` input. + ### GitLab-managed Terraform state backend This component - by leveraging the [`gitlab-tofu`](src/gitlab-tofu.sh) CLI internally - @@ -263,16 +277,21 @@ Due to the limitations described in https://gitlab.com/gitlab-org/gitlab/-/issue it's currently required to provide the component version in the `component` include field and as the `version` input. Check out the [Usage](#Usage) section for examples. +There are `alpine` and `debian` variants available. + Each component release deploys the following images: -- `$CI_TEMPLATE_REGISTRY_HOST/components/opentofu/gitlab-opentofu:<VERSION>-opentofu<OPENTOFU_VERSION>` -- `$CI_TEMPLATE_REGISTRY_HOST/components/opentofu/gitlab-opentofu:<VERSION>-opentofu` +- `$CI_TEMPLATE_REGISTRY_HOST/components/opentofu/gitlab-opentofu:<VERSION>-opentofu<OPENTOFU_VERSION>-<OS_VARIANT>` +- `$CI_TEMPLATE_REGISTRY_HOST/components/opentofu/gitlab-opentofu:<VERSION>-opentofu-<OS_VARIANT>` - Includes the latest stable OpenTofu version at the time of releasing the component -- `$CI_TEMPLATE_REGISTRY_HOST/components/opentofu/gitlab-opentofu:<VERSION>` +- `$CI_TEMPLATE_REGISTRY_HOST/components/opentofu/gitlab-opentofu:<VERSION>-<OS_VARIANT>` - Includes the latest stable OpenTofu version at the time of releasing the component -In the above examples `<VERSION>` references the component version and `<OPENTOFU_VERSION>` -an OpenTofu release, from [here](https://github.com/opentofu/opentofu/releases). +In the above examples `<VERSION>` references the component version, `<OPENTOFU_VERSION>` +an OpenTofu release, from [here](https://github.com/opentofu/opentofu/releases) and +`OS_VARIANT` either `alpine` or `debian`. + +The release notes contain a full list of images deployed to the registry. *Note: unfortunately, these image versions are not SemVer compatible, because `-` indicates a prerelease (which they are not in this case). diff --git a/Dockerfile b/Dockerfile.alpine similarity index 96% rename from Dockerfile rename to Dockerfile.alpine index 75f8f167935318bb33038a639b61d7e15d4204a6..65d8090d978344126f0c342c8e4b34f073351196 100644 --- a/Dockerfile +++ b/Dockerfile.alpine @@ -1,4 +1,4 @@ -ARG BASE_IMAGE +ARG BASE_IMAGE=alpine:3.20.3 FROM $BASE_IMAGE diff --git a/Dockerfile.debian b/Dockerfile.debian new file mode 100644 index 0000000000000000000000000000000000000000..aa12b49c1f085edd6fb7cbf7a7faafa17f622950 --- /dev/null +++ b/Dockerfile.debian @@ -0,0 +1,48 @@ +ARG BASE_IMAGE=debian:12.7 + +FROM $BASE_IMAGE + +ARG TARGETARCH + +RUN apt-get update && apt-get install -y \ + curl \ + wget \ + git \ + jq \ + openssh-client \ + unzip \ + && rm -rf /var/lib/apt/lists/* + +# NOTE: cosign is not yet available in the debian apt sources +ARG COSIGN_VERSION=2.4.0 +WORKDIR /tmp +RUN wget https://github.com/sigstore/cosign/releases/download/v${COSIGN_VERSION}/cosign_${COSIGN_VERSION}_${TARGETARCH}.deb && \ + dpkg -i *.deb && \ + rm -f /tmp/*.deb + +# NOTE: glab is not yet available in the debian apt sources +ARG GLAB_VERSION=1.46.1 +WORKDIR /tmp +RUN if [ "${TARGETARCH}" = "amd64" ]; then hack_glab_arch="x86_64"; else hack_glab_arch="${TARGETARCH}"; fi && \ + echo "arch=$hack_glab_arch" && \ + wget https://gitlab.com/gitlab-org/cli/-/releases/v${GLAB_VERSION}/downloads/glab_${GLAB_VERSION}_Linux_${hack_glab_arch}.deb && \ + dpkg -i *.deb && \ + rm -f /tmp/*.deb + +# Install OpenTofu using the installer script in standalone mode +# see https://opentofu.org/docs/intro/install/standalone +# We may want to switch to installing manually from GitHub and verifying signature +ARG OPENTOFU_VERSION +RUN curl --proto '=https' --tlsv1.2 -fsSL https://get.opentofu.org/install-opentofu.sh -o install-opentofu.sh && \ + chmod +x install-opentofu.sh && \ + ./install-opentofu.sh --install-method standalone --opentofu-version "${OPENTOFU_VERSION}" && \ + rm ./install-opentofu.sh && \ + rm -rf /tmp/* && \ + tofu --version + +WORKDIR / + +COPY --chmod=755 src/gitlab-tofu.sh /usr/bin/gitlab-tofu + +# Override ENTRYPOINT +ENTRYPOINT [] diff --git a/README.md b/README.md index d4d5a3805cad21e2ee42b48f0d9f68e973e24be7..44eb77f9a15cf448cf94fedf902a511674b04e53 100644 --- a/README.md +++ b/README.md @@ -99,6 +99,20 @@ fmt: ... ``` +### OpenTofu Version + +The OpenTofu version can be specified with the `opentofu_version` input. +More details can be found [here](#available-opentofu-versions). + +### Base Image OS + +The GitLab OpenTofu images come in multiple base image variants: + +- `alpine` (default) +- `debian` + +The base image OS can be specified with the `base_os` input. + ### GitLab-managed Terraform state backend This component - by leveraging the [`gitlab-tofu`](src/gitlab-tofu.sh) CLI internally - @@ -280,16 +294,21 @@ Due to the limitations described in https://gitlab.com/gitlab-org/gitlab/-/issue it's currently required to provide the component version in the `component` include field and as the `version` input. Check out the [Usage](#Usage) section for examples. +There are `alpine` and `debian` variants available. + Each component release deploys the following images: -- `$CI_TEMPLATE_REGISTRY_HOST/components/opentofu/gitlab-opentofu:<VERSION>-opentofu<OPENTOFU_VERSION>` -- `$CI_TEMPLATE_REGISTRY_HOST/components/opentofu/gitlab-opentofu:<VERSION>-opentofu` +- `$CI_TEMPLATE_REGISTRY_HOST/components/opentofu/gitlab-opentofu:<VERSION>-opentofu<OPENTOFU_VERSION>-<OS_VARIANT>` +- `$CI_TEMPLATE_REGISTRY_HOST/components/opentofu/gitlab-opentofu:<VERSION>-opentofu-<OS_VARIANT>` - Includes the latest stable OpenTofu version at the time of releasing the component -- `$CI_TEMPLATE_REGISTRY_HOST/components/opentofu/gitlab-opentofu:<VERSION>` +- `$CI_TEMPLATE_REGISTRY_HOST/components/opentofu/gitlab-opentofu:<VERSION>-<OS_VARIANT>` - Includes the latest stable OpenTofu version at the time of releasing the component -In the above examples `<VERSION>` references the component version and `<OPENTOFU_VERSION>` -an OpenTofu release, from [here](https://github.com/opentofu/opentofu/releases). +In the above examples `<VERSION>` references the component version, `<OPENTOFU_VERSION>` +an OpenTofu release, from [here](https://github.com/opentofu/opentofu/releases) and +`OS_VARIANT` either `alpine` or `debian`. + +The release notes contain a full list of images deployed to the registry. *Note: unfortunately, these image versions are not SemVer compatible, because `-` indicates a prerelease (which they are not in this case). diff --git a/templates/apply.yml b/templates/apply.yml index e19771e3a1deb919facca40439b3b00518022c0d..bf123ad3ab5098055709c6182d041c9ddc555c4a 100644 --- a/templates/apply.yml +++ b/templates/apply.yml @@ -15,6 +15,14 @@ spec: default: 'latest' description: 'Version of this component. Has to be the same as the one in the component include entry.' + base_os: + default: 'alpine' + options: + - 'alpine' + - 'debian' + - '$GITLAB_OPENTOFU_BASE_IMAGE_OS' + description: 'Base OS of GitLab OpenTofu image.' + opentofu_version: default: '1.8.2' options: @@ -91,6 +99,6 @@ spec: TF_APPLY_NO_PLAN: $[[ inputs.no_plan ]] TF_PLAN_NAME: $[[ inputs.plan_name ]] image: - name: '$[[ inputs.image_registry_base ]]/$[[ inputs.image_name ]]:$[[ inputs.version ]]-opentofu$[[ inputs.opentofu_version ]]' + name: '$[[ inputs.image_registry_base ]]/$[[ inputs.image_name ]]:$[[ inputs.version ]]-opentofu$[[ inputs.opentofu_version ]]-$[[ inputs.base_os ]]' script: - gitlab-tofu apply diff --git a/templates/custom-command.yml b/templates/custom-command.yml index 3acee3604f5514f90901d0cc3634234e70507d45..2a9bf3542396b5431dea11bef02c58539a8ab080 100644 --- a/templates/custom-command.yml +++ b/templates/custom-command.yml @@ -15,6 +15,14 @@ spec: default: 'latest' description: 'Version of this component. Has to be the same as the one in the component include entry.' + base_os: + default: 'alpine' + options: + - 'alpine' + - 'debian' + - '$GITLAB_OPENTOFU_BASE_IMAGE_OS' + description: 'Base OS of GitLab OpenTofu image.' + opentofu_version: default: '1.8.2' options: @@ -70,7 +78,7 @@ spec: __CACHE_KEY_HACK: "$[[ inputs.root_dir ]]" TF_ROOT: $[[ inputs.root_dir ]] image: - name: '$[[ inputs.image_registry_base ]]/$[[ inputs.image_name ]]:$[[ inputs.version ]]-opentofu$[[ inputs.opentofu_version ]]' + name: '$[[ inputs.image_registry_base ]]/$[[ inputs.image_name ]]:$[[ inputs.version ]]-opentofu$[[ inputs.opentofu_version ]]-$[[ inputs.base_os ]]' script: - gitlab-tofu $[[ inputs.command ]] diff --git a/templates/destroy.yml b/templates/destroy.yml index fb6749700802e55a20e4abfb9b3cc4a949996f99..66a17a757711dd24333d9657029c00c6f984cea5 100644 --- a/templates/destroy.yml +++ b/templates/destroy.yml @@ -15,6 +15,14 @@ spec: default: 'latest' description: 'Version of this component. Has to be the same as the one in the component include entry.' + base_os: + default: 'alpine' + options: + - 'alpine' + - 'debian' + - '$GITLAB_OPENTOFU_BASE_IMAGE_OS' + description: 'Base OS of GitLab OpenTofu image.' + opentofu_version: default: '1.8.2' options: @@ -90,6 +98,6 @@ spec: TF_APPLY_NO_PLAN: $[[ inputs.no_plan ]] TF_PLAN_NAME: $[[ inputs.plan_name ]] image: - name: '$[[ inputs.image_registry_base ]]/$[[ inputs.image_name ]]:$[[ inputs.version ]]-opentofu$[[ inputs.opentofu_version ]]' + name: '$[[ inputs.image_registry_base ]]/$[[ inputs.image_name ]]:$[[ inputs.version ]]-opentofu$[[ inputs.opentofu_version ]]-$[[ inputs.base_os ]]' script: - gitlab-tofu apply -destroy diff --git a/templates/fmt.yml b/templates/fmt.yml index 6ab765aeec1ff613f24255aa930b78111d8f2595..2ad408bd018a92459fe798ddfaded397cf4a9f11 100644 --- a/templates/fmt.yml +++ b/templates/fmt.yml @@ -15,6 +15,14 @@ spec: default: 'latest' description: 'Version of this component. Has to be the same as the one in the component include entry.' + base_os: + default: 'alpine' + options: + - 'alpine' + - 'debian' + - '$GITLAB_OPENTOFU_BASE_IMAGE_OS' + description: 'Base OS of GitLab OpenTofu image.' + opentofu_version: default: '1.8.2' options: @@ -78,6 +86,6 @@ spec: __CACHE_KEY_HACK: "$[[ inputs.root_dir ]]" TF_ROOT: $[[ inputs.root_dir ]] image: - name: '$[[ inputs.image_registry_base ]]/$[[ inputs.image_name ]]:$[[ inputs.version ]]-opentofu$[[ inputs.opentofu_version ]]' + name: '$[[ inputs.image_registry_base ]]/$[[ inputs.image_name ]]:$[[ inputs.version ]]-opentofu$[[ inputs.opentofu_version ]]-$[[ inputs.base_os ]]' script: - gitlab-tofu fmt diff --git a/templates/full-pipeline.yml b/templates/full-pipeline.yml index e57a17737b153d52925c1cc63ff581a818f61151..f2637c1dfcd866c59df06a0b4456627a408b5f91 100644 --- a/templates/full-pipeline.yml +++ b/templates/full-pipeline.yml @@ -24,6 +24,14 @@ spec: default: 'latest' description: 'Version of this component. Has to be the same as the one in the component include entry.' + base_os: + default: 'alpine' + options: + - 'alpine' + - 'debian' + - '$GITLAB_OPENTOFU_BASE_IMAGE_OS' + description: 'Base OS of GitLab OpenTofu image.' + opentofu_version: default: '1.8.2' options: @@ -84,6 +92,7 @@ include: as: 'fmt' stage: $[[ inputs.stage_validate ]] version: $[[ inputs.version ]] + base_os: $[[ inputs.base_os ]] opentofu_version: $[[ inputs.opentofu_version ]] image_registry_base: $[[ inputs.image_registry_base ]] image_name: $[[ inputs.image_name ]] @@ -93,6 +102,7 @@ include: as: 'validate' stage: $[[ inputs.stage_validate ]] version: $[[ inputs.version ]] + base_os: $[[ inputs.base_os ]] opentofu_version: $[[ inputs.opentofu_version ]] image_registry_base: $[[ inputs.image_registry_base ]] image_name: $[[ inputs.image_name ]] @@ -103,6 +113,7 @@ include: as: 'test' stage: $[[ inputs.stage_test ]] version: $[[ inputs.version ]] + base_os: $[[ inputs.base_os ]] opentofu_version: $[[ inputs.opentofu_version ]] image_registry_base: $[[ inputs.image_registry_base ]] image_name: $[[ inputs.image_name ]] @@ -116,6 +127,7 @@ include: as: 'plan' stage: $[[ inputs.stage_build ]] version: $[[ inputs.version ]] + base_os: $[[ inputs.base_os ]] opentofu_version: $[[ inputs.opentofu_version ]] image_registry_base: $[[ inputs.image_registry_base ]] image_name: $[[ inputs.image_name ]] @@ -127,6 +139,7 @@ include: as: 'apply' stage: $[[ inputs.stage_deploy ]] version: $[[ inputs.version ]] + base_os: $[[ inputs.base_os ]] opentofu_version: $[[ inputs.opentofu_version ]] image_registry_base: $[[ inputs.image_registry_base ]] image_name: $[[ inputs.image_name ]] @@ -138,6 +151,7 @@ include: as: 'destroy' stage: $[[ inputs.stage_cleanup ]] version: $[[ inputs.version ]] + base_os: $[[ inputs.base_os ]] opentofu_version: $[[ inputs.opentofu_version ]] image_registry_base: $[[ inputs.image_registry_base ]] image_name: $[[ inputs.image_name ]] diff --git a/templates/graph.yml b/templates/graph.yml index d39cf4f068420afa0b09a30a80894544d1445807..2ff3da0f3a2c4f65e620a7e7982224ec5bafece8 100644 --- a/templates/graph.yml +++ b/templates/graph.yml @@ -15,6 +15,14 @@ spec: default: 'latest' description: 'Version of this component. Has to be the same as the one in the component include entry.' + base_os: + default: 'alpine' + options: + - 'alpine' + - 'debian' + - '$GITLAB_OPENTOFU_BASE_IMAGE_OS' + description: 'Base OS of GitLab OpenTofu image.' + opentofu_version: default: '1.8.2' options: @@ -76,7 +84,7 @@ spec: TF_ROOT: $[[ inputs.root_dir ]] TF_STATE_NAME: $[[ inputs.state_name ]] image: - name: '$[[ inputs.image_registry_base ]]/$[[ inputs.image_name ]]:$[[ inputs.version ]]-opentofu$[[ inputs.opentofu_version ]]' + name: '$[[ inputs.image_registry_base ]]/$[[ inputs.image_name ]]:$[[ inputs.version ]]-opentofu$[[ inputs.opentofu_version ]]-$[[ inputs.base_os ]]' script: - gitlab-tofu graph > "$[[ inputs.graph_file ]]" artifacts: diff --git a/templates/job-templates.yml b/templates/job-templates.yml index 78071d110d87177eab4e0b8b6ec2bce5ec7dad55..496c6d2ae9d85f7d6e86e25b9d5927064b926898 100644 --- a/templates/job-templates.yml +++ b/templates/job-templates.yml @@ -24,6 +24,14 @@ spec: default: 'latest' description: 'Version of this component. Has to be the same as the one in the component include entry.' + base_os: + default: 'alpine' + options: + - 'alpine' + - 'debian' + - '$GITLAB_OPENTOFU_BASE_IMAGE_OS' + description: 'Base OS of GitLab OpenTofu image.' + opentofu_version: default: '1.8.2' options: @@ -84,6 +92,7 @@ include: as: '$[[ inputs.job_name_prefix ]]fmt' stage: $[[ inputs.stage_validate ]] version: $[[ inputs.version ]] + base_os: $[[ inputs.base_os ]] opentofu_version: $[[ inputs.opentofu_version ]] image_registry_base: $[[ inputs.image_registry_base ]] image_name: $[[ inputs.image_name ]] @@ -93,6 +102,7 @@ include: as: '$[[ inputs.job_name_prefix ]]validate' stage: $[[ inputs.stage_validate ]] version: $[[ inputs.version ]] + base_os: $[[ inputs.base_os ]] opentofu_version: $[[ inputs.opentofu_version ]] image_registry_base: $[[ inputs.image_registry_base ]] image_name: $[[ inputs.image_name ]] @@ -103,6 +113,7 @@ include: as: '$[[ inputs.job_name_prefix ]]graph' stage: $[[ inputs.stage_validate ]] version: $[[ inputs.version ]] + base_os: $[[ inputs.base_os ]] opentofu_version: $[[ inputs.opentofu_version ]] image_registry_base: $[[ inputs.image_registry_base ]] image_name: $[[ inputs.image_name ]] @@ -112,6 +123,7 @@ include: as: '$[[ inputs.job_name_prefix ]]test' stage: $[[ inputs.stage_test ]] version: $[[ inputs.version ]] + base_os: $[[ inputs.base_os ]] opentofu_version: $[[ inputs.opentofu_version ]] image_registry_base: $[[ inputs.image_registry_base ]] image_name: $[[ inputs.image_name ]] @@ -122,6 +134,7 @@ include: as: '$[[ inputs.job_name_prefix ]]plan' stage: $[[ inputs.stage_build ]] version: $[[ inputs.version ]] + base_os: $[[ inputs.base_os ]] opentofu_version: $[[ inputs.opentofu_version ]] image_registry_base: $[[ inputs.image_registry_base ]] image_name: $[[ inputs.image_name ]] @@ -132,6 +145,7 @@ include: as: '$[[ inputs.job_name_prefix ]]apply' stage: $[[ inputs.stage_deploy ]] version: $[[ inputs.version ]] + base_os: $[[ inputs.base_os ]] opentofu_version: $[[ inputs.opentofu_version ]] image_registry_base: $[[ inputs.image_registry_base ]] image_name: $[[ inputs.image_name ]] @@ -143,6 +157,7 @@ include: as: '$[[ inputs.job_name_prefix ]]destroy' stage: $[[ inputs.stage_cleanup ]] version: $[[ inputs.version ]] + base_os: $[[ inputs.base_os ]] opentofu_version: $[[ inputs.opentofu_version ]] image_registry_base: $[[ inputs.image_registry_base ]] image_name: $[[ inputs.image_name ]] diff --git a/templates/plan.yml b/templates/plan.yml index 7eaeb8a219d139b3423b51c69424aeef94ee3d0f..8ceba23462d92864b2c0aceb2b30fb5c58a04809 100644 --- a/templates/plan.yml +++ b/templates/plan.yml @@ -15,6 +15,14 @@ spec: default: 'latest' description: 'Version of this component. Has to be the same as the one in the component include entry.' + base_os: + default: 'alpine' + options: + - 'alpine' + - 'debian' + - '$GITLAB_OPENTOFU_BASE_IMAGE_OS' + description: 'Base OS of GitLab OpenTofu image.' + opentofu_version: default: '1.8.2' options: @@ -100,7 +108,7 @@ spec: TF_STATE_NAME: $[[ inputs.state_name ]] TF_PLAN_NAME: $[[ inputs.plan_name ]] image: - name: '$[[ inputs.image_registry_base ]]/$[[ inputs.image_name ]]:$[[ inputs.version ]]-opentofu$[[ inputs.opentofu_version ]]' + name: '$[[ inputs.image_registry_base ]]/$[[ inputs.image_name ]]:$[[ inputs.version ]]-opentofu$[[ inputs.opentofu_version ]]-$[[ inputs.base_os ]]' script: - "args=\"\"\nif [ \"$[[ inputs.destroy ]]\" == \"true\" ]; then \n echo \"Planning for a destroy\"\n args=\"-destroy\"\nfi\n" - gitlab-tofu plan $args diff --git a/templates/test.yml b/templates/test.yml index b8384016820c2335fb205b1408afb373277ae65a..231b09fe7f95187d77af5ca3a1d88e131eea4117 100644 --- a/templates/test.yml +++ b/templates/test.yml @@ -15,6 +15,14 @@ spec: default: 'latest' description: 'Version of this component. Has to be the same as the one in the component include entry.' + base_os: + default: 'alpine' + options: + - 'alpine' + - 'debian' + - '$GITLAB_OPENTOFU_BASE_IMAGE_OS' + description: 'Base OS of GitLab OpenTofu image.' + opentofu_version: default: '1.8.2' options: @@ -76,6 +84,6 @@ spec: TF_ROOT: $[[ inputs.root_dir ]] TF_STATE_NAME: $[[ inputs.state_name ]] image: - name: '$[[ inputs.image_registry_base ]]/$[[ inputs.image_name ]]:$[[ inputs.version ]]-opentofu$[[ inputs.opentofu_version ]]' + name: '$[[ inputs.image_registry_base ]]/$[[ inputs.image_name ]]:$[[ inputs.version ]]-opentofu$[[ inputs.opentofu_version ]]-$[[ inputs.base_os ]]' script: - gitlab-tofu test diff --git a/templates/validate-plan-apply.yml b/templates/validate-plan-apply.yml index 55d621a2bb364dfba1e2ba98dabd5ed7a98a7e8a..ee4bb68bf4d5b1b6bfb343f5c6b28332d5d8fa98 100644 --- a/templates/validate-plan-apply.yml +++ b/templates/validate-plan-apply.yml @@ -18,6 +18,14 @@ spec: default: 'latest' description: 'Version of this component. Has to be the same as the one in the component include entry.' + base_os: + default: 'alpine' + options: + - 'alpine' + - 'debian' + - '$GITLAB_OPENTOFU_BASE_IMAGE_OS' + description: 'Base OS of GitLab OpenTofu image.' + opentofu_version: default: '1.8.2' options: @@ -74,6 +82,7 @@ include: as: 'fmt' stage: $[[ inputs.stage_validate ]] version: $[[ inputs.version ]] + base_os: $[[ inputs.base_os ]] opentofu_version: $[[ inputs.opentofu_version ]] image_registry_base: $[[ inputs.image_registry_base ]] image_name: $[[ inputs.image_name ]] @@ -83,6 +92,7 @@ include: as: 'validate' stage: $[[ inputs.stage_validate ]] version: $[[ inputs.version ]] + base_os: $[[ inputs.base_os ]] opentofu_version: $[[ inputs.opentofu_version ]] image_registry_base: $[[ inputs.image_registry_base ]] image_name: $[[ inputs.image_name ]] @@ -93,6 +103,7 @@ include: as: 'plan' stage: $[[ inputs.stage_build ]] version: $[[ inputs.version ]] + base_os: $[[ inputs.base_os ]] opentofu_version: $[[ inputs.opentofu_version ]] image_registry_base: $[[ inputs.image_registry_base ]] image_name: $[[ inputs.image_name ]] @@ -104,6 +115,7 @@ include: as: 'apply' stage: $[[ inputs.stage_deploy ]] version: $[[ inputs.version ]] + base_os: $[[ inputs.base_os ]] opentofu_version: $[[ inputs.opentofu_version ]] image_registry_base: $[[ inputs.image_registry_base ]] image_name: $[[ inputs.image_name ]] diff --git a/templates/validate-plan-destroy.yml b/templates/validate-plan-destroy.yml index f9084d97fc9c44833e23c513e1e8f475b0645782..431d4c5e5b4ee0931ed12209a7333bc7ad26bbb0 100644 --- a/templates/validate-plan-destroy.yml +++ b/templates/validate-plan-destroy.yml @@ -18,6 +18,14 @@ spec: default: 'latest' description: 'Version of this component. Has to be the same as the one in the component include entry.' + base_os: + default: 'alpine' + options: + - 'alpine' + - 'debian' + - '$GITLAB_OPENTOFU_BASE_IMAGE_OS' + description: 'Base OS of GitLab OpenTofu image.' + opentofu_version: default: '1.8.2' options: @@ -77,6 +85,7 @@ include: as: 'fmt' stage: $[[ inputs.stage_validate ]] version: $[[ inputs.version ]] + base_os: $[[ inputs.base_os ]] opentofu_version: $[[ inputs.opentofu_version ]] image_registry_base: $[[ inputs.image_registry_base ]] image_name: $[[ inputs.image_name ]] @@ -86,6 +95,7 @@ include: as: 'validate' stage: $[[ inputs.stage_validate ]] version: $[[ inputs.version ]] + base_os: $[[ inputs.base_os ]] opentofu_version: $[[ inputs.opentofu_version ]] image_registry_base: $[[ inputs.image_registry_base ]] image_name: $[[ inputs.image_name ]] @@ -96,6 +106,7 @@ include: as: 'plan' stage: $[[ inputs.stage_build ]] version: $[[ inputs.version ]] + base_os: $[[ inputs.base_os ]] opentofu_version: $[[ inputs.opentofu_version ]] image_registry_base: $[[ inputs.image_registry_base ]] image_name: $[[ inputs.image_name ]] @@ -109,6 +120,7 @@ include: as: 'destroy' stage: $[[ inputs.stage_cleanup ]] version: $[[ inputs.version ]] + base_os: $[[ inputs.base_os ]] opentofu_version: $[[ inputs.opentofu_version ]] image_registry_base: $[[ inputs.image_registry_base ]] image_name: $[[ inputs.image_name ]] diff --git a/templates/validate-plan.yml b/templates/validate-plan.yml index 2134488dcdcc1f2a487f6b62b92db70a4df1f24f..0241cc67f9288b5b7be7977f66ebf1936edd9eb5 100644 --- a/templates/validate-plan.yml +++ b/templates/validate-plan.yml @@ -15,6 +15,14 @@ spec: default: 'latest' description: 'Version of this component. Has to be the same as the one in the component include entry.' + base_os: + default: 'alpine' + options: + - 'alpine' + - 'debian' + - '$GITLAB_OPENTOFU_BASE_IMAGE_OS' + description: 'Base OS of GitLab OpenTofu image.' + opentofu_version: default: '1.8.2' options: @@ -67,6 +75,7 @@ include: as: 'fmt' stage: $[[ inputs.stage_validate ]] version: $[[ inputs.version ]] + base_os: $[[ inputs.base_os ]] opentofu_version: $[[ inputs.opentofu_version ]] image_registry_base: $[[ inputs.image_registry_base ]] image_name: $[[ inputs.image_name ]] @@ -76,6 +85,7 @@ include: as: 'validate' stage: $[[ inputs.stage_validate ]] version: $[[ inputs.version ]] + base_os: $[[ inputs.base_os ]] opentofu_version: $[[ inputs.opentofu_version ]] image_registry_base: $[[ inputs.image_registry_base ]] image_name: $[[ inputs.image_name ]] @@ -86,6 +96,7 @@ include: as: 'plan' stage: $[[ inputs.stage_build ]] version: $[[ inputs.version ]] + base_os: $[[ inputs.base_os ]] opentofu_version: $[[ inputs.opentofu_version ]] image_registry_base: $[[ inputs.image_registry_base ]] image_name: $[[ inputs.image_name ]] diff --git a/templates/validate.yml b/templates/validate.yml index 09c01ad2264e86bc83d72639e34bf33aeabe5159..c34b9a23ece323918c34d57446bc2b5237f54688 100644 --- a/templates/validate.yml +++ b/templates/validate.yml @@ -15,6 +15,14 @@ spec: default: 'latest' description: 'Version of this component. Has to be the same as the one in the component include entry.' + base_os: + default: 'alpine' + options: + - 'alpine' + - 'debian' + - '$GITLAB_OPENTOFU_BASE_IMAGE_OS' + description: 'Base OS of GitLab OpenTofu image.' + opentofu_version: default: '1.8.2' options: @@ -76,6 +84,6 @@ spec: TF_STATE_NAME: $[[ inputs.state_name ]] TF_IGNORE_INIT_ERRORS: 'true' # Tofu can report errors which might be the reason init failed. image: - name: '$[[ inputs.image_registry_base ]]/$[[ inputs.image_name ]]:$[[ inputs.version ]]-opentofu$[[ inputs.opentofu_version ]]' + name: '$[[ inputs.image_registry_base ]]/$[[ inputs.image_name ]]:$[[ inputs.version ]]-opentofu$[[ inputs.opentofu_version ]]-$[[ inputs.base_os ]]' script: - gitlab-tofu validate diff --git a/tests/integration-tests/Defaults.gitlab-ci.yml b/tests/integration-tests/Defaults.gitlab-ci.yml index 572ee7d9565ae9a23af135686cad3a7846a58151..09762e0d0e81c605c21a819db2dff78494815e71 100644 --- a/tests/integration-tests/Defaults.gitlab-ci.yml +++ b/tests/integration-tests/Defaults.gitlab-ci.yml @@ -3,6 +3,7 @@ include: inputs: image_registry_base: $GITLAB_OPENTOFU_IMAGE_BASE version: $CI_COMMIT_SHA + base_os: $GITLAB_OPENTOFU_BASE_IMAGE_OS opentofu_version: $OPENTOFU_VERSION root_dir: $TEST_TF_ROOT state_name: $TEST_TF_STATE_NAME diff --git a/tests/integration-tests/ModuleRelease.gitlab-ci.yml b/tests/integration-tests/ModuleRelease.gitlab-ci.yml index 77db9b05e033ca0d28538b45ccb36b988d9ad40b..fd8dc3fac72e1d8ebedde2ffcbd30852c43e0352 100644 --- a/tests/integration-tests/ModuleRelease.gitlab-ci.yml +++ b/tests/integration-tests/ModuleRelease.gitlab-ci.yml @@ -1,6 +1,6 @@ variables: MODULE_SYSTEM: local - MODULE_VERSION: 0.0.0-$CI_COMMIT_SHA + MODULE_VERSION: 0.0.0-$CI_COMMIT_SHA-$CI_PIPELINE_ID include: - component: $CI_SERVER_FQDN/$CI_PROJECT_PATH/module-release@$CI_COMMIT_SHA diff --git a/tests/integration.gitlab-ci.yml b/tests/integration.gitlab-ci.yml index 6411f291aceba82f8f69fce3d2ccea981eb8864d..7b1f5fbae32a5eb2edaa3bb68a773a14884624d2 100644 --- a/tests/integration.gitlab-ci.yml +++ b/tests/integration.gitlab-ci.yml @@ -9,8 +9,12 @@ component: strategy: depend parallel: matrix: - - PIPELINE_NAME: [Defaults] - - PIPELINE_NAME: [JobTemplates] - - PIPELINE_NAME: [TestJob] - - PIPELINE_NAME: [ModuleRelease] - - PIPELINE_NAME: [Destroy] + - PIPELINE_NAME: + - Defaults + - JobTemplates + - TestJob + - ModuleRelease + - Destroy + GITLAB_OPENTOFU_BASE_IMAGE_OS: + - alpine + - debian diff --git a/tests/unit.gitlab-ci.yml b/tests/unit.gitlab-ci.yml index 697449fc2e08e19eb162ae20ed2f1b5c1da45dc8..aa8f46268dbfbda8f9e152f539ecf96f434e168c 100644 --- a/tests/unit.gitlab-ci.yml +++ b/tests/unit.gitlab-ci.yml @@ -5,7 +5,16 @@ variables: image: "$GITLAB_OPENTOFU_IMAGE_NAME" before_script: # Install dependencies - - apk add bats parallel + - | + if which apk >/dev/null; then + apk add bats parallel + elif which apt-get >/dev/null; then + apt-get update + apt-get install -y bats parallel + else + echo "Error: unable to install test dependencies, must either have apk or apt-get available." + exit 1 + fi - mkdir -p /tmp/bats-libs - git clone --depth 1 --branch v0.3.0 https://github.com/bats-core/bats-support.git /tmp/bats-libs/bats-support - git clone --depth 1 --branch v2.1.0 https://github.com/bats-core/bats-assert.git /tmp/bats-libs/bats-assert @@ -24,7 +33,7 @@ variables: unit-test:gitlab-tofu: extends: - .unit-test-base - - .opentofu-versions + - .image-matrix script: - bats --jobs 8 --report-formatter junit --filter-tags '!source' tests/unit/gitlab-tofu.bats @@ -34,13 +43,26 @@ unit-test:gitlab-tofu:source: variables: OPENTOFU_VERSION: $LATEST_OPENTOFU_VERSION script: - - apk add "$PKG" + - | + if which apk >/dev/null; then + if [ "$SHELL" = "ksh" ]; then + apk add loksh + else + apk add "$SHELL" + fi + elif which apt-get >/dev/null; then + apt-get update + apt-get install -y "$SHELL" + else + echo "Error: unable to install test dependencies, must either have apk or apt-get available." + exit 1 + fi - bats --jobs 8 --report-formatter junit --filter-tags 'source' tests/unit/gitlab-tofu.bats parallel: matrix: - SHELL: "bash" - PKG: "bash" + GITLAB_OPENTOFU_BASE_IMAGE_OS: ['alpine', 'debian'] - SHELL: "zsh" - PKG: "zsh" + GITLAB_OPENTOFU_BASE_IMAGE_OS: ['alpine', 'debian'] - SHELL: "ksh" - PKG: "loksh" + GITLAB_OPENTOFU_BASE_IMAGE_OS: ['alpine', 'debian'] diff --git a/tests/unit/gitlab-tofu.bats b/tests/unit/gitlab-tofu.bats index 8dd3155e6680b4e7771973fd533343c9ca5335da..0770c928ff00acc5adfaafac7001006740063292 100644 --- a/tests/unit/gitlab-tofu.bats +++ b/tests/unit/gitlab-tofu.bats @@ -170,7 +170,7 @@ test -z "$TF_GITLAB_SOURCED" test "$TF_GITLAB_SOURCED" EOF - mkdir /usr/local/sbin + mkdir -p /usr/local/sbin cat <<'EOF' > /usr/local/sbin/tofu #!/usr/bin/env sh -e echo "Called tofu, but shouldn't have!!"