Illustration by Freepik Stories
CodePipelineは、AWSが提供するCD(継続的デリバリー)サービスです。GitHubやBitBucket等のリポジトリにPushされたアプリケーションを、検証環境や本番環境に自動的にビルド・デプロイできます。 今回はCodePipelineを利用して、GitHubにPushしたアプリケーションをAmazon Lightsailのインスタンスにデプロイする環境を構築します。
作成する環境
この記事では、以下のようなCD環境の構築を目指します。
- GitHubリポジトリのmasterブランチに変更を加える
- CodePipelineが実行される
- Amazon Lightsailのインスタンスに自動的にデプロイされる
全体の流れ
以下のような流れで環境を構築します。
- IAMロールを作成
- S3バケットを作成
- IAMポリシーを作成
- IAMユーザーを作成
- Lightsailインスタンスを作成/CodeDeployエージェントをインストール
- CodeDeployでデプロイするアプリケーションを設定
- GitHubリポジトリとCodePipelineを連携
- appspec.ymlを作成/masterブランチに統合
おおよその作業内容はAWS公式のブログに従います。 適宜参照してください。
メモを用意
すべての工程を完了するまでに、以下のメモを完成させる必要があります。 テキストエディター等にコピーして、必要なタイミングで埋めましょう。
- S3 Bucket Name: <S3のバケットの名称>
- Access Key ID: <アクセスキーID>
- Secret Key: <シークレットキー>
- IAM User ARN: <IAMユーザーARN>
1. IAMロールを作成
はじめにCodeDeploy用のIAMロールを作成します。
IAMのコンソールにアクセスしましょう。
1.1. 「ロール」→「ロールの作成」をクリック
画面左側のペインから「ロール」を選択し「ロールの作成」をクリックします。
1.2. 「AWSサービス」→「CodeDeploy」を選択
ロールの作成画面で「AWSサービス」→「CodeDeploy」を選択します。
1.3.「CodeDeploy」を選択
「ユースケースの選択」で「CodeDeploy」を選択します。
1.4. 確認画面まで進む
確認画面まで「次のステップ」をクリックして進みます。
1.5. 「ロール名」と「ロールの説明」を入力
確認画面で「ロール名」と「ロールの説明」を入力します。
1.6. 「ロールの作成」をクリック
「ロールの作成」をクリックするとロールが作成されます。
2. S3バケットを作成
続いて、S3にバケットを作成します。 GitHubのリポジトリにPushしたコードは、このバケットに保存された後、CodeDeployによってデプロイされます。
S3のコンソールにアクセスします。
2.1.「バケットを作成する」をクリック
2.2.「バケット名」を入力
2.3. バケットを作成
他の設定はそのままに、Step4まで進んでバケットを作成してください。
2.4. バケット名をメモ
バケット名を冒頭で示したメモに記録しましょう。後で使います。
3. IAMポリシーを作成
次に、IAMポリシーを作成します。
再度IAMのコンソールにアクセスします。
3.1. ナビゲーションペインから「ポリシー」を選択→「ポリシーの作成」
画面左側のナビゲーションペインから「ポリシー」を選択します。
そして「ポリシーの作成」をクリックします。
3.2. ポリシーをJOSNで設定
「ポリシーの作成」画面で「JSON」のタブをクリックします。
以下のJSONを入力します。「バケット名」には、先ほどメモしたバケット名を入力します。 たとえば、バケット名が「code-deploy」なら "arn:aws:s3:::/code-deploy*" とします。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:Get*", "s3:List*" ], "Resource": [ "arn:aws:s3:::<メモしたS3バケット名>/*" ] } ] }
入力が完了したら「ポリシーの確認」をクリックします。
3.3. ポリシーの確認
「ポリシーの確認」の画面でポリシーの名前を設定します。 ここでは「CodeDeployS3BucketPolicy」としました。
「ポリシーの作成」をクリックして完了します。
4. IAMユーザーの作成
次に、IAMユーザーを作成します。
再度IAMのコンソールにアクセスしましょう。
4.1. ナビゲーションペインから「ユーザー」を選択
画面左側のナビゲーションペインから「ユーザー」を選択します。
4.2. 「ユーザーを追加」をクリック
「ユーザーを追加」をクリックします。
4.3. 「プログラムによるアクセス」にチェック
「ユーザーを追加」の画面で、ユーザー名を入力し、「プログラムによるアクセス」にチェックを入れます。
4.4. ポリシーをアタッチ
「アクセス許可の設定」で「既存のポリシーを直接アタッチ」をクリックし、先ほど作成したポリシーを検索してチェックを入れます。
4.5. ユーザーを作成
確認画面まで進み「ユーザーの作成」をクリックします。
4.6. キーIDをメモ
ユーザー作成直後の画面でアクセスキーIDとシークレットキーIDをメモします。
4.7. ARNをメモ
「閉じる」をクリックした後に表示されるユーザーの一覧から、作成したユーザー名をクリックします。 「概要」画面でユーザーのARNを確認してメモします。
ここまでで、冒頭に示したメモが完成します。
5. Lightsailのインスタンスを作成し、CodeDeployのエージェントをインストールする
続いて、Amazon Lightsailのインスタンスを作成します。 インスタンスの作成と同時にCodeDeployエージェントのインストールもします。
Lightsailのホームページに移動しましょう。
5.1. 「インスタンスの作成」をクリック
「インスタンスの作成」をクリックします。
5.2. 「OSのみ」→「Amazon Linux」を選択
「プラットフォームの選択」で「Linux/Unix」を選択、 「設計図の選択」で「OSのみ」を選択して「Amazon Linux」を選択します。
5.3. 起動スクリプトの追加
「起動スクリプトの追加」をクリックすると、以下の画像のようなフォームが出てきます。
ここに起動スクリプトとして、以下のテキストを入力します。 <>で囲まれた部分は、これまでに作成したメモの値で置き換えます。 <リージョン>には任意のリージョンを入力します。
mkdir /etc/codedeploy-agent/ mkdir /etc/codedeploy-agent/conf cat <<EOT >> /etc/codedeploy-agent/conf/codedeploy.onpremises.yml --- aws_access_key_id: <アクセスキーID> aws_secret_access_key: <シークレットアクセスキー> iam_user_arn: <IAMユーザーARN> region: <リージョン> EOT wget https://aws-codedeploy-us-west-2.s3.us-west-2.amazonaws.com/latest/install chmod +x ./install sudo ./install auto
5.4. インスタンスを作成
「インスタンスプランの選択」以下で、任意のプランを選択し「インスタンス名」を入力して「インスタンスの作成」をクリックします。
5.5. ターミナルを開く
インスタンスが起動するまで少し待ちます。 起動したら、右上にあるターミナルのアイコンをクリックし、ターミナルを開きます。
5.6. CodeDeployエージェントの起動確認
起動スクリプトが正しく実行され、CodeDeployエージェントが起動していることを確認します。 以下のコマンドを実行します。
sudo service codedeploy-agent status
以下が出力されれば、正しくできています。
The AWS CodeDeploy agent is running as PID <任意のPID>
5.7. インスタンスの登録
続いて、LightsailのインスタンスをCodeDeployに登録します。
ローカルPCのコンソール(ターミナルやコマンドプロンプトなど)を開きます。 下記のコマンドを実行します。<>の部分は、ご自身のメモの値で置き換えてください。
aws deploy register-on-premises-instance --instance-name <インスタンスの名前> --iam-user-arn <IAMユーザーARN> --region <リージョン>
※上記のコマンドはローカルPCのコンソールで実行します。操作の流れでLightsail上のターミナルで実行すると上手く動きません。 参考までに、Lightsail上で実行してしまうと以下のようなエラーになります。LightsailのコンソールではなくローカルPCで実行しましょう。
An error occurred (AccessDeniedException) when calling the RegisterOnPremisesInstance operation: User: arn:aws:sts:: xxx is not authorized to perform: codedeploy:RegisterOnPremisesInstance on resource: arn:aws:codedeploy:xxx
コマンドが正常に実行された場合、何も出力せずに完了します。
5.8. タグ付け
次に、タグを付与します。以下のコマンドをローカルPCのターミナルで実行します。 これまでと同様に<>の部分は、ご自身のメモの値で置き換えてください。
ここで付与したタグは、後でインスタンスを特定するのに使用します。 ここでは「key=Name, Value=CodeDeployLightsail」としました。
aws deploy add-tags-to-on-premises-instances --instance-names <インスタンスの名前> --tags Key=Name,Value=CodeDeployLightsail --region <リージョン>
こちらも正常に実行された場合は何も出力せずに完了します。
5.9. インスタンスの登録を確認
最後に、インスタンスが正常に登録されたことを、以下のコマンドで確認します。
aws deploy list-on-premises-instances --region <リージョン>
作成したインスタンスの名前が表示されたら完了です。
{ "instanceNames": [ "作成したインスタンスの名前" ] }
6. CodeDeploy にデプロイするアプリケーションを設定する
さて、いよいよCodeDeployを設定します。
CodeDeployのコンソールにアクセスしましょう。
6.1.「アプリケーションの作成」をクリック
「アプリケーションの作成」をクリックします。
6.2.「アプリケーション名」を入力→「EC2/オンプレミス」を選択
「アプリケーション名」を入力し、「コンピューティングプラットフォーム」に「EC2/オンプレミス」を選択します。 選択したら「アプリケーションの作成」をクリックします。
6.3.「デプロイグループの作成」をクリック
「デプロイグループの作成」をクリックします。
6.4.「デプロイグループ名」を入力→「サービスロール」を選択
「デプロイグループ名」を入力します。 「サービスロール」は冒頭で作成したロールを選択します。
6.5.「オンプレミスインスタンス」を選択→Lightsailのインスタンスを指定
「オンプレミスインスタンス」を選択し、先ほど5.8で aws deploy add-tags-to-on-premises-instances ...
のコマンドで設定した key value を入力します。
この記事通りに指定した場合「key=Name, Value=CodeDeployLightsail」です。
6.6.「ロードバランシングを有効にする」のチェックを外す
Load balancerの項目で「ロードバランシングを有効にする」のチェックを外します。
6.7. デプロイグループの作成
「デプロイグループの作成」をクリックします。
7. GitHubリポジトリとCodePipelineを連携する
デプロイの設定ができたら、GitHubとCodePipelineを連携します。 これによって、コードの変更をGitHubのリポジトリにPushしたときに、Lightsailインスタンスに自動的にデプロイされるようにします。
CodePipelineのコンソールにアクセスします。
7.1. 「パイプラインの作成」をクリック
「パイプラインの作成」をクリックします。
7.2. パイプラインの名前を入力
パイプラインの名前を入力します。
7.3.「高度な設定」→「カスタムロケーション」→ S3バケットを選択
「高度な設定」をクリックし、カスタムロケーションを選択して、冒頭で作成したS3バケットを選択します。
7.4. GitHubアカウントを連携
次のソースプロバイダーの画面でGitHubを選択します。
「GitHubに接続する」をクリックして、GitHubアカウントを連携します。
7.5. リポジトリとブランチを選択
連携が完了したら、CodePipelineに組み込むリポジトリとブランチを選択します。
7.6.「ビルドステージを追加する」をスキップ
次の「ビルドステージを追加する」の画面はスキップします。
7.7. 「デプロイステージを追加」→「デプロイプロバイダー」→「AWS CodeDeploy」
「デプロイステージを追加する」画面で「デプロイプロバイダー」に「AWS CodeDeploy」を選択します。
アプリケーション名とデプロイグループはこれまでに設定したものを選択します。
7.8. パイプラインを作成
「パイプラインを作成する」をクリックします。これでパイプラインが作成され、GitHub上のコードがデプロイされます。
8. appspec.ymlを用意してリポジトリに追加
さて、以上で「GitHubにPush」→「CodePipelineを実行」ができるようになりました。 最後に「appspec.yml」という設定ファイルを作成して、リポジトリに追加します。
appspec.ymlはCodeDeployがデプロイ時に実行することを指示するファイルです。 appspec.ymlに、デプロイ時に実行したいことを記述し、GitHubのリポジトリのルートディレクトリに配置します。
appspec.ymlに何を書くべきかはデプロイするアプリケーションの構成によって異なるため詳細は割愛しますが、 例として以下のようなファイルを用意します。
version: 0.0 os: linux files: - source: / # インスタンスにコピーするファイル・ディレクトリを指定します destination: /home/ec2-user/sample-app # インスタンス上でアプリケーションを配置するディレクトリを指定します hooks: ApplicationStart: - location: start_app.sh # アプリケーションを起動するshファイルを指定できます timeout: 300 runas: ec2-user # shを実行するユーザーを指定します
これによって、S3バケットのルートディレクトリ以下にあるファイルやディレクトリが、インスタンスの/home/ec2-user/sample-app
以下に配置されます。
その後ec2-userの権限でstart_app.shが実行されます。
サーバーの起動コマンドなどをこのshファイルの中に仕込んでおけば、Codepipelineを実行するたびに、サーバーが起動できるようになります。
※appspec.ymlに関する詳細は、公式ドキュメントを参照してください。
まとめ
今回は、CodePipelineを利用してアプリケーションをAmazon Lightsailのインスタンスに継続的にデプロイする方法について書きました。
株式会社アビストAIソリューション事業部では、このような技術者向けの記事を今後も公開する予定です。 Twitterアカウントもあるので、ぜひフォローしてください。
記事の内容に関するご指摘や、コメントもお待ちしております。
AIソリューション事業部 公式Twitterアカウント @abist_ai