ブログ

ryuzeeによるブログ記事。不定期更新
アジャイル開発に取り組むチーム向けのコーチングや、技術顧問、認定スクラムマスター研修などの各種トレーニングを提供しています。ぜひお気軽にご相談ください(初回相談無料)

AWS CodeDeployで簡単デプロイ(CLI編)

全国100万人のデプロイ・プロビジョニング自動化マニアのみなさんこんにちは!

AWSから新たにDeploy用のサービスAWS CodeDeployがリリースされたので早速試してみました。 これを使うと複数のサーバに同時にアプリケーションをリリースするのが簡単にできます。もうCapistranoとかでごちゃごちゃやる必要はない感じです!! 詳細を知りたい方は公式サイトのドキュメントを見てみるとよいです。

ただ、GUIでやるのも面白く無いので、awscliを使ってやっていきましょう!!

EC2インスタンスの準備

まず、us-west-2でEC2インスタンスを何台か起動しましょう。これがデプロイ先のサーバになります。

  • デプロイ先サーバの識別にはEC2インスタンスのタグを利用しますので、同時にデプロイする対象には、同じタグを設定します(EC2のタグのFilterと同じ挙動です)。ここでは起動したインスタンスのNameタグに、sampleapp1_aという名前を設定しました。
  • またデプロイ先のサーバからはAWSのAPIをコールするので、IAM Roleの設定が必要です。

またCodeDeploy用のデーモンをインストールする必要があるので、以下のようなスクリプトを実行します。EC2インスタンスの起動時にUser Dataを使って設定しても構いません。

#!/bin/bash
yum -y update
yum install -y aws-cli
cd /home/ec2-user
wget https://aws-codedeploy-us-west-2.s3.amazonaws.com/latest/install .
chmod +x ./install
./install auto

awscliの最新化

CodeDeployではアプリケーションという単位でデプロイが管理されます。 アプリケーションを作るためにawscliを利用しますので、まずは以下のようにしてawscliを最新化します。

sudo pip install --upgrade awscli

CodeDeployアプリケーションの作成

以下のように実行して、アプリケーションを作ります。

aws deploy create-application \
  --application-name sampleapp1 \
  --region us-west-2

以下のように表示されれば作成は成功です。マネジメントコンソールで、sampleapp1というアプリケーションが作られているのが確認できるはずです。

{
    "applicationId": "0c63b4fc-34ab-42c8-95d7-b9201f45b7b1"
}

Service Roleの作成

CodeDeployがAWSの各サービスとやりとりするためのService Roleを作成します。

role.json

{
    "Version": "2008-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": "sts:AssumeRole",
            "Principal": {
                "Service": [
                    "codedeploy.us-west-2.amazonaws.com",
                    "codedeploy.us-east-1.amazonaws.com"
                ]
            }
        }
    ]
}

作成したら以下を実行します。

aws iam create-role \
  --role-name sampleapp1-role \
  --assume-role-policy-document file://role.json

以下のように実行結果が表示されます。Arnを控えておいてください。

{
    "Role": {
        "AssumeRolePolicyDocument": {
            "Version": "2008-10-17",
            "Statement": [
                {
                    "Action": "sts:AssumeRole",
                    "Principal": {
                        "Service": [
                            "codedeploy.us-west-2.amazonaws.com",
                            "codedeploy.us-east-1.amazonaws.com"
                        ]
                    },
                    "Effect": "Allow",
                    "Sid": ""
                }
            ]
        },
        "RoleId": "AROAIDHZOQ7HEHQNGX3OI",
        "CreateDate": "2014-11-13T06:21:51.216Z",
        "RoleName": "sampleapp1-role",
        "Path": "/",
        "Arn": "arn:aws:iam::660875509136:role/sampleapp1-role"
    }
}

次にRoleのポリシーを設定します。

policy.json

{
    "Version": "2008-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Resource": "*",
            "Action": [
                "ec2:Describe*"
            ]
        },
        {
            "Effect": "Allow",
            "Resource": "*",
            "Action": [
                "autoscaling:CompleteLifecycleAction",
                "autoscaling:DeleteLifecycleHook",
                "autoscaling:DescribeLifecycleHooks",
                "autoscaling:DescribeAutoScalingGroups",
                "autoscaling:PutLifecycleHook",
                "autoscaling:RecordLifecycleActionHeartbeat"
            ]
        }
    ]
}

のように作成し、以下を実行します。

aws iam put-role-policy \
  --role-name sampleapp1-role \
  --policy-name sampleapp1-policy \
  --policy-document file://policy.json

Deployment Groupの作成

Deployment Groupとは、デプロイ対象のサーバ群だと考えると分かりやすいと思います。 例えば5台のWebサーバから構成されるシステムで中身が同じであれば、これを1つのDeployment Groupとして定義することで、アプリケーションを5台にデプロイすることができます。なお、デプロイのタイミングで一気に同時でデプロイする、順番にデプロイする、半分づつデプロイする、とかを決められます。

aws deploy create-deployment-group \
  --application-name sampleapp1 \
  --region us-west-2 \
  --deployment-group-name deploygroup1 \
  --service-role-arn arn:aws:iam::660875509136:role/sampleapp1-role \
  --ec2-tag-filters Key=Name,Value=sampleapp1_a,Type=KEY_AND_VALUE

以下のように表示されれば作成は成功です。

{
    "deploymentGroupId": "c8115519-4784-461a-a5a2-4d407d3dd50d"
}

デプロイ対象のコードの準備

今回はとりあえずawscliでの作業を目的としているので適当な感じでいきます。 まず適当なディレクトリを作成して、そこに移動してください。 CodeDeployでもっとも大事なファイルは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

この例では、/var/www/htmlに、index.htmlを配置すること、デプロイの前にscriptsディレクトリの中のスクリプトを実行し、アプリケーション停止時にも指定した処理を実行するようになっています。(ApplicationStop, BeforeInstall, AfterInstall, ApplicationStart, ValidateServiceが指定でき、順に実行されます) 詳しい説明はAWSのサイトを見るとよいと思います。

またデプロイ対象のindex.htmlやscripts系のファイルは上記の設定にしたがって配置しておきます。

リビジョンを用意する

次にS3にアップします。なお、S3のBucketは、同一リージョンにあることが必要そう(他のリージョンで試したらダメだった)なので、適宜新たに作成してください。(GitHubとの連携もできますが今回は割愛します)

aws deploy push \
  --application-name sampleapp1 \
  --s3-location s3://deploy-test-yoshiba/sampleapp1/app.zip \
  --source ./ \
  --region us-west-2

デプロイの実行

最後に実際のデプロイを実施します。以下のコマンドを実行します。しばらく待つと変更が反映されるはずです。

aws deploy create-deployment \
  --application-name sampleapp1 \
  --s3-location bucket=aws-pro-serve-yoshiba,key=sampleapp1/app.zip,bundleType=zip,eTag="76a2612bb5cf05a86d2da2cde95759e0" \
  --deployment-group-name deploygroup1 \
  --region us-west-2

これでデプロイが実行されて、コードが本番に反映されます。 以降変更を反映する場合は最後の2つの手順だけをおこなえばOKということになります。

らくちんですね!!