hero_picture
Cover Image for EC2上で動作しているアプリケーションに対してAWS CodeDeployとGithub Actions(OIDC)を使って自動デプロイをしてみる

EC2上で動作しているアプリケーションに対してAWS CodeDeployとGithub Actions(OIDC)を使って自動デプロイをしてみる

こんにちは。システム開発事業部の辻井です。

今回は、Github ActionsとAWS CodeDeployの2つを使ってEC2上で動作しているアプリケーションの自動デプロイについてお話したいと思います。

OIDC(OpenID Connect)を使って実装していきます。

手順

AWS IAM

  1. IDプロバイダの作成
    まず、AWSコンソール上からIAMに入り、IDプロバイダの作成を行います。
    以下の内容で作成します。
      1タイプ:OpenID Connect
      2URL:https://token.actions.githubusercontent.com
      3対象者:sts.amazonaws.com
  2. IAMロールの作成
    サイドメニューのIAMロールから、OIDCとCodeDeploy用のIAMロールを作成します。
    カスタム信頼ポリシーを選択してそれぞれ以下の内容で作成していきます。
      1# OIDC用のIAMロール
      2{
      3    "Version": "2012-10-17",
      4    "Statement": [
      5        {
      6            "Sid": "",
      7            "Effect": "Allow",
      8            "Principal": {
      9                "Federated": "arn:aws:iam::<アカウントID>:oidc-provider/token.actions.githubusercontent.com"
      10            },
      11            "Action": "sts:AssumeRoleWithWebIdentity",
      12            "Condition": {
      13                "StringEquals": {
      14                    "token.actions.githubusercontent.com:aud": "sts.amazonaws.com",
      15                    "token.actions.githubusercontent.com:sub": "repo:<githubユーザー名>/<githubリポジトリ名>:ref:refs/heads/<デプロイ先のブランチ名>"
      16                }
      17            }
      18        }
      19    ]
      20}
      1
      2# CodeDeploy用のサービスロール
      3{
      4    "Version": "2012-10-17",
      5    "Statement": [
      6        {
      7            "Sid": "",
      8            "Effect": "Allow",
      9            "Principal": {
      10                "Service": [
      11                    "codedeploy.amazonaws.com"
      12                ]
      13            },
      14            "Action": "sts:AssumeRole"
      15        }
      16    ]
      17}

EC2

  1. IAMポリシーをアタッチ
    CodeDeploy Agentのインストール、EC2からCodeDeployにアクセスできるように以下のポリシーをEC2に紐づけているIAMロールにアタッチします。
      1- AmazonEC2RoleforAWSCodeDeploy(S3のGetObject、GetObjectVersion、ListObjectが既に紐づいているなら不要)
      2- AWSCodeDeployRole
  2. CodeDeployエージェントのインストール、起動
    公式の手順に基づいてEC2内にコードデプロイエージェントをインストールします。
    https://docs.aws.amazon.com/ja_jp/codedeploy/latest/userguide/codedeploy-agent-operations-install-linux.html
    systemctl start codedeploy-agent を実行して起動まで行っておきましょう。

AWS CodeDeploy

  1. アプリケーションの作成
    アプリケーション名とコンピューティングプラットフォームを選択します。EC2/オンプレミス、ECS、Lambdaに対応してますが、今回はEC2への自動デプロイなのでEC2/オンプレミスで作成します。
      1アプリケーション名 : 任意の名前
      2コンピューティングプラットフォーム : EC2/オンプレミス
  2. デプロイグループの作成
    以下の内容でデプロイグループ作成する
      1デプロイグループ名 : 任意の名前
      2サービスロール : IAMロールの作成で作ったCodeDeploy用サービスロールのarn
      3デプロイ方法 : インプレース
      4環境設定 : Amazon EC2 インスタンス
      5タグ : Name - 自動デプロイするEC2のインスタンス名
      6デプロイ設定 : CodeDeployDefault.AllAtOnce

Github Actions(リポジトリ側の設定)

  1. アプリケーションのリポジトリ内に.github/workflowディレクトリを作成します。
  2. .github/workflow内にdeploy.yml(名前は何でもOK)を作成し、以下の内容を記載します。(実際に使う場合はサービスに合わせて内容を修正してください)
      1name: Deploy for production
      2
      3on:
      4  push:
      5    branches:
      6      - <デプロイ先のブランチ名>
      7
      8jobs:
      9  deploy:
      10    runs-on: ubuntu-latest
      11    permissions:
      12      id-token: write
      13      contents: read
      14
      15    steps:
      16      - name: Checkout code
      17        uses: actions/checkout@v3
      18
      19      - name: Configure AWS credentials from OIDC
      20        uses: aws-actions/configure-aws-credentials@v4
      21        with:
      22          aws-region: '<使用しているリージョン>'
      23          role-to-assume: ${{ secrets.IAM_ROLE_ARN }}
      24
      25      - name: Deploy application to CodeDeploy
      26        run: |
      27          aws deploy create-deployment \
      28            --application-name <CodeDeployのアプリ名> \
      29            --deployment-group-name <CodeDeployのデプロイグループ名> \
      30            --github-location repository=<githubユーザー名>/<githubリポジトリ名>,commitId="${{ github.sha }}" \
      31            --file-exists-behavior OVERWRITE
  3. リポジトリのルートディレクトリにappspec.ymlを作成し、EC2へのデプロイ先を記載します。
    hookを使うことで色々なタイミングでスクリプトを実行することが可能になります。
    https://docs.aws.amazon.com/ja_jp/codedeploy/latest/userguide/reference-appspec-file-structure-hooks.html#appspec-hooks-server
      1  # This is an appspec.
      2  version: 0.0
      3  os: linux
      4  
      5  files:
      6   # hookに指定しているスクリプトの情報をそれぞれ記載する。
      7    # BeforeInstall分
      8    - source: <実行するスクリプトのパス>
      9      destination: <実行するスクリプトがあるディレクトリへの絶対パス>
      10    # Install分
      11    - source: <実行するスクリプトのパス>
      12      destination: <実行するスクリプトがあるディレクトリへの絶対パス>
      13    # AfterInstall分
      14    - source: <実行するスクリプトのパス>
      15      destination: <実行するスクリプトがあるディレクトリへの絶対パス>
      16  hooks:
      17	  # hookの例
      18    BeforeInstall:
      19      - location: <実行するスクリプトの相対パス>
      20        runas: root
      21    Install:
      22      - location: <実行するスクリプトの相対パス>
      23        runas: root
      24    AfterInstall:
      25      - location: <実行するスクリプトの相対パス>
      26        runas: root
      27

      npmなどのビルドやphpのcomposer installはすべてが反映し終わったAfterInstallで実行しましょう!

まとめ

いかがでしたでしょうか。

複雑そうに見えて意外と簡単に実装できる内容かと思います。(AWSコンソールをポチポチすることが多いので)

自動デプロイを実装すると本番デプロイが一気に楽になります。

メインブランチに向けているPull Requestのマージボタンを押すだけで本番デプロイが完了するので、わざわざサーバ内に入って移動してgit pullして…という手順が省けます。

まだ簡単なスクリプトしか組んでいないので今後は成否をSlackに通知するなどの機能をどんどん付け足していきたいですね!