ALB+ECS+nginx+S3を使ってVPC内でHTTPS静的Webホスティングをする

スポンサーリンク
ハンズオン
スポンサーリンク

はじめに

本記事はVPC内でHTTPS通信を使ったWebサイトを構築したい方や、ALBやECSを実際に操作してみたい方におすすめの記事です。

セキュリティの要件などの制約でプライベートな環境でWebサイトを公開、かつ、通信は暗号化したいといったケースがあるかと思います。

実際、S3の静的Webホスティングを利用することで簡単にWebサイトを構築することができますが、S3の静的WebホスティングはHTTP通信であり、S3単体では通信の暗号化はできません。
またCloudFrontと組み合わせることHTTPS通信でWebサイトを構築することはできますが、CloudFrontはインターネット向けのサービスであるため、プライベートな環境内での公開には向いていません。

そこで本記事では静的Webファイルをコンテナイメージに埋め込み、VPC内にALB+ECSを配備することでVPC内でWebサイトを公開する方法をハンズオン形式で紹介します。
記事内で実際の画面を使っていますので、AWSにあまり慣れていない方でも理解しやすいようになっています。

環境構成

構成図

今回利用するサービスとその流れを示した構成図です。

ハンズオンの費用

ハンズオン時間を2時間と想定した場合の利用料は約0.247 USD(約37円)です。
そのまま配備していると課金が発生してしまうため、ハンズオン終了後に必ず削除してください。

サービス 費用 説明
ALB 0.0486 USD 1時間あたり0.0243USD
LCUは少額のため無視
ECS 0.0308 USD 1時間あたり約0.0154USD
VPCエンドポイント×6
(api.ecr/dkr.ecr/logs をAZで配備)
※S3のゲートウェイエンドポイントは無料です。
0.168 USD 1時間あたり 0.084 USD
ECR 0.00 USD 少額のため無視
CloudWatchログ 0.00 USD 少額のため無視
CloudShell 0.00 USD Cloudshell自体は無料

ハンズオンでの注意事項

今回はハンズオンなので、デフォルトのセキュリティグループを利用しています。実際に本番環境で利用する場合は、最小限のアクセスとなるようにセキュリティグループを設定してください。

またhttpsで接続するため、ACMの証明書を利用します。パブリックの証明書を取得していない場合は、httpsでアクセスできないため、httpでアクセスするように読み替えてハンズオンを実施してください。

環境準備

CloudWatchログの作成

ECSのログの出力先のロググループを作成します。

CloudWatchのサービス画面を開きます。

左メニューからロググループを選択します。

「ロググループを作成」を選択します。

「ロググループ名」と「保持期間の設定」に値を入力します。
「ロググループ名」は規約に沿った任意の名前、「保持期間の設定」はハンズオンのため「1日」を選択します。本番利用する場合はログを保持したい日数を設定してください。
「ログクラス」はデフォルト値のスタンダード、KMSキーで暗号化する場合は。「KMSキー ARN」に利用するKMSキーのARNを入力してください。

入力が終わったら「作成」を選択してロググループを作成します。

ECRでプライベートリポジトリの作成

ECRでコンテナイメージを管理するリポジトリを作成します。

ECRのサービス画面を開きます。

「リポジトリを作成」を選択します。

「リポジトリ名」を入力して「作成」ボタンを選択します。

リポジトリが作成されます。作成したリポジトリを選択します。

「プッシュコマンドを表示」を選択します。

プッシュ用のコマンドが表示されます。
コンテナイメージをプッシュする際のコマンドが表示されます。後で利用するのでコマンドをメモしておいてください。

プライベートリポジトリにコンテナイメージをプッシュ

作成したリポジトリにコンテナイメージをプッシュします。

CloudShellの画面を開きます。

GitHubにサンプルを公開していますので、cloneしてください。

git clone https://github.com/TeTeTe-Jack/aws-handson-nginx-container.git

先ほどメモしたプッシュコマンドを実行してコンテナイメージを作成&コンテナイメージECRにプッシュします。

aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin 【アカウントID12桁】.dkr.ecr.【リージョン】.amazonaws.com
docker build -t 【ECRリポジトリ名】 .
docker tag 【ECRリポジトリ名】:latest 【アカウントID12桁】.dkr.ecr.【リージョン】.amazonaws.com/【ECRリポジトリ名】:latest
docker push 【アカウントID12桁】.dkr.ecr.【リージョン】.amazonaws.com/【ECRリポジトリ名】:latest

