CodeDeployを使ってアプリケーションをEC2インスタンスへデプロイする


はじめに

CodeDeployを使ってEC2インスタンスへアプリケーションをデプロイしたいと思います。
基本的にはコマンドラインを利用しますが、一部難しい部分があるためそこはコンソール操作で行います。

前提条件

以下の準備ができている上で作業を行います。

  • GitHub アカウント: アプリケーションのアップロード先を用意するのに必要です。
  • EC2インスタンス: アプリケーションのデプロイ先で利用します。
    • IAMロールがアタッチされていること。
    • sshとhttpアクセスができること。
  • コマンドインストール
    • gitコマンド: リポジトリへプッシュするのに必要です。
    • aws-cli: CodeDeployやIAMロールを作成するのに利用します。

構成

作業

まずはGitHub関連の設定を行い、その後にCodeDeployの設定を行なっていきます。

GitHub リポジトリの準備

GitHubへログインし [ New ] をクリックします。

Repository nameCodeDeployGitHubDemo を入力し、Public を選択して [ Create repository ] をクリックします。

コマンドラインでリポジトリの初期コミットを行います。

作業ディレクトリの用意
$ mkdir /tmp/CodeDeployGitHubDemo
$ cd /tmp/CodeDeployGitHubDemo
READMEの作成
$ touch README.md
init
$ git init
add
$ git add README.md
commit
$ git commit -m "My first commit"
remote
$ git remote add origin https://github.com/************/CodeDeployGitHubDemo.git
push
$ git push -u origin master

以上でリポジトリの準備が完了です。

アプリケーションをGitHubリポジトリへアップロード

今回はAWSで提供しているサンプルアプリケーションを利用します。
作業は先ほどgitで準備をしたディレクトリで行います。
まず、アプリケーションをダウンロードします。

アプリケーションのダウンロード
$ aws s3 cp s3://aws-codedeploy-ap-northeast-1/samples/latest/SampleApp_Linux.zip . --region ap-northeast-1

リポジトリへアップロードをします。

展開
$ unzip SampleApp_Linux.zip
$ rm SampleApp_Linux.zip
add
$ git add .
commit
$ git commit -m "Added sample app"
push
$ git push

以上でアップロードが完了です。

また、CodeDeployでは appspec.yml というファイルが必要になります。
今回ダウンロードしたコンテンツにはこのファイルが存在するため、そのまま利用します。

appspec.yml
version: 0.0
os: linux
files:
  - source: /index.html
    destination: /var/www/html/
hooks:
  BeforeInstall:
    - location: scripts/install_dependencies
      timeout: 300
      runas: root
    - location: scripts/start_server
      timeout: 300
      runas: root
  ApplicationStop:
    - location: scripts/stop_server
      timeout: 300
      runas: root

ファイルの詳細説明は割愛しますが、簡単に説明すると apacheをインストール して index.html を配置しています。

CodeDeployエージェントのインストール

インスタンスにサインインし、エージェントをインストールします。
まずはエージェントをインストールするために必要なパッケージのインストールです。

必要パッケージのインストール
$ sudo yum install ruby
$ sudo yum install wget

エージェントインストールツールのダウンロードを行います。

