はじめに
本記事は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動画コースで学習することを推奨します。