diff --git a/.buildkite/pipeline.yaml b/.buildkite/pipeline.yaml index 38a28bc8..ca278cc3 100644 --- a/.buildkite/pipeline.yaml +++ b/.buildkite/pipeline.yaml @@ -1,6 +1,6 @@ x-anchors: - push: &push - label: ":helm::docker: push controller image and helm chart" + push-helm: &push-helm + label: ":helm::docker: build and push helm chart" plugins: - kubernetes: checkout: @@ -10,7 +10,7 @@ x-anchors: containers: - name: deploy image: alpine:latest - command: [.buildkite/steps/build-and-push.sh] + command: [.buildkite/steps/build-and-push-helm.sh] envFrom: - secretRef: name: deploy-secrets @@ -162,7 +162,7 @@ steps: files: junit-*.xml format: junit - - label: ":docker: build controller" + - label: ":docker: build and push controller image" key: controller plugins: - kubernetes: @@ -170,7 +170,7 @@ steps: containers: - name: ko image: golang:1.23 - command: [.buildkite/steps/controller.sh] + command: [.buildkite/steps/build-and-push-controller.sh] envFrom: - secretRef: name: deploy-secrets @@ -181,7 +181,7 @@ steps: # On feature branches, don't wait for tests. We may want to deploy # to a test cluster to debug the feature branch. - if: build.branch != pipeline.default_branch && build.tag !~ /^.+\$/ - <<: *push + <<: *push-helm key: push-feature-branch depends_on: - tidy @@ -193,7 +193,7 @@ steps: # On the main branch or tags, wait for tests. We don't want to # push a new image or chart unless the tests pass. - if: build.branch == pipeline.default_branch || build.tag =~ /^.+\$/ - <<: *push + <<: *push-helm key: push-main-or-tag depends_on: - tidy diff --git a/.buildkite/steps/assume-role.sh b/.buildkite/steps/assume-role.sh new file mode 100755 index 00000000..29fb8f09 --- /dev/null +++ b/.buildkite/steps/assume-role.sh @@ -0,0 +1,29 @@ +#!/bin/sh +set -eu + +echo "~~~ :buildkite::key::aws: Requesting an OIDC token for AWS from Buildkite" + +role_arn='arn:aws:iam::172840064832:role/pipeline-buildkite-kubernetes-stack-kubernetes-agent-stack' +BUILDKITE_OIDC_TOKEN="$(buildkite-agent oidc request-token --audience sts.amazonaws.com)" + +echo "~~~ :aws: Assuming role using OIDC token" +ASSUME_ROLE_RESPONSE="$(aws sts assume-role-with-web-identity \ + --role-arn "${role_arn}" \ + --role-session-name "buildkite-job-${BUILDKITE_JOB_ID}" \ + --web-identity-token "${BUILDKITE_OIDC_TOKEN}" +)" +ASSUME_ROLE_CMD_STATUS=$? + +if [ "${ASSUME_ROLE_CMD_STATUS}" -ne 0 ]; then + echo "^^^ +++" + echo "Failed to assume AWS role:" + echo "${ASSUME_ROLE_RESPONSE}" + exit 1 +fi + +AWS_ACCESS_KEY_ID="$(echo "${ASSUME_ROLE_RESPONSE}" | jq -r ".Credentials.AccessKeyId")" +AWS_SECRET_ACCESS_KEY="$(echo "${ASSUME_ROLE_RESPONSE}" | jq -r ".Credentials.SecretAccessKey")" +AWS_SESSION_TOKEN="$(echo "${ASSUME_ROLE_RESPONSE}" | jq -r ".Credentials.SessionToken")" +export AWS_ACCESS_KEY_ID +export AWS_SECRET_ACCESS_KEY +export AWS_SESSION_TOKEN diff --git a/.buildkite/steps/build-and-push-controller.sh b/.buildkite/steps/build-and-push-controller.sh new file mode 100755 index 00000000..8e17cad2 --- /dev/null +++ b/.buildkite/steps/build-and-push-controller.sh @@ -0,0 +1,62 @@ +#!/usr/bin/env bash + +set -Eeufo pipefail + +echo --- Installing packages +apt-get update && apt-get install -y --no-install-recommends awscli jq + +echo --- Installing ko +KO_VERSION="0.13.0" +OS="$(go env GOOS)" +ARCH="$(uname -m)" +curl -sSfL "https://github.com/ko-build/ko/releases/download/v${KO_VERSION}/ko_${KO_VERSION}_${OS^}_${ARCH}.tar.gz" | tar -xzv -C /bin ko + +tag="$(git describe)" +version="${tag#v}" + +# Is this a release version (version-tagged)? +if [[ "${version}" == "${BUILDKITE_TAG#v}" ]] ; then + # Publish to both PECR and GHCR + controller_repo_pecr="public.ecr.aws/buildkite/agent-stack-k8s/controller" + controller_repo_ghcr="ghcr.io/buildkite/agent-stack-k8s/controller" +else + # Publish dev images to PECR dev repo only + controller_repo_pecr="public.ecr.aws/buildkite/agent-stack-k8s-dev/controller" +fi + +if [[ "${controller_repo_pecr:-}" != "" ]] ; then + . .buildkite/steps/assume-role.sh + + echo ~~~ Logging into Public ECR + ko login public.ecr.aws -u AWS --password "$(aws --region us-east-1 ecr-public get-login-password)" + + echo --- Building with ko for Public ECR + controller_image_pecr="$( + VERSION="${tag}" \ + KO_DOCKER_REPO="${controller_repo_pecr}" \ + ko build --bare --tags "${version}" --platform linux/amd64,linux/arm64 \ + )" + buildkite-agent meta-data set controller-image-pecr "${controller_image_pecr}" +fi +if [[ "${controller_repo_ghcr:-}" != "" ]] ; then + echo --- Logging into to GHCR + ko login ghcr.io -u "${REGISTRY_USERNAME}" --password "${REGISTRY_PASSWORD}" + + echo --- Building with ko for GHCR + controller_image_ghcr="$( + VERSION="${tag}" \ + KO_DOCKER_REPO="${controller_repo_ghcr}" \ + ko build --bare --tags "${version}" --platform linux/amd64,linux/arm64 \ + )" + buildkite-agent meta-data set controller-image-ghcr "${controller_image_ghcr}" +fi + +buildkite-agent annotate --style success --append <