From 210447771e8ff472b870fbeae9dc538b371d8624 Mon Sep 17 00:00:00 2001 From: Michael Ackerman <25309928+kittysnacks@users.noreply.github.com> Date: Mon, 24 Jun 2024 12:27:25 -0700 Subject: [PATCH 1/9] Added Docker files for pandoc and livepoll servers. OHM-1246: Dockerize pandoc and livepoll servers --- docker-compose.yml | 41 ++++++++++++++++++++++++++++++++++++++ docker/Dockerfile-livepoll | 10 ++++++++++ docker/Dockerfile-pandoc | 19 ++++++++++++++++++ 3 files changed, 70 insertions(+) create mode 100644 docker-compose.yml create mode 100644 docker/Dockerfile-livepoll create mode 100644 docker/Dockerfile-pandoc diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..32e2867 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,41 @@ +version: '3' + +services: + + pandoc: + build: + context: ./ + dockerfile: docker/Dockerfile-pandoc + expose: + - 80 + ports: + - "8081:80" + + hostname: pandoc + domainname: example.com + + restart: unless-stopped + privileged: true + stdin_open: false + tty: false + + livepoll: + build: + context: ./ + dockerfile: docker/Dockerfile-livepoll + expose: + - 80 + ports: + - "8082:3000" + + hostname: livepoll + domainname: example.com + + restart: unless-stopped + privileged: true + stdin_open: false + tty: false + + environment: + LIVEPOLL_USE_INSECURE_HTTP: true + diff --git a/docker/Dockerfile-livepoll b/docker/Dockerfile-livepoll new file mode 100644 index 0000000..3788f3c --- /dev/null +++ b/docker/Dockerfile-livepoll @@ -0,0 +1,10 @@ +FROM node:22 + +WORKDIR /app + +COPY livepoll/* /app/ + +RUN npm install + +CMD ["node", "/app/index.js"] + diff --git a/docker/Dockerfile-pandoc b/docker/Dockerfile-pandoc new file mode 100644 index 0000000..7bd0de5 --- /dev/null +++ b/docker/Dockerfile-pandoc @@ -0,0 +1,19 @@ +FROM php:8.2-apache + +RUN apt-get update \ + && apt-get install -y --no-install-recommends --no-install-suggests \ + pandoc \ + && apt-get clean + +COPY pandoc/* /var/www/html/ +COPY pandoc/cleanup-old-files /etc/cron.daily + +RUN chmod 755 /etc/cron.daily/cleanup-old-files + +RUN mkdir \ + /var/www/datatmp \ + /var/www/html/imgs \ + && chown www-data:www-data \ + /var/www/datatmp \ + /var/www/html/imgs + From 1d1d580e781a2b347597e396b51cfec25f6e60b2 Mon Sep 17 00:00:00 2001 From: Michael Ackerman <25309928+kittysnacks@users.noreply.github.com> Date: Mon, 24 Jun 2024 15:13:33 -0700 Subject: [PATCH 2/9] Run cron in its own container for pandoc's daily cleanup script. OHM-1246: Dockerize pandoc and livepoll servers --- docker-compose.yml | 27 +++++++++++++++++++++++++++ docker/Dockerfile-pandoc-cron | 13 +++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 docker/Dockerfile-pandoc-cron diff --git a/docker-compose.yml b/docker-compose.yml index 32e2867..2ae38b8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -11,6 +11,10 @@ services: ports: - "8081:80" + volumes: + - pandoc-temp-datatmp:/var/www/datatmp + - pandoc-temp-imgs:/var/www/html/imgs + hostname: pandoc domainname: example.com @@ -19,6 +23,25 @@ services: stdin_open: false tty: false + # The pandoc container does not run cron, so run cron + # in its own container with a shared volume. + pandoc-cron: + build: + context: ./ + dockerfile: docker/Dockerfile-pandoc-cron + + volumes: + - pandoc-temp-datatmp:/var/www/datatmp + - pandoc-temp-imgs:/var/www/html/imgs + + hostname: pandoc-cron + domainname: example.com + + restart: unless-stopped + privileged: true + stdin_open: false + tty: false + livepoll: build: context: ./ @@ -39,3 +62,7 @@ services: environment: LIVEPOLL_USE_INSECURE_HTTP: true +volumes: + pandoc-temp-datatmp: + pandoc-temp-imgs: + diff --git a/docker/Dockerfile-pandoc-cron b/docker/Dockerfile-pandoc-cron new file mode 100644 index 0000000..270b0ae --- /dev/null +++ b/docker/Dockerfile-pandoc-cron @@ -0,0 +1,13 @@ +FROM debian:12.5 + +RUN apt-get update \ + && apt-get install -y --no-install-suggests --no-install-recommends \ + cron \ + && apt-get clean + +COPY pandoc/cleanup-old-files /etc/cron.daily + +RUN chmod 755 /etc/cron.daily/cleanup-old-files + +CMD ["cron", "-f"] + From e8b5faebbe186bedddf137bfa7b2d2f784bd39ac Mon Sep 17 00:00:00 2001 From: Michael Ackerman <25309928+kittysnacks@users.noreply.github.com> Date: Mon, 24 Jun 2024 15:16:52 -0700 Subject: [PATCH 3/9] Removed cron files from pandoc Docker container. OHM-1246: Dockerize pandoc and livepoll servers --- docker/Dockerfile-pandoc | 3 --- 1 file changed, 3 deletions(-) diff --git a/docker/Dockerfile-pandoc b/docker/Dockerfile-pandoc index 7bd0de5..01d97a5 100644 --- a/docker/Dockerfile-pandoc +++ b/docker/Dockerfile-pandoc @@ -6,9 +6,6 @@ RUN apt-get update \ && apt-get clean COPY pandoc/* /var/www/html/ -COPY pandoc/cleanup-old-files /etc/cron.daily - -RUN chmod 755 /etc/cron.daily/cleanup-old-files RUN mkdir \ /var/www/datatmp \ From f25dc36cba6b17a3f4e2c5deb4c722b9a324a374 Mon Sep 17 00:00:00 2001 From: Michael Ackerman <25309928+kittysnacks@users.noreply.github.com> Date: Mon, 24 Jun 2024 15:20:23 -0700 Subject: [PATCH 4/9] Added livepoll password default to docker-compose.yml file. OHM-1246: Dockerize pandoc and livepoll servers --- docker-compose.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/docker-compose.yml b/docker-compose.yml index 2ae38b8..6e36b23 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -60,6 +60,7 @@ services: tty: false environment: + LIVEPOLL_PASSWORD: testing LIVEPOLL_USE_INSECURE_HTTP: true volumes: From d29e2e7f634cbbc2188487d3ab15478fabd865ed Mon Sep 17 00:00:00 2001 From: Jeff DeWan Date: Tue, 15 Oct 2024 14:15:28 -0700 Subject: [PATCH 5/9] OP-517: Need to add github action files to repository main branch --- .github/actions/private-ecr-login/action.yml | 39 ++++ .github/workflows/build-livepoll.yml | 230 +++++++++++++++++++ .github/workflows/manual-deploy.yml | 30 +++ .github/workflows/shared-deploy.yml | 143 ++++++++++++ .github/workflows/tag-deploy-livepoll.yml | 16 ++ .github/workflows/tag-deploy-pandoc.yml | 16 ++ .github/workflows/terraform-deploy.yml | 88 +++++++ .github/workflows/terraform.yml | 31 +++ 8 files changed, 593 insertions(+) create mode 100644 .github/actions/private-ecr-login/action.yml create mode 100644 .github/workflows/build-livepoll.yml create mode 100644 .github/workflows/manual-deploy.yml create mode 100644 .github/workflows/shared-deploy.yml create mode 100644 .github/workflows/tag-deploy-livepoll.yml create mode 100644 .github/workflows/tag-deploy-pandoc.yml create mode 100644 .github/workflows/terraform-deploy.yml create mode 100644 .github/workflows/terraform.yml diff --git a/.github/actions/private-ecr-login/action.yml b/.github/actions/private-ecr-login/action.yml new file mode 100644 index 0000000..774a645 --- /dev/null +++ b/.github/actions/private-ecr-login/action.yml @@ -0,0 +1,39 @@ +name: 'Log into Private ECR' +description: 'Github OIDC auth and assume role into account, then use AWS ECR Login action' +inputs: + aws_ci_account: + description: 'AWS Account ID for CI' + required: false + default: 824635284302 + aws_user_account: + description: 'AWS Account ID for users' + required: false + default: 265299512749 +outputs: + registry: + description: "ECR Registry" + value: ${{ steps.login-ecr.outputs.registry }} +runs: + using: "composite" + steps: + - name: assume oidc role + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-region: us-west-2 + role-to-assume: arn:aws:iam::${{ inputs.aws_user_account }}:role/ci-oidc-role + role-session-name: github-actions-oidc + role-duration-seconds: 900 + - name: assume target role + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-access-key-id: ${{ env.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ env.AWS_SECRET_ACCESS_KEY }} + aws-session-token: ${{ env.AWS_SESSION_TOKEN }} + aws-region: us-west-2 + role-to-assume: arn:aws:iam::${{ inputs.aws_ci_account }}:role/ci-role + role-session-name: github-actions-private-ecr + role-duration-seconds: 900 + + - name: Login to Private ECR + id: login-ecr + uses: aws-actions/amazon-ecr-login@v2 \ No newline at end of file diff --git a/.github/workflows/build-livepoll.yml b/.github/workflows/build-livepoll.yml new file mode 100644 index 0000000..8858f07 --- /dev/null +++ b/.github/workflows/build-livepoll.yml @@ -0,0 +1,230 @@ +name: build-and-push +env: + LIVEPOLL_ECR_REPOSITORY: livepoll + PANDOC_ECR_REPOSITORY: pandoc +on: + pull_request: + types: [ opened, synchronize, reopened ] + push: + branches: + - main + - rc/** + +jobs: + # this job gets a password for public ECR to use in future steps + ecr-public-auth: + runs-on: ubuntu-latest + name: Login to Public ECR + timeout-minutes: 5 + permissions: + id-token: write # Used for AWS OIDC auth + outputs: + ECR_PASSWORD: ${{ steps.ecr-auth.outputs.ECR_PASSWORD }} + steps: + # This is required to role chain from the OIDC role to other cross-account roles + # https://github.com/aws-actions/configure-aws-credentials/issues/279 + - name: OIDC Auth + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-region: us-west-2 + role-to-assume: arn:aws:iam::265299512749:role/ci-oidc-role + role-session-name: github-actions + role-duration-seconds: 900 + + - name: Assume role in CI Account + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-access-key-id: ${{ env.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ env.AWS_SECRET_ACCESS_KEY }} + aws-session-token: ${{ env.AWS_SESSION_TOKEN }} + aws-region: us-west-2 + role-to-assume: arn:aws:iam::824635284302:role/ci-role + role-session-name: github-actions + role-duration-seconds: 1200 + + - name: Set Public ECR Auth + id: ecr-auth + run: echo "ECR_PASSWORD=$(aws ecr-public --region us-east-1 get-login-password)" >> $GITHUB_OUTPUT + + validate-terraform: + runs-on: ubuntu-latest + name: Validate Terraform + timeout-minutes: 5 + permissions: + id-token: write # Used for AWS OIDC auth + contents: read + actions: read + steps: + - uses: actions/checkout@v4 + name: Checkout project + + - name: OIDC Auth to AWS + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-region: us-west-2 + role-to-assume: arn:aws:iam::${{ secrets.aws_user_account }}:role/ci-oidc-role + role-session-name: github-actions + role-duration-seconds: 900 + + - name: Setup Terraform + uses: hashicorp/setup-terraform@v3 + + - name: Terraform Init + id: init + run: terraform init -backend=false + working-directory: deploy/terraform + + - name: Terraform Format + id: fmt + run: terraform fmt -check + + - name: Terraform Validate + id: validate + run: terraform validate -no-color + working-directory: deploy/terraform + + build-and-push-livepoll: + runs-on: ubuntu-latest + name: Build and Push Livepoll Docker Image + timeout-minutes: 30 + needs: [ecr-public-auth, validate-terraform] + permissions: + id-token: write # Used for AWS OIDC auth + contents: read + actions: read + steps: + - uses: actions/checkout@v4 + name: Checkout project + + - id: read_tree_hash + name: Read git tree hash + run: | + tree_hash=$(git rev-parse HEAD:) + echo "tree_hash=$tree_hash" >> $GITHUB_OUTPUT + + - id: set_branch_name + name: Read git branch name + run: | + branch_name=${GITHUB_REF##*/} + echo "branch_name=$branch_name" >> $GITHUB_OUTPUT + + - uses: ./.github/actions/private-ecr-login + name: Login to Private ECR + id: login-ecr + + - name: Login to Public ECR + uses: docker/login-action@v3 + with: + registry: public.ecr.aws/j7v6u1e0 + username: AWS + password: ${{ needs.ecr-public-auth.outputs.ECR_PASSWORD }} + + - name: Check for prebuilt image + id: prebuilt_check + run: | + docker manifest inspect ${{ steps.login-ecr.outputs.registry }}/${{ env.LIVEPOLL_ECR_REPOSITORY }}:gha-tree-${{ steps.read_tree_hash.outputs.tree_hash }} || echo "image_exists=$?" >> $GITHUB_OUTPUT + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + if: steps.prebuilt_check.outputs.image_exists != 0 + + - name: Docker build and push + uses: docker/build-push-action@v5 + if: steps.prebuilt_check.outputs.image_exists != 0 + env: + ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} + with: + context: . + file: docker/Dockerfile-livepoll + platforms: linux/amd64 + push: true + tags: | + ${{ steps.login-ecr.outputs.registry }}/${{ env.LIVEPOLL_ECR_REPOSITORY }}:gha-commit-${{ github.sha }} + ${{ steps.login-ecr.outputs.registry }}/${{ env.LIVEPOLL_ECR_REPOSITORY }}:gha-tree-${{ steps.read_tree_hash.outputs.tree_hash }} + ${{ steps.login-ecr.outputs.registry }}/${{ env.LIVEPOLL_ECR_REPOSITORY }}:gha-build-${{ steps.set_branch_name.outputs.branch_name }}-${{ github.run_number }}-${{ github.run_attempt }} + ${{ steps.login-ecr.outputs.registry }}/${{ env.LIVEPOLL_ECR_REPOSITORY }}:gha-build-${{ steps.set_branch_name.outputs.branch_name }}-latest + cache-from: type=gha + cache-to: type=gha,mode=max + + build-and-push-pandoc: + runs-on: ubuntu-latest + name: Build and Push Pandoc Docker Image + timeout-minutes: 30 + needs: [ecr-public-auth, validate-terraform] + permissions: + id-token: write # Used for AWS OIDC auth + contents: read + actions: read + steps: + - uses: actions/checkout@v4 + name: Checkout project + + - id: read_tree_hash + name: Read git tree hash + run: | + tree_hash=$(git rev-parse HEAD:) + echo "tree_hash=$tree_hash" >> $GITHUB_OUTPUT + + - id: set_branch_name + name: Read git branch name + run: | + branch_name=${GITHUB_REF##*/} + echo "branch_name=$branch_name" >> $GITHUB_OUTPUT + + - uses: ./.github/actions/private-ecr-login + name: Login to Private ECR + id: login-ecr + + - name: Login to Public ECR + uses: docker/login-action@v3 + with: + registry: public.ecr.aws/j7v6u1e0 + username: AWS + password: ${{ needs.ecr-public-auth.outputs.ECR_PASSWORD }} + + - name: Check for prebuilt image + id: prebuilt_check + run: | + docker manifest inspect ${{ steps.login-ecr.outputs.registry }}/${{ env.PANDOC_ECR_REPOSITORY }}:gha-tree-${{ steps.read_tree_hash.outputs.tree_hash }} || echo "image_exists=$?" >> $GITHUB_OUTPUT + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + if: steps.prebuilt_check.outputs.image_exists != 0 + + - name: Docker build and push + uses: docker/build-push-action@v5 + if: steps.prebuilt_check.outputs.image_exists != 0 + env: + ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} + with: + context: . + file: docker/Dockerfile-pandoc + target: pandoc + platforms: linux/amd64 + push: true + tags: | + ${{ steps.login-ecr.outputs.registry }}/${{ env.PANDOC_ECR_REPOSITORY }}:gha-commit-${{ github.sha }} + ${{ steps.login-ecr.outputs.registry }}/${{ env.PANDOC_ECR_REPOSITORY }}:gha-tree-${{ steps.read_tree_hash.outputs.tree_hash }} + ${{ steps.login-ecr.outputs.registry }}/${{ env.PANDOC_ECR_REPOSITORY }}:gha-build-${{ steps.set_branch_name.outputs.branch_name }}-${{ github.run_number }}-${{ github.run_attempt }} + ${{ steps.login-ecr.outputs.registry }}/${{ env.PANDOC_ECR_REPOSITORY }}:gha-build-${{ steps.set_branch_name.outputs.branch_name }}-latest + cache-from: type=gha + cache-to: type=gha,mode=max + + - name: Docker build and push + uses: docker/build-push-action@v5 + if: steps.prebuilt_check.outputs.image_exists != 0 + env: + ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} + with: + context: . + file: docker/Dockerfile-pandoc + target: cron + platforms: linux/amd64 + push: true + tags: | + ${{ steps.login-ecr.outputs.registry }}/${{ env.PANDOC_ECR_REPOSITORY }}:gha-commit-${{ github.sha }}-cron + ${{ steps.login-ecr.outputs.registry }}/${{ env.PANDOC_ECR_REPOSITORY }}:gha-tree-${{ steps.read_tree_hash.outputs.tree_hash }}-cron + ${{ steps.login-ecr.outputs.registry }}/${{ env.PANDOC_ECR_REPOSITORY }}:gha-build-${{ steps.set_branch_name.outputs.branch_name }}-${{ github.run_number }}-${{ github.run_attempt }}-cron + ${{ steps.login-ecr.outputs.registry }}/${{ env.PANDOC_ECR_REPOSITORY }}:gha-build-${{ steps.set_branch_name.outputs.branch_name }}-latest-cron + cache-from: type=gha + cache-to: type=gha,mode=max \ No newline at end of file diff --git a/.github/workflows/manual-deploy.yml b/.github/workflows/manual-deploy.yml new file mode 100644 index 0000000..d0d5985 --- /dev/null +++ b/.github/workflows/manual-deploy.yml @@ -0,0 +1,30 @@ +name: manual-deploy +on: + workflow_dispatch: + inputs: + environment: + description: 'Environment' + required: true + default: 'dev' + type: choice + options: + - dev + - staging + project: + description: 'Project' + required: true + default: 'livepoll' + type: choice + options: + - livepoll + - pandoc +jobs: + ecs-deploy: + name: ECS Deployment + uses: ./.github/workflows/shared-deploy.yml + with: + environment: ${{ github.event.inputs.environment }} + project: ${{ github.event.inputs.project }} + secrets: + aws_user_account: ${{ secrets.AWS_USER_ACCOUNT }} + aws_ci_account: ${{ secrets.AWS_CI_ACCOUNT }} \ No newline at end of file diff --git a/.github/workflows/shared-deploy.yml b/.github/workflows/shared-deploy.yml new file mode 100644 index 0000000..ae877c6 --- /dev/null +++ b/.github/workflows/shared-deploy.yml @@ -0,0 +1,143 @@ +name: shared-deployment-workflow +permissions: + id-token: write # Used for AWS OIDC auth + contents: read # This is required for actions/checkout +on: + workflow_call: + inputs: + environment: + description: 'Environment name passed from the caller workflow' + required: true + type: string + project: + description: 'Project name passed from the caller workflow' + required: true + type: string + secrets: + aws_user_account: + description: 'AWS Account ID for IAM users' + required: true + aws_ci_account: + description: 'AWS Account ID for IAM users' + required: true + +jobs: + # this job gets a password for public ECR to use in future steps + ecr-public-auth: + runs-on: ubuntu-latest + name: Login to Public ECR + timeout-minutes: 5 + permissions: + id-token: write # Used for AWS OIDC auth + outputs: + ECR_PASSWORD: ${{ steps.ecr-auth.outputs.ECR_PASSWORD }} + steps: + # This is required to role chain from the OIDC role to other cross-account roles + # https://github.com/aws-actions/configure-aws-credentials/issues/279 + - name: OIDC Auth + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-region: us-west-2 + role-to-assume: arn:aws:iam::${{ secrets.aws_user_account }}:role/ci-oidc-role + role-session-name: github-actions + role-duration-seconds: 900 + + - name: Assume role in CI Account + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-access-key-id: ${{ env.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ env.AWS_SECRET_ACCESS_KEY }} + aws-session-token: ${{ env.AWS_SESSION_TOKEN }} + aws-region: us-west-2 + role-to-assume: arn:aws:iam::${{ secrets.aws_ci_account }}:role/ci-role + role-session-name: github-actions + role-duration-seconds: 1200 + + - name: Set Public ECR Auth + id: ecr-auth + run: echo "ECR_PASSWORD=$(aws ecr-public --region us-east-1 get-login-password)" >> $GITHUB_OUTPUT + + terraform-deploy: + name: Terraform Deployment + uses: ./.github/workflows/terraform-deploy.yml + with: + environment: ${{ inputs.environment }} + project: ${{ inputs.project }} + secrets: + aws_user_account: ${{ secrets.AWS_USER_ACCOUNT }} + aws_ci_account: ${{ secrets.AWS_CI_ACCOUNT }} + + ecs-deploy: + name: ECS Deployment + timeout-minutes: 30 + runs-on: ubuntu-latest + needs: [ecr-public-auth,terraform-deploy] + steps: + - uses: actions/checkout@v4 + name: Checkout project + + - uses: ./.github/actions/private-ecr-login + name: Login to Private ECR + id: login-ecr + + - name: Login to Public ECR + uses: docker/login-action@v3 + with: + registry: public.ecr.aws/o9c0t3w1 + username: AWS + password: ${{ needs.ecr-public-auth.outputs.ECR_PASSWORD }} + + + - id: read_env_json + name: Read Environment JSON + run: | + env_json=$(jq -c '.environments[] | select(.environment_label=="${{ inputs.environment }}")' ./deploy/${{ inputs.project }}-environments.json) + echo "env_json=$env_json" >> $GITHUB_OUTPUT + - id: set_env_metadata + name: Set Environment Metadata + run: | + echo "account=${{ fromJSON(steps.read_env_json.outputs.env_json).account }}" >> $GITHUB_OUTPUT + echo "ssm_prefix=${{ fromJSON(steps.read_env_json.outputs.env_json).ssm_prefix }}" >> $GITHUB_OUTPUT + echo "webapp_ssm_prefix=${{ fromJSON(steps.read_env_json.outputs.env_json).webapp.ssm_prefix }}" >> $GITHUB_OUTPUT + echo "shoryuken_ssm_prefix=${{ fromJSON(steps.read_env_json.outputs.env_json).shoryuken.ssm_prefix }}" >> $GITHUB_OUTPUT + echo "cluster_name=${{ fromJSON(steps.read_env_json.outputs.env_json).fargate.cluster_name }}" >> $GITHUB_OUTPUT + + - name: OIDC Auth to AWS + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-region: us-west-2 + role-to-assume: arn:aws:iam::${{ secrets.aws_user_account }}:role/ci-oidc-role + role-session-name: github-actions + role-duration-seconds: 900 + + - name: Assume role in target account + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-access-key-id: ${{ env.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ env.AWS_SECRET_ACCESS_KEY }} + aws-session-token: ${{ env.AWS_SESSION_TOKEN }} + aws-region: us-west-2 + role-to-assume: arn:aws:iam::${{ steps.set_env_metadata.outputs.account }}:role/ci-role + role-session-name: github-actions + role-duration-seconds: 1200 + + - id: read_tree_hash + name: Read git tree hash + run: | + tree_hash=$(git rev-parse HEAD:) + echo "tree_hash=$tree_hash" >> $GITHUB_OUTPUT + + - name: Verify image + run: | + if ! docker manifest inspect ${{ steps.login-ecr.outputs.registry }}/${{ inputs.project }}:gha-tree-${{ steps.read_tree_hash.outputs.tree_hash }}; then + echo "If this is a PR build, you may need to pull in changes from the target branch into your PR branch." + exit 1 + fi + + - name: Run deploy script + run: | + deploy/ecs_deploy.sh \ + --cluster-name ${{ steps.set_env_metadata.outputs.cluster_name }} \ + --ssm-prefix ${{ steps.set_env_metadata.outputs.ssm_prefix }} \ + --account-number ${{ secrets.aws_ci_account }} \ + --project-name ${{ inputs.project }} \ No newline at end of file diff --git a/.github/workflows/tag-deploy-livepoll.yml b/.github/workflows/tag-deploy-livepoll.yml new file mode 100644 index 0000000..12f8351 --- /dev/null +++ b/.github/workflows/tag-deploy-livepoll.yml @@ -0,0 +1,16 @@ +name: tag-deploy +on: + push: + tags: + - release/livepoll/* + +jobs: + ecs-deploy: + name: ECS Deployment + uses: ./.github/workflows/shared-deploy.yml + with: + environment: prod + project: livepoll + secrets: + aws_user_account: ${{ secrets.AWS_USER_ACCOUNT }} + aws_ci_account: ${{ secrets.AWS_CI_ACCOUNT }} \ No newline at end of file diff --git a/.github/workflows/tag-deploy-pandoc.yml b/.github/workflows/tag-deploy-pandoc.yml new file mode 100644 index 0000000..cd0ba9d --- /dev/null +++ b/.github/workflows/tag-deploy-pandoc.yml @@ -0,0 +1,16 @@ +name: tag-deploy +on: + push: + tags: + - release/pandoc/* + +jobs: + ecs-deploy: + name: ECS Deployment + uses: ./.github/workflows/shared-deploy.yml + with: + environment: prod + project: pandoc + secrets: + aws_user_account: ${{ secrets.AWS_USER_ACCOUNT }} + aws_ci_account: ${{ secrets.AWS_CI_ACCOUNT }} \ No newline at end of file diff --git a/.github/workflows/terraform-deploy.yml b/.github/workflows/terraform-deploy.yml new file mode 100644 index 0000000..ad2c09b --- /dev/null +++ b/.github/workflows/terraform-deploy.yml @@ -0,0 +1,88 @@ +name: terraform-deployment-workflow +permissions: + id-token: write # Used for AWS OIDC auth + contents: read # This is required for actions/checkout +on: + workflow_call: + inputs: + environment: + description: 'Environment name passed from the caller workflow' + required: true + type: string + project: + description: 'Project name passed from the caller workflow' + required: true + type: string + secrets: + aws_user_account: + description: 'AWS Account ID for IAM users' + required: true + aws_ci_account: + description: 'AWS Account ID for IAM users' + required: true + +jobs: + # this job gets a password for public ECR to use in future steps + terraform-deploy: + name: Terraform Deployment + timeout-minutes: 30 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + name: Checkout project + + - id: read_env_json + name: Read Environment JSON + run: | + env_json=$(jq -c '.environments[] | select(.environment_label=="${{ inputs.environment }}")' ./deploy/${{ inputs.project }}-environments.json) + echo "env_json=$env_json" >> $GITHUB_OUTPUT + + - id: set_env_metadata + name: Set Environment Metadata + run: | + echo "account=${{ fromJSON(steps.read_env_json.outputs.env_json).account }}" >> $GITHUB_OUTPUT + echo "region=${{ fromJSON(steps.read_env_json.outputs.env_json).region }}" >> $GITHUB_OUTPUT + echo "terraform_state_key=${{ fromJSON(steps.read_env_json.outputs.env_json).terraform_state_key }}" >> $GITHUB_OUTPUT + echo "ssm_prefix=${{ fromJSON(steps.read_env_json.outputs.env_json).ssm_prefix }}" >> $GITHUB_OUTPUT + echo "cluster_name=${{ fromJSON(steps.read_env_json.outputs.env_json).fargate.cluster_name }}" >> $GITHUB_OUTPUT + + + - name: OIDC Auth to AWS + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-region: us-west-2 + role-to-assume: arn:aws:iam::${{ secrets.aws_user_account }}:role/ci-oidc-role + role-session-name: github-actions + role-duration-seconds: 900 + + # Based on https://developer.hashicorp.com/terraform/tutorials/automation/github-actions + - name: Setup Terraform + uses: hashicorp/setup-terraform@v3 + + - name: Terraform Init + id: init + run: terraform init -backend-config=key=${{ steps.set_env_metadata.outputs.terraform_state_key }} + working-directory: deploy/${{ inputs.project }}/terraform + + - name: Terraform Format + id: fmt + run: terraform fmt -check + + - name: Terraform Validate + id: validate + run: terraform validate -no-color + working-directory: deploy/${{ inputs.project }}/terraform + + - name: Terraform Plan + id: plan + run: | + terraform plan -no-color -input=false -out terraform.tfplan \ + -var environment=${{ inputs.environment }} \ + -var account=${{ steps.set_env_metadata.outputs.account }} \ + -var region=${{ steps.set_env_metadata.outputs.region }} + working-directory: deploy/${{ inputs.project }}/terraform + + - name: Terraform Apply + id: apply + run: terraform apply -auto-approve -input=false terraform.tfplan + working-directory: deploy/${{ inputs.project }}/terraform \ No newline at end of file diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml new file mode 100644 index 0000000..8780537 --- /dev/null +++ b/.github/workflows/terraform.yml @@ -0,0 +1,31 @@ +name: terraform-deploy +on: + workflow_dispatch: + inputs: + environment: + description: 'Environment' + required: true + default: 'dev' + type: choice + options: + - dev + - staging + - prod + project: + description: 'Project' + required: true + default: 'livepoll' + type: choice + options: + - livepoll + - pandoc +jobs: + terraform-deploy: + name: Terraform Deployment + uses: ./.github/workflows/terraform-deploy.yml + with: + environment: ${{ github.event.inputs.environment }} + project: ${{ github.event.inputs.project }} + secrets: + aws_user_account: ${{ secrets.AWS_USER_ACCOUNT }} + aws_ci_account: ${{ secrets.AWS_CI_ACCOUNT }} From 781ca1d7e7c9fcf0a2235317286b807ece3c3596 Mon Sep 17 00:00:00 2001 From: Jeff DeWan <94399475+jeff-dewan-lumen@users.noreply.github.com> Date: Tue, 5 Nov 2024 10:33:34 -0800 Subject: [PATCH 6/9] OP-517: Add deploy pipelines for livepoll and pandoc (#1) * OP-517: Add deploy pipelines for livepoll and pandoc * OP-517: Need to add github action files to repository main branch * Rename * Remove ECR public * Remove ECR public * Remove ECR public * Fix project path * fmt * fix terraform * fix terraform * Remove public ecr * Add docker entrypoint * Install awscli and jq * Split entrypoint and fix pandoc * Fix entrypoint * Add health.html, update docker-compose * Add health.html, update docker-compose * Deploy cron and remove terraform and entrypoint for pandoc * Remove pandoc terraform * Remove pandoc terraform * Run empty terraform * Remove cron deploy, chown files * Cleanup * Remove pandoc cron container and rely on EFS lifecycle rules to archive old files * Fix build * Bump PHP to latest and use production PHP defaults for pandoc --- .github/actions/private-ecr-login/action.yml | 39 +++++ .github/workflows/build-and-push.yml | 172 +++++++++++++++++++ .github/workflows/manual-deploy.yml | 30 ++++ .github/workflows/shared-deploy.yml | 100 +++++++++++ .github/workflows/tag-deploy-livepoll.yml | 16 ++ .github/workflows/tag-deploy-pandoc.yml | 16 ++ .github/workflows/terraform-deploy.yml | 89 ++++++++++ .github/workflows/terraform.yml | 31 ++++ deploy/ecs_deploy.sh | 60 +++++++ deploy/livepoll-environments.json | 43 +++++ deploy/pandoc-environments.json | 43 +++++ deploy/terraform/livepoll/_locals.tf | 5 + deploy/terraform/livepoll/_provider.tf | 34 ++++ deploy/terraform/livepoll/parameter_store.tf | 19 ++ deploy/terraform/livepoll/variables.tf | 11 ++ deploy/terraform/pandoc/_locals.tf | 5 + deploy/terraform/pandoc/_provider.tf | 34 ++++ deploy/terraform/pandoc/variables.tf | 11 ++ docker-compose.yml | 21 --- docker/Dockerfile-livepoll | 11 +- docker/Dockerfile-pandoc | 8 +- docker/Dockerfile-pandoc-cron | 13 -- docker/livepoll-entrypoint.sh | 54 ++++++ pandoc/cleanup-old-files | 5 - 24 files changed, 828 insertions(+), 42 deletions(-) create mode 100644 .github/actions/private-ecr-login/action.yml create mode 100644 .github/workflows/build-and-push.yml create mode 100644 .github/workflows/manual-deploy.yml create mode 100644 .github/workflows/shared-deploy.yml create mode 100644 .github/workflows/tag-deploy-livepoll.yml create mode 100644 .github/workflows/tag-deploy-pandoc.yml create mode 100644 .github/workflows/terraform-deploy.yml create mode 100644 .github/workflows/terraform.yml create mode 100755 deploy/ecs_deploy.sh create mode 100644 deploy/livepoll-environments.json create mode 100644 deploy/pandoc-environments.json create mode 100644 deploy/terraform/livepoll/_locals.tf create mode 100644 deploy/terraform/livepoll/_provider.tf create mode 100644 deploy/terraform/livepoll/parameter_store.tf create mode 100644 deploy/terraform/livepoll/variables.tf create mode 100644 deploy/terraform/pandoc/_locals.tf create mode 100644 deploy/terraform/pandoc/_provider.tf create mode 100644 deploy/terraform/pandoc/variables.tf delete mode 100644 docker/Dockerfile-pandoc-cron create mode 100755 docker/livepoll-entrypoint.sh delete mode 100644 pandoc/cleanup-old-files diff --git a/.github/actions/private-ecr-login/action.yml b/.github/actions/private-ecr-login/action.yml new file mode 100644 index 0000000..774a645 --- /dev/null +++ b/.github/actions/private-ecr-login/action.yml @@ -0,0 +1,39 @@ +name: 'Log into Private ECR' +description: 'Github OIDC auth and assume role into account, then use AWS ECR Login action' +inputs: + aws_ci_account: + description: 'AWS Account ID for CI' + required: false + default: 824635284302 + aws_user_account: + description: 'AWS Account ID for users' + required: false + default: 265299512749 +outputs: + registry: + description: "ECR Registry" + value: ${{ steps.login-ecr.outputs.registry }} +runs: + using: "composite" + steps: + - name: assume oidc role + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-region: us-west-2 + role-to-assume: arn:aws:iam::${{ inputs.aws_user_account }}:role/ci-oidc-role + role-session-name: github-actions-oidc + role-duration-seconds: 900 + - name: assume target role + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-access-key-id: ${{ env.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ env.AWS_SECRET_ACCESS_KEY }} + aws-session-token: ${{ env.AWS_SESSION_TOKEN }} + aws-region: us-west-2 + role-to-assume: arn:aws:iam::${{ inputs.aws_ci_account }}:role/ci-role + role-session-name: github-actions-private-ecr + role-duration-seconds: 900 + + - name: Login to Private ECR + id: login-ecr + uses: aws-actions/amazon-ecr-login@v2 \ No newline at end of file diff --git a/.github/workflows/build-and-push.yml b/.github/workflows/build-and-push.yml new file mode 100644 index 0000000..180eaac --- /dev/null +++ b/.github/workflows/build-and-push.yml @@ -0,0 +1,172 @@ +name: build-and-push +env: + LIVEPOLL_ECR_REPOSITORY: livepoll + PANDOC_ECR_REPOSITORY: pandoc +on: + pull_request: + types: [ opened, synchronize, reopened ] + push: + branches: + - main + - rc/** + +jobs: + validate-terraform: + runs-on: ubuntu-latest + name: Validate Terraform + timeout-minutes: 5 + permissions: + id-token: write # Used for AWS OIDC auth + contents: read + actions: read + steps: + - uses: actions/checkout@v4 + name: Checkout project + + - name: OIDC Auth to AWS + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-region: us-west-2 + role-to-assume: arn:aws:iam::${{ secrets.aws_user_account }}:role/ci-oidc-role + role-session-name: github-actions + role-duration-seconds: 900 + + - name: Setup Terraform + uses: hashicorp/setup-terraform@v3 + + - name: Livepoll Terraform Init + run: terraform init -backend=false + working-directory: deploy/terraform/livepoll + + - name: Livepoll Terraform Format + run: terraform fmt -check + working-directory: deploy/terraform/livepoll + + - name: Livepoll Terraform Validate + id: validate + run: terraform validate -no-color + working-directory: deploy/terraform/livepoll + + - name: Pandoc Terraform Init + run: terraform init -backend=false + working-directory: deploy/terraform/pandoc + + - name: Pandoc Terraform Format + run: terraform fmt -check + working-directory: deploy/terraform/pandoc + + - name: Pandoc Terraform Validate + run: terraform validate -no-color + working-directory: deploy/terraform/pandoc + + build-and-push-livepoll: + runs-on: ubuntu-latest + name: Build and Push Livepoll Docker Image + timeout-minutes: 30 + needs: [validate-terraform] + permissions: + id-token: write # Used for AWS OIDC auth + contents: read + actions: read + steps: + - uses: actions/checkout@v4 + name: Checkout project + + - id: read_tree_hash + name: Read git tree hash + run: | + tree_hash=$(git rev-parse HEAD:) + echo "tree_hash=$tree_hash" >> $GITHUB_OUTPUT + + - id: set_branch_name + name: Read git branch name + run: | + branch_name=${GITHUB_REF##*/} + echo "branch_name=$branch_name" >> $GITHUB_OUTPUT + + - uses: ./.github/actions/private-ecr-login + name: Login to Private ECR + id: login-ecr + + - name: Check for prebuilt image + id: prebuilt_check + run: | + docker manifest inspect ${{ steps.login-ecr.outputs.registry }}/${{ env.LIVEPOLL_ECR_REPOSITORY }}:gha-tree-${{ steps.read_tree_hash.outputs.tree_hash }} || echo "image_exists=$?" >> $GITHUB_OUTPUT + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + if: steps.prebuilt_check.outputs.image_exists != 0 + + - name: Docker build and push + uses: docker/build-push-action@v5 + if: steps.prebuilt_check.outputs.image_exists != 0 + env: + ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} + with: + context: . + file: docker/Dockerfile-livepoll + platforms: linux/amd64 + push: true + tags: | + ${{ steps.login-ecr.outputs.registry }}/${{ env.LIVEPOLL_ECR_REPOSITORY }}:gha-commit-${{ github.sha }} + ${{ steps.login-ecr.outputs.registry }}/${{ env.LIVEPOLL_ECR_REPOSITORY }}:gha-tree-${{ steps.read_tree_hash.outputs.tree_hash }} + ${{ steps.login-ecr.outputs.registry }}/${{ env.LIVEPOLL_ECR_REPOSITORY }}:gha-build-${{ steps.set_branch_name.outputs.branch_name }}-${{ github.run_number }}-${{ github.run_attempt }} + ${{ steps.login-ecr.outputs.registry }}/${{ env.LIVEPOLL_ECR_REPOSITORY }}:gha-build-${{ steps.set_branch_name.outputs.branch_name }}-latest + cache-from: type=gha + cache-to: type=gha,mode=max + + build-and-push-pandoc: + runs-on: ubuntu-latest + name: Build and Push Pandoc Docker Image + timeout-minutes: 30 + needs: [validate-terraform] + permissions: + id-token: write # Used for AWS OIDC auth + contents: read + actions: read + steps: + - uses: actions/checkout@v4 + name: Checkout project + + - id: read_tree_hash + name: Read git tree hash + run: | + tree_hash=$(git rev-parse HEAD:) + echo "tree_hash=$tree_hash" >> $GITHUB_OUTPUT + + - id: set_branch_name + name: Read git branch name + run: | + branch_name=${GITHUB_REF##*/} + echo "branch_name=$branch_name" >> $GITHUB_OUTPUT + + - uses: ./.github/actions/private-ecr-login + name: Login to Private ECR + id: login-ecr + + - name: Check for prebuilt image + id: prebuilt_check + run: | + docker manifest inspect ${{ steps.login-ecr.outputs.registry }}/${{ env.PANDOC_ECR_REPOSITORY }}:gha-tree-${{ steps.read_tree_hash.outputs.tree_hash }} || echo "image_exists=$?" >> $GITHUB_OUTPUT + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + if: steps.prebuilt_check.outputs.image_exists != 0 + + - name: Docker build and push + uses: docker/build-push-action@v5 + if: steps.prebuilt_check.outputs.image_exists != 0 + env: + ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} + with: + context: . + file: docker/Dockerfile-pandoc + platforms: linux/amd64 + push: true + tags: | + ${{ steps.login-ecr.outputs.registry }}/${{ env.PANDOC_ECR_REPOSITORY }}:gha-commit-${{ github.sha }} + ${{ steps.login-ecr.outputs.registry }}/${{ env.PANDOC_ECR_REPOSITORY }}:gha-tree-${{ steps.read_tree_hash.outputs.tree_hash }} + ${{ steps.login-ecr.outputs.registry }}/${{ env.PANDOC_ECR_REPOSITORY }}:gha-build-${{ steps.set_branch_name.outputs.branch_name }}-${{ github.run_number }}-${{ github.run_attempt }} + ${{ steps.login-ecr.outputs.registry }}/${{ env.PANDOC_ECR_REPOSITORY }}:gha-build-${{ steps.set_branch_name.outputs.branch_name }}-latest + cache-from: type=gha + cache-to: type=gha,mode=max diff --git a/.github/workflows/manual-deploy.yml b/.github/workflows/manual-deploy.yml new file mode 100644 index 0000000..d0d5985 --- /dev/null +++ b/.github/workflows/manual-deploy.yml @@ -0,0 +1,30 @@ +name: manual-deploy +on: + workflow_dispatch: + inputs: + environment: + description: 'Environment' + required: true + default: 'dev' + type: choice + options: + - dev + - staging + project: + description: 'Project' + required: true + default: 'livepoll' + type: choice + options: + - livepoll + - pandoc +jobs: + ecs-deploy: + name: ECS Deployment + uses: ./.github/workflows/shared-deploy.yml + with: + environment: ${{ github.event.inputs.environment }} + project: ${{ github.event.inputs.project }} + secrets: + aws_user_account: ${{ secrets.AWS_USER_ACCOUNT }} + aws_ci_account: ${{ secrets.AWS_CI_ACCOUNT }} \ No newline at end of file diff --git a/.github/workflows/shared-deploy.yml b/.github/workflows/shared-deploy.yml new file mode 100644 index 0000000..770bf3b --- /dev/null +++ b/.github/workflows/shared-deploy.yml @@ -0,0 +1,100 @@ +name: shared-deployment-workflow +permissions: + id-token: write # Used for AWS OIDC auth + contents: read # This is required for actions/checkout +on: + workflow_call: + inputs: + environment: + description: 'Environment name passed from the caller workflow' + required: true + type: string + project: + description: 'Project name passed from the caller workflow' + required: true + type: string + secrets: + aws_user_account: + description: 'AWS Account ID for IAM users' + required: true + aws_ci_account: + description: 'AWS Account ID for IAM users' + required: true + +jobs: + terraform-deploy: + name: Terraform Deployment + uses: ./.github/workflows/terraform-deploy.yml + with: + environment: ${{ inputs.environment }} + project: ${{ inputs.project }} + secrets: + aws_user_account: ${{ secrets.AWS_USER_ACCOUNT }} + aws_ci_account: ${{ secrets.AWS_CI_ACCOUNT }} + + ecs-deploy: + name: ECS Deployment + timeout-minutes: 30 + runs-on: ubuntu-latest + needs: [terraform-deploy] + steps: + - uses: actions/checkout@v4 + name: Checkout project + + - uses: ./.github/actions/private-ecr-login + name: Login to Private ECR + id: login-ecr + + - id: read_env_json + name: Read Environment JSON + run: | + env_json=$(jq -c '.environments[] | select(.environment_label=="${{ inputs.environment }}")' ./deploy/${{ inputs.project }}-environments.json) + echo "env_json=$env_json" >> $GITHUB_OUTPUT + - id: set_env_metadata + name: Set Environment Metadata + run: | + echo "account=${{ fromJSON(steps.read_env_json.outputs.env_json).account }}" >> $GITHUB_OUTPUT + echo "ssm_prefix=${{ fromJSON(steps.read_env_json.outputs.env_json).ssm_prefix }}" >> $GITHUB_OUTPUT + echo "webapp_ssm_prefix=${{ fromJSON(steps.read_env_json.outputs.env_json).webapp.ssm_prefix }}" >> $GITHUB_OUTPUT + echo "shoryuken_ssm_prefix=${{ fromJSON(steps.read_env_json.outputs.env_json).shoryuken.ssm_prefix }}" >> $GITHUB_OUTPUT + echo "cluster_name=${{ fromJSON(steps.read_env_json.outputs.env_json).fargate.cluster_name }}" >> $GITHUB_OUTPUT + + - name: OIDC Auth to AWS + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-region: us-west-2 + role-to-assume: arn:aws:iam::${{ secrets.aws_user_account }}:role/ci-oidc-role + role-session-name: github-actions + role-duration-seconds: 900 + + - name: Assume role in target account + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-access-key-id: ${{ env.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ env.AWS_SECRET_ACCESS_KEY }} + aws-session-token: ${{ env.AWS_SESSION_TOKEN }} + aws-region: us-west-2 + role-to-assume: arn:aws:iam::${{ steps.set_env_metadata.outputs.account }}:role/ci-role + role-session-name: github-actions + role-duration-seconds: 1200 + + - id: read_tree_hash + name: Read git tree hash + run: | + tree_hash=$(git rev-parse HEAD:) + echo "tree_hash=$tree_hash" >> $GITHUB_OUTPUT + + - name: Verify image + run: | + if ! docker manifest inspect ${{ steps.login-ecr.outputs.registry }}/${{ inputs.project }}:gha-tree-${{ steps.read_tree_hash.outputs.tree_hash }}; then + echo "If this is a PR build, you may need to pull in changes from the target branch into your PR branch." + exit 1 + fi + + - name: Run deploy script + run: | + deploy/ecs_deploy.sh \ + --cluster-name ${{ steps.set_env_metadata.outputs.cluster_name }} \ + --ssm-prefix ${{ steps.set_env_metadata.outputs.ssm_prefix }} \ + --account-number ${{ secrets.aws_ci_account }} \ + --project-name ${{ inputs.project }} \ No newline at end of file diff --git a/.github/workflows/tag-deploy-livepoll.yml b/.github/workflows/tag-deploy-livepoll.yml new file mode 100644 index 0000000..12f8351 --- /dev/null +++ b/.github/workflows/tag-deploy-livepoll.yml @@ -0,0 +1,16 @@ +name: tag-deploy +on: + push: + tags: + - release/livepoll/* + +jobs: + ecs-deploy: + name: ECS Deployment + uses: ./.github/workflows/shared-deploy.yml + with: + environment: prod + project: livepoll + secrets: + aws_user_account: ${{ secrets.AWS_USER_ACCOUNT }} + aws_ci_account: ${{ secrets.AWS_CI_ACCOUNT }} \ No newline at end of file diff --git a/.github/workflows/tag-deploy-pandoc.yml b/.github/workflows/tag-deploy-pandoc.yml new file mode 100644 index 0000000..cd0ba9d --- /dev/null +++ b/.github/workflows/tag-deploy-pandoc.yml @@ -0,0 +1,16 @@ +name: tag-deploy +on: + push: + tags: + - release/pandoc/* + +jobs: + ecs-deploy: + name: ECS Deployment + uses: ./.github/workflows/shared-deploy.yml + with: + environment: prod + project: pandoc + secrets: + aws_user_account: ${{ secrets.AWS_USER_ACCOUNT }} + aws_ci_account: ${{ secrets.AWS_CI_ACCOUNT }} \ No newline at end of file diff --git a/.github/workflows/terraform-deploy.yml b/.github/workflows/terraform-deploy.yml new file mode 100644 index 0000000..44e6118 --- /dev/null +++ b/.github/workflows/terraform-deploy.yml @@ -0,0 +1,89 @@ +name: terraform-deployment-workflow +permissions: + id-token: write # Used for AWS OIDC auth + contents: read # This is required for actions/checkout +on: + workflow_call: + inputs: + environment: + description: 'Environment name passed from the caller workflow' + required: true + type: string + project: + description: 'Project name passed from the caller workflow' + required: true + type: string + secrets: + aws_user_account: + description: 'AWS Account ID for IAM users' + required: true + aws_ci_account: + description: 'AWS Account ID for IAM users' + required: true + +jobs: + # this job gets a password for public ECR to use in future steps + terraform-deploy: + name: Terraform Deployment + timeout-minutes: 30 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + name: Checkout project + + - id: read_env_json + name: Read Environment JSON + run: | + env_json=$(jq -c '.environments[] | select(.environment_label=="${{ inputs.environment }}")' ./deploy/${{ inputs.project }}-environments.json) + echo "env_json=$env_json" >> $GITHUB_OUTPUT + + - id: set_env_metadata + name: Set Environment Metadata + run: | + echo "account=${{ fromJSON(steps.read_env_json.outputs.env_json).account }}" >> $GITHUB_OUTPUT + echo "region=${{ fromJSON(steps.read_env_json.outputs.env_json).region }}" >> $GITHUB_OUTPUT + echo "terraform_state_key=${{ fromJSON(steps.read_env_json.outputs.env_json).terraform_state_key }}" >> $GITHUB_OUTPUT + echo "ssm_prefix=${{ fromJSON(steps.read_env_json.outputs.env_json).ssm_prefix }}" >> $GITHUB_OUTPUT + echo "cluster_name=${{ fromJSON(steps.read_env_json.outputs.env_json).fargate.cluster_name }}" >> $GITHUB_OUTPUT + + + - name: OIDC Auth to AWS + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-region: us-west-2 + role-to-assume: arn:aws:iam::${{ secrets.aws_user_account }}:role/ci-oidc-role + role-session-name: github-actions + role-duration-seconds: 900 + + # Based on https://developer.hashicorp.com/terraform/tutorials/automation/github-actions + - name: Setup Terraform + uses: hashicorp/setup-terraform@v3 + + - name: Terraform Init + id: init + run: terraform init -backend-config=key=${{ steps.set_env_metadata.outputs.terraform_state_key }} + working-directory: deploy/terraform/${{ inputs.project }} + + - name: Terraform Format + id: fmt + run: terraform fmt -check + working-directory: deploy/terraform/${{ inputs.project }} + + - name: Terraform Validate + id: validate + run: terraform validate -no-color + working-directory: deploy/terraform/${{ inputs.project }} + + - name: Terraform Plan + id: plan + run: | + terraform plan -no-color -input=false -out terraform.tfplan \ + -var environment=${{ inputs.environment }} \ + -var account=${{ steps.set_env_metadata.outputs.account }} \ + -var region=${{ steps.set_env_metadata.outputs.region }} + working-directory: deploy/terraform/${{ inputs.project }} + + - name: Terraform Apply + id: apply + run: terraform apply -auto-approve -input=false terraform.tfplan + working-directory: deploy/terraform/${{ inputs.project }} diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml new file mode 100644 index 0000000..8780537 --- /dev/null +++ b/.github/workflows/terraform.yml @@ -0,0 +1,31 @@ +name: terraform-deploy +on: + workflow_dispatch: + inputs: + environment: + description: 'Environment' + required: true + default: 'dev' + type: choice + options: + - dev + - staging + - prod + project: + description: 'Project' + required: true + default: 'livepoll' + type: choice + options: + - livepoll + - pandoc +jobs: + terraform-deploy: + name: Terraform Deployment + uses: ./.github/workflows/terraform-deploy.yml + with: + environment: ${{ github.event.inputs.environment }} + project: ${{ github.event.inputs.project }} + secrets: + aws_user_account: ${{ secrets.AWS_USER_ACCOUNT }} + aws_ci_account: ${{ secrets.AWS_CI_ACCOUNT }} diff --git a/deploy/ecs_deploy.sh b/deploy/ecs_deploy.sh new file mode 100755 index 0000000..9c0cc92 --- /dev/null +++ b/deploy/ecs_deploy.sh @@ -0,0 +1,60 @@ +#!/bin/bash +# +# This script: +# - deploys a docker image to an ECS environment +# +# Required environment variables: +# - GITHUB_WORKFLOW - provided by GHA +# - GITHUB_RUN_NUMBER - provided by GHA +# - GITHUB_RUN_ATTEMPT - provided by GHA +# - GITHUB_SHA - provided by GHA + +set -euox pipefail + +export AWS_ECR_IMAGE_TAG=gha-tree-$(git rev-parse HEAD:) +export VERSION_LABEL=gha-build-$GITHUB_WORKFLOW-$GITHUB_RUN_NUMBER-$GITHUB_RUN_ATTEMPT + +while [[ $# -gt 0 ]]; do + case $1 in + -c|--cluster-name) + ECS_CLUSTER_NAME="$2" + shift # past argument + shift # past value + ;; + -s|--ssm-prefix) + SSM_PREFIX="$2" + shift # past argument + shift # past value + ;; + -n|--account-number) + AWS_CI_ACCOUNT="$2" + shift # past argument + shift # past value + ;; + -p|--project-name) + PROJECT_NAME="$2" + shift + shift + ;; + -*|--*) + echo "Unknown option $1" + exit 1 + ;; + esac +done + +ECS_SERVICE_NAME="${ECS_CLUSTER_NAME}" +ECR_REPOSITORY="${PROJECT_NAME}" +CONTAINER_NAME="${PROJECT_NAME}" + +echo -e "\n============================================================" +echo " Beginning deployment to AWS Fargate environment: $ECS_CLUSTER_NAME $ECS_SERVICE_NAME" +echo -e "============================================================\n" + +# Deploy the latest image to Fargate for the webapp +docker run -e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY -e AWS_SESSION_TOKEN \ + fabfuel/ecs-deploy:1.15.0 ecs deploy --region us-west-2 --no-deregister --timeout 600 --rollback \ + -i ${CONTAINER_NAME} $AWS_CI_ACCOUNT.dkr.ecr.us-west-2.amazonaws.com/$ECR_REPOSITORY:$AWS_ECR_IMAGE_TAG \ + -e ${CONTAINER_NAME} PARAMETER_STORE_PREFIX_LIST ${SSM_PREFIX} \ + -e ${CONTAINER_NAME} AWS_REGION us-west-2 \ + $ECS_CLUSTER_NAME $ECS_SERVICE_NAME diff --git a/deploy/livepoll-environments.json b/deploy/livepoll-environments.json new file mode 100644 index 0000000..ffb7ef0 --- /dev/null +++ b/deploy/livepoll-environments.json @@ -0,0 +1,43 @@ +{ + "environments": [ + { + "environment_label": "dev", + "account": 725843923591, + "region": "us-west-2", + "terraform_state_key": "accounts/lumen-stage/us-west-2/dev/livepoll-app/config/terraform.tfstate", + "ssm_prefix": "/lumen-services/us-west-2/dev/livepoll", + "fargate": { + "cluster_name": "dev-livepoll" + }, + "webapp": { + "ssm_prefix": "/lumen-services/us-west-2/dev/livepoll/webapp" + } + }, + { + "environment_label": "staging", + "account": 725843923591, + "region": "us-west-2", + "terraform_state_key": "accounts/lumen-stage/us-west-2/staging/livepoll-app/config/terraform.tfstate", + "ssm_prefix": "/lumen-services/us-west-2/staging/livepoll", + "fargate": { + "cluster_name": "staging-livepoll" + }, + "webapp": { + "ssm_prefix": "/lumen-services/us-west-2/staging/livepoll/webapp" + } + }, + { + "environment_label": "prod", + "account": 523740042085, + "region": "us-west-2", + "terraform_state_key": "accounts/lumen-prod/us-west-2/prod/livepoll-app/config/terraform.tfstate", + "ssm_prefix": "/lumen-services/us-west-2/prod/livepoll", + "fargate": { + "cluster_name": "prod-livepoll" + }, + "webapp": { + "ssm_prefix": "/lumen-services/us-west-2/prod/livepoll/webapp" + } + } + ] +} \ No newline at end of file diff --git a/deploy/pandoc-environments.json b/deploy/pandoc-environments.json new file mode 100644 index 0000000..f742786 --- /dev/null +++ b/deploy/pandoc-environments.json @@ -0,0 +1,43 @@ +{ + "environments": [ + { + "environment_label": "dev", + "account": 725843923591, + "region": "us-west-2", + "terraform_state_key": "accounts/lumen-stage/us-west-2/dev/pandoc-app/config/terraform.tfstate", + "ssm_prefix": "/lumen-services/us-west-2/dev/pandoc", + "fargate": { + "cluster_name": "dev-pandoc" + }, + "webapp": { + "ssm_prefix": "/lumen-services/us-west-2/dev/pandoc/webapp" + } + }, + { + "environment_label": "staging", + "account": 725843923591, + "region": "us-west-2", + "terraform_state_key": "accounts/lumen-stage/us-west-2/staging/pandoc-app/config/terraform.tfstate", + "ssm_prefix": "/lumen-services/us-west-2/staging/pandoc", + "fargate": { + "cluster_name": "staging-pandoc" + }, + "webapp": { + "ssm_prefix": "/lumen-services/us-west-2/staging/pandoc/webapp" + } + }, + { + "environment_label": "prod", + "account": 523740042085, + "region": "us-west-2", + "terraform_state_key": "accounts/lumen-prod/us-west-2/prod/pandoc-app/config/terraform.tfstate", + "ssm_prefix": "/lumen-services/us-west-2/prod/pandoc", + "fargate": { + "cluster_name": "prod-pandoc" + }, + "webapp": { + "ssm_prefix": "/lumen-services/us-west-2/prod/pandoc/webapp" + } + } + ] +} \ No newline at end of file diff --git a/deploy/terraform/livepoll/_locals.tf b/deploy/terraform/livepoll/_locals.tf new file mode 100644 index 0000000..d80b489 --- /dev/null +++ b/deploy/terraform/livepoll/_locals.tf @@ -0,0 +1,5 @@ +locals { + service_name = "livepoll" + parameter_store_prefix = "/lumen-services/${var.region}/${var.environment}/${local.service_name}" + parameter_store_prefix_webapp = "${local.parameter_store_prefix}/webapp" +} \ No newline at end of file diff --git a/deploy/terraform/livepoll/_provider.tf b/deploy/terraform/livepoll/_provider.tf new file mode 100644 index 0000000..63e3723 --- /dev/null +++ b/deploy/terraform/livepoll/_provider.tf @@ -0,0 +1,34 @@ +provider "aws" { + region = var.region + + assume_role { + role_arn = "arn:aws:iam::${var.account}:role/ci-role" + } + + default_tags { + tags = { + Environment = var.environment + Terraform = "true" + Terraform_Project = local.service_name + Service = local.service_name + } + } +} + +terraform { + required_version = ">= 1.0.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.0" + } + } + backend "s3" { + encrypt = true + bucket = "lumen-terraform-state" + dynamodb_table = "lumen-terraform-state-lock" + region = "us-west-2" + role_arn = "arn:aws:iam::824635284302:role/terraform" + } +} diff --git a/deploy/terraform/livepoll/parameter_store.tf b/deploy/terraform/livepoll/parameter_store.tf new file mode 100644 index 0000000..8f8456c --- /dev/null +++ b/deploy/terraform/livepoll/parameter_store.tf @@ -0,0 +1,19 @@ +resource "aws_ssm_parameter" "LIVEPOLL_USE_INSECURE_HTTP" { + name = "${local.parameter_store_prefix}/LIVEPOLL_USE_INSECURE_HTTP" + type = "SecureString" + value = "true" # initial value only, updates not handled in terraform + + lifecycle { + ignore_changes = [value] + } +} + +resource "aws_ssm_parameter" "LIVEPOLL_PASSWORD" { + name = "${local.parameter_store_prefix}/LIVEPOLL_PASSWORD" + type = "SecureString" + value = "replace_me" # initial value only, updates not handled in terraform + + lifecycle { + ignore_changes = [value] + } +} \ No newline at end of file diff --git a/deploy/terraform/livepoll/variables.tf b/deploy/terraform/livepoll/variables.tf new file mode 100644 index 0000000..e960b8d --- /dev/null +++ b/deploy/terraform/livepoll/variables.tf @@ -0,0 +1,11 @@ +variable "environment" { + type = string +} + +variable "region" { + type = string +} + +variable "account" { + type = string +} diff --git a/deploy/terraform/pandoc/_locals.tf b/deploy/terraform/pandoc/_locals.tf new file mode 100644 index 0000000..e228494 --- /dev/null +++ b/deploy/terraform/pandoc/_locals.tf @@ -0,0 +1,5 @@ +locals { + service_name = "pandoc" + parameter_store_prefix = "/lumen-services/${var.region}/${var.environment}/${local.service_name}" + parameter_store_prefix_webapp = "${local.parameter_store_prefix}/webapp" +} \ No newline at end of file diff --git a/deploy/terraform/pandoc/_provider.tf b/deploy/terraform/pandoc/_provider.tf new file mode 100644 index 0000000..63e3723 --- /dev/null +++ b/deploy/terraform/pandoc/_provider.tf @@ -0,0 +1,34 @@ +provider "aws" { + region = var.region + + assume_role { + role_arn = "arn:aws:iam::${var.account}:role/ci-role" + } + + default_tags { + tags = { + Environment = var.environment + Terraform = "true" + Terraform_Project = local.service_name + Service = local.service_name + } + } +} + +terraform { + required_version = ">= 1.0.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.0" + } + } + backend "s3" { + encrypt = true + bucket = "lumen-terraform-state" + dynamodb_table = "lumen-terraform-state-lock" + region = "us-west-2" + role_arn = "arn:aws:iam::824635284302:role/terraform" + } +} diff --git a/deploy/terraform/pandoc/variables.tf b/deploy/terraform/pandoc/variables.tf new file mode 100644 index 0000000..e960b8d --- /dev/null +++ b/deploy/terraform/pandoc/variables.tf @@ -0,0 +1,11 @@ +variable "environment" { + type = string +} + +variable "region" { + type = string +} + +variable "account" { + type = string +} diff --git a/docker-compose.yml b/docker-compose.yml index 6e36b23..a3c0997 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,5 +1,3 @@ -version: '3' - services: pandoc: @@ -23,25 +21,6 @@ services: stdin_open: false tty: false - # The pandoc container does not run cron, so run cron - # in its own container with a shared volume. - pandoc-cron: - build: - context: ./ - dockerfile: docker/Dockerfile-pandoc-cron - - volumes: - - pandoc-temp-datatmp:/var/www/datatmp - - pandoc-temp-imgs:/var/www/html/imgs - - hostname: pandoc-cron - domainname: example.com - - restart: unless-stopped - privileged: true - stdin_open: false - tty: false - livepoll: build: context: ./ diff --git a/docker/Dockerfile-livepoll b/docker/Dockerfile-livepoll index 3788f3c..deeb460 100644 --- a/docker/Dockerfile-livepoll +++ b/docker/Dockerfile-livepoll @@ -1,10 +1,19 @@ FROM node:22 +RUN apt-get update \ + && apt-get install -y --no-install-recommends --no-install-suggests \ + jq \ + awscli \ + && apt-get clean + WORKDIR /app COPY livepoll/* /app/ RUN npm install -CMD ["node", "/app/index.js"] +COPY docker/livepoll-entrypoint.sh /usr/bin/docker-entrypoint.sh +ENTRYPOINT [ "/usr/bin/docker-entrypoint.sh" ] + +CMD ["node", "/app/index.js"] diff --git a/docker/Dockerfile-pandoc b/docker/Dockerfile-pandoc index 01d97a5..9921665 100644 --- a/docker/Dockerfile-pandoc +++ b/docker/Dockerfile-pandoc @@ -1,11 +1,13 @@ -FROM php:8.2-apache +FROM php:8.3-apache RUN apt-get update \ && apt-get install -y --no-install-recommends --no-install-suggests \ pandoc \ + jq \ + awscli \ && apt-get clean -COPY pandoc/* /var/www/html/ +COPY --chown=www-data:www-data pandoc/* /var/www/html/ RUN mkdir \ /var/www/datatmp \ @@ -14,3 +16,5 @@ RUN mkdir \ /var/www/datatmp \ /var/www/html/imgs +# enable php production defaults +RUN cp $PHP_INI_DIR/php.ini-production $PHP_INI_DIR/php.ini \ No newline at end of file diff --git a/docker/Dockerfile-pandoc-cron b/docker/Dockerfile-pandoc-cron deleted file mode 100644 index 270b0ae..0000000 --- a/docker/Dockerfile-pandoc-cron +++ /dev/null @@ -1,13 +0,0 @@ -FROM debian:12.5 - -RUN apt-get update \ - && apt-get install -y --no-install-suggests --no-install-recommends \ - cron \ - && apt-get clean - -COPY pandoc/cleanup-old-files /etc/cron.daily - -RUN chmod 755 /etc/cron.daily/cleanup-old-files - -CMD ["cron", "-f"] - diff --git a/docker/livepoll-entrypoint.sh b/docker/livepoll-entrypoint.sh new file mode 100755 index 0000000..b943458 --- /dev/null +++ b/docker/livepoll-entrypoint.sh @@ -0,0 +1,54 @@ +#!/bin/bash +set -eo pipefail + +# Required environment variables: +# - PARAMETER_STORE_PREFIX_LIST: Comma-separated list of paths in SSM Parameter Store from which environment variables are pulled. +# If items from multiple paths conflict, the later one is used. + +# https://www.geekcafe.com/blog/how-to-load-parameter-store-values-into-an-ec2s-environment-variables +setup_parameter_store() { + PREFIX=$1 + + parameters=$(aws ssm get-parameters-by-path \ + --path "${PREFIX}" \ + --region ${AWS_REGION} \ + --with-decrypt \ + ) + success=$? + + if [ $success -eq 0 ]; then + # bail if no parameters found + param_count=$(echo "$parameters" | jq '.Parameters | length') + if [ $param_count -eq 0 ]; then + echo "No parameters found in '${PREFIX}!'" + exit 1 + fi + + # split("/")[-1] will grab the last token as the "name" for the env variable + export_statement=$(echo "$parameters" \ + | jq -r '.Parameters[] | "echo \"Pulling from " + .Name + "\"; export " + (.Name | split("/")[-1]) + "=\"" + .Value + "\""' \ + ) + sorted=$(echo "$export_statement" | sort) + + # eval the export strings + eval "$sorted" + else + echo "Failed to retrieve AWS SSM Parameters from '${PREFIX}!'" + exit 1 + fi +} + +if [ ! -z ${PARAMETER_STORE_PREFIX_LIST} ]; then + prefixes=$(echo $PARAMETER_STORE_PREFIX_LIST | tr "," "\n") + + for prefix in $prefixes + do + setup_parameter_store $prefix + done + +else + echo "PARAMETER_STORE_PREFIX_LIST is not set, skipping parameter store setup." +fi + +# Then exec the container's main process (what's set as CMD in the Dockerfile). +exec "$@" \ No newline at end of file diff --git a/pandoc/cleanup-old-files b/pandoc/cleanup-old-files deleted file mode 100644 index 3a06f20..0000000 --- a/pandoc/cleanup-old-files +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh - -find /var/www/datatmp/* -mtime +1 -exec rm {} \; - -find /var/www/html/imgs/* -mtime +1 -exec rm {} \; From 208b9f3424160c5831e52f2c63f6cafaeb43e330 Mon Sep 17 00:00:00 2001 From: Jeff DeWan Date: Thu, 19 Dec 2024 12:57:08 -0800 Subject: [PATCH 7/9] Lock terraform version --- .github/workflows/build-and-push.yml | 2 ++ .github/workflows/terraform-deploy.yml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/.github/workflows/build-and-push.yml b/.github/workflows/build-and-push.yml index 180eaac..13a7b18 100644 --- a/.github/workflows/build-and-push.yml +++ b/.github/workflows/build-and-push.yml @@ -33,6 +33,8 @@ jobs: - name: Setup Terraform uses: hashicorp/setup-terraform@v3 + with: + terraform_version: 1.9.8 - name: Livepoll Terraform Init run: terraform init -backend=false diff --git a/.github/workflows/terraform-deploy.yml b/.github/workflows/terraform-deploy.yml index 44e6118..b098c08 100644 --- a/.github/workflows/terraform-deploy.yml +++ b/.github/workflows/terraform-deploy.yml @@ -58,6 +58,8 @@ jobs: # Based on https://developer.hashicorp.com/terraform/tutorials/automation/github-actions - name: Setup Terraform uses: hashicorp/setup-terraform@v3 + with: + terraform_version: 1.9.8 - name: Terraform Init id: init From 9c5382fca777ed95979f62b6f6991b480a1d70fc Mon Sep 17 00:00:00 2001 From: Jeff DeWan Date: Thu, 19 Dec 2024 13:58:15 -0800 Subject: [PATCH 8/9] Cleanup unused workflow --- .github/workflows/build-livepoll.yml | 230 --------------------------- 1 file changed, 230 deletions(-) delete mode 100644 .github/workflows/build-livepoll.yml diff --git a/.github/workflows/build-livepoll.yml b/.github/workflows/build-livepoll.yml deleted file mode 100644 index 8858f07..0000000 --- a/.github/workflows/build-livepoll.yml +++ /dev/null @@ -1,230 +0,0 @@ -name: build-and-push -env: - LIVEPOLL_ECR_REPOSITORY: livepoll - PANDOC_ECR_REPOSITORY: pandoc -on: - pull_request: - types: [ opened, synchronize, reopened ] - push: - branches: - - main - - rc/** - -jobs: - # this job gets a password for public ECR to use in future steps - ecr-public-auth: - runs-on: ubuntu-latest - name: Login to Public ECR - timeout-minutes: 5 - permissions: - id-token: write # Used for AWS OIDC auth - outputs: - ECR_PASSWORD: ${{ steps.ecr-auth.outputs.ECR_PASSWORD }} - steps: - # This is required to role chain from the OIDC role to other cross-account roles - # https://github.com/aws-actions/configure-aws-credentials/issues/279 - - name: OIDC Auth - uses: aws-actions/configure-aws-credentials@v4 - with: - aws-region: us-west-2 - role-to-assume: arn:aws:iam::265299512749:role/ci-oidc-role - role-session-name: github-actions - role-duration-seconds: 900 - - - name: Assume role in CI Account - uses: aws-actions/configure-aws-credentials@v4 - with: - aws-access-key-id: ${{ env.AWS_ACCESS_KEY_ID }} - aws-secret-access-key: ${{ env.AWS_SECRET_ACCESS_KEY }} - aws-session-token: ${{ env.AWS_SESSION_TOKEN }} - aws-region: us-west-2 - role-to-assume: arn:aws:iam::824635284302:role/ci-role - role-session-name: github-actions - role-duration-seconds: 1200 - - - name: Set Public ECR Auth - id: ecr-auth - run: echo "ECR_PASSWORD=$(aws ecr-public --region us-east-1 get-login-password)" >> $GITHUB_OUTPUT - - validate-terraform: - runs-on: ubuntu-latest - name: Validate Terraform - timeout-minutes: 5 - permissions: - id-token: write # Used for AWS OIDC auth - contents: read - actions: read - steps: - - uses: actions/checkout@v4 - name: Checkout project - - - name: OIDC Auth to AWS - uses: aws-actions/configure-aws-credentials@v4 - with: - aws-region: us-west-2 - role-to-assume: arn:aws:iam::${{ secrets.aws_user_account }}:role/ci-oidc-role - role-session-name: github-actions - role-duration-seconds: 900 - - - name: Setup Terraform - uses: hashicorp/setup-terraform@v3 - - - name: Terraform Init - id: init - run: terraform init -backend=false - working-directory: deploy/terraform - - - name: Terraform Format - id: fmt - run: terraform fmt -check - - - name: Terraform Validate - id: validate - run: terraform validate -no-color - working-directory: deploy/terraform - - build-and-push-livepoll: - runs-on: ubuntu-latest - name: Build and Push Livepoll Docker Image - timeout-minutes: 30 - needs: [ecr-public-auth, validate-terraform] - permissions: - id-token: write # Used for AWS OIDC auth - contents: read - actions: read - steps: - - uses: actions/checkout@v4 - name: Checkout project - - - id: read_tree_hash - name: Read git tree hash - run: | - tree_hash=$(git rev-parse HEAD:) - echo "tree_hash=$tree_hash" >> $GITHUB_OUTPUT - - - id: set_branch_name - name: Read git branch name - run: | - branch_name=${GITHUB_REF##*/} - echo "branch_name=$branch_name" >> $GITHUB_OUTPUT - - - uses: ./.github/actions/private-ecr-login - name: Login to Private ECR - id: login-ecr - - - name: Login to Public ECR - uses: docker/login-action@v3 - with: - registry: public.ecr.aws/j7v6u1e0 - username: AWS - password: ${{ needs.ecr-public-auth.outputs.ECR_PASSWORD }} - - - name: Check for prebuilt image - id: prebuilt_check - run: | - docker manifest inspect ${{ steps.login-ecr.outputs.registry }}/${{ env.LIVEPOLL_ECR_REPOSITORY }}:gha-tree-${{ steps.read_tree_hash.outputs.tree_hash }} || echo "image_exists=$?" >> $GITHUB_OUTPUT - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - if: steps.prebuilt_check.outputs.image_exists != 0 - - - name: Docker build and push - uses: docker/build-push-action@v5 - if: steps.prebuilt_check.outputs.image_exists != 0 - env: - ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} - with: - context: . - file: docker/Dockerfile-livepoll - platforms: linux/amd64 - push: true - tags: | - ${{ steps.login-ecr.outputs.registry }}/${{ env.LIVEPOLL_ECR_REPOSITORY }}:gha-commit-${{ github.sha }} - ${{ steps.login-ecr.outputs.registry }}/${{ env.LIVEPOLL_ECR_REPOSITORY }}:gha-tree-${{ steps.read_tree_hash.outputs.tree_hash }} - ${{ steps.login-ecr.outputs.registry }}/${{ env.LIVEPOLL_ECR_REPOSITORY }}:gha-build-${{ steps.set_branch_name.outputs.branch_name }}-${{ github.run_number }}-${{ github.run_attempt }} - ${{ steps.login-ecr.outputs.registry }}/${{ env.LIVEPOLL_ECR_REPOSITORY }}:gha-build-${{ steps.set_branch_name.outputs.branch_name }}-latest - cache-from: type=gha - cache-to: type=gha,mode=max - - build-and-push-pandoc: - runs-on: ubuntu-latest - name: Build and Push Pandoc Docker Image - timeout-minutes: 30 - needs: [ecr-public-auth, validate-terraform] - permissions: - id-token: write # Used for AWS OIDC auth - contents: read - actions: read - steps: - - uses: actions/checkout@v4 - name: Checkout project - - - id: read_tree_hash - name: Read git tree hash - run: | - tree_hash=$(git rev-parse HEAD:) - echo "tree_hash=$tree_hash" >> $GITHUB_OUTPUT - - - id: set_branch_name - name: Read git branch name - run: | - branch_name=${GITHUB_REF##*/} - echo "branch_name=$branch_name" >> $GITHUB_OUTPUT - - - uses: ./.github/actions/private-ecr-login - name: Login to Private ECR - id: login-ecr - - - name: Login to Public ECR - uses: docker/login-action@v3 - with: - registry: public.ecr.aws/j7v6u1e0 - username: AWS - password: ${{ needs.ecr-public-auth.outputs.ECR_PASSWORD }} - - - name: Check for prebuilt image - id: prebuilt_check - run: | - docker manifest inspect ${{ steps.login-ecr.outputs.registry }}/${{ env.PANDOC_ECR_REPOSITORY }}:gha-tree-${{ steps.read_tree_hash.outputs.tree_hash }} || echo "image_exists=$?" >> $GITHUB_OUTPUT - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - if: steps.prebuilt_check.outputs.image_exists != 0 - - - name: Docker build and push - uses: docker/build-push-action@v5 - if: steps.prebuilt_check.outputs.image_exists != 0 - env: - ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} - with: - context: . - file: docker/Dockerfile-pandoc - target: pandoc - platforms: linux/amd64 - push: true - tags: | - ${{ steps.login-ecr.outputs.registry }}/${{ env.PANDOC_ECR_REPOSITORY }}:gha-commit-${{ github.sha }} - ${{ steps.login-ecr.outputs.registry }}/${{ env.PANDOC_ECR_REPOSITORY }}:gha-tree-${{ steps.read_tree_hash.outputs.tree_hash }} - ${{ steps.login-ecr.outputs.registry }}/${{ env.PANDOC_ECR_REPOSITORY }}:gha-build-${{ steps.set_branch_name.outputs.branch_name }}-${{ github.run_number }}-${{ github.run_attempt }} - ${{ steps.login-ecr.outputs.registry }}/${{ env.PANDOC_ECR_REPOSITORY }}:gha-build-${{ steps.set_branch_name.outputs.branch_name }}-latest - cache-from: type=gha - cache-to: type=gha,mode=max - - - name: Docker build and push - uses: docker/build-push-action@v5 - if: steps.prebuilt_check.outputs.image_exists != 0 - env: - ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} - with: - context: . - file: docker/Dockerfile-pandoc - target: cron - platforms: linux/amd64 - push: true - tags: | - ${{ steps.login-ecr.outputs.registry }}/${{ env.PANDOC_ECR_REPOSITORY }}:gha-commit-${{ github.sha }}-cron - ${{ steps.login-ecr.outputs.registry }}/${{ env.PANDOC_ECR_REPOSITORY }}:gha-tree-${{ steps.read_tree_hash.outputs.tree_hash }}-cron - ${{ steps.login-ecr.outputs.registry }}/${{ env.PANDOC_ECR_REPOSITORY }}:gha-build-${{ steps.set_branch_name.outputs.branch_name }}-${{ github.run_number }}-${{ github.run_attempt }}-cron - ${{ steps.login-ecr.outputs.registry }}/${{ env.PANDOC_ECR_REPOSITORY }}:gha-build-${{ steps.set_branch_name.outputs.branch_name }}-latest-cron - cache-from: type=gha - cache-to: type=gha,mode=max \ No newline at end of file From 620c306e2b6e72bfb9ebd35bee5a340d23a584fd Mon Sep 17 00:00:00 2001 From: Jeff DeWan Date: Thu, 19 Dec 2024 13:59:08 -0800 Subject: [PATCH 9/9] Fix github action --- .github/workflows/shared-deploy.yml | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/.github/workflows/shared-deploy.yml b/.github/workflows/shared-deploy.yml index 8010c8a..770bf3b 100644 --- a/.github/workflows/shared-deploy.yml +++ b/.github/workflows/shared-deploy.yml @@ -44,17 +44,6 @@ jobs: - uses: ./.github/actions/private-ecr-login name: Login to Private ECR id: login-ecr -<<<<<<< HEAD -======= - - - name: Login to Public ECR - uses: docker/login-action@v3 - with: - registry: public.ecr.aws/o9c0t3w1 - username: AWS - password: ${{ needs.ecr-public-auth.outputs.ECR_PASSWORD }} - ->>>>>>> origin/master - id: read_env_json name: Read Environment JSON