🛠️
GitHub Actions で キャッシュを効かせてDockerビルドをしてECRにデプロイする with Terraform
はじめに
こんにちは。
株式会社ソーシャルPLUSでインフラエンジニアをやっている、isです。
主にAWS、CICD、IaC周りのことを書いていこうと思っています。
概要
-
DockerfileをビルドをしてECRにデプロイするCICDをGitHubActionsで作成します
-
記事を書こうと思ったきっかけ
- GitHubActionsでのキャッシュの効かせ方が近年変わったため備忘録用
- OIDC, Docker Layer Cache, Terraform, GitHubActionsの組み合わせた記事があまりなかったため
- CICDでキャッシュを効かせることでビルド時間が10min -> 3minになったのでキャッシュが大事だということを共有したい
-
この記事でのポイント
- ECRなどAWSの構成をTerraformで管理する
- GitHubActionsとAWSの認証はOpenID Connectを使って認証することでセキュリティを高める
- GitHubActionsでのDockerビルド時にキャッシュを効かせることでCICDの高速化を行う
動作環境
-
GitHubActions
-
AWS
-
DevContainers(Terraformを実行する環境)
-
サンプル
-
今回作成するCICDの構成図
- デプロイするDockerfileはとてもシンプルな物を使用します
FROM python:bullseye
Terraform で ECR + OIDC を作成
main.tf
provider "aws" {
region = "us-east-1"
}
data "aws_caller_identity" "current" {}
data "aws_region" "current" {}
locals {
account_id = data.aws_caller_identity.current.account_id
region = data.aws_region.current.id
}
# ECRリポジトリを作成
resource "aws_ecr_repository" "ECRRepository" {
name = "python-test"
}
# GitHubActionsからECRにPushするための権限を付与
resource "aws_iam_policy" "ecr_push_policy" {
name = "ci-cd-ecr-push"
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
"Effect" : "Allow",
"Action" : [
"ecr:GetDownloadUrlForLayer",
"ecr:BatchGetImage",
"ecr:BatchCheckLayerAvailability",
"ecr:PutImage",
"ecr:InitiateLayerUpload",
"ecr:UploadLayerPart",
"ecr:CompleteLayerUpload"
],
"Resource" : ["arn:aws:ecr:${local.region}:${local.account_id}:repository/${aws_ecr_repository.ECRRepository.name}"]
}
]
})
}
# GitHubActionsで使用するOIDCプロバイダを作成
module "oidc_github" {
source = "unfunco/oidc-github/aws"
version = "1.7.1"
github_repositories = [
"${var.github_organization}/${var.github_repository}"
]
# 作成したECR Push用の権限を付与
iam_role_policy_arns = [
aws_iam_policy.ecr_push_policy.arn
]
}
- 環境変数からGitHubのOrganization名とリポジトリ名を取得するための変数を定義します
variables.tf
variable "github_organization" {
type = string
description = "GithubのOrganization名. or Organizationに所属していない場合Githubのユーザ名"
default = "i-s-23"
}
variable "github_repository" {
type = string
description = "Githubのリポジトリ名"
default = "github-actions-docker-push-terraform"
}
GitHubActions で Dockerビルド + ECRへPushする
-
ActionsでDockerのLayer Cacheを使う方法
- GithubActionsでCacheを使う方法は複数あってややこしいですが今回は
docker/build-push-action
の機能を使います - ActionsのCacheの設定が上手くいっていればActionsの実行画面で確認が可能です
- GithubActionsは追加料金なしでPrivateリポジトリでもリポジトリ毎に10GBまでのキャッシュが利用できる(10GBを超えた分から勝手に消える)のでたいていのCICDで困ることなく使えます
- GithubActionsでCacheを使う方法は複数あってややこしいですが今回は
-
AWSの認証情報で使用するregionとIAM Role ArnはそれぞれGithubActionsのSecretとVariablesに登録する必要があります
.github/workflows/docker-push.yml
name: Docker Build and Push
on:
push:
# mainブランチにPushされた時のみ実行
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
# OIDCで使用するTokenの権限
permissions:
id-token: write
contents: read
steps:
- uses: actions/checkout@v4
- name: Configure AWS credentials # AWSの認証をOIDCで行う設定
uses: aws-actions/configure-aws-credentials@v4.0.1
with:
role-to-assume: ${{ secrets.AWS_IAM_ROLE_ARN }}
aws-region: ${{ vars.AWS_REGION }}
- uses: aws-actions/amazon-ecr-login@v2.0.1 # ECRへのログイン
id: login-ecr
- name: Set up buildx
uses: docker/setup-buildx-action@v3.0.0 # Docker Buildxを使いビルドの高速化を行う
- run: echo "REPOSITORY_NAME=${GITHUB_REPOSITORY#${GITHUB_REPOSITORY_OWNER}/}" >> $GITHUB_ENV
- name: Set up meta data # Dockerイメージにタグを付与
id: meta
uses: docker/metadata-action@v5.3.0
with:
images: |
${{ env.ECR_REGISTRY }}/${{ env.ECR_REPOSITORY }}
tags: |
value=latest
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} # AWSのECRのレジストリ名を取得
ECR_REPOSITORY: python-test
- name: docker build and push ECR
uses: docker/build-push-action@v5.1.0
with:
context: .
platforms: linux/amd64 # アーキテクチャを指定
file: ./Dockerfile
push: true
tags: ${{ steps.meta.outputs.tags }}
cache-from: type=gha # GithubActionsのCacheを使うという設定
cache-to: type=gha,mode=max
provenance: false
- mainブランチにPushされるとCICDが実行されてECRにイメージがPushされます
- このようにECRでLatestのタグが付与された状態になっていれば成功です
- このようにECRでLatestのタグが付与された状態になっていれば成功です
Discussion