From 2b7018b31cbba9549fc65d62e36b66fd4aa77942 Mon Sep 17 00:00:00 2001 From: milldr Date: Fri, 6 Sep 2024 10:04:55 -0400 Subject: [PATCH 1/3] collapsible text instead of details --- .../ecs-ecspresso/ecs-ecspresso.mdx | 363 ++++++++-------- .../eks-argocd/eks-argocd.mdx | 400 +++++++++--------- .../software-delivery/lambda/lambda.mdx | 333 +++++++-------- 3 files changed, 544 insertions(+), 552 deletions(-) diff --git a/docs/layers/software-delivery/ecs-ecspresso/ecs-ecspresso.mdx b/docs/layers/software-delivery/ecs-ecspresso/ecs-ecspresso.mdx index e4cffc6f8..a69f866eb 100644 --- a/docs/layers/software-delivery/ecs-ecspresso/ecs-ecspresso.mdx +++ b/docs/layers/software-delivery/ecs-ecspresso/ecs-ecspresso.mdx @@ -7,6 +7,7 @@ import Intro from '@site/src/components/Intro'; import KeyPoints from '@site/src/components/KeyPoints'; import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; +import CollapsibleText from '@site/src/components/CollapsibleText'; We use the [`ecspresso`](https://github.com/kayac/ecspresso) deployment tool for Amazon ECS to manage ECS services using a code-driven approach, alongside reusable GitHub Action workflows. This setup allows tasks to be defined with Terraform within the infrastructure repository, and task definitions to reside alongside the application code. Ecspresso provides extensive configuration options via YAML, JSON, and Jsonnet, and includes plugins for enhanced functionality such as Terraform state lookups. @@ -57,192 +58,192 @@ sequenceDiagram ### Github Action Workflows -The basic deployment flow is for feature branches. You can use the following -sample workflow to add pull request deploys to your application repository: +The basic deployment flow is for feature branches. You can use the following sample workflow to add pull request deploys to your application repository: -
-Deploy +:::tip Latest Examples - - - - -```yaml -name: Feature Branch -on: - pull_request: - branches: [ 'main' ] - types: [opened, synchronize, reopened, closed, labeled, unlabeled] - -permissions: - pull-requests: write - deployments: write - id-token: write - contents: read - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: false - -jobs: - monorepo: - uses: cloudposse/github-actions-workflows/.github/workflows/controller-monorepo.yml@main - with: - file: ./deploy/config.yaml - - ci: - uses: cloudposse/github-actions-workflows/.github/workflows/ci-dockerized-app-build.yml@main - needs: [ monorepo ] - with: - organization: "cloudposse" - repository: ${{ github.event.repository.name }} - secrets: - ecr-region: ${{ secrets.ECR_REGION }} - ecr-iam-role: ${{ secrets.ECR_IAM_ROLE }} - registry: ${{ secrets.ECR_REGISTRY }} - secret-outputs-passphrase: ${{ secrets.GHA_SECRET_OUTPUT_PASSPHRASE }} - - cd: - uses: cloudposse/github-actions-workflows/.github/workflows/cd-preview-ecspresso.yml@main - needs: [ ci, monorepo ] - if: ${{ always() && needs.monorepo.outputs.apps != '[]' }} - strategy: - matrix: - app: ${{ fromJson(needs.monorepo.outputs.apps) }} - with: - image: ${{ needs.ci.outputs.image }} - tag: ${{ needs.ci.outputs.tag }} - repository: ${{ github.event.repository.name }} - app: ${{ matrix.app }} - open: ${{ github.event.pull_request.state == 'open' }} - labels: ${{ toJSON(github.event.pull_request.labels.*.name) }} - ref: ${{ github.event.pull_request.head.ref }} - exclusive: true - enable-migration: ${{ contains(fromJSON(needs.monorepo.outputs.migrations), matrix.app) }} - settings: ${{ needs.monorepo.outputs.settings }} - env-label: | - qa1: deploy/qa1 - secrets: - secret-outputs-passphrase: ${{ secrets.GHA_SECRET_OUTPUT_PASSPHRASE }} -``` +Check out our [example-app-on-ecs](https://github.com/cloudposse-examples/app-on-ecs) for the latest example of how to use `ecspresso` with GitHub Actions. - - - - -```yaml -name: 2 - Main Branch -on: - push: - branches: [ main ] - -permissions: - contents: write - id-token: write - pull-requests: read - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: false - -jobs: - monorepo: - uses: cloudposse/github-actions-workflows/.github/workflows/controller-monorepo.yml@main - with: - file: ./deploy/config.yaml - - ci: - uses: cloudposse/github-actions-workflows/.github/workflows/ci-dockerized-app-build.yml@main - needs: [ monorepo ] - with: - organization: "cloudposse" - repository: ${{ github.event.repository.name }} - secrets: - ecr-region: ${{ secrets.ECR_REGION }} - ecr-iam-role: ${{ secrets.ECR_IAM_ROLE }} - registry: ${{ secrets.ECR_REGISTRY }} - secret-outputs-passphrase: ${{ secrets.GHA_SECRET_OUTPUT_PASSPHRASE }} - - cd: - uses: cloudposse/github-actions-workflows/.github/workflows/cd-ecspresso.yml@main - needs: [ ci, monorepo ] - strategy: - matrix: - app: ${{ fromJson(needs.monorepo.outputs.apps) }} - with: - image: ${{ needs.ci.outputs.image }} - tag: ${{ needs.ci.outputs.tag }} - repository: ${{ github.event.repository.name }} - app: ${{ matrix.app }} - environment: dev - enable-migration: ${{ contains(fromJSON(needs.monorepo.outputs.migrations), matrix.app) }} - settings: ${{ needs.monorepo.outputs.settings }} - secrets: - secret-outputs-passphrase: ${{ secrets.GHA_SECRET_OUTPUT_PASSPHRASE }} - - release: - uses: cloudposse/github-actions-workflows/.github/workflows/controller-draft-release.yml@main - needs: [ cd ] -``` +::: - - - - -```yaml -name: 3 - Release -on: - release: - types: [published] - -permissions: - id-token: write - contents: write - -concurrency: - group: ${{ github.workflow }} - cancel-in-progress: false - -jobs: - monorepo: - uses: cloudposse/github-actions-workflows/.github/workflows/controller-monorepo.yml@main - with: - file: ./deploy/config.yaml - - ci: - uses: cloudposse/github-actions-workflows/.github/workflows/ci-dockerized-app-promote.yml@main - needs: [ monorepo ] - with: - organization: "cloudposse" - repository: ${{ github.event.repository.name }} - version: ${{ github.event.release.tag_name }} - secrets: - ecr-region: ${{ secrets.ECR_REGION }} - ecr-iam-role: ${{ secrets.ECR_IAM_ROLE }} - registry: ${{ secrets.ECR_REGISTRY }} - secret-outputs-passphrase: ${{ secrets.GHA_SECRET_OUTPUT_PASSPHRASE }} - - cd: - uses: cloudposse/github-actions-workflows/.github/workflows/cd-ecspresso.yml@main - needs: [ ci, monorepo ] - strategy: - matrix: - app: ${{ fromJson(needs.monorepo.outputs.apps) }} - with: - image: ${{ needs.ci.outputs.image }} - tag: ${{ needs.ci.outputs.tag }} - repository: ${{ github.event.repository.name }} - app: ${{ matrix.app }} - environment: "staging" - enable-migration: ${{ contains(fromJSON(needs.monorepo.outputs.migrations), matrix.app) }} - settings: ${{ needs.monorepo.outputs.settings }} - secrets: - secret-outputs-passphrase: ${{ secrets.GHA_SECRET_OUTPUT_PASSPHRASE }} -``` - - + + + + ```yaml + name: 1 - Feature Branch + on: + pull_request: + branches: [ main ] + types: [opened, synchronize, reopened, closed, labeled, unlabeled] + + permissions: + pull-requests: write + deployments: write + id-token: write + contents: read + + concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: false + + jobs: + monorepo: + uses: cloudposse/github-actions-workflows/.github/workflows/controller-monorepo.yml@main + with: + file: ./deploy/config.yaml + + ci: + uses: cloudposse/github-actions-workflows/.github/workflows/ci-dockerized-app-build.yml@main + needs: [ monorepo ] + with: + organization: "cloudposse" + repository: ${{ github.event.repository.name }} + secrets: + ecr-region: ${{ secrets.ECR_REGION }} + ecr-iam-role: ${{ secrets.ECR_IAM_ROLE }} + registry: ${{ secrets.ECR_REGISTRY }} + secret-outputs-passphrase: ${{ secrets.GHA_SECRET_OUTPUT_PASSPHRASE }} + + cd: + uses: cloudposse/github-actions-workflows/.github/workflows/cd-preview-ecspresso.yml@main + needs: [ ci, monorepo ] + if: ${{ always() && needs.monorepo.outputs.apps != '[]' }} + strategy: + matrix: + app: ${{ fromJson(needs.monorepo.outputs.apps) }} + with: + image: ${{ needs.ci.outputs.image }} + tag: ${{ needs.ci.outputs.tag }} + repository: ${{ github.event.repository.name }} + app: ${{ matrix.app }} + open: ${{ github.event.pull_request.state == 'open' }} + labels: ${{ toJSON(github.event.pull_request.labels.*.name) }} + ref: ${{ github.event.pull_request.head.ref }} + exclusive: true + enable-migration: ${{ contains(fromJSON(needs.monorepo.outputs.migrations), matrix.app) }} + settings: ${{ needs.monorepo.outputs.settings }} + env-label: | + qa1: deploy/qa1 + secrets: + secret-outputs-passphrase: ${{ secrets.GHA_SECRET_OUTPUT_PASSPHRASE }} + ``` + + + + + + ```yaml + name: 2 - Main Branch + on: + push: + branches: [ main ] + + permissions: + contents: write + id-token: write + pull-requests: read + + concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: false + + jobs: + monorepo: + uses: cloudposse/github-actions-workflows/.github/workflows/controller-monorepo.yml@main + with: + file: ./deploy/config.yaml + + ci: + uses: cloudposse/github-actions-workflows/.github/workflows/ci-dockerized-app-build.yml@main + needs: [ monorepo ] + with: + organization: "cloudposse" + repository: ${{ github.event.repository.name }} + secrets: + ecr-region: ${{ secrets.ECR_REGION }} + ecr-iam-role: ${{ secrets.ECR_IAM_ROLE }} + registry: ${{ secrets.ECR_REGISTRY }} + secret-outputs-passphrase: ${{ secrets.GHA_SECRET_OUTPUT_PASSPHRASE }} + + cd: + uses: cloudposse/github-actions-workflows/.github/workflows/cd-ecspresso.yml@main + needs: [ ci, monorepo ] + strategy: + matrix: + app: ${{ fromJson(needs.monorepo.outputs.apps) }} + with: + image: ${{ needs.ci.outputs.image }} + tag: ${{ needs.ci.outputs.tag }} + repository: ${{ github.event.repository.name }} + app: ${{ matrix.app }} + environment: dev + enable-migration: ${{ contains(fromJSON(needs.monorepo.outputs.migrations), matrix.app) }} + settings: ${{ needs.monorepo.outputs.settings }} + secrets: + secret-outputs-passphrase: ${{ secrets.GHA_SECRET_OUTPUT_PASSPHRASE }} + + release: + uses: cloudposse/github-actions-workflows/.github/workflows/controller-draft-release.yml@main + needs: [ cd ] + ``` + + + + + + ```yaml + name: 3 - Release + on: + release: + types: [published] + + permissions: + id-token: write + contents: write + + concurrency: + group: ${{ github.workflow }} + cancel-in-progress: false + + jobs: + monorepo: + uses: cloudposse/github-actions-workflows/.github/workflows/controller-monorepo.yml@main + with: + file: ./deploy/config.yaml + + ci: + uses: cloudposse/github-actions-workflows/.github/workflows/ci-dockerized-app-promote.yml@main + needs: [ monorepo ] + with: + organization: "cloudposse" + repository: ${{ github.event.repository.name }} + version: ${{ github.event.release.tag_name }} + secrets: + ecr-region: ${{ secrets.ECR_REGION }} + ecr-iam-role: ${{ secrets.ECR_IAM_ROLE }} + registry: ${{ secrets.ECR_REGISTRY }} + secret-outputs-passphrase: ${{ secrets.GHA_SECRET_OUTPUT_PASSPHRASE }} + + cd: + uses: cloudposse/github-actions-workflows/.github/workflows/cd-ecspresso.yml@main + needs: [ ci, monorepo ] + strategy: + matrix: + app: ${{ fromJson(needs.monorepo.outputs.apps) }} + with: + image: ${{ needs.ci.outputs.image }} + tag: ${{ needs.ci.outputs.tag }} + repository: ${{ github.event.repository.name }} + app: ${{ matrix.app }} + environment: "staging" + enable-migration: ${{ contains(fromJSON(needs.monorepo.outputs.migrations), matrix.app) }} + settings: ${{ needs.monorepo.outputs.settings }} + secrets: + secret-outputs-passphrase: ${{ secrets.GHA_SECRET_OUTPUT_PASSPHRASE }} + ``` + + -
## References - [Ecspresso](https://github.com/kayac/ecspresso) : Tool repo diff --git a/docs/layers/software-delivery/eks-argocd/eks-argocd.mdx b/docs/layers/software-delivery/eks-argocd/eks-argocd.mdx index aefc215fe..9d6dc0bc8 100644 --- a/docs/layers/software-delivery/eks-argocd/eks-argocd.mdx +++ b/docs/layers/software-delivery/eks-argocd/eks-argocd.mdx @@ -8,6 +8,7 @@ import KeyPoints from '@site/src/components/KeyPoints'; import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import Note from '@site/src/components/Note'; +import CollapsibleText from '@site/src/components/CollapsibleText'; Argo CD is an open-source declarative, GitOps continuous delivery tool for Kubernetes applications. It enables developers to manage and deploy applications on Kubernetes clusters using Git repositories as the source of truth for configuration and definitions. Argo CD follows the GitOps methodology, which means that the entire application configuration, including manifests, parameters, and even application state, is stored in a Git repository. @@ -97,106 +98,105 @@ sequenceDiagram Application repository will create a deployment when a workflow is triggered and call the relevant shared workflow. -
-Deploy +:::tip Latest Examples - - - - -```yaml -# .github/workflows/feature-branch.yaml -name: Feature Branch -on: - pull_request: - branches: [ 'main' ] - types: [opened, synchronize, reopened, closed, labeled, unlabeled] - -permissions: - pull-requests: write - deployments: write - id-token: write - contents: read - -jobs: - do: - uses: cloudposse/github-actions-workflows-docker-ecr-eks-helm-argocd/.github/workflows/feature-branch.yml@main - with: - organization: "${{ github.event.repository.owner.login }}" - repository: "${{ github.event.repository.name }}" - open: ${{ github.event.pull_request.state == 'open' }} - labels: ${{ toJSON(github.event.pull_request.labels.*.name) }} - ref: ${{ github.event.pull_request.head.ref }} - secrets: - github-private-actions-pat: "${{ secrets.PUBLIC_REPO_ACCESS_TOKEN }}" - registry: "${{ secrets.ECR_REGISTRY }}" - secret-outputs-passphrase: "${{ secrets.GHA_SECRET_OUTPUT_PASSPHRASE }}" - ecr-region: "${{ secrets.ECR_REGION }}" - ecr-iam-role: "${{ secrets.ECR_IAM_ROLE }}" -``` - - - - - -```yaml -# .github/workflows/main-branch.yaml -name: Main Branch -on: - push: - branches: [ main ] - -permissions: - contents: write - id-token: write - -jobs: - do: - uses: cloudposse/github-actions-workflows-docker-ecr-eks-helm-argocd/.github/workflows/main-branch.yml@main - with: - organization: "${{ github.event.repository.owner.login }}" - repository: "${{ github.event.repository.name }}" - secrets: - github-private-actions-pat: "${{ secrets.PUBLIC_REPO_ACCESS_TOKEN }}" - registry: "${{ secrets.ECR_REGISTRY }}" - secret-outputs-passphrase: "${{ secrets.GHA_SECRET_OUTPUT_PASSPHRASE }}" - ecr-region: "${{ secrets.ECR_REGION }}" - ecr-iam-role: "${{ secrets.ECR_IAM_ROLE }}" -``` - - - - +Check out our [example-app-on-eks](https://github.com/cloudposse-examples/app-on-eks-with-argocd) for the latest example of how to use ArgoCD with GitHub Actions. -```yaml -# .github/workflows/release.yaml -name: Release -on: - release: - types: [published] - -permissions: - id-token: write - contents: write - -jobs: - perform: - uses: cloudposse/github-actions-workflows-docker-ecr-eks-helm-argocd/.github/workflows/release.yml@main - with: - organization: "${{ github.event.repository.owner.login }}" - repository: "${{ github.event.repository.name }}" - version: ${{ github.event.release.tag_name }} - secrets: - github-private-actions-pat: "${{ secrets.PUBLIC_REPO_ACCESS_TOKEN }}" - registry: "${{ secrets.ECR_REGISTRY }}" - secret-outputs-passphrase: "${{ secrets.GHA_SECRET_OUTPUT_PASSPHRASE }}" - ecr-region: "${{ secrets.ECR_REGION }}" - ecr-iam-role: "${{ secrets.ECR_IAM_ROLE }}" -``` +::: - + + + + ```yaml + # .github/workflows/feature-branch.yaml + name: Feature Branch + on: + pull_request: + branches: [ 'main' ] + types: [opened, synchronize, reopened, closed, labeled, unlabeled] + + permissions: + pull-requests: write + deployments: write + id-token: write + contents: read + + jobs: + do: + uses: cloudposse/github-actions-workflows-docker-ecr-eks-helm-argocd/.github/workflows/feature-branch.yml@main + with: + organization: "${{ github.event.repository.owner.login }}" + repository: "${{ github.event.repository.name }}" + open: ${{ github.event.pull_request.state == 'open' }} + labels: ${{ toJSON(github.event.pull_request.labels.*.name) }} + ref: ${{ github.event.pull_request.head.ref }} + secrets: + github-private-actions-pat: "${{ secrets.PUBLIC_REPO_ACCESS_TOKEN }}" + registry: "${{ secrets.ECR_REGISTRY }}" + secret-outputs-passphrase: "${{ secrets.GHA_SECRET_OUTPUT_PASSPHRASE }}" + ecr-region: "${{ secrets.ECR_REGION }}" + ecr-iam-role: "${{ secrets.ECR_IAM_ROLE }}" + ``` + + + + + ```yaml + # .github/workflows/main-branch.yaml + name: Main Branch + on: + push: + branches: [ main ] + + permissions: + contents: write + id-token: write + + jobs: + do: + uses: cloudposse/github-actions-workflows-docker-ecr-eks-helm-argocd/.github/workflows/main-branch.yml@main + with: + organization: "${{ github.event.repository.owner.login }}" + repository: "${{ github.event.repository.name }}" + secrets: + github-private-actions-pat: "${{ secrets.PUBLIC_REPO_ACCESS_TOKEN }}" + registry: "${{ secrets.ECR_REGISTRY }}" + secret-outputs-passphrase: "${{ secrets.GHA_SECRET_OUTPUT_PASSPHRASE }}" + ecr-region: "${{ secrets.ECR_REGION }}" + ecr-iam-role: "${{ secrets.ECR_IAM_ROLE }}" + ``` + + + + + ```yaml + # .github/workflows/release.yaml + name: Release + on: + release: + types: [published] + + permissions: + id-token: write + contents: write + + jobs: + perform: + uses: cloudposse/github-actions-workflows-docker-ecr-eks-helm-argocd/.github/workflows/release.yml@main + with: + organization: "${{ github.event.repository.owner.login }}" + repository: "${{ github.event.repository.name }}" + version: ${{ github.event.release.tag_name }} + secrets: + github-private-actions-pat: "${{ secrets.PUBLIC_REPO_ACCESS_TOKEN }}" + registry: "${{ secrets.ECR_REGISTRY }}" + secret-outputs-passphrase: "${{ secrets.GHA_SECRET_OUTPUT_PASSPHRASE }}" + ecr-region: "${{ secrets.ECR_REGION }}" + ecr-iam-role: "${{ secrets.ECR_IAM_ROLE }}" + ``` + + -
That workflow calls a Reusable Workflow, `cloudposse/github-actions-workflows-docker-ecr-eks-helm-argocd`, that is designed to deploy a dockerized application from ECR to EKS using ArgoCD specifically. @@ -207,114 +207,110 @@ Hotfix workflows are designed to push changes directly to a released version in In order to enable hotfix workflows, create two additional workflows and modify the existing release workflow. See each of the following workflows: -
-Hotfix Workflows - - - -Before running any hotfix workflows, we must first create release branches with any release. Modify the existing release workflow to include the `hotfix` job below. - -```yaml -# .github/workflows/release.yaml -name: Release -on: - release: - types: [published] - -permissions: - id-token: write - contents: write - -jobs: - perform: - ... - - hotfix: - name: release / branch - uses: cloudposse/github-actions-workflows-docker-ecr-eks-helm-argocd/.github/workflows/hotfix-mixin.yml@main - with: - version: ${{ github.event.release.tag_name }} -``` - - - - -This `hotfix-branch.yaml` workflow will deploy a duplicate app in the _production_ cluster to a new namespace. We need to deploy to production to validate a hotfix directly for production. - -Deploy this workflow by creating a Pull Request into the a release branch and adding the `deploy` label. - -```yaml -# .github/workflows/hotfix-branch.yaml -name: Hotfix Branch -on: - pull_request: - branches: [ 'release/**' ] - types: [opened, synchronize, reopened, closed, labeled, unlabeled] - -permissions: - pull-requests: write - deployments: write - id-token: write - contents: read - -jobs: - do: - uses: cloudposse/github-actions-workflows-docker-ecr-eks-helm-argocd/.github/workflows/hotfix-branch.yml@main - with: - organization: "${{ github.event.repository.owner.login }}" - repository: "${{ github.event.repository.name }}" - open: ${{ github.event.pull_request.state == 'open' }} - labels: ${{ toJSON(github.event.pull_request.labels.*.name) }} - ref: ${{ github.event.pull_request.head.ref }} - path: deploy - secrets: - github-private-actions-pat: "${{ secrets.PRIVATE_REPO_ACCESS_TOKEN }}" - registry: "${{ secrets.ECR_REGISTRY }}" - secret-outputs-passphrase: "${{ secrets.GHA_SECRET_OUTPUT_PASSPHRASE }}" - ecr-region: "${{ secrets.ECR_REGION }}" - ecr-iam-role: "${{ secrets.ECR_IAM_ROLE }}" -``` - - - - -Once we've validated a Pull Request for a given hotfix, we can merge that change into the release branch. When changes are pushed to a release branch, the "Hotfix Release" workflow is triggered. _This workflow will deploy the given change directly to production_. - -Before deploying, the workflow will create a minor version release and test it. -After the deployment, it will create a reintegration pull request to bring the hotfix back into the main branch and lower environments. - -In order to enable the "Hotfix Release" workflow, add the following: - -```yaml -# .github/workflows/hotfix-release.yaml -name: Hotfix Release -on: - push: - branches: [ 'release/**' ] - -permissions: - contents: write - id-token: write - -jobs: - do: - uses: cloudposse/github-actions-workflows-docker-ecr-eks-helm-argocd/.github/workflows/hotfix-release.yml@main - with: - organization: "${{ github.event.repository.owner.login }}" - repository: "${{ github.event.repository.name }}" - path: deploy - secrets: - github-private-actions-pat: "${{ secrets.PRIVATE_REPO_ACCESS_TOKEN }}" - registry: "${{ secrets.ECR_REGISTRY }}" - secret-outputs-passphrase: "${{ secrets.GHA_SECRET_OUTPUT_PASSPHRASE }}" - ecr-region: "${{ secrets.ECR_REGION }}" - ecr-iam-role: "${{ secrets.ECR_IAM_ROLE }}" -``` - - + + Before running any hotfix workflows, we must first create release branches with any release. Modify the existing release workflow to include the `hotfix` job below. + + ```yaml + # .github/workflows/release.yaml + name: Release + on: + release: + types: [published] + + permissions: + id-token: write + contents: write + + jobs: + perform: + ... + + hotfix: + name: release / branch + uses: cloudposse/github-actions-workflows-docker-ecr-eks-helm-argocd/.github/workflows/hotfix-mixin.yml@main + with: + version: ${{ github.event.release.tag_name }} + ``` + + + + This `hotfix-branch.yaml` workflow will deploy a duplicate app in the _production_ cluster to a new namespace. We need to deploy to production to validate a hotfix directly for production. + + Deploy this workflow by creating a Pull Request into the a release branch and adding the `deploy` label. + + + ```yaml + # .github/workflows/hotfix-branch.yaml + name: Hotfix Branch + on: + pull_request: + branches: [ 'release/**' ] + types: [opened, synchronize, reopened, closed, labeled, unlabeled] + + permissions: + pull-requests: write + deployments: write + id-token: write + contents: read + + jobs: + do: + uses: cloudposse/github-actions-workflows-docker-ecr-eks-helm-argocd/.github/workflows/hotfix-branch.yml@main + with: + organization: "${{ github.event.repository.owner.login }}" + repository: "${{ github.event.repository.name }}" + open: ${{ github.event.pull_request.state == 'open' }} + labels: ${{ toJSON(github.event.pull_request.labels.*.name) }} + ref: ${{ github.event.pull_request.head.ref }} + path: deploy + secrets: + github-private-actions-pat: "${{ secrets.PRIVATE_REPO_ACCESS_TOKEN }}" + registry: "${{ secrets.ECR_REGISTRY }}" + secret-outputs-passphrase: "${{ secrets.GHA_SECRET_OUTPUT_PASSPHRASE }}" + ecr-region: "${{ secrets.ECR_REGION }}" + ecr-iam-role: "${{ secrets.ECR_IAM_ROLE }}" + ``` + + + + Once we've validated a Pull Request for a given hotfix, we can merge that change into the release branch. When changes are pushed to a release branch, the "Hotfix Release" workflow is triggered. _This workflow will deploy the given change directly to production_. + + Before deploying, the workflow will create a minor version release and test it. + After the deployment, it will create a reintegration pull request to bring the hotfix back into the main branch and lower environments. + + In order to enable the "Hotfix Release" workflow, add the following: + + + ```yaml + # .github/workflows/hotfix-release.yaml + name: Hotfix Release + on: + push: + branches: [ 'release/**' ] + + permissions: + contents: write + id-token: write + + jobs: + do: + uses: cloudposse/github-actions-workflows-docker-ecr-eks-helm-argocd/.github/workflows/hotfix-release.yml@main + with: + organization: "${{ github.event.repository.owner.login }}" + repository: "${{ github.event.repository.name }}" + path: deploy + secrets: + github-private-actions-pat: "${{ secrets.PRIVATE_REPO_ACCESS_TOKEN }}" + registry: "${{ secrets.ECR_REGISTRY }}" + secret-outputs-passphrase: "${{ secrets.GHA_SECRET_OUTPUT_PASSPHRASE }}" + ecr-region: "${{ secrets.ECR_REGION }}" + ecr-iam-role: "${{ secrets.ECR_IAM_ROLE }}" + ``` + + + -
These workflows also call the same Reusuable Workflow repository, `cloudposse/github-actions-workflows-docker-ecr-eks-helm-argocd`, as well as several of the same Reusuable Workflows called from that repository. For example, `cloudposse/github-actions-workflows` and `cloudposse/actions-private`. diff --git a/docs/layers/software-delivery/lambda/lambda.mdx b/docs/layers/software-delivery/lambda/lambda.mdx index 72ee82cdd..af30e99cc 100644 --- a/docs/layers/software-delivery/lambda/lambda.mdx +++ b/docs/layers/software-delivery/lambda/lambda.mdx @@ -8,6 +8,7 @@ import Intro from '@site/src/components/Intro'; import KeyPoints from '@site/src/components/KeyPoints'; import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; +import CollapsibleText from '@site/src/components/CollapsibleText'; Deploy Lambda functions using GitHub Workflows with a code-driven approach. The build process updates S3 with assets and SSM with the new version, requiring a Terraform run for promotion. GitHub Workflows manage the entire lifecycle, from building and packaging Lambda functions to deploying them with reusable workflows. @@ -58,184 +59,178 @@ flowchart LR Application repository updates S3 with build assets, then updates SSM with the new version. Each SSM update is basically a promotion, and requires a Terraform run to realize the change. -
-Build and Dev Promote - - - - ```yaml - # .github/workflows/reusable-publish-lambda-zip.yaml - name: Publish Lambda Function - on: - workflow_call: - inputs: - function-name: - required: true - type: string - source-folder: - required: true - type: string - artifacts-bucket-and-prefix: - required: true - type: string - aws-region: - required: true - type: string - secrets: - cicd-role-arn: - required: true - - permissions: - id-token: write - contents: read - - jobs: - publish: - runs-on: self-hosted - steps: - - name: Configure AWS credentials - uses: aws-actions/configure-aws-credentials@v4 - with: - role-to-assume: ${{ inputs.cicd-role-arn }} - aws-region: ${{ inputs.aws-region }} - - name: Checkout - uses: actions/checkout@v4 - - name: Package Lambda - run: | - cd ${{ inputs.source-folder }} && zip ${{ github.sha }}.zip * - - name: Push Lambda - run: | - aws s3 cp ${{ inputs.source-folder }}/${{ github.sha }}.zip s3://${{ inputs.artifacts-bucket-and-prefix }}/${{ inputs.function-name }}/ --sse - - name: Write tag to SSM - run: | - aws ssm put-parameter --name /lambda/${{ inputs.function-name}}/tag --type String --value ${{ github.sha }} --overwrite - ``` - + + ```yaml + # .github/workflows/reusable-publish-lambda-zip.yaml + name: Publish Lambda Function + on: + workflow_call: + inputs: + function-name: + required: true + type: string + source-folder: + required: true + type: string + artifacts-bucket-and-prefix: + required: true + type: string + aws-region: + required: true + type: string + secrets: + cicd-role-arn: + required: true + + permissions: + id-token: write + contents: read + + jobs: + publish: + runs-on: self-hosted + steps: + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ inputs.cicd-role-arn }} + aws-region: ${{ inputs.aws-region }} + - name: Checkout + uses: actions/checkout@v4 + - name: Package Lambda + run: | + cd ${{ inputs.source-folder }} && zip ${{ github.sha }}.zip * + - name: Push Lambda + run: | + aws s3 cp ${{ inputs.source-folder }}/${{ github.sha }}.zip s3://${{ inputs.artifacts-bucket-and-prefix }}/${{ inputs.function-name }}/ --sse + - name: Write tag to SSM + run: | + aws ssm put-parameter --name /lambda/${{ inputs.function-name}}/tag --type String --value ${{ github.sha }} --overwrite + ``` + - - - ```yaml - # .github/workflows/reusable-promote-lambda-zip.yaml - name: Publish Lambda Function - on: - workflow_call: - inputs: - function-name: - required: true - type: string - artifacts-bucket-and-prefix: - required: true - type: string - aws-region: - required: true - type: string - secrets: - cicd-role-arn: - required: true - staging-role-arn: - required: true - prod-role-arn: - required: true - - permissions: - id-token: write - contents: read - - jobs: - publish: - runs-on: self-hosted - steps: - - name: Configure AWS credentials for 'cicd' role - uses: aws-actions/configure-aws-credentials@v4 - with: - role-to-assume: ${{ inputs.cicd-role-arn }} - aws-region: ${{ inputs.aws-region }} - - name: Configure AWS credentials for source stage - 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 }} - role-duration-seconds: 3000 - role-skip-session-tagging: true - role-to-assume: ${{ inputs.staging-role-arn }} - aws-region: ${{ inputs.aws-region }} - - name: Checkout - uses: actions/checkout@v4 - - name: Get tag from SSM - id: get-tag-from-ssm - run: | - TAG=`aws ssm get-parameter --name /lambda/${{ inputs.function-name }}/tag | jq -r .Parameter.Value` - echo "tag=$TAG" >> $GITHUB_OUTPUT - - name: Copy Lambda to local - run: | - aws s3 cp s3://${{ inputs.artifacts-bucket-and-prefix }}/${{ inputs.function-name }}/${{ steps.get-tag-from-ssm.outputs.tag }}.zip . - - name: Configure AWS credentials for 'cicd' role - uses: aws-actions/configure-aws-credentials@v4 - with: - role-to-assume: ${{ inputs.cicd-role-arn }} - aws-region: ${{ inputs.aws-region }} - - name: Configure AWS credentials for destination stage - 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 }} - role-duration-seconds: 3000 - role-skip-session-tagging: true - role-to-assume: ${{ inputs.prod-role-arn }} - aws-region: ${{ inputs.aws-region }} - - name: Copy Lambda to destination bucket - run: | - aws s3 cp ${{ steps.get-tag-from-ssm.outputs.tag }}.zip \ - s3://${{ inputs.artifacts-bucket-and-prefix }}/${{ inputs.function-name }}/ --sse - - name: Write tag to SSM - run: | - aws ssm put-parameter --name /lambda/${{ inputs.function-name}}/tag --type String --value ${{ steps.get-tag-from-ssm.outputs.tag }} --overwrite - ``` - + + ```yaml + # .github/workflows/reusable-promote-lambda-zip.yaml + name: Publish Lambda Function + on: + workflow_call: + inputs: + function-name: + required: true + type: string + artifacts-bucket-and-prefix: + required: true + type: string + aws-region: + required: true + type: string + secrets: + cicd-role-arn: + required: true + staging-role-arn: + required: true + prod-role-arn: + required: true + + permissions: + id-token: write + contents: read + + jobs: + publish: + runs-on: self-hosted + steps: + - name: Configure AWS credentials for 'cicd' role + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ inputs.cicd-role-arn }} + aws-region: ${{ inputs.aws-region }} + - name: Configure AWS credentials for source stage + 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 }} + role-duration-seconds: 3000 + role-skip-session-tagging: true + role-to-assume: ${{ inputs.staging-role-arn }} + aws-region: ${{ inputs.aws-region }} + - name: Checkout + uses: actions/checkout@v4 + - name: Get tag from SSM + id: get-tag-from-ssm + run: | + TAG=`aws ssm get-parameter --name /lambda/${{ inputs.function-name }}/tag | jq -r .Parameter.Value` + echo "tag=$TAG" >> $GITHUB_OUTPUT + - name: Copy Lambda to local + run: | + aws s3 cp s3://${{ inputs.artifacts-bucket-and-prefix }}/${{ inputs.function-name }}/${{ steps.get-tag-from-ssm.outputs.tag }}.zip . + - name: Configure AWS credentials for 'cicd' role + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ inputs.cicd-role-arn }} + aws-region: ${{ inputs.aws-region }} + - name: Configure AWS credentials for destination stage + 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 }} + role-duration-seconds: 3000 + role-skip-session-tagging: true + role-to-assume: ${{ inputs.prod-role-arn }} + aws-region: ${{ inputs.aws-region }} + - name: Copy Lambda to destination bucket + run: | + aws s3 cp ${{ steps.get-tag-from-ssm.outputs.tag }}.zip \ + s3://${{ inputs.artifacts-bucket-and-prefix }}/${{ inputs.function-name }}/ --sse + - name: Write tag to SSM + run: | + aws ssm put-parameter --name /lambda/${{ inputs.function-name}}/tag --type String --value ${{ steps.get-tag-from-ssm.outputs.tag }} --overwrite + ``` + - - ```yaml - # .github/workflows/reusable-promote-lambda-zip.yaml - name: Deploy Lambda via Spacelift - on: - workflow_call: - inputs: - function-name: - required: true - type: string - stack: - required: true - type: string - secrets: - spacelift-api-key-id: - required: true - spacelift-api-key-secret: - required: true - - jobs: - deploy: - runs-on: self-hosted - container: 123456789012.dkr.ecr.us-east-2.amazonaws.com/acme/infra:latest - steps: - - name: Trigger Spacelift Stack Execution - env: - SPACELIFT_API_ENDPOINT: https://acme.app.spacelift.io - SPACELIFT_API_KEY_ID: ${{ secrets.spacelift-api-key-id }} - SPACELIFT_API_KEY_SECRET: ${{ secrets.spacelift-api-key-secret }} - run: | - spacectl stack deploy --id ${{ inputs.stack }}-lambda-${{ inputs.function-name}} --tail - ``` - + + ```yaml + # .github/workflows/reusable-promote-lambda-zip.yaml + name: Deploy Lambda via Spacelift + on: + workflow_call: + inputs: + function-name: + required: true + type: string + stack: + required: true + type: string + secrets: + spacelift-api-key-id: + required: true + spacelift-api-key-secret: + required: true + + jobs: + deploy: + runs-on: self-hosted + container: 123456789012.dkr.ecr.us-east-2.amazonaws.com/acme/infra:latest + steps: + - name: Trigger Spacelift Stack Execution + env: + SPACELIFT_API_ENDPOINT: https://acme.app.spacelift.io + SPACELIFT_API_KEY_ID: ${{ secrets.spacelift-api-key-id }} + SPACELIFT_API_KEY_SECRET: ${{ secrets.spacelift-api-key-secret }} + run: | + spacectl stack deploy --id ${{ inputs.stack }}-lambda-${{ inputs.function-name}} --tail + ``` + -
### Implementation From 26ba3799427fc92430e2a0e20f491d0c4d99d727 Mon Sep 17 00:00:00 2001 From: milldr Date: Fri, 6 Sep 2024 10:12:27 -0400 Subject: [PATCH 2/3] Update example app links for ecs-ecspresso and eks-argocd --- docs/layers/software-delivery/ecs-ecspresso/ecs-ecspresso.mdx | 2 +- docs/layers/software-delivery/eks-argocd/eks-argocd.mdx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/layers/software-delivery/ecs-ecspresso/ecs-ecspresso.mdx b/docs/layers/software-delivery/ecs-ecspresso/ecs-ecspresso.mdx index a69f866eb..9aa3f6600 100644 --- a/docs/layers/software-delivery/ecs-ecspresso/ecs-ecspresso.mdx +++ b/docs/layers/software-delivery/ecs-ecspresso/ecs-ecspresso.mdx @@ -62,7 +62,7 @@ The basic deployment flow is for feature branches. You can use the following sam :::tip Latest Examples -Check out our [example-app-on-ecs](https://github.com/cloudposse-examples/app-on-ecs) for the latest example of how to use `ecspresso` with GitHub Actions. +Check out our [example app-on-ecs](https://github.com/cloudposse-examples/app-on-ecs) for the latest example of how to use `ecspresso` with GitHub Actions. ::: diff --git a/docs/layers/software-delivery/eks-argocd/eks-argocd.mdx b/docs/layers/software-delivery/eks-argocd/eks-argocd.mdx index 9d6dc0bc8..5db87ed98 100644 --- a/docs/layers/software-delivery/eks-argocd/eks-argocd.mdx +++ b/docs/layers/software-delivery/eks-argocd/eks-argocd.mdx @@ -100,7 +100,7 @@ Application repository will create a deployment when a workflow is triggered and :::tip Latest Examples -Check out our [example-app-on-eks](https://github.com/cloudposse-examples/app-on-eks-with-argocd) for the latest example of how to use ArgoCD with GitHub Actions. +Check out our [example app-on-eks-with-argocd](https://github.com/cloudposse-examples/app-on-eks-with-argocd) for the latest example of how to use ArgoCD with GitHub Actions. ::: From 656b9e866781295ecedd96318cec2f9415ad6106 Mon Sep 17 00:00:00 2001 From: milldr Date: Fri, 6 Sep 2024 11:07:51 -0400 Subject: [PATCH 3/3] Update workflow YAML file titles with descriptive names --- .../ecs-ecspresso/ecs-ecspresso.mdx | 6 +++--- .../eks-argocd/eks-argocd.mdx | 18 ++++++------------ .../layers/software-delivery/lambda/lambda.mdx | 9 +++------ 3 files changed, 12 insertions(+), 21 deletions(-) diff --git a/docs/layers/software-delivery/ecs-ecspresso/ecs-ecspresso.mdx b/docs/layers/software-delivery/ecs-ecspresso/ecs-ecspresso.mdx index 9aa3f6600..21a112b14 100644 --- a/docs/layers/software-delivery/ecs-ecspresso/ecs-ecspresso.mdx +++ b/docs/layers/software-delivery/ecs-ecspresso/ecs-ecspresso.mdx @@ -69,7 +69,7 @@ Check out our [example app-on-ecs](https://github.com/cloudposse-examples/app-on - ```yaml + ```yaml title=".github/workflows/feature-branch.yaml" name: 1 - Feature Branch on: pull_request: @@ -132,7 +132,7 @@ Check out our [example app-on-ecs](https://github.com/cloudposse-examples/app-on - ```yaml + ```yaml title=".github/workflows/main-branch.yaml" name: 2 - Main Branch on: push: @@ -191,7 +191,7 @@ Check out our [example app-on-ecs](https://github.com/cloudposse-examples/app-on - ```yaml + ```yaml title=".github/workflows/release.yaml" name: 3 - Release on: release: diff --git a/docs/layers/software-delivery/eks-argocd/eks-argocd.mdx b/docs/layers/software-delivery/eks-argocd/eks-argocd.mdx index 5db87ed98..73ee7a393 100644 --- a/docs/layers/software-delivery/eks-argocd/eks-argocd.mdx +++ b/docs/layers/software-delivery/eks-argocd/eks-argocd.mdx @@ -107,8 +107,7 @@ Check out our [example app-on-eks-with-argocd](https://github.com/cloudposse-exa - ```yaml - # .github/workflows/feature-branch.yaml + ```yaml title=".github/workflows/feature-branch.yaml" name: Feature Branch on: pull_request: @@ -141,8 +140,7 @@ Check out our [example app-on-eks-with-argocd](https://github.com/cloudposse-exa - ```yaml - # .github/workflows/main-branch.yaml + ```yaml title=".github/workflows/main-branch.yaml" name: Main Branch on: push: @@ -169,8 +167,7 @@ Check out our [example app-on-eks-with-argocd](https://github.com/cloudposse-exa - ```yaml - # .github/workflows/release.yaml + ```yaml title=".github/workflows/release.yaml" name: Release on: release: @@ -211,8 +208,7 @@ In order to enable hotfix workflows, create two additional workflows and modify Before running any hotfix workflows, we must first create release branches with any release. Modify the existing release workflow to include the `hotfix` job below. - ```yaml - # .github/workflows/release.yaml + ```yaml title=".github/workflows/release.yaml" name: Release on: release: @@ -240,8 +236,7 @@ In order to enable hotfix workflows, create two additional workflows and modify Deploy this workflow by creating a Pull Request into the a release branch and adding the `deploy` label. - ```yaml - # .github/workflows/hotfix-branch.yaml + ```yaml title=".github/workflows/hotfix-branch.yaml" name: Hotfix Branch on: pull_request: @@ -282,8 +277,7 @@ In order to enable hotfix workflows, create two additional workflows and modify In order to enable the "Hotfix Release" workflow, add the following: - ```yaml - # .github/workflows/hotfix-release.yaml + ```yaml title=".github/workflows/hotfix-release.yaml" name: Hotfix Release on: push: diff --git a/docs/layers/software-delivery/lambda/lambda.mdx b/docs/layers/software-delivery/lambda/lambda.mdx index af30e99cc..3266301a7 100644 --- a/docs/layers/software-delivery/lambda/lambda.mdx +++ b/docs/layers/software-delivery/lambda/lambda.mdx @@ -62,8 +62,7 @@ Each SSM update is basically a promotion, and requires a Terraform run to realiz - ```yaml - # .github/workflows/reusable-publish-lambda-zip.yaml + ```yaml title=".github/workflows/reusable-publish-lambda-zip.yaml" name: Publish Lambda Function on: workflow_call: @@ -113,8 +112,7 @@ Each SSM update is basically a promotion, and requires a Terraform run to realiz - ```yaml - # .github/workflows/reusable-promote-lambda-zip.yaml + ```yaml title=".github/workflows/reusable-promote-lambda-zip.yaml" name: Publish Lambda Function on: workflow_call: @@ -197,8 +195,7 @@ Each SSM update is basically a promotion, and requires a Terraform run to realiz - ```yaml - # .github/workflows/reusable-promote-lambda-zip.yaml + ```yaml title=".github/workflows/reusable-promote-lambda-zip.yaml" name: Deploy Lambda via Spacelift on: workflow_call: