BitbucketでAWS CodeDeployを利用した自動デプロイ


Bitbucketでバージョン管理を行い、AWS上のインスタンスでアプリケーションを動かしているけど毎回本番サーバーに入ってpullしている。。自動化したいけどGitHubじゃないので困っている。。そんな人が対象です。

ここでは、Bitbucket Pipelinesを利用し、AWS CodeDeployを使ってEC2へ自動デプロイを行います。

最終的なデータフロー

CodeDeploy用のIAMユーザーを作成する

はじめに、CodeDeploy用のユーザーを新規作成します。

ここではCodeDeployerという名前で作成し、アクセス種類はプログラムによるアクセスを選択しました。
なお、作成後発行されるAccess key IDとSecret access keyはダウンロードして控えておきます。

ポリシーのアタッチ

作成したユーザーに対し、ポリシーを設定します。
ここでは、AWSCodeDeployFullAccess, AmazonS3FullAccessの二つをアタッチすることで、CodeDeployとS3を利用できるように設定します。

CodeDeployロールの作成

次に、CodeDeploy用のロールを作成します。AWSサービス > CodeDeployを選択し、CodeDeployRoleAPIというロール名で作成しました。
ポリシーについては、ここではAmazonEC2FullAccess, AWSCodeDeployRoleを付与しています。

S3 Bucketの作成

ソースコードのリビジョンを格納するバケットを作成します。ここではcodedeploy-bucketという名前で作成しました。

デプロイしたいEC2インスタンスの設定

対象のEC2に、デプロイするインスタンスを識別するためのタグを付与します。
ここではキーをDeploy, 値をCodeDeployに設定しました。

CodeDeploy AgentをEC2インスタンスにインストール

詳しくは公式ドキュメントに書かれていますが、以下の手順でインストールすることができます。

$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

EC2インスタンスのロールを作成

AWSサービスのエンティティを選択後、EC2サービスを選択します
具体的な手順については、こちらに書かれています。

手順通り、ポリシーをJSONで作成します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "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/*"
            ]
        }
    ]
}

このポリシーは、CodeDeploy-EC2-PermissionsAPIという名前で作成しました。
続いてロールの作成に移ります。

このロールは、CodeDeploy-EC2-Instance-Profile-APIという名前で作成しました。

作成したCodeDeployのロールをEC2に割り当てる

インスタンスを選択し、アクション > インスタンスの設定から、IAMロールの割り当て/置換を選択します。

ここで、ロールを後からアタッチしたEC2の場合、CodeDeployに失敗することがあることから、codedeploy-agentの再起動をかけておくと良いです。

$ sudo service codedeploy-agent restart

CodeDeployの設定

AWS側の設定としては最後に、アプリケーションの作成を行います。

デプロイグループの作成を行います。
サービスロールについては先ほど作成したCodeDeployのロールを指定します。
環境設定についても、先ほどEC2に設定したタグを指定します。

今回、デプロイ設定はCodeDeployDefault.OneAtATimeに設定しました。

Bitbucket Pipelinesの設定

前提条件として、Bitbucketにリポジトリがある状態としています。

Pipelinesの有効化

リポジトリの設定 > PipelinesのSettingsから、Enable Piplinesのボタンを押すだけで、簡単に有効化できました。

環境変数の設定

続いて環境変数の設定を行います。
リポジトリの設定 > PipelinesのRepositoly variblesから、以下の項目を設定します。
この環境変数については、次の手順で示すスクリプト内で利用されます。
なお、AWS_ACCESS_KEY_IDとAWS_SECRET_ACCESS_KEYは、デプロイ用のユーザーのものを設定します。

  • AWS_SECRET_ACCESS_KEY
  • AWS_ACCESS_KEY_ID
  • AWS_DEFAULT_REGION
  • APPLICATION_NAME
  • DEPLOYMENT_CONFIG
  • DEPLOYMENT_GROUP_NAME
  • S3_BUCKET

CodeDeployをトリガーするパイプラインの構築

ここでは、AWS LABで用意されているサンプルファイルを利用します。

特に、bitbucket-pipelines.ymlから呼ばれるcodedeploy_deploy.pyについては、BitbucketのリビジョンをAWS S3に載せ、CodeDeployにデプロイを実行させる役割を担っています。
appspec.yml同様、これらのファイルはlocalプロジェクトのルートディレクトリに配置するようにします。

CodeDeployではデプロイグループのリビジョンを監視するため、初めてデプロイするファイルが既にデプロイ先にある場合、上書きできないようになっており、デプロイが失敗してしまうので注意が必要です。

各ファイルの修正

◼︎ bitbucket-pipelines.yml

  • branchesがmasterを向いているので、必要に応じて修正が必要です。
  • 具体的な書き方については、こちらにまとまっています。
  • また、zipコマンドが隠しファイルを対象外としているため、必要であれば- zip -r /tmp/artifact.zip .に修正する必要があります。

◼︎ appspec.ymlおよび各シェルファイル

  • 本記事では省略しますが、こちらの記事を参考に修正しました。

おわり

上手く設定ができて入れば、エラーなくデプロイができるはずです。
エラーが出た場合はPiplinesまたは AWSのCodeDeployのログから原因を突き止めます。

今回はBitbucket上の指定したbranchに更新があればpiplineが動き、AWS上のEC2へ自動デプロイを行う方法をまとめました。

一方、手動でボタン一つ手間はあるもののAWS CodeDeploy for Bitbucketを利用し、比較的簡単に自動デプロイを行う方法も見つけましたので共有します。

参考記事