CodeDeployからPrivateLinkを経由してプライベート環境にあるEC2にデプロイをしてみた

2022.03.28

やっとエルデンリングをクリアしました。AWS事業本部コンサルティング部の後藤です。

最近資格勉強も兼ねてCode系サービスを触っています。今回はプライベート環境下にあるEC2に対してCodeDeployでデプロイを行うのにVPC Endpoint(PrivateLink)を利用した方法を試してみました。NAT Gatewayを使用する事でも可能ですが、通信を全てAWS内で行えるためよりセキュアな方法だと思います。

それでは、やっていきましょう!

環境説明

今回使用する構成は以下の通りです。

CodePipelineでCodeCommitのリポジトリに対して更新が入るとCodeDeployが対象のEC2にデプロイを行うような構成にしています。

デプロイ対象EC2構築

デプロイ対象となるEC2をPrivateSubnetに構築します。今回OSはAmazon Linux 2を使用しています。

EC2には以下AWS管理ポリシーとカスタムポリシーの計3つを付与したIAMロールを付与しています。

  • AmazonEC2RoleforSSM
  • AmazonEC2RoleforAWSCodeDeploy
  • カスタムポリシー

カスタムポリシーの権限は以下の通りです。この権限はCodeDeployがPrivateLink経由でデプロイを行うのに必要な権限となります。

{
    "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": "*"
        }
    ]
}

AmazonEC2RoleForSSMはSSMを使用してCodeDeployAgentの導入と接続するために必要となります。AmazonEC2RoleForAWSCodeDeployはCodeDeployからデプロイを行うのに必要となります。

VPC Endpoint構築

EC2を構築したPrivate Subnetに対して、以下VPC Endpointを作成しています。

  • com.amazonaws.ap-northeast-1.ssm
  • com.amazonaws.ap-northeast-1.ssmmessages
  • com.amazonaws.ap-northeast-1.ec2messages
  • com.amazonaws.ap-northeast-1.s3(※Gateway Type)
  • com.amazonaws.ap-northeast-1.codedeploy
  • com.amazonaws.ap-northeast-1.codedeploy-commands-secure

CodeDeployが対象EC2に対してPrivateLink経由でデプロイを行うのにcom.amazonaws.ap-northeast-1.codedeploycom.amazonaws.ap-northeast-1.codedeploy-commands-secureが必要となります。

CodeDeployAgent導入と設定変更

構築したEC2がSSMで認識出来たことを確認したら、SSMコンソール画面上の「ディストリビューター」からAmazon所有のパッケージ「AWSCodeDeployAgent」を選択して「1回限りのインストール」をクリックします。

RunCommand画面に遷移し、既にCodeDeployAgentを導入する設定となっているため対象のEC2を選択して実行します。成功と表示されれば問題なくCodeDeployAgentが導入されていると思いますので、セッションマネージャーからEC2に接続して確認しましょう。

$ cat /opt/codedeploy-agent/.version
agent_version: OFFICIAL_1.3.2-1902_rpm

$ systemctl status codedeploy-agent
● codedeploy-agent.service - AWS CodeDeploy Host Agent
   Loaded: loaded (/usr/lib/systemd/system/codedeploy-agent.service; enabled; vendor preset: disabled)
   Active: active (running) since Sun 2022-03-27 07:13:25 UTC; 14min ago

CodeDeployAgentが導入出来たら、PrivateLink経由でデプロイを行うために設定ファイル/etc/codedeploy-agent/conf/codedeployagent.ymlの末尾にenable_auth_policytrueで追記します。

# cat /etc/codedeploy-agent/conf/codedeployagent.yml
:log_aws_wire: false
:log_dir: '/var/log/aws/codedeploy-agent/'
:pid_dir: '/opt/codedeploy-agent/state/.pid/'
:program_name: codedeploy-agent
:root_dir: '/opt/codedeploy-agent/deployment-root'
:verbose: false
:wait_between_runs: 1
:proxy_uri:
:max_revisions: 5
:enable_auth_policy: true

設定ファイルの変更を適用するためサービスを再起動します。

# systemctl restart codedeploy-agent

Codeサービス構築

CodeCommit、CodeDeploy、CodePipelineを構築します。

CodeCommit、CodePipelineはデフォルト設定、CodeDeployでは対象がEC2となるように設定しています。CodeDeployのサービスロールにはAWS管理ポリシー「AWSCodeDeployRole」を付与しています。

いざデプロイ開始

CodeCommitのリポジトリをCloneします。CodeCommitはgit-remote-codecommit(GRC)を使用する事で認証情報の入力無しにリポジトリを利用する事が出来るためオススメです。

git clone codecommit::ap-northeast-1://cicd-private-test-commit

今回はAWSが提供しているSampleAppを使用してデプロイを行います。SampleAppはApacheの導入、index.htmlの設置を行う内容になっています。

SampleApplicationは以下で取得可能です。

aws s3 cp s3://aws-codedeploy-ap-northeast-1/samples/latest/SampleApp_Linux.zip . --region ap-northeast-1

zipを解凍し、中身をCodeCommitのリポジトリにPushします。

$ unzip SampleApp_Linux.zip
$ rm SampleApp_Linux.zip
$ git add .
$ git commit -m "Added sample app"
$ git push

CodeCommitのリポジトリ変更を検知してCodePipelineが動き、CodeDeployによって対象EC2にデプロイを行います。Pipeline上で全て成功となればデプロイ完了です。

デプロイ内容を確認するため、ALBのURLを実際に踏んでみます。

SampleAppのindex.htmlが表示されたため、問題なくデプロイが完了されたこと確認出来ました。

まとめ

プライベート環境下にあるEC2に対してPrivateLinkを経由してCodeDeployのデプロイを行う方法を試してみました。PrivateLinkを使用する事でデプロイ経路は完全にAWS内で留める事が出来るため、NAT Gatewayを使用するより、よりセキュアな構成になっているかと思います。費用的には今回のようにSSM用のエンドポイント等を用意すると同じくらいになりますが、CodeDeploy用の2つのエンドポイントだけであれば、NAT Gatewayよりは多少安く利用する事が可能です。