業界・業務から探す
導入目的・課題から探す
データ・AIについて学ぶ
News
Hakkyについて
ウェビナーコラム
◆トップ【Hakkyの社内Wiki】Strapi
AI

執筆者:Handbook編集部

GitHub Actions経由でAWSのECR/ECSを更新

この記事では AWS のアクセスキーなどの機密情報を GitHub Actions で扱う方法についてまとめます。

OIDC

GitHub Actions のワークフローは、クラウドプロバイダー (AWS、GCP、Azure など) にアクセスしてソフトウェアを配布したりクラウドサービスを利用したりするように設計されていることがよくあります。

OpenID Connect(OIDC)を使用すると、ワークフローの実行時にクレデンシャルを発行し、クラウドへのデプロイ時の認証に使用することが可能になります。このクレデンシャルは一時的であるため永続的なアクセスキーを使用する場合と比較し、漏洩時の悪用リスクを軽減します。クラウドプロバイダーも OIDC をサポートしている必要があり、現在 OIDC をサポートしているプロバイダーは、AWS、Azure、GCP、HashiCorp Vault などです。

info
備考

AWS では OIDC を「Web Identity」、GCP では「Workload Identity」と呼んだりしています。

Github Actions 経由で ECR / ECS を更新

今回は AWS の Web Identity を使っての ECR/ECS の更新を GitHub Actions 経由で行う方法を紹介します。

Terraform で OIDC を設定

以下のコードで OIDC プロバイダーを定義し、それを参照する Role を定義します。

# variables.tf

variable "env" {
  default = "prod"
}

variable "github_provider" {
  default = "arn:aws:iam::<AWS_ACCOUNT_ID>:oidc-provider/token.actions.githubusercontent.com"
}

variable "github_org" {
  default = "mycompany-inc"
}

variable "github_repo" {
  default = "my-repo"
}
# iam.tf

resource "aws_iam_openid_connect_provider" "main" {
  url             = "https://token.actions.githubusercontent.com"
  client_id_list  = ["sts.amazonaws.com"]
  thumbprint_list = ["6938fd4d98bab03faadb97b34396831e3780aea1"]
}

resource "aws_iam_role" "github_actions" {
  name = "${var.env}-github-actions"
  assume_role_policy = jsonencode(
    {
      "Version" = "2012-10-17"
      "Statement" = [
        {
          "Principal" : {
            "Federated" : var.github_provider
          },
          "Action" : [
            "sts:AssumeRoleWithWebIdentity",
          ],
          "Effect" = "Allow",
          "Condition" : {
            "StringLike" : {
              "token.actions.githubusercontent.com:aud" : "sts.amazonaws.com",
              "token.actions.githubusercontent.com:sub" : "repo:${var.github_org}/${var.github_repo}:*"
            }
          },
        }
      ]
    }
  )
}

resource "aws_iam_policy" "github_actions_policy" {
  name = "${var.env}-github-actions-policy"
  policy = jsonencode(
    {
      "Version" : "2012-10-17",
      "Statement" : [
        {
          "Sid" : "ImageUploader",
          "Action" : [
            "ecr:GetDownloadUrlForLayer",
            "ecr:BatchCheckLayerAvailability",
            "ecr:PutImage",
            "ecr:InitiateLayerUpload",
            "ecr:UploadLayerPart",
            "ecr:CompleteLayerUpload",
            "ecr:GetAuthorizationToken",
          ],
          "Effect"   = "Allow",
          "Resource" = "*"
        }
      ],
  })
}

resource "aws_iam_role_policy_attachment" "github_actions_ecr_policy_attachment" {
  policy_arn = aws_iam_policy.github_actions_policy.arn
  role       = aws_iam_role.github_actions.id
}

resource "aws_iam_role_policy_attachment" "github_actions_ecs_full_access" {
  policy_arn = "arn:aws:iam::aws:policy/AmazonECS_FullAccess"
  role       = aws_iam_role.github_actions.id
}

Github Actions の YML ファイルを定義

GitHub の Project の Setting > Secrets から以下の secret を登録します。

  • AWS_ROLE_ARN(Terraform で定義した Role の ARN)
  • AWS_ECR_REPO_NAME
  • TASK_DEFINITION_FAMILY_NAME
  • ECS_CLUSTER_NAME

そしてリポジトリの.github/workflows/deploy.ymlに以下のようなymlファイルを記述します。

# .github/workflows/deploy.yml

name: Deploy

on:
  push:
    branches:
      - main

permissions:
  id-token: write
  contents: read

jobs:
  build-and-push:
    runs-on: ubuntu-18.04
    steps:
      - name: Checkout
        uses: actions/checkout@v1

      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
          aws-region: ap-northeast-1

      - name: Login to Amazon ECR
        id: login-ecr
        uses: aws-actions/amazon-ecr-login@v1

      - name: Build and push api image to Amazon ECR
        env:
          ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
          ECR_REPOSITORY: ${{ secrets.AWS_ECR_REPO_NAME }}
        run: |
          docker build -t $ECR_REGISTRY/$ECR_REPOSITORY . --no-cache
          docker push $ECR_REGISTRY/$ECR_REPOSITORY

      - name: Download task definition
        env:
          TASK_DEFINITION_FAMILY_NAME: ${{ secrets.TASK_DEFINITION_FAMILY_NAME }}
        run: |
          aws ecs describe-task-definition --task-definition $TASK_DEFINITION_FAMILY_NAME --query taskDefinition > task-definition.json
      - name: Deploy Amazon ECS task definition
        uses: aws-actions/amazon-ecs-deploy-task-definition@v1
        with:
          task-definition: task-definition.json
          service: ${{ secrets.TASK_DEFINITION_FAMILY_NAME }}
          cluster: ${{ secrets.ECS_CLUSTER_NAME }}
          wait-for-service-stability: true

参考

info
備考

Hakky ではエンジニアを募集中です!まずは話してみたいなどでも構いませんので、ぜひお気軽に採用ページからお問い合わせくださいませ。

2025年06月15日に最終更新
読み込み中...