Skip to content

CI/CD from GitHub Actions to AWS

a merge to main runs GitHub Actions, which assumes an IAM role with its OIDC token, then pushes to ECR and deploys to ECS with CloudFormation.

awsgithublogos7 nodes4 groups7 edges
Open full size
CI/CD from GitHub Actions to AWS with OIDC, ECR, CloudFormation and ECSCI/CD from GitHub Actions to AWS with OIDC, ECR, CloudFormation and ECSCI/CD from GitHub Actions to AWS with OIDC, ECR, CloudFormation and ECSCI/CD from GitHub Actions to AWS with OIDC, ECR, CloudFormation and ECS
github-actions-cicd.yamlOn GitHub
# yaml-language-server: $schema=../references/diagram.schema.json
title: CI/CD from GitHub Actions to AWS
subtitle: A merge to main runs a workflow that assumes an IAM role, pushes the image and deploys the stack
direction: down
layout: { merge: false, spacing: compact }

legend:
  solid: Pipeline step
  dotted: Image pull

groups:
  repo: { type: box, label: GitHub repository web-app, icon: github:mark-github }
  cloud: { type: aws:cloud }
  # IAM is a global service, so its role sits in the cloud but outside the Region. Declared before the Region so step 3 reads first.
  global: { type: aws:generic-dashed, label: Global service, in: cloud }
  region: { type: aws:region, label: us-east-1, in: cloud }

nodes:
  dev: { icon: github:person, label: Developer }
  pr: { icon: github:git-pull-request, label: Pull request, note: Checks and review, in: repo }
  actions: { icon: logos:github-actions, label: GitHub Actions, note: deploy.yml on main, in: repo }
  role: { icon: aws:iam-role, label: IAM role, note: Trusts GitHub OIDC, in: global }
  ecr: { icon: aws:ecr, label: Amazon ECR, note: Amazon Elastic Container Registry, in: region }
  stack: { icon: aws:cloudformation, label: AWS CloudFormation, note: App stack, in: region }
  service: { icon: aws:elastic-container-service, label: Amazon ECS, note: Amazon Elastic Container Service on Fargate, in: region }

edges:
  - dev -> pr: { label: open, step: 1 }
  - pr -> actions: { label: merge to main, step: 2 }
  # The job calls sts:AssumeRoleWithWebIdentity with its OIDC token, then pushes and deploys with the temporary credentials.
  - actions -> global: { label: assume role with OIDC, step: 3 }
  - actions -> ecr: { label: push image, step: 4 }
  - actions -> stack: { label: deploy, step: 5 }
  - stack -> service: { label: update service, step: 6 }
  # The service pulls from the registry; laid out ecr -> service, with the arrowhead on the registry.
  - { from: ecr, to: service, arrow: start, line: dotted, label: pull image }

Start from this one

Copies the spec to diagram.yaml, then renders every format.

$ orrery init github-actions-cicd$ orrery render diagram.yaml -f all --theme both