📝

プライベートなEC2にCodeDeployでデプロイしてみた

2021/11/10に公開

DVAでCodeDeployを触っているうちに楽しくなってきたと同時に、
「なんだかプライベートなEC2にもVPCエンドポイント経由でデプロイしたいなあ」
と思って調べていたらできたので、今回はプライベートなEC2にCodeDeployでデプロイする方法を紹介します。

先に参考資料

Use CodeDeploy with Amazon Virtual Private Cloud (公式ドキュメント)
【AWSの呼吸 弐ノ型】CodeDeployでVPCエンドポイントを設定する
最初は公式ドキュメントを呼んだのですが、いまいちよくわからなかったので、後者のブログを参考にしました。
すごくわかりやすかったです!

構成図

temp-CodeDeploy.drawio.png

・プライベートサブネットにEC2インスタンスを起動し、アクセス用にパブリックサブネットにALBを設置
・EC2はエンドポイント経由でCodeDeploy、S3と通信
・SSMはプライベートなEC2にセッションマネージャーでアクセスするために使用

構築は以下の流れで行います。

  1. VPCエンドポイント作成
  2. EC2用IAMロール作成
  3. EC2インスタンス起動
  4. EC2インスタンスにCodeDployエージェントをインストール
  5. ALB作成
  6. CodeDeployの設定
  7. EC2インスタンスにデプロイ

前提

  • VPCは10.0.0.0/16で作成済み
  • VPCのDNSホスト名の解決を「有効」に変更しておく(デフォルトでは無効)
  • ALB用のパブリックサブネットは10.0.1.0/2410.0.2.0/24で作成済み
  • プライベートサブネットは10.0.10.0/24で作成済み

注意!

今回はVPCエンドポイントのうち、PrivateLinkを5つ使用します。PrivateLinkは時間単位で結構な課金額になるので、検証後の消し忘れには十分注意して下さい。
同様にEC2インスタンス、ALBなども時間単位での課金ですので、使用したリソースは最後に削除しましょう。

1. VPCエンドポイント作成

今回はVPCエンドポイントのうち、PrivateLinkと呼ばれるタイプを5つ、S3用のゲートウェイ型を1つ作成します。
PrivateLinkは以下の5つです。
・com.amazonaws.ap-northeast-1.ssm
・com.amazonaws.ap-northeast-1.ssmmessages
・com.amazonaws.ap-northeast-1.ec2messages
・com.amazonaws.ap-northeast-1.codedeploy
・com.amazonaws.ap-northeast-1.codedeploy-commands-secure

ゲートウェイ型は以下の1つです。
・com.amazonaws.ap-northeast-1.s3

PrivateLinkの作成方法については、
プライベートなEC2にSSMセッションマネージャーで接続してみた
を参考にしてください。

ゲートウェイ型の作成方法も似ていますが、一部異なるので紹介しておきます。
「s3」で検索し、タイプが「Gateway」のサービスを選択します。
image.png

ゲートウェイ型はルートテーブルと紐づけます。
紐づけるルートテーブルは、プライベートサブネットが紐づけられているものを選択します。
image.png

ゲートウェイ型ではセキュリティグループを使用しないので、残りの設定はデフォルトのままでOKです。
image.png

すべてのVPCエンドポイント作成した状態です。
image.png

これでVPCエンドポイント作成は完了です。

2. EC2用IAMロール作成

IAMロールの作成方法については、こちらを参考にしてください。
IAMロールには2つのマネージドポリシーと1つのカスタムポリシーをアタッチします。
マネージドポリシーは以下の2つです。
・AmazonSSMManagedInstanceCore
 SSMセッションマネージャーでの接続用
・AmazonEC2RoleforAWSCodeDeploy
 CodeDeployでのデプロイ時のS3へのアクセス権

カスタムポリシーには以下のポリシーを記載して作成します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "codedeploy-commands-secure:GetDeploymentSpecification",
                "codedeploy-commands-secure:PollHostCommand",
                "codedeploy-commands-secure:PutHostCommandAcknowledgement",
                "codedeploy-commands-secure:PutHostCommandComplete"
            ],
            "Effect": "Allow",
            "Resource": "*"
        }
    ]
}

作成時に以下のような警告が出ますが、ポリシー自体は作成できるので無視して作成してください。
image.png

最終的に以下のポリシーをアタッチしたロールができます。
image.png

これでIAMロールの作成は完了です。

3. EC2インスタンス起動

EC2インスタンスの起動方法はこちらを参考にしてください。
今回は1台だけ起動できればよいので、ap-northeast-1aのプライベートサブネットに起動しました。
セキュリティグループについては、ALB用のセキュリティグループからのHTTP通信のみ許可します。
ALB用のセキュリティグループがない場合は後から作成して、EC2用のグループの設定を変更してください。
変更方法はこちらをご覧ください。
image.png

image.png

これでEC2インスタンスの起動は完了ですが、セッションマネージャーでの接続確認をしておきます。
以下の画面で接続できない場合はPrivateLink関連やIAMロールの設定が間違っている可能性があるので、こちらを参考に見直してみてください。
image.png

4. EC2インスタンスにCodeDployエージェントをインストール

セッションマネージャーでCodeDeployエージェントをインストールします。
インストール方法は
Amazon Linux または RHEL 用の CodeDeploy エージェントをインストールする
を参考にしてください。

今回だとユーザーデータでyum updateは済んでるので、以下のコマンドを順に実行しています。
sudo yum install ruby -y
sudo yum install wget -y
cd /home/ec2-user
wget https://aws-codedeploy-ap-northeast-1.s3.ap-northeast-1.amazonaws.com/latest/install
chmod +x ./install
sudo ./install auto
sudo service codedeploy-agent status