インストールツールのダウンロード
$ wget https://aws-codedeploy-ap-northeast-1.s3.ap-northeast-1.amazonaws.com/latest/install
--2021-04-22 05:30:49--  https://aws-codedeploy-ap-northeast-1.s3.ap-northeast-1.amazonaws.com/latest/install
aws-codedeploy-ap-northeast-1.s3.ap-northeast-1.amazonaws.com (aws-codedeploy-ap-northeast-1.s3.ap-northeast-1.amazonaws.com) をDNSに問いあわせています... 52.219.16.215
aws-codedeploy-ap-northeast-1.s3.ap-northeast-1.amazonaws.com (aws-codedeploy-ap-northeast-1.s3.ap-northeast-1.amazonaws.com)|52.219.16.215|:443 に接続しています... 接続しました。
HTTP による接続要求を送信しました、応答を待っています... 200 OK
長さ: 17231 (17K) []
`install' に保存中

100%[==============================================================================================================================>] 17,231      --.-K/s 時間 0s      

今回は東京リージョンですが、もし他のリージョンの場合は aws-codedeploy-ap-northeast-1ap-northeast-1 の部分を以下を参考に変更してください。
地域別のリソースキットバケット名

インストールを行います。

実行権限付与
$ chmod +x ./install
エージェントインストール
$ sudo ./install auto

インストールが完了したら以下のコマンドで起動していることを確認しておきます。

インストール確認
$ sudo service codedeploy-agent status
The AWS CodeDeploy agent is running as PID 7801

以上でCodeDeployエージェントのインストールが完了ですが、たまにうまく起動していない場合があるのでログを確認しておくと良いです。

codedeploy-agent.log
$ tail -f /var/log/aws/codedeploy-agent/codedeploy-agent.log

もし、以下のエラーが出力されていた場合、エージェントがIAMロールをうまく認識できずに起動している状態になります。

ERRORログ
2021-04-22 11:27:13 ERROR [codedeploy-agent(6387)]: InstanceAgent::Plugins::CodeDeployPlugin::CommandPoller: Missing credentials - please check if this instance was started with an IAM instance profile

IAMロールがインスタンスにアタッチされていることを確認した上でエージェントの再起動をしてください。
今回はS3アクセスが不要なため、ロールに必要な権限はありませんが、付与されていないとエージェントエラーとなりCodeDeployを実行した際に失敗となってしまいます。

CodeDeploy で利用するサービスロールの作成

まず、ロールを作成するのに必要な信頼ポリシーを用意します。

信頼ポリシーの作成
$ vim trust-policy.json
trust-policy.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "codedeploy.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

ポリシーを作成したらサービスロールを作成します。

サービスロールの作成
$ aws iam create-role \
  --role-name CodeDeployGitHubDemo-Role \
  --assume-role-policy-document file://trust-policy.json

CodeDeploy で利用するポリシーをアタッチします。

ポリシーのアタッチ
$ aws iam attach-role-policy \
  --role-name CodeDeployGitHubDemo-Role \
  --policy-arn arn:aws:iam::aws:policy/service-role/AWSCodeDeployRole

以上でロールの準備ができました。

CodeDeploy の設定

デプロイするためのアプリケーションとデプロイグループの作成を行います。

アプリケーションの作成

アプリケーション名は CodeDeployGitHubDemo-App で作成します。

アプリケーションの作成
$ aws deploy create-application --application-name CodeDeployGitHubDemo-App

デプロイグループの作成

アプリケーションを作成したらデプロイグループの作成です。
デプロイグループ名は CodeDeployGitHubDemo-DepGrp にします。
また、対象インスタンスを指定するためのタグキーに CodeDeploy を指定し、バリューを Demo を設定します。
これで、CodeDeployタグにDemoという値が設定されているインスタンスに対してデプロイ処理が行われるようになります。

デプロイグループの作成
$ aws deploy create-deployment-group \
  --application-name CodeDeployGitHubDemo-App \
  --ec2-tag-filters Key=CodeDeploy,Type=KEY_AND_VALUE,Value=Demo \
  --deployment-group-name CodeDeployGitHubDemo-DepGrp \
  --service-role-arn arn:aws:iam::123456789012:role/CodeDeployGitHubDemo-Role

デプロイの作成

GitHub連携を行う都合上、初めはコンソールから行う必要があります。
まずは [ デプロイの作成 ] をクリックします。

先ほど作成した デプロイグループ を指定し、リビジョンタイプ のところではGitHubを指定します。
GitHubトークン名 に先ほどアップロードしたGitHubのアカウントを入力すると GitHubに接続 がクリックできるようになるためクリックします。

すると以下のポップアップが表示されるため [ Authorize aws-codesuite ] をクリックします。

次に [ 確認 ] をクリックします。

成功すると リポジトリ名コミットID が表示されるので入力し、一番下にある [ デプロイの作成 ] をクリックして完了です。

以下のような画面へ遷移し、進行中成功 になれば無事にデプロイ完了となります。

ブラウザから対象インスタンスへアクセスすると以下の画面が確認できます。

また、一度GitHub連携できていれば2回目以降はコマンドで実行可能になります。

$ aws deploy create-deployment \
  --application-name CodeDeployGitHubDemo-App \
  --deployment-config-name CodeDeployDefault.OneAtATime \
  --deployment-group-name CodeDeployGitHubDemo-DepGrp \
  --description "My GitHub deployment demo" \
  --github-location repository=************/CodeDeployGitHubDemo,commitId=7e0a45963967c307d837477e74f5d34798a65e68

おわりに

今回、S3を利用しないためIAMロールは不要と思ったのですがないとうまく動かないことがわかりました。
基本を知ることで、一つ一つの設定について理解を深めることができて良かったです。