aws codeDeployとbitbucketを連結する

aws codeDeployとbitbucketを連結しようとしたときの覚書としてまとめておく。

流れとしては、以下のような感じ。

  1. awsのIAMの「ユーザー」で、デプロイするユーザを作成する。
  2. codeDeployのサービスロールで利用する、ロールを作成する。
  3. S3 Bucketの作成
  4. EC2インスタンス用のロールを作成して、インスタンスに設定する。
  5. EC2インスタンスでcodeDeploy Agentをインストールする。
  6. codeDeployでデプロイの設定をする。
  7. bitbucketで、pipelinesの有効化と環境変数の設定をする。
  8. bitbucketで管理しているコードにbitbucket-pipelines.yml、codedeploy_deploy.py、appspec.ymlなどのファイルを用意する。

上記まですると、sourcetreeとかで、コミットしてプッシュするとEC2インスタンスに自動的にデプロイされる。

1)awsのIAMの「ユーザー」で、デプロイするユーザを作成する。

ポリシーでは「AWSCodeDeployFullAccess 」と「 AmazonS3FullAccess」にチェックを入れる。

タグはわかりやすいものを設定しておく。「ユーザ作成」ボタンを押すと、ユーザが作成される。このとき、「アクセスIDキー」と「シークレットアクセスキー」が表示されるので、控えておく。なお「シークレットアクセスキー」については、ここ以外では確認できないので注意。

2)codeDeployのサービスロールで利用する、ロールを作成する。

IAMの「ロール」からロールを新規に作成する。

ポリシーは「AWSCodeDeployFullAccess」 と 「AmazonS3FullAccess」 と 「AmazonEC2FullAccess」にチェックを入れる。タグはわかりやすいものを設定する。ロール名についても同様。

3)S3 Bucketの作成。

awsのサービスから「ストレージ」にある「S3」を選択。「バケットを作成する」ボタンを押して作成を開始する。

オプションの設定やアクセス許可の設定はよいように設定する。作成ボタンを押して作成を完了させる。

4)EC2インスタンス用のロールを作成して、インスタンスに設定する。

IAMの「ロール」からEC2インスタンス用のロールを作成する。

ポリシーについては、「ポリシーの作成」ボタンから作成する。

作成するポリシーは「Amazon EC2 インスタンス用の IAM インスタンスプロファイルの作成 (コンソール)」を参考にする。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:Get*",
                "s3:List*"
            ],
            "Resource": [
                "arn:aws:s3:::codedeploy-bucket/*",
                "arn:aws:s3:::aws-codedeploy-us-east-2/*",
                "arn:aws:s3:::aws-codedeploy-us-east-1/*",
                "arn:aws:s3:::aws-codedeploy-us-west-1/*",
                "arn:aws:s3:::aws-codedeploy-us-west-2/*",
                "arn:aws:s3:::aws-codedeploy-ca-central-1/*",
                "arn:aws:s3:::aws-codedeploy-eu-west-1/*",
                "arn:aws:s3:::aws-codedeploy-eu-west-2/*",
                "arn:aws:s3:::aws-codedeploy-eu-west-3/*",
                "arn:aws:s3:::aws-codedeploy-eu-central-1/*",
                "arn:aws:s3:::aws-codedeploy-ap-northeast-1/*",
                "arn:aws:s3:::aws-codedeploy-ap-northeast-2/*",
                "arn:aws:s3:::aws-codedeploy-ap-southeast-1/*",
                "arn:aws:s3:::aws-codedeploy-ap-southeast-2/*",
                "arn:aws:s3:::aws-codedeploy-ap-south-1/*",
                "arn:aws:s3:::aws-codedeploy-sa-east-1/*",
                "arn:aws:s3:::hogehoge-codedeploy-bucket/*"
            ]
        }
    ]
}

「hogehoge-codedeploy-bucket」の部分は、「3)S3 Bucketの作成」で作ったS3バケットの名前を設定しておくこと。設定がないとデプロイの時点でエラーになります。

「ポリシーを確認」ボタンを押す。問題なければ次のページに移動する。

わかりやすい名前をつけて保存する。作成後、「ポリシー作成」ボタンを押した画面にもどり、ポリシーをリロードする。

作成したポリシーにチェックを入れて次のページに移動。タグなどはわかりやすいように設定して作成を完了させる。

