From f90b4512d9878c60f1ae76aaed40eb38e3c3c49f Mon Sep 17 00:00:00 2001 From: Jared Holgate Date: Wed, 11 Sep 2024 12:11:31 +0100 Subject: [PATCH] Use shared container image repo --- .../azure-devops-agent-aca/README.md | 30 --- .../azure-devops-agent-aca/dockerfile | 39 ---- .../azure-devops-agent-aca/start.sh | 115 ---------- .../azure-devops-agent-aci/README.md | 19 -- .../azure-devops-agent-aci/dockerfile | 29 --- .../azure-devops-agent-aci/start.sh | 98 -------- container-images/github-runner-aca/README.md | 33 --- .../github-runner-aca/app_token.sh | 89 -------- container-images/github-runner-aca/dockerfile | 49 ---- .../github-runner-aca/entrypoint.sh | 212 ------------------ .../github-runner-aca/install_actions.sh | 23 -- container-images/github-runner-aca/token.sh | 44 ---- .../github-runner-aci/ConfigureAndRun.ps1 | 65 ------ .../github-runner-aci/InstallAgent.ps1 | 19 -- container-images/github-runner-aci/README.md | 23 -- container-images/github-runner-aci/dockerfile | 35 --- variables.container.registry.tf | 14 +- 17 files changed, 7 insertions(+), 929 deletions(-) delete mode 100644 container-images/azure-devops-agent-aca/README.md delete mode 100644 container-images/azure-devops-agent-aca/dockerfile delete mode 100644 container-images/azure-devops-agent-aca/start.sh delete mode 100644 container-images/azure-devops-agent-aci/README.md delete mode 100644 container-images/azure-devops-agent-aci/dockerfile delete mode 100644 container-images/azure-devops-agent-aci/start.sh delete mode 100644 container-images/github-runner-aca/README.md delete mode 100644 container-images/github-runner-aca/app_token.sh delete mode 100644 container-images/github-runner-aca/dockerfile delete mode 100644 container-images/github-runner-aca/entrypoint.sh delete mode 100644 container-images/github-runner-aca/install_actions.sh delete mode 100644 container-images/github-runner-aca/token.sh delete mode 100644 container-images/github-runner-aci/ConfigureAndRun.ps1 delete mode 100644 container-images/github-runner-aci/InstallAgent.ps1 delete mode 100644 container-images/github-runner-aci/README.md delete mode 100644 container-images/github-runner-aci/dockerfile diff --git a/container-images/azure-devops-agent-aca/README.md b/container-images/azure-devops-agent-aca/README.md deleted file mode 100644 index 70ef854..0000000 --- a/container-images/azure-devops-agent-aca/README.md +++ /dev/null @@ -1,30 +0,0 @@ -# Linux Azure DevOps Agent Docker Image for Azure Container Apps - -> Note: You can update the [Dockerfile](dockerfile) to add any software that your require into the Azure DevOps Agent, if you don't want to have to download the bits during all pipelines executions. - -This docker file is used as a basic image for the Azure Verified Module to run Azure DevOps Agents in Azure Container Apps. - -## Credits - -The original Dockerfile and shell scripts are derived from [Microsoft Learn](https://learn.microsoft.com/en-us/azure/devops/pipelines/agents/docker?view=azure-devops#linux). - -## Environment Variables - -`AZP_URL`: The URL of the Azure DevOps organization. -`AZP_TOKEN`: The token used to authenticate the runner with Azure DevOps. This is a PAT (Personal Access Token) with the relevant scopes that requires a long expiration date. -`AZP_POOL`: The name of the agent pool. -`AZP_AGENT_NAME`: The name of the agent. -`AZP_AGENT_NAME_PREFIX`: The prefix for the agent name. Overrides `AZP_AGENT_NAME`. -`AZP_RANDOM_AGENT_SUFFIX`: Whether to add a random string to the `AZP_AGENT_NAME_PREFIX` to create a unique agent name. Default is `true`. - -## Build it - -```bash -docker build -t YOUR_IMAGE_NAME:YOUR_IMAGE_TAG . -``` - -## Push it - -```bash -docker push YOUR_IMAGE_NAME:YOUR_IMAGE_TAG -``` diff --git a/container-images/azure-devops-agent-aca/dockerfile b/container-images/azure-devops-agent-aca/dockerfile deleted file mode 100644 index 5d3908f..0000000 --- a/container-images/azure-devops-agent-aca/dockerfile +++ /dev/null @@ -1,39 +0,0 @@ -FROM mcr.microsoft.com/azure-powershell:ubuntu-22.04 -ENV TARGETARCH="linux-x64" - -# To make it easier for build and release pipelines to run apt-get, -# configure apt to not require confirmation (assume the -y argument by default) -ENV DEBIAN_FRONTEND=noninteractive -RUN echo "APT::Get::Assume-Yes \"true\";" > /etc/apt/apt.conf.d/90assumeyes - -RUN apt-get update \ -&& apt-get install -y --no-install-recommends \ - ca-certificates \ - curl \ - jq \ - git \ - iputils-ping \ - libicu70 \ - libcurl4 \ - libunwind8 \ - netcat \ - ruby \ - unzip \ - dnsutils - -RUN curl -sL https://aka.ms/InstallAzureCLIDeb | bash - -WORKDIR /azp/ - -COPY ./start.sh ./ -RUN chmod +x ./start.sh - -# Create agent user and set up home directory -RUN useradd -m -d /home/agent agent -RUN chown -R agent:agent /azp /home/agent - -USER agent -# Another option is to run the agent as root. -# ENV AGENT_ALLOW_RUNASROOT="true" - -ENTRYPOINT [ "./start.sh" ] \ No newline at end of file diff --git a/container-images/azure-devops-agent-aca/start.sh b/container-images/azure-devops-agent-aca/start.sh deleted file mode 100644 index 16296ed..0000000 --- a/container-images/azure-devops-agent-aca/start.sh +++ /dev/null @@ -1,115 +0,0 @@ -#!/bin/bash -set -e - -if [ -z "${AZP_URL}" ]; then - echo 1>&2 "error: missing AZP_URL environment variable" - exit 1 -fi - -if [ -z "${AZP_TOKEN_FILE}" ]; then - if [ -z "${AZP_TOKEN}" ]; then - echo 1>&2 "error: missing AZP_TOKEN environment variable" - exit 1 - fi - - AZP_TOKEN_FILE="/azp/.token" - echo -n "${AZP_TOKEN}" > "${AZP_TOKEN_FILE}" -fi - -unset AZP_TOKEN - -if [ -n "${AZP_WORK}" ]; then - mkdir -p "${AZP_WORK}" -fi - -export AGENT_ALLOW_RUNASROOT="1" - -cleanup() { - # If $AZP_PLACEHOLDER is set, skip cleanup - if [ -n "$AZP_PLACEHOLDER" ]; then - echo 'Running in placeholder mode, skipping cleanup' - else - if [ -e ./config.sh ]; then - print_header "Cleanup. Removing Azure Pipelines agent..." - - # If the agent has some running jobs, the configuration removal process will fail. - # So, give it some time to finish the job. - while true; do - ./config.sh remove --unattended --auth "PAT" --token $(cat "${AZP_TOKEN_FILE}") && break - - echo "Retrying in 30 seconds..." - sleep 30 - done - fi - fi -} - -print_header() { - lightcyan="\033[1;36m" - nocolor="\033[0m" - echo -e "\n${lightcyan}$1${nocolor}\n" -} - -# Let the agent ignore the token env variables -export VSO_AGENT_IGNORE="AZP_TOKEN,AZP_TOKEN_FILE" - -print_header "1. Determining matching Azure Pipelines agent..." - -AZP_AGENT_PACKAGES=$(curl -LsS \ - -u user:$(cat "${AZP_TOKEN_FILE}") \ - -H "Accept:application/json;" \ - "${AZP_URL}/_apis/distributedtask/packages/agent?platform=${TARGETARCH}&top=1") - -AZP_AGENT_PACKAGE_LATEST_URL=$(echo "${AZP_AGENT_PACKAGES}" | jq -r ".value[0].downloadUrl") - -if [ -z "${AZP_AGENT_PACKAGE_LATEST_URL}" -o "${AZP_AGENT_PACKAGE_LATEST_URL}" == "null" ]; then - echo 1>&2 "error: could not determine a matching Azure Pipelines agent" - echo 1>&2 "check that account "${AZP_URL}" is correct and the token is valid for that account" - exit 1 -fi - -print_header "2. Downloading and extracting Azure Pipelines agent..." - -echo "Agent package URL: ${AZP_AGENT_PACKAGE_LATEST_URL}" - -curl -LsS "${AZP_AGENT_PACKAGE_LATEST_URL}" | tar -xz & wait $! - -source ./env.sh - -trap "cleanup; exit 0" EXIT -trap "cleanup; exit 130" INT -trap "cleanup; exit 143" TERM - -print_header "3. Configuring Azure Pipelines agent..." - -_RANDOM_AGENT_SUFFIX=${AZP_RANDOM_AGENT_SUFFIX:="true"} -_AGENT_NAME=${AZP_AGENT_NAME:-${AZP_AGENT_NAME_PREFIX:-azure-devops-agent}-$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 13 ; echo '')} -if [[ ${_RANDOM_AGENT_SUFFIX} != "true" ]]; then - _AGENT_NAME=${AZP_AGENT_NAME:-${AZP_AGENT_NAME_PREFIX:-azure-devops-agent}-$(hostname)} - echo "AZP_RANDOM_AGENT_SUFFIX is ${AZP_RANDOM_AGENT_SUFFIX}. Setting agent name to ${_AGENT_NAME}" -fi - -echo "Agent name: ${_AGENT_NAME}" - -./config.sh --unattended \ - --agent "${_AGENT_NAME}" \ - --url "${AZP_URL}" \ - --auth "PAT" \ - --token $(cat "${AZP_TOKEN_FILE}") \ - --pool "${AZP_POOL:-Default}" \ - --work "${AZP_WORK:-_work}" \ - --replace \ - --acceptTeeEula & wait $! - -print_header "4. Running Azure Pipelines agent..." - -chmod +x ./run.sh - -# If $AZP_PLACEHOLDER is set, skipping running the agent -if [ -n "$AZP_PLACEHOLDER" ]; then - echo 'Running in placeholder mode, skipping running the agent' -else - # To be aware of TERM and INT signals call ./run.sh - # Running it with the --once flag at the end will shut down the agent after the build is executed - ./run.sh "$@" --once & wait $! -fi \ No newline at end of file diff --git a/container-images/azure-devops-agent-aci/README.md b/container-images/azure-devops-agent-aci/README.md deleted file mode 100644 index 7d51eda..0000000 --- a/container-images/azure-devops-agent-aci/README.md +++ /dev/null @@ -1,19 +0,0 @@ -# Linux Azure DevOps Agent Docker Image for Azure Container Instances - -IMPORTANT: This code is completely stolen from https://github.com/Azure/terraform-azurerm-aci-devops-agent - -This image is based on the [official documentation](https://docs.microsoft.com/en-us/azure/devops/pipelines/agents/docker?view=azure-devops#linux). - -> Note: You can update the [Dockerfile](Dockerfile) to add any software that your require into the Azure DevOps agent, if you don't want to have to download the bits during all pipelines executions. - -## Build it - -```bash -docker build -t YOUR_IMAGE_NAME:YOUR_IMAGE_TAG . -``` - -## Push it - -```bash -docker push YOUR_IMAGE_NAME:YOUR_IMAGE_TAG -``` diff --git a/container-images/azure-devops-agent-aci/dockerfile b/container-images/azure-devops-agent-aci/dockerfile deleted file mode 100644 index 77dbaec..0000000 --- a/container-images/azure-devops-agent-aci/dockerfile +++ /dev/null @@ -1,29 +0,0 @@ -FROM mcr.microsoft.com/azure-powershell:ubuntu-22.04 - -# To make it easier for build and release pipelines to run apt-get, -# configure apt to not require confirmation (assume the -y argument by default) -ENV DEBIAN_FRONTEND=noninteractive -RUN echo "APT::Get::Assume-Yes \"true\";" > /etc/apt/apt.conf.d/90assumeyes - -RUN apt-get update \ -&& apt-get install -y --no-install-recommends \ - ca-certificates \ - curl \ - jq \ - git \ - iputils-ping \ - libcurl4 \ - libunwind8 \ - netcat \ - ruby \ - unzip \ - dnsutils - -RUN curl -sL https://aka.ms/InstallAzureCLIDeb | bash - -WORKDIR /azp - -COPY ./start.sh . -RUN chmod +x start.sh - -CMD ["./start.sh"] \ No newline at end of file diff --git a/container-images/azure-devops-agent-aci/start.sh b/container-images/azure-devops-agent-aci/start.sh deleted file mode 100644 index bdee34e..0000000 --- a/container-images/azure-devops-agent-aci/start.sh +++ /dev/null @@ -1,98 +0,0 @@ -#!/bin/bash -set -e - -if [ -z "$AZP_URL" ]; then - echo 1>&2 "error: missing AZP_URL environment variable" - exit 1 -fi - -if [ -z "$AZP_TOKEN_FILE" ]; then - if [ -z "$AZP_TOKEN" ]; then - echo 1>&2 "error: missing AZP_TOKEN environment variable" - exit 1 - fi - - AZP_TOKEN_FILE=/azp/.token - echo -n $AZP_TOKEN > "$AZP_TOKEN_FILE" -fi - -unset AZP_TOKEN - -if [ -n "$AZP_WORK" ]; then - mkdir -p "$AZP_WORK" -fi - -rm -rf /azp/agent -mkdir /azp/agent -cd /azp/agent - -export AGENT_ALLOW_RUNASROOT="1" - -cleanup() { - if [ -e config.sh ]; then - print_header "Cleanup. Removing Azure Pipelines agent..." - - ./config.sh remove --unattended \ - --auth PAT \ - --token $(cat "$AZP_TOKEN_FILE") - fi -} - -print_header() { - lightcyan='\033[1;36m' - nocolor='\033[0m' - echo -e "${lightcyan}$1${nocolor}" -} - -# Let the agent ignore the token env variables -export VSO_AGENT_IGNORE=AZP_TOKEN,AZP_TOKEN_FILE - -# ACI in private vnet require time to get access to Internet -sleep 30 - -print_header "1. Determining matching Azure Pipelines agent..." - -AZP_AGENT_RESPONSE=$(curl -LsS \ - -u user:$(cat "$AZP_TOKEN_FILE") \ - -H 'Accept:application/json;api-version=3.0-preview' \ - "$AZP_URL/_apis/distributedtask/packages/agent?platform=linux-x64") - -if echo "$AZP_AGENT_RESPONSE" | jq . >/dev/null 2>&1; then - AZP_AGENTPACKAGE_URL=$(echo "$AZP_AGENT_RESPONSE" \ - | jq -r '.value | map([.version.major,.version.minor,.version.patch,.downloadUrl]) | sort | .[length-1] | .[3]') -fi - -if [ -z "$AZP_AGENTPACKAGE_URL" -o "$AZP_AGENTPACKAGE_URL" == "null" ]; then - echo 1>&2 "error: could not determine a matching Azure Pipelines agent - check that account '$AZP_URL' is correct and the token is valid for that account" - exit 1 -fi - -print_header "2. Downloading and installing Azure Pipelines agent..." - -curl -LsS $AZP_AGENTPACKAGE_URL | tar -xz & wait $! - -source ./env.sh - -trap 'cleanup; exit 130' INT -trap 'cleanup; exit 143' TERM - -print_header "3. Configuring Azure Pipelines agent..." - -./config.sh --unattended \ - --agent "${AZP_AGENT_NAME:-$(hostname)}" \ - --url "$AZP_URL" \ - --auth PAT \ - --token $(cat "$AZP_TOKEN_FILE") \ - --pool "${AZP_POOL:-Default}" \ - --work "${AZP_WORK:-_work}" \ - --replace \ - --acceptTeeEula & wait $! - -# remove the administrative token before accepting work -rm $AZP_TOKEN_FILE - -print_header "4. Running Azure Pipelines agent..." - -# `exec` the node runtime so it's aware of TERM and INT signals -# AgentService.js understands how to handle agent self-update and restart -exec ./externals/node/bin/node ./bin/AgentService.js interactive --once \ No newline at end of file diff --git a/container-images/github-runner-aca/README.md b/container-images/github-runner-aca/README.md deleted file mode 100644 index 843c854..0000000 --- a/container-images/github-runner-aca/README.md +++ /dev/null @@ -1,33 +0,0 @@ -# Linux GitHub Runner Docker Image for Azure Container Apps - -> Note: You can update the [Dockerfile](dockerfile) to add any software that your require into the GitHub Runner, if you don't want to have to download the bits during all pipelines executions. - -This docker file is used as a basic image for the Azure Verified Module to run GitHub Actions in Azure Container Apps. - -## Credits - -The original Dockerfile and shell scripts are derived from [myoung34/docker-github-actions-runner](https://github.com/myoung34/docker-github-actions-runner). - -## Environment Variables - -`REPO_URL`: The URL of the repository to add the runner to. -`ORG_NAME`: The name of the organization that the repository belongs to. -`ENTERPRISE_NAME`: The name of the enterprise that the repository belongs to. -`ACCESS_TOKEN`: The token used to authenticate the runner with GitHub. This is a PAT (Personal Access Token) with the relevant scopes that requires a long expiration date. -`RUNNER_NAME_PREFIX`: The prefix for the runner name. -`RANDOM_RUNNER_SUFFIX`: Whether to add a random string to the RUNNER_NAME_PREFIX to create a unique runner name. Default is `true`. -`RUNNER_SCOPE`: The scope of the runner. Valid values are `repo`, `org` and `ent`. -`RUNNER_GROUP`: The runner group if using them. -`EPHEMERAL`: Whether the runner is ephemeral or not. - -## Build it - -```bash -docker build --progress=plain --no-cache -t YOUR_IMAGE_NAME:YOUR_IMAGE_TAG . -``` - -## Push it - -```bash -docker push YOUR_IMAGE_NAME:YOUR_IMAGE_TAG -``` diff --git a/container-images/github-runner-aca/app_token.sh b/container-images/github-runner-aca/app_token.sh deleted file mode 100644 index 8c32384..0000000 --- a/container-images/github-runner-aca/app_token.sh +++ /dev/null @@ -1,89 +0,0 @@ -#!/bin/bash -# -# Request an ACCESS_TOKEN to be used by a GitHub APP -# Environment variable that need to be set up: -# * APP_ID, the GitHub's app ID -# * APP_PRIVATE_KEY, the content of GitHub app's private key in PEM format. -# * APP_LOGIN, the login name used to install GitHub's app -# -# https://github.com/orgs/community/discussions/24743#discussioncomment-3245300 -# - -set -o pipefail - -_GITHUB_HOST=${GITHUB_HOST:="github.com"} - -# If URL is not github.com then use the enterprise api endpoint -if [[ ${GITHUB_HOST} = "github.com" ]]; then - URI="https://api.${_GITHUB_HOST}" -else - URI="https://${_GITHUB_HOST}/api/v3" -fi - -API_VERSION=v3 -API_HEADER="Accept: application/vnd.github.${API_VERSION}+json" -CONTENT_LENGTH_HEADER="Content-Length: 0" -APP_INSTALLATIONS_URI="${URI}/app/installations" - - -# JWT parameters based off -# https://docs.github.com/en/developers/apps/building-github-apps/authenticating-with-github-apps#authenticating-as-a-github-app -# -# JWT token issuance and expiration parameters -JWT_IAT_DRIFT=60 -JWT_EXP_DELTA=600 - -JWT_JOSE_HEADER='{ - "alg": "RS256", - "typ": "JWT" -}' - - -build_jwt_payload() { - now=$(date +%s) - iat=$((now - JWT_IAT_DRIFT)) - jq -c \ - --arg iat_str "${iat}" \ - --arg exp_delta_str "${JWT_EXP_DELTA}" \ - --arg app_id_str "${APP_ID}" \ - ' - ($iat_str | tonumber) as $iat - | ($exp_delta_str | tonumber) as $exp_delta - | ($app_id_str | tonumber) as $app_id - | .iat = $iat - | .exp = ($iat + $exp_delta) - | .iss = $app_id - ' <<< "{}" | tr -d '\n' -} - -base64url() { - base64 | tr '+/' '-_' | tr -d '=\n' -} - -rs256_sign() { - openssl dgst -binary -sha256 -sign <(echo "$1") -} - -request_access_token() { - jwt_payload=$(build_jwt_payload) - encoded_jwt_parts=$(base64url <<<"${JWT_JOSE_HEADER}").$(base64url <<<"${jwt_payload}") - encoded_mac=$(echo -n "${encoded_jwt_parts}" | rs256_sign "${APP_PRIVATE_KEY}" | base64url) - generated_jwt="${encoded_jwt_parts}.${encoded_mac}" - - auth_header="Authorization: Bearer ${generated_jwt}" - - app_installations_response=$(curl -sX GET \ - -H "${auth_header}" \ - -H "${API_HEADER}" \ - "${APP_INSTALLATIONS_URI}" \ - ) - access_token_url=$(echo "${app_installations_response}" | jq --raw-output '.[] | select (.account.login == "'"${APP_LOGIN}"'" and .app_id == '"${APP_ID}"') .access_tokens_url') - curl -sX POST \ - -H "${CONTENT_LENGTH_HEADER}" \ - -H "${auth_header}" \ - -H "${API_HEADER}" \ - "${access_token_url}" | \ - jq --raw-output .token -} - -request_access_token diff --git a/container-images/github-runner-aca/dockerfile b/container-images/github-runner-aca/dockerfile deleted file mode 100644 index 00caa92..0000000 --- a/container-images/github-runner-aca/dockerfile +++ /dev/null @@ -1,49 +0,0 @@ -FROM mcr.microsoft.com/azure-powershell:ubuntu-22.04 - -# To make it easier for build and release pipelines to run apt-get, -# configure apt to not require confirmation (assume the -y argument by default) -ENV DEBIAN_FRONTEND=noninteractive -RUN echo "APT::Get::Assume-Yes \"true\";" > /etc/apt/apt.conf.d/90assumeyes - -RUN apt-get update \ -&& apt-get install -y --no-install-recommends \ - ca-certificates \ - curl \ - jq \ - git \ - dumb-init \ - sudo \ - iputils-ping \ - libcurl4 \ - libunwind8 \ - netcat \ - ruby \ - unzip \ - dnsutils \ - nodejs - -RUN curl -sL https://aka.ms/InstallAzureCLIDeb | bash - -RUN groupadd -g 121 runner \ - && useradd -mr -d /home/runner -u 1001 -g 121 runner \ - && usermod -aG sudo runner \ - && echo '%sudo ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers - -ENV AGENT_TOOLSDIRECTORY=/opt/hostedtoolcache -RUN mkdir -p /opt/hostedtoolcache - -SHELL ["/bin/bash", "-o", "pipefail", "-c"] - -WORKDIR /actions-runner -COPY install_actions.sh /actions-runner - -RUN chmod +x /actions-runner/install_actions.sh \ - && /actions-runner/install_actions.sh ${GH_RUNNER_VERSION} ${TARGETPLATFORM} \ - && rm /actions-runner/install_actions.sh \ - && chown runner /_work /actions-runner /opt/hostedtoolcache - -COPY token.sh entrypoint.sh app_token.sh / -RUN chmod +x /token.sh /entrypoint.sh /app_token.sh - -ENTRYPOINT ["/entrypoint.sh"] -CMD ["./bin/Runner.Listener", "run", "--startuptype", "service"] \ No newline at end of file diff --git a/container-images/github-runner-aca/entrypoint.sh b/container-images/github-runner-aca/entrypoint.sh deleted file mode 100644 index 5bdda1b..0000000 --- a/container-images/github-runner-aca/entrypoint.sh +++ /dev/null @@ -1,212 +0,0 @@ -#!/usr/bin/dumb-init /bin/bash -# shellcheck shell=bash - -export RUNNER_ALLOW_RUNASROOT=1 -export PATH=${PATH}:/actions-runner - -# Un-export these, so that they must be passed explicitly to the environment of -# any command that needs them. This may help prevent leaks. -export -n ACCESS_TOKEN -export -n RUNNER_TOKEN -export -n APP_ID -export -n APP_PRIVATE_KEY - -trap_with_arg() { - func="$1" ; shift - for sig ; do - trap "$func $sig" "$sig" - done -} - -deregister_runner() { - echo "Caught $1 - Deregistering runner" - if [[ -n "${ACCESS_TOKEN}" ]]; then - _TOKEN=$(ACCESS_TOKEN="${ACCESS_TOKEN}" bash /token.sh) - RUNNER_TOKEN=$(echo "${_TOKEN}" | jq -r .token) - fi - ./config.sh remove --token "${RUNNER_TOKEN}" - exit -} - -_DISABLE_AUTOMATIC_DEREGISTRATION=${DISABLE_AUTOMATIC_DEREGISTRATION:-false} - -_RANDOM_RUNNER_SUFFIX=${RANDOM_RUNNER_SUFFIX:="true"} - -_RUNNER_NAME=${RUNNER_NAME:-${RUNNER_NAME_PREFIX:-github-runner}-$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 13 ; echo '')} -if [[ ${RANDOM_RUNNER_SUFFIX} != "true" ]]; then - # In some cases this file does not exist - if [[ -f "/etc/hostname" ]]; then - # in some cases it can also be empty - if [[ $(stat --printf="%s" /etc/hostname) -ne 0 ]]; then - _RUNNER_NAME=${RUNNER_NAME:-${RUNNER_NAME_PREFIX:-github-runner}-$(cat /etc/hostname)} - echo "RANDOM_RUNNER_SUFFIX is ${RANDOM_RUNNER_SUFFIX}. /etc/hostname exists and has content. Setting runner name to ${_RUNNER_NAME}" - else - echo "RANDOM_RUNNER_SUFFIX is ${RANDOM_RUNNER_SUFFIX} ./etc/hostname exists but is empty. Not using /etc/hostname." - fi - else - echo "RANDOM_RUNNER_SUFFIX is ${RANDOM_RUNNER_SUFFIX} but /etc/hostname does not exist. Not using /etc/hostname." - fi -fi - -_RUNNER_WORKDIR=${RUNNER_WORKDIR:-/_work/${_RUNNER_NAME}} -_LABELS=${LABELS:-default} -_RUNNER_GROUP=${RUNNER_GROUP:-Default} -_GITHUB_HOST=${GITHUB_HOST:="github.com"} -_RUN_AS_ROOT=${RUN_AS_ROOT:="true"} -_START_DOCKER_SERVICE=${START_DOCKER_SERVICE:="false"} - -# ensure backwards compatibility -if [[ -z ${RUNNER_SCOPE} ]]; then - if [[ ${ORG_RUNNER} == "true" ]]; then - echo 'ORG_RUNNER is now deprecated. Please use RUNNER_SCOPE="org" instead.' - export RUNNER_SCOPE="org" - else - export RUNNER_SCOPE="repo" - fi -fi - -RUNNER_SCOPE="${RUNNER_SCOPE,,}" # to lowercase - -case ${RUNNER_SCOPE} in - org*) - [[ -z ${ORG_NAME} ]] && ( echo "ORG_NAME required for org runners"; exit 1 ) - _SHORT_URL="https://${_GITHUB_HOST}/${ORG_NAME}" - RUNNER_SCOPE="org" - if [[ -n "${APP_ID}" ]] && [[ -z "${APP_LOGIN}" ]]; then - APP_LOGIN=${ORG_NAME} - fi - ;; - - ent*) - [[ -z ${ENTERPRISE_NAME} ]] && ( echo "ENTERPRISE_NAME required for enterprise runners"; exit 1 ) - _SHORT_URL="https://${_GITHUB_HOST}/enterprises/${ENTERPRISE_NAME}" - RUNNER_SCOPE="enterprise" - ;; - - *) - [[ -z ${REPO_URL} ]] && ( echo "REPO_URL required for repo runners"; exit 1 ) - _SHORT_URL=${REPO_URL} - RUNNER_SCOPE="repo" - if [[ -n "${APP_ID}" ]] && [[ -z "${APP_LOGIN}" ]]; then - APP_LOGIN=${REPO_URL%/*} - APP_LOGIN=${APP_LOGIN##*/} - fi - ;; -esac - -configure_runner() { - ARGS=() - if [[ -n "${APP_ID}" ]] && [[ -n "${APP_PRIVATE_KEY}" ]] && [[ -n "${APP_LOGIN}" ]]; then - if [[ -n "${ACCESS_TOKEN}" ]] || [[ -n "${RUNNER_TOKEN}" ]]; then - echo "ERROR: ACCESS_TOKEN or RUNNER_TOKEN provided but are mutually exclusive with APP_ID, APP_PRIVATE_KEY and APP_LOGIN." >&2 - exit 1 - fi - echo "Obtaining access token for app_id ${APP_ID} and login ${APP_LOGIN}" - nl=" -" - ACCESS_TOKEN=$(APP_ID="${APP_ID}" APP_PRIVATE_KEY="${APP_PRIVATE_KEY//\\n/${nl}}" APP_LOGIN="${APP_LOGIN}" bash /app_token.sh) - elif [[ -n "${APP_ID}" ]] || [[ -n "${APP_PRIVATE_KEY}" ]] || [[ -n "${APP_LOGIN}" ]]; then - echo "ERROR: All of APP_ID, APP_PRIVATE_KEY and APP_LOGIN must be specified." >&2 - exit 1 - fi - - if [[ -n "${ACCESS_TOKEN}" ]]; then - echo "Obtaining the token of the runner" - _TOKEN=$(ACCESS_TOKEN="${ACCESS_TOKEN}" bash /token.sh) - RUNNER_TOKEN=$(echo "${_TOKEN}" | jq -r .token) - fi - - # shellcheck disable=SC2153 - if [ -n "${EPHEMERAL}" ]; then - echo "Ephemeral option is enabled" - ARGS+=("--ephemeral") - fi - - if [ -n "${DISABLE_AUTO_UPDATE}" ]; then - echo "Disable auto update option is enabled" - ARGS+=("--disableupdate") - fi - - if [ -n "${NO_DEFAULT_LABELS}" ]; then - echo "Disable adding the default self-hosted, platform, and architecture labels" - ARGS+=("--no-default-labels") - fi - - echo "Configuring" - ./config.sh \ - --url "${_SHORT_URL}" \ - --token "${RUNNER_TOKEN}" \ - --name "${_RUNNER_NAME}" \ - --work "${_RUNNER_WORKDIR}" \ - --labels "${_LABELS}" \ - --runnergroup "${_RUNNER_GROUP}" \ - --unattended \ - --replace \ - "${ARGS[@]}" - - [[ ! -d "${_RUNNER_WORKDIR}" ]] && mkdir "${_RUNNER_WORKDIR}" - -} - - -# Opt into runner reusage because a value was given -if [[ -n "${CONFIGURED_ACTIONS_RUNNER_FILES_DIR}" ]]; then - echo "Runner reusage is enabled" - - # directory exists, copy the data - if [[ -d "${CONFIGURED_ACTIONS_RUNNER_FILES_DIR}" ]]; then - echo "Copying previous data" - cp -p -r "${CONFIGURED_ACTIONS_RUNNER_FILES_DIR}/." "/actions-runner" - fi - - if [ -f "/actions-runner/.runner" ]; then - echo "The runner has already been configured" - else - configure_runner - fi -else - echo "Runner reusage is disabled" - configure_runner -fi - -if [[ -n "${CONFIGURED_ACTIONS_RUNNER_FILES_DIR}" ]]; then - echo "Reusage is enabled. Storing data to ${CONFIGURED_ACTIONS_RUNNER_FILES_DIR}" - # Quoting (even with double-quotes) the regexp brokes the copying - cp -p -r "/actions-runner/_diag" "/actions-runner/svc.sh" /actions-runner/.[^.]* "${CONFIGURED_ACTIONS_RUNNER_FILES_DIR}" -fi - - - -if [[ ${_DISABLE_AUTOMATIC_DEREGISTRATION} == "false" ]]; then - trap_with_arg deregister_runner SIGINT SIGQUIT SIGTERM INT TERM QUIT -fi - -# Start docker service if needed (e.g. for docker-in-docker) -if [[ ${_START_DOCKER_SERVICE} == "true" ]]; then - echo "Starting docker service" - _PREFIX="" - [[ ${_RUN_AS_ROOT} != "true" ]] && _PREFIX="sudo" - ${_PREFIX} service docker start -fi - -# Container's command (CMD) execution as runner user - - -if [[ ${_RUN_AS_ROOT} == "true" ]]; then - if [[ $(id -u) -eq 0 ]]; then - "$@" - else - echo "ERROR: RUN_AS_ROOT env var is set to true but the user has been overridden and is not running as root, but UID '$(id -u)'" - exit 1 - fi -else - if [[ $(id -u) -eq 0 ]]; then - [[ -n "${CONFIGURED_ACTIONS_RUNNER_FILES_DIR}" ]] && chown -R runner "${CONFIGURED_ACTIONS_RUNNER_FILES_DIR}" - chown -R runner "${_RUNNER_WORKDIR}" /actions-runner - # The toolcache is not recursively chowned to avoid recursing over prepulated tooling in derived docker images - chown runner /opt/hostedtoolcache/ - /usr/sbin/gosu runner "$@" - else - "$@" - fi -fi diff --git a/container-images/github-runner-aca/install_actions.sh b/container-images/github-runner-aca/install_actions.sh deleted file mode 100644 index 9c7f784..0000000 --- a/container-images/github-runner-aca/install_actions.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash -e -GH_RUNNER_VERSION=$1 -TARGETPLATFORM=$2 - -export TARGET_ARCH="x64" -if [[ $TARGETPLATFORM == "linux/arm64" ]]; then - export TARGET_ARCH="arm64" -fi - -if [[ $GH_RUNNER_VERSION == "" ]]; then - LASTEST_VERSION=$(curl "https://api.github.com/repos/actions/runner/releases/latest") - GH_RUNNER_VERSION=$(echo $LASTEST_VERSION | jq -r '.tag_name') - echo "GitHub Runner latest version: $GH_RUNNER_VERSION" -fi - -ReplaceWith="" -GH_RUNNER_VERSION=${GH_RUNNER_VERSION/v/${ReplaceWith}} - -curl -L "https://github.com/actions/runner/releases/download/v${GH_RUNNER_VERSION}/actions-runner-linux-${TARGET_ARCH}-${GH_RUNNER_VERSION}.tar.gz" > actions.tar.gz -tar -zxf actions.tar.gz -rm -f actions.tar.gz -./bin/installdependencies.sh -mkdir /_work diff --git a/container-images/github-runner-aca/token.sh b/container-images/github-runner-aca/token.sh deleted file mode 100644 index 64d2196..0000000 --- a/container-images/github-runner-aca/token.sh +++ /dev/null @@ -1,44 +0,0 @@ -#!/bin/bash - -_GITHUB_HOST=${GITHUB_HOST:="github.com"} - -# If URL is not github.com then use the enterprise api endpoint -if [[ ${GITHUB_HOST} = "github.com" ]]; then - URI="https://api.${_GITHUB_HOST}" -else - URI="https://${_GITHUB_HOST}/api/v3" -fi - -API_VERSION=v3 -API_HEADER="Accept: application/vnd.github.${API_VERSION}+json" -AUTH_HEADER="Authorization: token ${ACCESS_TOKEN}" -CONTENT_LENGTH_HEADER="Content-Length: 0" - -case ${RUNNER_SCOPE} in - org*) - _FULL_URL="${URI}/orgs/${ORG_NAME}/actions/runners/registration-token" - ;; - - ent*) - _FULL_URL="${URI}/enterprises/${ENTERPRISE_NAME}/actions/runners/registration-token" - ;; - - *) - _PROTO="https://" - # shellcheck disable=SC2116 - _URL="$(echo "${REPO_URL/${_PROTO}/}")" - _PATH="$(echo "${_URL}" | grep / | cut -d/ -f2-)" - _ACCOUNT="$(echo "${_PATH}" | cut -d/ -f1)" - _REPO="$(echo "${_PATH}" | cut -d/ -f2)" - _FULL_URL="${URI}/repos/${_ACCOUNT}/${_REPO}/actions/runners/registration-token" - ;; -esac - -RUNNER_TOKEN="$(curl -XPOST -fsSL \ - -H "${CONTENT_LENGTH_HEADER}" \ - -H "${AUTH_HEADER}" \ - -H "${API_HEADER}" \ - "${_FULL_URL}" \ -| jq -r '.token')" - -echo "{\"token\": \"${RUNNER_TOKEN}\", \"full_url\": \"${_FULL_URL}\"}" diff --git a/container-images/github-runner-aci/ConfigureAndRun.ps1 b/container-images/github-runner-aci/ConfigureAndRun.ps1 deleted file mode 100644 index 53a6f16..0000000 --- a/container-images/github-runner-aci/ConfigureAndRun.ps1 +++ /dev/null @@ -1,65 +0,0 @@ -$token = $env:GH_RUNNER_TOKEN -$url = $env:GH_RUNNER_URL -$runnerName = $env:GH_RUNNER_NAME -$runnerGroup = $env:GH_RUNNER_GROUP -$runnerMode = $env:GH_RUNNER_MODE - -$hasRunnerGroup = ($null -ne $runnerGroup -and $runnerGroup -ne "") -$isEphemeral = $true - -if($null -ne $runnerMode -and $runnerMode -ne "" -and $runnerMode.ToLower() -eq "persistent") { - $isEphemeral = $false -} - -# Get the runner registration token from the GitHub API if a PAT is supplied -$isPat = $false -if($token.StartsWith("ghp_") -or $token.StartsWith("github_pat_")) { - $isPat = $true -} - -if($isPat) { - $githubUrlSplit = $url.Split("/", [System.StringSplitOptions]::RemoveEmptyEntries) - $githubOrgRepoSegment = "" - $tokenApiUrl = "" - $tokenType = "" - - if($githubUrlSplit.Length -eq 3) { - $githubOrgRepoSegment = $githubUrlSplit[-1] - $tokenType = "orgs" - } else { - $githubOrgRepoSegment = $githubUrlSplit[-2] + "/" + $githubUrlSplit[-1] - $tokenType = "repos" - } - - $tokenApiUrl = "https://api.github.com/$($tokenType)/$($githubOrgRepoSegment)/actions/runners/registration-token" - - Write-Host "Generating a new runner registration token using the supplied PAT from the url $tokenApiUrl" - - $headers = @{} - $headers.Add("Authorization", "bearer $token") - $headers.Add("Accept", "application/vnd.github.v3+json") - - $token = (Invoke-RestMethod -Uri $tokenApiUrl -Headers $headers -Method Post).token -} - -# Register the runner -$env:RUNNER_ALLOW_RUNASROOT = "1" -if($hasRunnerGroup) { - if($isEphemeral) { - Write-Host "Registering the runner $runnerName with the runner group $runnerGroup and ephemeral mode" - ./config.sh --unattended --replace --url $url --token $token --name $runnerName --runnergroup $runnerGroup --ephemeral - } else { - Write-Host "Registering the runner $runnerName with the runner group $runnerGroup" - ./config.sh --unattended --replace --url $url --token $token --name $runnerName --runnergroup $runnerGroup - } -} else { - if($isEphemeral) { - Write-Host "Registering the runner $runnerName in ephemeral mode" - ./config.sh --unattended --replace --url $url --token $token --name $runnerName --ephemeral - } else { - Write-Host "Registering the runner $runnerName" - ./config.sh --unattended --replace --url $url --token $token --name $runnerName - } -} - -./run.sh diff --git a/container-images/github-runner-aci/InstallAgent.ps1 b/container-images/github-runner-aci/InstallAgent.ps1 deleted file mode 100644 index b22ca31..0000000 --- a/container-images/github-runner-aci/InstallAgent.ps1 +++ /dev/null @@ -1,19 +0,0 @@ -$releaseData = Invoke-RestMethod -Uri "https://api.github.com/repos/actions/runner/releases/latest" - -$releaseVersion = $releaseData.tag_name.Replace("v", "") - -$filter = "actions-runner-linux-x64-$releaseVersion.tar.gz" - -$releaseUrl = $releaseData.assets | Where-Object { $_.name -like $filter } | Select-Object 'browser_download_url' -$downloadUrl = $releaseUrl.browser_download_url - -Write-Output "Got Download Url $downloadUrl. Downloading now..." -$fileName = "actions-runner-latest.tar.gz" -Invoke-WebRequest -Uri $downloadUrl -OutFile $fileName | Out-String | Write-Verbose - -Write-Output "Got $fileName. Extracting now..." -tar xzf ./$fileName - -Write-Output "Extracted $fileName. Cleaning up now..." -Remove-Item $fileName -Force ; -Write-Output "All done..." diff --git a/container-images/github-runner-aci/README.md b/container-images/github-runner-aci/README.md deleted file mode 100644 index cf91d3d..0000000 --- a/container-images/github-runner-aci/README.md +++ /dev/null @@ -1,23 +0,0 @@ -# Linux GitHub Runner Docker Image for Azure Container Instances - -> Note: You can update the [Dockerfile](Dockerfile) to add any software that your require into the Azure DevOps agent, if you don't want to have to download the bits during all pipelines executions. - -## Environment Variables - -`GH_RUNNER_TOKEN`: The token used to authenticate the runner with GitHub. This can be a PAT or a self-hosted runner token. If supplying a self-hosted runner token, be aware that the token will expire after a few hours, so will only work with persistent runners. -`GH_RUNNER_URL`: The URL of the GitHub repository or organization (e.g. https://github.com/my-org or https://github.com/my-org/my-repo). -`GH_RUNNER_NAME`: The name of the runner as it appears in GitHub. -`GH_RUNNER_GROUP`: Optional. If not supplied, the runner will be added to the default group. This requires Enterprise licening. -`GH_RUNNER_MODE`: Supported values are `ephemeral` and `persistent`. Default is `ephemeral` if the env var is not supplied. - -## Build it - -```bash -docker build -t YOUR_IMAGE_NAME:YOUR_IMAGE_TAG . -``` - -## Push it - -```bash -docker push YOUR_IMAGE_NAME:YOUR_IMAGE_TAG -``` diff --git a/container-images/github-runner-aci/dockerfile b/container-images/github-runner-aci/dockerfile deleted file mode 100644 index a711634..0000000 --- a/container-images/github-runner-aci/dockerfile +++ /dev/null @@ -1,35 +0,0 @@ -FROM mcr.microsoft.com/azure-powershell:ubuntu-22.04 - -# To make it easier for build and release pipelines to run apt-get, -# configure apt to not require confirmation (assume the -y argument by default) -ENV DEBIAN_FRONTEND=noninteractive -RUN echo "APT::Get::Assume-Yes \"true\";" > /etc/apt/apt.conf.d/90assumeyes - -RUN apt-get update \ -&& apt-get install -y --no-install-recommends \ - ca-certificates \ - curl \ - jq \ - git \ - iputils-ping \ - libcurl4 \ - libunwind8 \ - netcat \ - ruby \ - unzip \ - dnsutils \ - nodejs - -RUN curl -sL https://aka.ms/InstallAzureCLIDeb | bash - -WORKDIR /actions-runner - -COPY InstallAgent.ps1 InstallAgent.ps1 - -RUN ["pwsh", "InstallAgent.ps1"] - -COPY ConfigureAndRun.ps1 ConfigureAndRun.ps1 - -ENTRYPOINT ["pwsh"] - -CMD ["ConfigureAndRun.ps1"] \ No newline at end of file diff --git a/variables.container.registry.tf b/variables.container.registry.tf index ba3c880..728e766 100644 --- a/variables.container.registry.tf +++ b/variables.container.registry.tf @@ -50,7 +50,7 @@ The images to build and push to the container registry. This is only relevant if - task_name: The name of the task to create for building the image (e.g. `image-build-task`) - dockerfile_path: The path to the Dockerfile to use for building the image (e.g. `dockerfile`) -- context_path: The path to the context of the Dockerfile in three sections `#:` (e.g. https://github.com/Azure/terraform-azurerm-avm-ptn-cicd-agents-and-runners#8ff4b85:container-images/azure-devops-agent) +- context_path: The path to the context of the Dockerfile in three sections `#:` (e.g. https://github.com/Azure/avm-container-images-cicd-agents-and-runners#bc4087f:azure-devops-agent) - context_access_token: The access token to use for accessing the context. Supply a PAT if targetting a private repository. - image_names: A list of the names of the images to build (e.g. `["image-name:tag"]`) @@ -60,23 +60,23 @@ DESCRIPTION variable "default_image_repository_url" { type = string description = "The default image repository URL to use if no custom image is provided." - default = "https://github.com/Azure/terraform-azurerm-avm-ptn-cicd-agents-and-runners" + default = "https://github.com/Azure/avm-container-images-cicd-agents-and-runners" } variable "default_image_repository_commit" { type = string description = "The default image repository commit to use if no custom image is provided." - default = "8051c83" + default = "bc4087f" } variable "default_image_repository_folder_paths" { type = map(string) description = "The default image repository folder path to use if no custom image is provided." default = { - azuredevops-container-app = "container-images/azure-devops-agent-aca" - github-container-app = "container-images/github-runner-aca" - azuredevops-container-instance = "container-images/azure-devops-agent-aci" - github-container-instance = "container-images/github-runner-aci" + azuredevops-container-app = "azure-devops-agent-aca" + github-container-app = "github-runner-aca" + azuredevops-container-instance = "azure-devops-agent-aci" + github-container-instance = "github-runner-aci" } }