再度ECRのリポジトリを確認するとイメージが表示されています。

IAMポリシー/ロールの作成

以下権限をもつECSのサービスロールを作成します。

  • ECRの認証権限
  • 作成したECRのリポジトリのプル権限
  • 作成したCloudWatchログにログを書き込む権限

IAMの画面を開き、IAMポリシーを作成します。

左のメニューから「ポリシー」を選択してください。

   IAMポリシーの画面が表示されます。「ポリシーの作成」を選択します。

ポリシー作成画面が表示されます。「JSON」を選択してください。

ポリシーエディタに以下を入力します。リージョン、アカウントID12桁、リポジトリ名は利用している値に置き換えてください。入力したら「次へ」を選択します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowToGetAuthorizationToken",
            "Effect": "Allow",
            "Action": [
                "ecr:GetAuthorizationToken"
            ],
            "Resource": "*"
        },
        {
            "Sid": "AllowToPullECRHandsonNginxImage",
            "Effect": "Allow",
            "Action": [
                "ecr:GetAuthorizationToken",
                "ecr:BatchGetImage",
                "ecr:GetDownloadUrlForLayer",
                "ecr:BatchImportUpstreamImage"
            ],
            "Resource": "arn:aws:ecr:【リージョン】:【アカウントID12桁】:repository/【リポジトリ名】"
        },
        {
            "Sid": "AllowPutLogToCloudWatchLogs",
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "arn:aws:logs:【リージョン】:【アカウントID12桁】:log-group:/ecs/handson-nginx:*"
        }
    ]
}

 

確認画面が表示されます。ポリシー名を入力して、「ポリシーを作成」を選択します。

次にIAMロールを作成します。左メニューから「ロール」を選択してください。

IAMロールの画面が表示されます。「ロールの作成」を選択します。

ロールの作成画面が表示されます。「信頼されたエンティティタイプ」は「AWSのサービス」、「ユースケース」は「Elastic Container Service task」を選択し。次へを選択します。

許可を追加する画面が表示されます。先ほど作成したポリシーを選択して次へを選択します。


確認画面が表示されます。「ロール名」を入力し「ロールを作成」を選択します。

これでIAMポリシー/ロールの作成は完了です。

VPCの作成

VPCを作成します。VPCはMulti-AZでそれぞれのAZに1つずつサブネットを配置します。

VPCの画面を開きます。

 

VPCの画面が表示されます。「VPCを作成」を選択します。

VPCの作成画面が表示されます。以下を入力します。
※ECRのイメージレイヤーはS3に保管されているため、S3のエンドポイントも含めてVPCを作成します。

  • 作成するリソース:VPCなど
  • 名前タグの自動生成:自動チェックをON、任意の名前を入力
  • アベイラビリティゾーン(AZ)の数:2
  • パブリックサブネット数:0
  • プライベートサブネット数:2
  • NATゲートウェイ:なし
  • VPCエンドポイント:S3ゲートウェイ

「VPCを作成」を選択するとVPCが作成されます。

各種エンドポイントの作成

エンドポイントを作成します。ECRのエンドポイントはdkrとapiの2つ、CloudWatchログ用のエンドポイント合計3つを作成します。

左メニューから「エンドポイント」を選択します。

エンドポイントの画面が表示されます。「エンドポイントを作成」を選択します。

 

エンドポイントの作成画面が表示されます。以下を選択してエンドポイントを作成します。

  • 名前タグ:任意で入力してください。
  • タイプ:AWSのサービス
  • サービス:com.amazonaws.【リージョン名】.ecr.dkr
  • VPC:作成したVPC
  • サブネット:2つのサブネットにチェック
  • セキュリティグループ:default

同様に以下のエンドポイントを作成してください。

  • com.amazonaws.【リージョン名】.ecr.api
  • com.amazonaws.【リージョン名】.logs

ターゲットグループの作成

ALBに紐づけるターゲットグループを作成します。

ターゲットグループの画面を開きます。

ターゲットグループの画面が表示されます。「ターゲットグループの作成」を選択します。

 

ターゲットグループの作成画面が表示されます。以下を入力して次へを選択します。

  • ターゲットタイプの種類:IPアドレス
  • ターゲットグループ名:任意
  • VPC:作成したVPC

ターゲット登録の画面が表示されます。ECSで自動で紐づけされるのでターゲットは登録せず、そのまま「ターゲットグループを作成」を選択します。

ALBの作成

ALBを作成します。
「ロードバランサー」のサービス画面を開きます。

「ロードバランサーの作成」を選択します。

