こんにちは。システム開発事業部の辻井です。
今回は、Github ActionsとAWS CodeDeployの2つを使ってEC2上で動作しているアプリケーションの自動デプロイについてお話したいと思います。
OIDC(OpenID Connect)を使って実装していきます。
手順
AWS IAM
- IDプロバイダの作成
まず、AWSコンソール上からIAMに入り、IDプロバイダの作成を行います。
以下の内容で作成します。1タイプ:OpenID Connect 2URL:https://token.actions.githubusercontent.com 3対象者:sts.amazonaws.com
- 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
- IAMポリシーをアタッチ
CodeDeploy Agentのインストール、EC2からCodeDeployにアクセスできるように以下のポリシーをEC2に紐づけているIAMロールにアタッチします。1- AmazonEC2RoleforAWSCodeDeploy(S3のGetObject、GetObjectVersion、ListObjectが既に紐づいているなら不要) 2- AWSCodeDeployRole
- CodeDeployエージェントのインストール、起動
公式の手順に基づいてEC2内にコードデプロイエージェントをインストールします。
https://docs.aws.amazon.com/ja_jp/codedeploy/latest/userguide/codedeploy-agent-operations-install-linux.html
systemctl start codedeploy-agent を実行して起動まで行っておきましょう。
AWS CodeDeploy
- アプリケーションの作成
アプリケーション名とコンピューティングプラットフォームを選択します。EC2/オンプレミス、ECS、Lambdaに対応してますが、今回はEC2への自動デプロイなのでEC2/オンプレミスで作成します。1アプリケーション名 : 任意の名前 2コンピューティングプラットフォーム : EC2/オンプレミス
- デプロイグループの作成
以下の内容でデプロイグループ作成する1デプロイグループ名 : 任意の名前 2サービスロール : IAMロールの作成で作ったCodeDeploy用サービスロールのarn 3デプロイ方法 : インプレース 4環境設定 : Amazon EC2 インスタンス 5タグ : Name - 自動デプロイするEC2のインスタンス名 6デプロイ設定 : CodeDeployDefault.AllAtOnce
Github Actions(リポジトリ側の設定)
- アプリケーションのリポジトリ内に.github/workflowディレクトリを作成します。
- .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
- リポジトリのルートディレクトリにappspec.ymlを作成し、EC2へのデプロイ先を記載します。
hookを使うことで色々なタイミングでスクリプトを実行することが可能になります。
https://docs.aws.amazon.com/ja_jp/codedeploy/latest/userguide/reference-appspec-file-structure-hooks.html#appspec-hooks-server1 # 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に通知するなどの機能をどんどん付け足していきたいですね!