作成後、awsのEC2のメニューで、「インスタンス」を選び、ロールを割り当てる。

5)EC2インスタンスでcodeDeploy Agentをインストールする。

AWS CodeDeploy エージェントのインストールまたは再インストール」を参考にEC2インスタンスにCodeDeploy Agentをインストールする。発行するコマンドは以下。

$sudo yum update
$sudo yum install ruby
$sudo yum install wget
$cd /home/ec2-user
$wget https://aws-codedeploy-us-east-1.s3.amazonaws.com/latest/install
$chmod +x ./install
$sudo ./install auto

6)codeDeployでデプロイの設定をする。

awsのサービスの「開発者用ツール」の「codeDeploy」を選ぶ。アプリケーションの作成から開始する。

続いて、デプロイグループの作成に進む。

のような感じで作成する。

7)bitbucketで、pipelinesの有効化と環境変数の設定をする。

bitbucketにアクセスして、設定画面に進み、pipelineのsettingをする。

続いて、Repository variablesよりawsでの登録内容を環境変数として登録する。

APPLICATION_NAME には、6のcodeDeployのアプリケーション作成の際につけた名前を登録する。

AWS_ACCESS_KEY_ID には、1のユーザ作成で取得した、アクセスIDキーの値を登録する。

AWS_DEFAULT_REGION には、EC2インスタンスを利用しているリージョンを登録する。東京の場合は、  ap-northeast-1 です。

AWS_SECRET_ACCESS_KEY には、1のユーザ作成で取得した、シークレットアクセスキーの値を登録する。

DEPLOYMENT_CONFIG には、6のcodeDeployのデプロイグループを作成した際に、選択したデプロイ設定の値を登録する。

DEPLOYMENT_GROUP_NAME には、6のcodeDeployのデプロイグループを作成したときに設定したデプロイグループの名前を登録する。

S3_BUCKET には、3のS3バケットを作成した際に設定したバケット名を登録する。

8)bitbucketで管理しているコードにbitbucket-pipelines.yml、codedeploy_deploy.py、appspec.ymlを用意する。

aws-codedeploy-bitbucket-pipelines-python」で、公開されているサンプルプログラムを利用させていただく。

bitbucket-pipelines.yml、codedeploy_deploy.pyは、bitbucketで管理しているコードのルートディレクトリにコピーする。デプロイを担当しているのは、このスクリプトなので、必要に応じて内容を修正する。

参考)bitbucket-pipelines.yml を設定する

appspec.ymlは、デプロイの作業内容を設定できる。自身の環境に応じて修正して利用する。なお、このファイルもbitbucketで管理しているコードのルートディレクトリに保存する。

参考)AWS CodeDeploy の AppSpec を読み解く

なお、hookスクリプトは、デプロイ後の環境で実行されるわけではないので、注意が必要です。

参考)CodeDeployフックのベストプラクティス

 

上記まで設定すると、問題がなければbitbucketにプッシュするだけで、自動的にEC2インスタンスにデプロイされるようになります。もし何らかの問題がある場合は、bitbucketのpipelineのログか、awsのcodeDeployのデプロイのログから原因を探ることになります。ただ、awsのcodeDeployのエラーはなんのことか分かりづらいので、EC2インスタンスにSSHなどでログインしてデプロイの生ログを見たほうが良いかもしれません。

生ログは、/opt/codedeploy-agent/deployment-root/deployment-logs/ 以下にあります。例えば、awsのcodeDeployのデプロイIDがd-GKQO01VKWなら、/opt/codedeploy-agent/deployment-root/deployment-logs/xxxxxxx/d-GKQO01VKW/ 以下を見るとよいです。

例えば、

InstanceAgent::Plugins::CodeDeployPlugin::CommandPoller: Error during perform: Aws::S3::Errors::AccessDenied - Access Denied - /opt/code
deploy-agent/vendor/gems/aws-sdk-core-2.10.104/lib/seahorse/client/plugins/raise_response_errors.rb:15:in `call'

のようなログがあれば、ロールのポリシーあたりでS3まわりに問題がないか確認するといった作業になります。

あと、AWSのcodeDeployはデプロイグループのアプリケーションのリビジョンを追跡して記録しているそうなので、デプロイ先のディレクトリにファイルとかがあるとエラーになるので注意が必要です。