こんにちは!技術4課のイーゴリです。
この記事では、AWS CodePipelineを使って、CodeCommit → CodeDeploy → Auto ScalingのEC2へのデプロイのプロセスを作ってみましたので、ご紹介したいと思います。
前回の記事で作成したリソースを使用しますので、まずは一番簡単なパイプラインについての記事を読んだほうが分かりやすいです。
- 構成図
- 前提条件
- Code Commit リポジトリの作成
- CodeCommitリポジトリにサンプルコードを追加する
- CodeBuild の設定
- EC2のゴールドイメージの作成
- Application Load Balancer (ALB) の作成
- EC2起動テンプレートの作成
- Auto Scaling グループの作成
- CodeDeploy の設定
- CodePipeline の設定
- CodePipeline の設定の修正
- 正常性の確認
- 注意点
構成図
変更前(前回の記事の構成)
開発者:CodeCommitにコードをアップロードすると、CloudWatch Eventsがこれを検知して、CodePipelineは定義されたCodeDeployを起動し、EC2へデプロイされます。
エンドユーザー:インターネットから直接にEC2のApacheに接続します。
デメリット:
- EC2がパブリックサブネットにあるため、EC2宛の不正アクセスの可能性が高まる(ソースIPの制限は可能だが、プライベートサブネットに置いたほうがベスト)
- 冗長性/可用性はない
- EC2のスケールアウトができない
前回(下記)の記事はCodePipeline+CodeCommit+CodeDeployの基本なので、あくまで練習環境として構築しました。今回の記事では、上記の環境のデメリットを改善したいと思います。
変更後(今回構築構成)
CodeCommitにコードをアップロードすると、CloudWatch Eventsがこれを検知して、CodePipelineは定義されたCodeDeployを起動し、オートスケーリンググループのEC2へデプロイされます。
エンドユーザー:インターネットからApplication Load Balancer (ALB) 経由でEC2のNginxに接続します。
メリット:
- 直接にEC2にアクセスはない(セキュリティが高まる)
- オートスケーリンググループ及びApplication Load Balancer (ALB) による複数のAZの可用性がある
- オートスケーリンググループによるEC2のスケールアウトができる
記事の目標
前回の記事で構築した環境の弱点を改善します。
前提条件
- インストール済みのGitクライアント
- パブリックサブネットにあるNATゲートウェイ
- 構築されたEC2
- 発行済みのIAMユーザー用のGit 認証情報
IAMユーザー用のGit 認証情報の生成手順
Code Commit リポジトリの作成
前回の記事で作成したCodeCommit リポジトリを使用しますので、このステップはスキップします。
新規でCode Commit リポジトリの作成をしたい場合、この記事の項目を参照してください。
CodeCommitリポジトリにサンプルコードを追加する
前回の記事でクローンした「index.html」及び「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
変更後:
version: 0.0 os: linux files: - source: /index.html destination: /var/www/html/ file_exists_behavior: OVERWRITE
※すでにindex.htmlがあるので、「file_exists_behavior: OVERWRITE」を追加しないと、「すでにファイルが存在するので、展開できません」というエラーが発生します。
The deployment failed because a specified file already exists at this location
上記のエラーが発生する時に、CodeDeployエージェント1.3.2以降の場合、appspec.ymlのfilesのセクションに「file_exists_behavior」のオプションを指定するとデプロイが実行できます。
新規で展開する場合、「file_exists_behavior: OVERWRITE」なしで問題ないです。
CodeBuild の設定
CodeBuild の設定はCodePipelineのパイプラインを作成する時に設定しますが、今回はhtmlのみを使うため、CodeBuidステップ及びbuildspec.yml ファイルの作成をスキップします。
EC2のゴールドイメージの作成
CodeDeployエージェントのインストール
事前準備(IAMロール作成)
- 「EC2InstanceDeployRole」というポリシーを追加し、IAMロールを作成します。
- IAMロールを対象のEC2に付与します。
- EC2からのインターネットアクセスがあることを確認します。
エージェントのインストール
エージェントをインストールするには下記のURLの手順を使います。
対象EC2に入って、下記のコマンドを実行します。
$ sudo yum update $ sudo yum install ruby $ sudo yum install wget $ cd /home/ec2-user $ wget https://aws-codedeploy-ap-northeast-1.s3.ap-northeast-1.amazonaws.com/latest/install $ sudo chmod +x ./install $ sudo ./install auto $ sudo service codedeploy-agent status The AWS CodeDeploy agent is running as PID 2629
注意点: 上記のwgetコマンドは東京リージョン向けのコマンドでしたが、東京リージョン以外の場合、 下記のコマンドをご参考ください。
wget https://bucket-name.s3.region-identifier.amazonaws.com/latest/install
<bucket-name>及び<region-identifier>はこちらに記載してありますので、ご参考ください。
ちなみに、EC2を作成する時に「ユーザーデータ」に上記のコマンドを入れると、便利です。
Nginxのインストール
$ sudo amazon-linux-extras install nginx1 $ systemctl status nginx.service ● nginx.service - The nginx HTTP and reverse proxy server Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; vendor preset: disabled) Active: inactive (dead) $ sudo systemctl start nginx $ systemctl status nginx.service ● nginx.service - The nginx HTTP and reverse proxy server Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled) Active: active (running) since 諸略
nginxの自動起動を設定する
$ sudo systemctl enable nginx
確認
$ sudo systemctl list-unit-files | grep nginx nginx.service enabled
ブラウザでパブリックIPにアクセスしますと、下記の画面が表示されます。
今回の記事では、appspec.ymlで指定した「/var/www/html/」のパスを、Nginxで設定したいため、「nginx.conf」ファイルを編集します。
$ sudo vi /etc/nginx/nginx.conf server { listen 80; listen [::]:80; server_name _; root /var/www/html/; ← rootフォルダを設定
再起動
systemctl restart nginx
/var/www/html/にあるindex.htmlに変更されましたので、EC2のゴールドイメージの準備は完了です!
AMIの取得
[イメージ名]を記載した後で、[イメージを作成]をクリックします。
注意:EC2のAMI取得時に再起動されますので、再起動なしでAMI取得をしたい場合、[再起動しない]のところに、チェックを入れます。
Application Load Balancer (ALB) の作成
ターゲットグループの作成
[サービス]>[EC2]>[ターゲットグループ]>[ターゲットグループの作成]をクリックします。
プロトコルバージョンやヘルスチェックの設定を必要に応じて設定してください。
私の場合、デフォルトのまま設定し、[次へ]をクリックします。
インスタンスを追加せずに[ターゲットグループの作成]をクリックします。
完了です。
ロードバランサーの作成
[サービス]>[EC2]>[ロードバランサー]>[ロードバランサーの作成]をクリックします。
Application Load Balancerを選択します。
パブリックサブネットに置きます。
リスナーを設定し、上記で作成したターゲットグループを選択します。
事前にターゲットグループを作成せずにロードバランサーの作成の画面でターゲットグループを作成した場合、ターゲットグループの一覧にないので、更新ボタンを押してください。
注意点:今回の記事ではリスナーとしてHTTP(暗号化なし)を使っていますが、非推奨となりますので、HTTPS(暗号化あり)を使ってください。
[ロードバランサーの作成]をクリックします。
EC2起動テンプレートの作成
AutoScaling Group のためにEC2起動テンプレートの作成を行います。
[サービス]>[EC2]>[起動テンプレート]>[起動テンプレート を作成]をクリックします。
[Auto Scaling のガイダンス]は任意項目です。
上記に作成したAMIを選択します。
必要に応じて、他の設定を行ってください。
ここで前回作成したIAMロール(EC2-CodeDeploy)を付与します。
[起動テンプレート]を作成します。
完了です。
Auto Scaling グループの作成
起動テンプレートの作成が完了しましたら、該当の起動テンプレートを選択し、[アクション]>[Auto Scaling グループを作成]をクリックします。
下記の画面で、プライベートサブネットを選択します。
インスタンスタイプなどの箇所は必要に応じて設定を行い、[次へ]をクリックします。
既存のロードバランサーにアタッチします。
ヘルスチェックの[ELB]の選択肢にもチェックを入れます。
なお、[ヘルスチェックの猶予期間]のところで、パイプラインが完了するまでの時間を考慮した上、設定する必要があります。そして[次へ]をクリックします。
オートスケーリングの設定は必要に応じて設定する必要があります。
- EC2数を固定したい場合、下記の画面の3つの欄で同じ数値を入力します。
- 私の場合、すぐ2台起動したいのと、最小のEC2数:2台、最大のEC2数:3台で設定します。
平均CPU使用率は80%を超える場合、3台まで増やせるという設定を行います。
他の設定は任意ですので、最後までデフォルト値のまま進みます。
オートスケーリンググループのステータスで「キャパシティーの更新」が表示されますので、[EC2]の[インスタンス]欄で、EC2が起動されます。
CodeDeploy の設定
前回の記事では、CodeDeploy の設定を設定したため、ご参考ください。
今回の記事では、EC2のAutoScaling Groupのために既存の[MyApp1]アプリケーションで新規のデプロイグループを作成します。
既存の[MyApp1]をクリックし、デプロイグループを作成します。
既存のIAMロールを選択します。
デプロイタイプのデプロイ方法は必要に応じて設定しますが、私は[インプレース]のまま進みます。[環境設定]で[Amazon EC2 Auto Scaling グループ]を選択します。そして該当のASG(私の場合、[asg-1])を選択し、次に進みます。
CodePipeline の設定
前回の記事でPipelineを作りましたので、新規作成をスキップしますが、新規で作成する場合、前回の記事をご参考ください。
CodePipeline の設定の修正
CodePipelineの修正をし、1台のEC2の構成からAuto Scaling + ALB の構成に切り替えます。
[サービス]>[CodePipeline]>該当のパイプラインをクリックします。
[編集]をクリックします。
[Deploy]の[ステージを編集する]をクリックします。
編集マークをクリックします。
デプロイグループで「MyApp1」(1台のEC2)から「MyApp2」(Auto Scaling グループ + ALB)に変更し、[完了]をクリックします。
「完了」をクリックします。
もう一度「完了」をクリックします。
[保存]をクリックします。
[変更をリリースする]をクリックします。
[リリースする]をクリックします。
正常性の確認
ターゲットグループに入ると、起動されているEC2が[healthy]の状態になっています。
ロードバランサーのDNS名でアクションすると、「index.html」は正常に稼働しています。
例えば、CodeCommitで何かの変更を行い、もう一度プッシュします。
% cd test-rep % git add . % git commit -m "5rd commit" % git push
※「5rd」の「rd」を削除し忘れたため、正しい英語ではありませんので、真似しないでくださいねー(笑)
[CodeDeploy]>[デプロイメント]>デプロイ履歴の該当のデプロイIDをクリックします。
[デプロイのライフサイクルイベント]の[イベント]の[View events]をクリックします。
確認が完了です!
注意点
パブリックサブネットにNATゲートウェイ/NATインスタンスがないとデプロイの処理中に、CodeDeploy Agentのエラーが発生しますので、ご注意ください。
エラー内容:
CodeDeploy agent was not able to receive the lifecycle event. Check the CodeDeploy agent logs on your host and make sure the agent is running and can connect to the CodeDeploy server.
以上、御一読ありがとうございました。
本田 イーゴリ (記事一覧)
カスタマーサクセス部
・2024 Japan AWS Top Engineers (Security)
・AWS SAP, DOP, SCS, DBS, SAA, DVA, CLF
・Azure AZ-900
・EC-Council CCSE
趣味:日本国内旅行(47都道府県制覇)・ドライブ・音楽