これでCodeDeployエージェントはインストールできましたが、PrivateLink用にもう1作業行います。
/etc/codedeploy-agent/conf/codedeployagent.ymlを編集します。
nano /etc/codedeploy-agent/conf/codedeployagent.ymlでファイルを開きます。
image.png

ファイル末尾に:enable_auth_policy: trueを追記します。
image.png

これでファイルを保存し、catコマンドで追記されたか確認しておきます。
image.png

これで動けば問題ありませんが、動かない場合や不安な場合は、service codedeploy-agent restartでCodeDeployエージェントを再起動します。再起動後も念のためエージェントが動いているか確認しています。
image.png

これでセッションマネージャーでの作業は完了です。

5. ALB作成

ALBの作成方法については、こちらを参考にしてください。
ALB稼働後にDNS名でアクセスし、Apacheのデフォルトページが表示されればOKです。
ちなみに、ターゲットグループのヘルスチェックでは失敗していますが、/var/www/html/にindex.htmlを作成していないだけなので問題ありません。デプロイ後にはヘルスチェックが通ります。
image.png

image.png

うまくいかない場合は、
・EC2セキュリティグループの設定でALBのセキュリティグループからのHTTP通信を許可しているか
・ALBをパブリックサブネットに設置したか
などをご確認ください。

6. CodeDeployの設定

ネットワーク周りができたので、ここからはCodeDeployの設定です。
CodeDeployを初めて触る場合は、先にIAMロールを作成しましょう。
作成方法はCodeDeploy のサービスロールの作成を参考に「EC2/オンプレミスのデプロイの場合」の手順に従ってください。

ドキュメント通りに作成すると以下のようなロールができるはずです。
image.png

ロールができたらCodeDeployコンソールに移動しましょう。
image.png

サイドバーから「アプリケーション」をクリックします。
image.png

「アプリケーションの作成」をクリックします。
image.png

任意のアプリケーション名を入力し、プラットフォームから「EC2/オンプレミス」を選択して作成します。
image.png

アプリケーション作成後、「デプロイグループの作成」をクリックします。
image.png

任意のデプロイグループ名を入力し、サービスロールには作成したCodeDeploy用のロールを選択します。
image.png

デプロイタイプはデフォルトの「インプレース」にしておき、環境設定で「Amazon EC2インスタンス」を選択します。
タグで対象インスタンスを選択できるので、起動済みのインスタンスを選択します。
image.png

実はCodeDeployエージェントはここでもインストールできるのですが、ファイルの設定変更が必要だったので直接インストールしました。
インストール済みなので、ここでは「なし」でOKです。
image.png

デプロイ設定はデフォルトのままにしておき、ロードバランサーはせっかくなので作成済みのものを指定しましょう。
こうすると、デプロイ時に対象インスタンスがALBからデタッチ→デプロイ→ALBに再アタッチという流れを自動で行ってくれます。
以上の設定でグループを作成します。
image.png

これでデプロイの準備が整いました。

7. EC2インスタンスにデプロイ

それではプライベートなEC2インスタンスにデプロイしてみましょう。
デプロイグループのコンソールから「デプロイの作成」をクリックします。
image.png

デプロイ設定のリビジョンには公式が提供している以下のサンプルアプリのURLを入力します。

https://aws-codedeploy-ap-northeast-1.s3.amazonaws.com/samples/latest/SampleApp_Linux.zip

image.png

その他の設定はデフォルトのままで、「デプロイの作成」をクリックします。
image.png

デプロイが始まると、デプロイイベントを見ることできます。
image.png

image.png

ALBを利用する設定にしたので、自動的にALBからのデタッチが行われています。
ターゲットグループのデフォルト設定だとデタッチまで5分かかるので、しばらく待ちましょう。
image.png

デタッチされるとEC2がS3からファイルをダウンロードするフェーズに入ります。
image.png

デプロイが成功すると、EC2インスタンスがALBに再アタッチされます。
このタイミングでターゲットグループのヘルスチェックもクリアできています。
image.png

無事デプロイ完了しました。
image.png

再度ALBのDNS名でアクセスしてみましょう。
image.png

サンプルアプリのページが表示されれば成功です!
おめでとうございます!

まとめ

今回はプライベートなEC2にCodeDeployでデプロイしてみました。
セキュリティを考えたときに、サーバーはプライベートサブネットに置いた方が安全ということはわかりますが、プライベートに置いたときに他のサービスとの連携方法も考える必要があります。
今回はVPCエンドポイントを使用し、CodeDeployのファイルも少しいじることで実現できました。
他にも色々なサービスとの連携もできそうなので、試してみたいと思います。
今回の内容が少しでも参考になれば幸いです。

改めて課金に関する注意

冒頭でも記載しましたが、今回使用したVPCエンドポイントやALB、EC2は時間単位で課金が発生します。
そのため、検証後に不要になったらきちんと削除しましょう。
今回作成したリソースは以下の通りです。
・VPCエンドポイント×6(ゲートウェイ型は無料)
・EC2用IAMロール(無料)
・EC2インスタンス
・ALB
・CodeDeployアプリケーション
・CodeDeploy用IAMロール(無料)

参考資料

Use CodeDeploy with Amazon Virtual Private Cloud (公式ドキュメント)
【AWSの呼吸 弐ノ型】CodeDeployでVPCエンドポイントを設定する
プライベートなEC2にSSMセッションマネージャーで接続してみた
パブリックなALBからプライベートなEC2にアクセスしてみた
セッションマネージャーのハマりどころをパターンごとに整理してみる
Amazon Linux または RHEL 用の CodeDeploy エージェントをインストールする
CodeDeploy のサービスロールの作成

Discussion