動作環境
- AWS EC2(Red Hat Enterprise Linux 8.4 )
やりたいこと
mainブランチへのマージをトリガーに、EC2上で git pull
コマンドを実行して最新のコードを反映させたい
というのが今回のやりたいことです。
前提
どうやるか
今回は、github actionsと、AWS Systems Managerを使用して、EC2インスタンス上でコマンドを実行させてみようと思います。
SSM Agentのセットアップ
まず最初のステップは、EC2にSSM Agentをインストールすることです。
インスタンスの種類によってはデフォルトでインストールされているようですが、今回利用するRed Hat Enterprise Linux 8のインスタンスには入っていないので、入れる必要があります。
公式ドキュメントのこちらのページにRHELでのインストール方法が記されていますので、これの通りやります。
RHEL8系のインストール手順を見ると、まずは事前準備としてpython2か3が入っている必要があるようなので、入れます。
$ sudo yum install python3.9
続いて、SSMのインストーラーをダウンロードします。
$ sudo dnf install -y https://s3.ap-northeast-1.amazonaws.com/amazon-ssm-ap-northeast-1/latest/linux_amd64/amazon-ssm-agent.rpm
無事完了すると、SSM Agentのサービスプロセスが起動していることを確認できます。
$ sudo systemctl status amazon-ssm-agent ● amazon-ssm-agent.service - amazon-ssm-agent Loaded: loaded (/etc/systemd/system/amazon-ssm-agent.service; enabled; vendor preset: disabled) Active: active (running) since Sun 2021-08-15 23:41:54 JST; 42s ago Main PID: 20343 (amazon-ssm-agen) Tasks: 13 (limit: 4821) Memory: 27.3M CGroup: /system.slice/amazon-ssm-agent.service ├─20343 /usr/bin/amazon-ssm-agent └─20397 /usr/bin/ssm-agent-worker
IAM Roleの作成
続いて、EC2に付与するIAMロールの作成を行います。
management consoleからやります。
IAMのコンソールからロールの作成に行き、ユースケースとしてEC2を選択します。
続いて、ポリシーを付与する画面で、「AmazonEC2RoleforSSM」と検索して、出てきたポリシーを付与します。
あとは、お好きな名前とdescriptionを書いてRoleを作成して、EC2インスタンスに付与してください。
AWSコンソール上でRun Commandする
github actionsの設定に入る前に、SSM Run Commandが動くかどうかの確認と、github actions上で実行するコマンドを明らかにしておきましょう。
そのために、AWSコンソール上からRun Commandを実行し、git pull
コマンドを実行させてみます。
AWS SSMのコンソールの左のナビゲーションの中に、「Run Command」があるので、そこから「コマンドの実行」へ移ります。
コマンドドキュメントとして「AWS-RunShellScript」を選びます。
コマンドのパラメータの入力欄に、実行したいコマンドを書き込みます。
注意点として、SSMのRun Commandはrootユーザーで実行されてしまうので、ec2-userでgitの設定を行なっている場合はうまく動きません。
git pullコマンドを実行するときは、sudo -u ec2-user git pull
とすることでec2-userとして実行させましょう。
次に、ターゲットとして、コマンドを実行したいEC2を選びます。 タグやリソースグループでの指定も行えるようですが、今回はインスタンスを手動で選択します。
SSMのRun Commandのコンソールでは、親切にもAWS CLIで同じRun Commandを実行する際のコマンドを自動で生成してくれていますので、控えておきましょう。
実行し、しばらくすると成功か失敗かわかります。
github actions上からRun Commandを実行する
すでにSSM Run Commandを実行するコマンドはわかっているので、あとはGithub Actionsから実行してやるだけです。
.github/workflows/ 配下にyamlを作成し、以下のように書きます。
name: Deploy to Sandbox on: push: branches: - main env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} jobs: deploy: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v2 - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v1 with: aws-access-key-id: ${{ env.AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ env.AWS_SECRET_ACCESS_KEY }} aws-region: ap-northeast-1 - name: Execute SSM Run Command id: exec run: | export RESPONSE=$(aws ssm send-command --document-name "AWS-RunShellScript" --document-version "1" --targets '[{"Key":"InstanceIds","Values":["i-078b1fde3fc75d7fb"]}]' --parameters '{"workingDirectory":[""],"executionTimeout":["3600"],"commands":["cd /home/ec2-user/grpc-sample/", "sudo -u ec2-user git pull"]}' --timeout-seconds 600 --max-concurrency "50" --max-errors "0" --region ap-northeast-1) export COMMAND_ID=$(echo $RESPONSE | jq .Command.CommandId) echo "::set-output name=commandId::${COMMAND_ID}" - name: Check Run Command Result run: | bash -x ./.github/scripts/check_command_result.sh ${{ steps.exec.outputs.commandId }}
「Execute SSM Run Command」のステップでRun Commandを実行した後に、「Check Run Command Result」のステップで、Run Commandの成否をチェックしています。
シェルスクリプトで実行していて、そのコードは以下の通りです。
#!/bin/bash function succeeded () { status=$(aws ssm get-command-invocation --command-id $1 --instance-id ご自身のEC2インスタンスIDに書き換えてください | jq .Status) if [ $status = "Success" ]; then echo true else echo false fi } commandId=$1 i=1 while [ $i -le 10 ]; do succeeded=$(succeeded $commandId) if [ $succeeded ]; then exit 0 fi i=$($i + 1 ) sleep 3 done exit 1