Application Load Balancerの欄の「作成」ボタンを選択します。

以下を入力して「ロードバランサーを作成」を選択します。

  • ロードバランサー名:任意の名前
  • スキーム:内部
  • VPC:作成したVPC
  • セキュリティグループ:default
  • プロトコル:HTTPS
  • デフォルトアクション:作成したターゲットグループ
  • 証明書の取得先:ACMから
  • 証明書の選択:設定するFQDNに合わせて選択

ECSタスクの定義

ECSのタスクを定義します。

ECS(Elastic Container Service)の画面を開きます。

左メニューから「タスク定義」を選択します。

「新しいタスク定義の作成」を選択します。

以下を入力してタスク定義を作成します。ポイントとなる部分だけ記載しています。

  • タスク定義ファミリー:任意の名前を入力
  • 起動タイプ:AWS Fargateを選択
  • タスクサイズ:CPUは.25 vCPU、メモリ.5 GBを選択(最小のリソース)
  • タスクロール:作成したIAMロール
  • タスク実行ロール:作成したIAMロール
  • コンテナの詳細:
    • 名前:任意の名前
    • イメージURL:作成したECRのURL
    • 必須のコンテナ:はい
  • ポートマッピング:
    • コンテナポート:80
    • プロtpコル:TCP
    • ポート目:任意
    • アプリケーションプロトコル:HTTP
  • ログ収集
    • ログ収集の場所:Amazon CloudWatch
    • awslogs-group:作成したロググループ

タスク定義の作成は完了です。続いてサービス起動の設定をします。

ECSでサービス起動

クラスターを作成しサービスを起動します。

左メニューから「クラスター」を選択します。

「クラスターの作成」を選択します。

「クラスター名」を入力してクラスターを作成します。

クラスターが作成されます。作成したクラスター作成します。

クラスターの詳細画面が表示されます。「サービス」タブの「作成」ボタンを選択します。

サービスの作成画面が表示されます。
以下を入力して以下を入力してサービスを作成します。ポイントだけ記載しています。

  • タスク定義ファミリー:作成したタスク定義を選択
  • タスク定義ファミリーのバージョン:最新バージョンを選択してください。
  • サービス名:任意の名前を入力してください。
  • VPC:作成したVPC
  • サブネット:VPCのサブネットを選択
  • セキュリティグループ:デフォルトのセキュリティグループ
  • パブリックIP:オフ
  • ロードバランシングを使用:ON
  • ロードバランサーの種類:Application Load Balancer
  • Application Load Balancer:既存のロードバランサーを使用
  • ロードバランサー:作成したALB
  • リスナー:既存のリスナーを使用
  • リスナー:443:HTTPS
  • ターゲットグループ:既存のターゲットグループを使用
  • ターゲットグループ名:作成したターゲットグループ

しばらくするとタスクが実行中となります。

Route 53

作成したALBに対して名前解決できるようにします。

「Route 53」サービスを開きます。

左メニューから「ホストゾーン」を選択します。

「ホストゾーンの作成」を選択します。

ドメイン名はALBで指定した証明書と同じドメインを設定してください。タイプはプライベートホストゾーンを選択し、ホストゾーンを関連付けるVPCに作成したVPCを設定してください。

作成したホストゾーンにレコードを追加します。
「レコードを作成」を選択します。

レコード名は任意、レコードタイプはAレコード、エイリアスをONにし、トラフィックのルーティング先に作成したALBを設定します。

動作確認用にVPC内でCloudShellを起動

VPC内にCloudShellの環境を作成します。

「CloudShell」のサービスを開きます。

「Create a VPC environment」を選択

作成したVPCとそのサブネット/セキュリティグループを選択し、「Create」を選択します。

動作確認

作成したCloudShellでcurlを使って、Route 53で設定したFQDNを指定してアクセスします。
実行すると設定したhtmlが出力されます。

まとめ

本記事ではALB+ECSを使ってVPC内で静的ウェブホスティングをする方法を紹介しました。

実際にECSを操作してみたことで、利用のイメージがついたのではないでしょうか。

本記事の内容を応用することで、以下ができます。

  • nginxのコンテナイメージをリバースプロキシとして設定しS3静的ウェブホスティングにリダイレクトする
  • 双方向通信が必要なサービス(チャットボットなど)のコンテナを起動させる

幅広くAWSの開発系のスキルを身に着けたい方はUdemy動画コースで学習することを推奨します。

IT資格の人気オンラインコース

タイトルとURLをコピーしました