Zenn
Open6

AWS初心者向け ECSアプリケーションを構築するまでのAWSの諸設定手順

watterwatter

1. IAM・コスト管理 編

目次
  1. AWSアカウント・ルートユーザーについて
  2. AWSのコストに関して
  3. IAMユーザー、IAMロール、IAMポリシーについて
  4. 最小権限に基づいたポリシーの設定方法
  5. 細かい設定はさておき許可の上限を決める「Permissions Boundary」
  6. IAMポリシーが想定通りかを確認する「IAM Policy Simulator」

まずAWSアカウントは作成しておく。AWSの使用料はAWSアカウント単位になる。

1.AWSアカウント・ルートユーザーについて

  1. AWSアカウント作成と同時にルートユーザーが作成されるので、ルートユーザーでログインする。
  2. IAMと検索し、「ユーザー」から「ユーザーの作成」をクリックする。
  3. 下記画像のように設定しIAMユーザーを設定する。
  4. 作成したIAMユーザーに対して許可タブの「許可を追加」でAdministratorAccessを設定する。
  5. ルートユーザーからはログアウトし、作成したIAMユーザーでログインする。ログインURLはIAMユーザー作成時のクレデンシャル情報(CSV)ファイル内にURLとして記載されている。

2. AWSのコストに関して見方や注意点

  1. マネジメントコンソールのダッシュボードまたは、検索にてBillingと打つと「Billing and Cost Management」が表示されるのでこちらをクリックする。
  2. ダッシュボード上でAWSリソースごとの月額コストが確認できる。
  3. 上記コストを効率的に減らすリコメンデーションを「コスト最適化ハブ」を有効化することで利用できる。こちらは追加料金なしなので基本的には有効化したほうが良い。
  4. コストは従量課金制ですが細かいコストの内訳は、都度公式の料金表か公式コストシュミレーターを利用してみた方が良いです。基本的に勉強目的で利用する際は、作成したリソースは停止できるものは停止するか不要なら即座に破棄することでコストを抑えます。

請求アラートの作成方法

1.Billing and Cost Managementからナビゲーションペイン「請求設定」でアラート設定の「編集」をクリックする。
2. Cloudwatchアラームを有効化する。
3. Cloudwatchと検索し、ナビゲーションペイン「アラーム」から「アラームの作成」クリックする。

  1. メトリクスの選択 を選択します。AWS名前空間で [請求] を選択し、[概算合計請求額] を選択します
  2. 設定値は画像のように設定する。「よりも」のしいき値は、実際にこれを超えたら通知して欲しいという予算額を設定しましょう。ここでは5USD(だいたい800円くらい)にします。
    6アラートメールをSNSで通知しますが、トピックがないので作成します。
  3. SNSと検索し、トピックから「トピックの作成」をクリック。
  4. トピックのキューはスタンダードに設定して適当な名前をつけて作成をクリック。
  5. 作成されたトピックのサブスクリプションタブから「サブスクリプションを作成」をクリック
  6. プロトコル「Eメール」で通知したいメールアドレスを記入しサブスクリプションを作成する。
  7. 再度作成中の請求アラームに戻り先ほど作成したSNSトピックとサブスクリプション(メールアドレス)が表示されていることを確認する。
  8. 次へで次の画面にいきアラームの名前をつけて、アラームを作成する。
  9. これで請求アラームが完成です。(サブスクリプションとして設定したメールアドレスに有効確認のメールが送られているので承認すること。)

.

3. IAMロール、IAMポリシーに関して

LambdaやECSなどAWSサービスが他のAWSサービス・リソースに対して何ができて何ができないかを決めるにはIAMロールとIAMポリシーを設定します。
サービスに実際に設定するのは、IAMロールでIAMロールに設定する権限制御に名前をつけてまとめたものがIAMポリシーという感じです。
IAMポリシーにはAWS標準のものもたくさんありますが、大事なことはActionと
どのリソースに対してそれができるかの複合条件で決まるので、ほとんどの場合は、
IAMポリシーを自作してIAMロールにアタッチします。
IAMポリシーは以下のようなものです。

{
            "Sid": "IAMRead",
            "Effect": "Allow",
            "Action": [
                "iam:Get*",
                "iam:List*"
            ],
            "Resource": "*"
        },
        {
            "Sid": "IAMPolicies",
            "Effect": "Allow",
            "Action": [
                "iam:CreatePolicy",
                "iam:DeletePolicy",
                "iam:CreatePolicyVersion",
                "iam:DeletePolicyVersion",
                "iam:SetDefaultPolicyVersion"
            ],
            "Resource": "arn:aws:iam::XXXXXXYYYYYY:policy/AWSCookbook*"
        },
        {
            "Sid": "ProtectPB",
            "Effect": "Deny",
            "Action": [
                "iam:CreatePolicyVersion",
                "iam:DeletePolicy",
                "iam:DeletePolicyVersion",
                "iam:SetDefaultPolicyVersion"
            ],
            "Resource": [
                "arn:aws:iam::XXXXXXYYYYYY:policy/AWSCookbook105PB",
                "arn:aws:iam::XXXXXXYYYYYY:policy/AWSCookbook105Policy"
            ]
        }
  • Sidでオブジェクト単位に分けられたものが1つ1つのルールです。
  • Effectは"Allow"or"Deny"です。後続で指定するActionができるのかできないのかを決めます。
  • Actionは具体的にどのような操作ができるかかorできないかを指定します。
  • Resourceがそのアクションが実行できる or できない対象となるAWSリソースを指します。
    ここにはできる限り固有のAWSリソースを指定します。(リソースのARNを指定します。)
    ある程度まで指定して*でワイルドカードで残りを指定するのも有効なResourceの記載方法です。

4.最小権限の原則に基づいたポリシーを設定するには?

Cloudtrailの証跡を取れるようS3バケットとCloudtrailの証跡をオンにする。
その後ある程度の期間は、通常通りに操作を実行した後
IAMユーザーのCloudTrailイベントに基づいてポリシーを生成 をクリックすることで
実際の必要な操作からポリシーを生成可能。

Cloudtrailのイベントの証跡を取れるようにするには?

  1. Cloudtrailイベント証跡配置用のS3バケットを作成する。

  2. S3バケットにCloudtrailからのアクセスとPutを許可するバケットポリシーを付与する。

     {
         "Version": "2012-10-17",
         "Statement": [
             {
                 "Sid": "S3CloudTrail",
                 "Effect": "Allow",
                 "Principal": {"Service": "cloudtrail.amazonaws.com"},
                 "Action": "s3:GetBucketAcl",
                 "Resource": "arn:aws:s3:::BUCKET_NAME"
             },
             {
                 "Sid": "S3CloudTrail",
                 "Effect": "Allow",
                 "Principal": {"Service": "cloudtrail.amazonaws.com"},
                 "Action": "s3:PutObject",
                 "Resource": "arn:aws:s3:::BUCKET_NAME/AWSLogs/AWS_ACCOUNT_ID/*",
                 "Condition": {"StringEquals": {"s3:x-amz-acl": "bucket-owner-full-control"}}
             }
         ]
     }
    
    1. Cloudtrailの証跡の作成から1で作成したS3バケットを選択し証跡を作成し、ログ記録を開始する。

    5.とりあえず細かい権限は後から決めるとして、最大でどこまで権限を与えるかを決めたいなら「許可の境界」(Permissions Boundary)を設定する。

    1. IAMユーザーの許可タブから「許可の境界」を選択する。
       

    2. 設定するポリシーは、先にIAMポリシーで作っておくと良い。

    3. ここで設定したポリシー以上のActionは暗黙的にDenyされるので注意すること。

6.作成したIAMポリシーが目論見通り作成出来ているかを確認するには「IAM Policy Simulator」を利用する。

  1. こちらサイトにアクセスする。
  1. こちらのサイトでは実際のログインIAMアカウント・ユーザーから取得したIAMユーザー、ロール、ポリシーが表示されるのでAllowされるor DenyされるアクションとそのリソースARNを指定して想定通りかをチェック可能。
watterwatter

2. ネットワーク編

目次
  1. VPC、サブネット、InternetGateway、NAT Gateway、ルートテーブル、ECSアプリケーション用セキュリティグループを設定する。
  2. VPCの説明
  3. サブネットの説明
  4. IGWの説明
  5. NATゲートウェイの説明
  6. ルートテーブルの説明
  7. セキュリティグループの説明

最終的にECSアプリケーションを以下のようなネットワーク構成で作成したい。

1.VPC、サブネット、InternetGateway、NAT Gateway、ルートテーブル、ECSアプリケーション用セキュリティグループを設定する。

1. VPC、サブネット、ルートテーブル、NATゲートウェイの作成

us-east-1リージョン(米国バージニア北部)にVPCを作成する。2つのAZにまたがり
privateサブネット、publicサブネットとpublicサブネットの1つにNATゲートウェイを設定したいため
マネジメントコンソールでVPCも含めたリソースを一括で作成する。
↓以下画像を参考にする。

2. VPCの確認

2Publicサブネット・2Privateサブネットが作成され、Publicサブネットのルートテーブルは1つに作成されている。Privateサブネットは、AZごとにルートテーブルが用意されているので2ルートテーブル存在し、
VPCデフォルトのルートテーブルも存在するため合計4つのルートテーブルが作成されている。

3. ルートテーブルの中身確認

まずPublicサブネットのルートテーブルを確認する。
作成したVPC(10.0.0.0/16)に入る通信は、Publicサブネット内部に送るのでlocalが設定され
それ以外の通信(インターネットから入っている通信)は、全てInternetGatewayに向かうようルートが設定されている。ネットワーク構成の通りのルートとなっているため変更不要である。

3.サブネットについて

基本的には、どのようなリソースを置く空間か、public用・private用かで分けます。
パブリックサブネットは、インターネットゲートウェイへのルートを持つサブネットです。
簡潔にいうとインターネットへの通信が可能なサブネットです。

プライベートサブネットは、インターネットゲートウェイへのルートを持たないサブネットです。

サブネットを作りすぎると利用できるリソース数も減るので、サブネットは必要最低限を作成するように心掛けた方が良いです。
例えばvpcを「10.0.0.0/16」で作成している場合にてサブネットを256個(8bit)分作ります。各サブネットのIP CIDRを/24で構成すると既存のVPCのCIDRから8bit分は埋まるので、各サブネット内に配置できるリソースの数は、8bit分なので256個になります。
つまり10.0.1.0/24というip CIDRのサブネットがあるならそのサブネット内で利用できるリソースのipは
10.0.1.1 ~ 10.0.1.254の範囲になります。
目的にもよりますがPrivateサブネットにECSやRDSなど複数リソースを置く場合には、サブネットのサブネットマスクは、/24では小さいかもしれないので、要注意です。

4.IGWについて

VPC内のリソースとインターネットとやりとりするのに必要なのがInternet Gatewayです。
Internet Gatewayは無料です。

5. NATゲートウェイについて

NATゲートウェイは、Privateサブネット内のリソースがインターネットにアクセスできるようにする役割を持っています。
インターネットと通信するためにはパブリックIPが必要ですが、Privateサブネットに配置したリソースはインターネットから見えるようにはしたくありません。
そこでNATゲートウェイが登場します。NATゲートウェイがインターネットへの通信とプライベートなリソースとのやり取りとの中間に位置しインターネットとのやり取りを担ってくれます。(NATゲートウェイ経由でインターネットゲートウェイに通信を向かわせることで実現します。)

6.ルートテーブルについて

先ほどNATゲートウェイを作成しましたがこれだけでは通信はできません。
通信がどこに向かうかというルートをルートテーブルで決まることで初めてインターネットとの通信が可能になります。
ネットワーク図
で見るようにネットワークとの入り口は、Publicサブネットになります。
こちらでVPCの内側と外側に向かう経路を決めます。
これは一般的に似たような構成になります。

外部(インターネット)からVPC内部に来る通信は、内部リソース宛を指すLocal(VPCのIP CIDR)を指定し、内から外へ向かう通信はInternet Gatewayに向けます。

ルートの適用順序(優先順位)

ルートとして追加した順番通りにはなりません。
公式サイトより以下のようなルールで決まります。そのため一番上に0.0.0.0/0のすべての通信のルートを書いたからといってすべてそのルートを通るようなことはありません。

7. セキュリティグループについて

通信の制御(許可)をするのがセキュリティグループです。
ECSやLambdaなどのAWSリソース単位に設定できます。
インバウンドルール(Ingress)でリソースに入る通信を許可し
アウトバウンドルール(Egress...イーグレスと発音します)でリソースから出ていく通信の許可を設定します。
注意したいのはセキュリティグループのルールはステートフルだということです。
つまりIngressで設定した通信は目的のリソースに到達後レスポンスを呼び出し元に返すために
再度リソースから出ていきますが、これはIngressで許可した通信であることをAWSが覚えているので
アウトバウンドルール(Egress)で上記レスポンスを許可するルールを設定していなくてもEgressの通信は許可されます。
=>インバウンドルールで書いた通信をわざわざアウトバウンドルールで書く必要はないということです。

watterwatter

S3編

目次
  1. S3とは
  2. 実際にS3バケットを作る
  3. S3バケットにライフサイクルルールを設定する

1. S3とは

AWS S3 (Amazon Simple Storage Service) を使うメリットは以下の通りです:

  • スケーラビリティ: 自動的にスケールし、どんな量のデータでも保存可能です。
  • 耐久性: 99.999999999% (11 9's) の耐久性を提供し、データの損失リスクを最小限に抑えます。
  • 可用性: 高い可用性を提供し、データへのアクセスが常に可能です。
  • セキュリティ: データの暗号化やアクセス制御などの高度なセキュリティ機能を提供します。
  • コスト効率: 使用した分だけ支払う従量課金制で、コストを最適化できます。
  • 統合性: 他のAWSサービスとの統合が容易で、データ処理や分析が簡単に行えます。
  • データ管理: バージョニング、ライフサイクル管理、レプリケーションなどのデータ管理機能が充実しています。

これらの特徴により、AWS S3は信頼性が高く、柔軟でコスト効率の良いストレージソリューションとして広く利用されています。

2. 実際にS3でバケットを作る

バケットとは多種多様なファイルを置くためのフォルダのようなものです。
フォルダと同様に階層化できます。
基本的なユースケースでは汎用バケットを選択します。
S3などAWSサービスごとに認識すべきポイントとして、そのサービスがゾーンサービスなのかリージョンサービスなのか、グローバルサービスなのかを気にする必要があります。
S3はリージョンサービスです。
サービスの区分については、↓を参照
https://docs.aws.amazon.com/ja_jp/whitepapers/latest/aws-fault-isolation-boundaries/zonal-services.html


S3バケット作成時にACL無効がデフォルトになっていますが、
基本的にはACL無効で良いです。ACL無効だとバケットを作成したAWSアカウントしか利用できないように思えますがバケットポリシーを設定することで、他AWSリソースやアカウントからのアクセスが可能になります。

パブリックアクセスは特別な要件がない限りは設定しないです。
バージョニングは、要件によってはオンにします。例えば同名ファイルが日時で配置されるようなケースなどでバックアップ取りたいならオンにします。追加で料金が発生します。
暗号化に関しても特別な要件がない限りはデフォルトで良いかと思います。

サービスがどこにあるかを気にする理由としては、アプリケーション(ここではECSアプリを例にして)からS3にアクセスするという時にアクセス方法が問題になるためです。
何も設定しないとS3にアクセスするにはインターネットを経由するためそのためバケットポリシーが必要になったりします。
VPCエンドポイントを用いることでインターネットを介さないでもS3バケットにアクセスできるようになるためプライベートなリソースからS3にアクセスする用途があるときは、VPCエンドポイントでS3を接続できるようにすると良いです。

3. S3バケットにライフサイクルルールを設定する

  1. バケットの「管理」タブからライフサイクルルールを確認できます。こちらで新規のライフサイクルルールを作成してみます。
  2. ライフサイクルルールのアクションとして、現行バージョンを有効期限切れ、非現行バージョンを有効期限にするなどあります。画像のチェックのように設定すると現行バージョンをから非現行バージョンへ移行する+非現行バージョンに対する削除アクションを同時に実行してくれるルールになります。
  • 現行バージョン...まだルールの対象になっていない状態のオブジェクトのこと
  • 非現行バージョン...現行バージョンから有効期限が切れた古いオブジェクトのこと
  1. 現行バージョンから非現行バージョンになる日数、非現行バージョンを削除するルールにチェックを入れた場合は、非現行バージョンになってからどれくらい日数が経ったオブジェクトを削除するかの日数を決めます。オプションで非現行バージョンのうち、何個かは残すというような設定も可能です
  2. 画面下部で分かりやすくオブジェクトが有効期限になってから削除されるまでの流れが日数ベースで表示されます。
watterwatter

4. RDS編

目次
  1. RDSとは
  2. RDS用サブネットグループの作成
  3. RDSアクセス用のEC2インスタンスの立ち上げ
  4. エンジンモード「サーバーレス」のRDSクラスターの作成
  5. RDS用セキュリティグループの作成
  6. EC2インスタンスからのpsqlコマンドでのRDSインスタンスへのアクセス

1.RDSとは

2.RDS用サブネットグループの作成

RDSクラスターを作成する前にRDSインスタンス(リーダーとライター)が配置されるサブネットのグループを作成する。ここでは、以前に作成したPrivateSubnet2つを指定する。

サブネットグループが利用できるのはRDSやElastiCacheなどの一部のサービスで、
主な目的としては、以下のようなものです。

  • 高可用性を確保するために、複数のアベイラビリティゾーンにまたがるサブネットを含めることが推奨されます。
  • ネットワーク分離を実現し、セキュリティを強化するために使用されます。

3. RDSアクセス用のEC2インスタンスの立ち上げ

後述の手順で作成したRDSにアクセスするためにEC2インスタンスを利用します。
まずEC2インスタンスを作成します。


キーペアが未作成の場合は、新規で作成し無くさないようにローカルでしっかりと保存する。

上記設定でEC2インスタンスを作成します。
RDSクラスター作成後にEC2インスタンスのネットワークアクションから「RDSデータベースを接続」アクション実施することで必要なセキュリティグループ設定を作成してくれるので、
RDSクラスター作成後に実行してみたいと思います。

Session ManagerでEC2インスタンスにアクセスするための手順

通常ローカルPCからEC2インスタンスにアクセスする場合は、パブリックIPが必要です。
プライベートサブネットにEC2インスタンスを配置する場合は、NATゲートウェイがあるなら
パブリックIPが適用できますが、今回はNATゲートウェイがなくても接続できるよう
セッションマネージャーでアクセスできる設定を提供したいと思います。

  1. EC2がセッションマネージャークライアントを利用するためのIAMロールの作成...IAMロールで「AmazonSSMManagedInstanceCore」ポリシーをアタッチしたIAMロールを作成します。

  2. EC2インスタンスのIAMロールに作成したIAMロールをアタッチします。

  3. SystemsMangerエンドポイントにアクセスできるようvpcエンドポイントを作成します。

  4. EC2の接続タブからセッションマネージャーで接続するか、直接検索でセッションマネージャーと検索して接続に使いたいEC2インスタンスを指定して接続します。

4. RDSクラスターの作成

  1. RDSから「データベースの作成」をクリックする。
  2. エンジンタイプを選択する。ここではAurora PostgreSQLを選択する。
  3. 画像のように設定値を選びます。
  4. パスワードは、実際の開発ではSecrets Mangerに持たせた方が良いですが、ここでは初心者向けのマネジメントコンソールでの操作中心なのでパスワードは個人で保持するようにします。パスワードはランダム生成のものにします。
  5. クラスターストレージやインスタンスタイプは最も料金が安くなるように設定します。
  6. ネットワーク設定で先ほど作成したEC2にアクセスするように設定する。
  7. サブネットグループは、前の手順で作成したサブネットグループを設定する。
  8. ポートはデフォルトの5432のままにする
  9. 追加の設定は、デフォルトのままにする。
  10. 最終的なコストがこちらに表示されます。こちらは月間でフル稼働した場合のコストなので起動しない間は停止させることで不要なコストをなくす事ができます。(コンソールによる停止は、一週間しか継続しないのでEventbridge SchedulerでこのRDSクラスターを恒久的に停止させます)
  11. 作成したRDSインスタンスのネットワーク設定を確認します。
  12. 自動作成されたセキュリティグループを見ると、ec2-rdsの方がアウトバウンドルールでRDSへのPort:5432での通信を、rds-ec2の方がインバウンドルールでのec2のsgを指定していることが分かります。これによりEC2インスタンスから作成したRDSインスタンスへのアクセスが可能になっているはずです
  13. EC2インスタンスのアクション>接続>セッションマネージャーから EC2インスタンスにアクセスする。
  14. psqlコマンドをインストールする。コマンドは
sudo dnf install postgresql15
  1. インストール完了後 RDS作成時に記載されたエンドポイント名、ユーザー名でpostgreにログインする。
psql --host=endpoint --port=5432 --dbname=postgres --username=postgres
  1. ログインできたらpostgres=>の表記に変わります。
  2. データベースを1つ作ってみます。
CREATE DATABASE mydatabase;
  1. CREATE DATABASEできたら問題ないです。ここまででRDSでPostgreSQLつか準備は完了です。
watterwatter

5. ECS編

目次
  1. ECSとは。まずコンテナ開発について
  2. ECRでのリポジトリ作成とDocker Imageのpush
  3. Cloudformationを利用したECSクラスター、サービス、タスク定義の作成
  4. ECSクラスター、サービス、タスクについての説明
  5. HTTPS接続のためのopenssl証明書の作成とアップロード
  6. Application Load Balancerの作成とセキュリティグループ、ターゲットグループの作成

本講座で利用するDockerfileと関連するファイル、Cloudformationテンプレートファイルは、
こちらのGithubリポジトリに配置してます。
https://github.com/wat1881mayer/ecs-app-1

1. Dockerとは?、またその利点

まずコンテナ技術に関して

比較されるものとしてVagrantがサーバー側(ホスト)仮想化です。
比較図は、こちら

メリット

  1. アプリケーションの依存関係をコンテナ内で完結できる。...例えばローカルPCにインストールしたNode.jsのバージョンが違うからアプリの挙動が若干違うなどなどの問題を解決できます。Dockerfileで細かく記述された環境を誰でも再現できるためです。
  2. ローカルから別環境(開発環境、ステージング環境、本番環境)での構築・テストが効率化されます。(環境が同じなので)
    以下がDockerのコンテナワークフローです。

Docker Desktopまたは Rancher Desktopのインストール

Docker DesktopまたはRancher Desktopをインストールして、DockerデーモンをローカルPC
に動かせるようにしましょう。
ついでにDocker Desktopは今までは商用利用が無料でしたが、現在では商用利用は有料です。
そのため商用利用でも無料なRancher Desktopを代替品として使ってます。

AWS CLIを使用可能な状態にする。

ここではIAMユーザーのアクセスキーを作成して、AWS CLIのプロファイルとして構成します。

  1. AWS IAMのユーザーでアクセスキーを作成する。
  2. 作成したアクセスキーとシークレットキーは厳密に保管する。
  3. aws configureでprofile名を設定してaws cliがAWSリソースにアクセス可能な状態にする。
     aws configure --profile profile-name
    
    ここでCSVファイルでダウンロードした、Access Key IdとSecret Keyを画面の指示に従い入力する。
  4. これでセットアップ完了。以下コマンドで作成されたprofile情報が反映されているか確認する。
     aws configure list --profile profile-name
    

2. ECRでのリポジトリ作成とDocker Imageのpush

1. ECRにリポジトリを作成する。

  1. まずECRにてプライベートリポジトリを作成します。

  2. ローカルでECSアプリ本体となるDockerfileのあるパスをカレントディレクトリとする。

  3. Docker デーモンが起動している状態で以下コマンドを実行する。

     docker build  . -t  <your-account-id>.dkr.ecr.<region>.amazonaws.com/ecs-app:latest
    
  4. dockerイメージができたら追加でタグを設定する。(ここでは、1.0と設定)

 docker tag ecs-app:latest <your-account-id>.dkr.ecr.<region>.amazonaws.com/ecs-app:latest
 <your-account-id>.dkr.ecr.<region>.amazonaws.com/ecs-app:1.0  
  1. ECRへのログイン情報を取得し、Dockerにログインする
aws ecr get-login-password --region region | docker login --username AWS --password-stdin  aws_account_id.dkr.ecr.region.amazonaws.com
  1. ECRにdockerイメージをpushする。
     docker push <your-account-id>.dkr.ecr.<region>.amazonaws.com/ecs-learning:latest
       docker push <your-account-id>.dkr.ecr.<region>.amazonaws.com/ecs-learning:1.0
    

3. Cloudformationを利用したECSクラスター、サービス、タスク定義の作成

  1. ECSタスク実行用IAMロール「ECS-Learning-TaskExecutionRole」を作成する。ポリシーには「AmazonECSTaskExecutionRolePolicy」をアタッチする。

  2. クラスター、タスク定義、サービスを記載したCloudformationテンプレートを用意する。

  3. 作成したcfテンプレートをアップロードする。

  4. スタックの名前を記載する。

  5. 諸々のオプションは今回は設定せずスキップ。(Cloudformationの講座ではないので詳細は割愛)

  6. 確認画面で諸々の設定値を確認し、送信をクリックする。

  7. あとはECSクラスター、ECSサービス、ECSタスクが作成するので完了まで見守ります。

watterwatter

5. ALB 編(ECS 後編)

目次
  1. ALB(Application Load Balancer)とは。
  2. ALBのリスナーについて
  3. ALBのターゲットグループについて
  4. ALB、リスナー、ターゲットグループ、セキュリティグループをCloudformationで作成する
  5. HTTPS接続のためのopenssl証明書の作成とアップロード

1. ALBとは?

AWSのApplication Load Balancer (ALB) は、Amazon Web Services (AWS) が提供するロードバランサーの一種で、アプリケーション層 (OSIモデルのレイヤー7) で動作します。ALBは、HTTPおよびHTTPSトラフィックを処理し、リクエストを複数のターゲット(例: EC2インスタンス、コンテナ、Lambda関数など)に分散させることで、高可用性とスケーラビリティを実現します。

主な特徴

  1. レイヤー7のロードバランシング:
     HTTP/HTTPSリクエストの内容(ヘッダー、パス、クエリ文字列など)に基づいてルーティングを行います。
  2. ターゲットグループ:
    トラフィックを分散する先をターゲットグループとして管理します。ターゲットにはEC2インスタンス、  ECSタスク、Lambda関数などを指定可能です。
  3. リスナーとルール:
     リスナーは特定のポート(例: 80, 443)で受信するトラフィックを定義します。
     ルールを設定することで、リクエストの条件に応じたルーティングが可能です。
  4. ヘルスチェック:
     ターゲットの正常性を監視し、正常なターゲットにのみトラフィックを送信します。
  5. SSL/TLSのサポート:
     HTTPSトラフィックを処理するためにSSL/TLS証明書を設定できます。
  6. ウェブソケットとHTTP/2のサポート:
     モダンなウェブアプリケーションの要件に対応しています。

主なユースケース

  • マイクロサービスアーキテクチャでのトラフィック分散。
  • コンテンツベースのルーティング(例: 特定のURLパスに基づくルーティング)。
  • サーバーレスアプリケーション(Lambda関数)へのトラフィック分散。
  • HTTPSトラフィックの終端処理(SSL/TLSのオフロード)。
  • ALBは、スケーラブルで柔軟なアプリケーション層のトラフィック管理を提供するため、モダンなウェブアプリケーションやマイクロサービスに適しています。

2. リスナーについて

リスナーは特定のポート(例: 80, 443)で受信するトラフィックを定義します。
ルールを設定することで、リクエストの条件に応じたルーティングが可能です。

3. ターゲットグループについて

トラフィックを分散する先をターゲットグループとして管理します。ターゲットにはEC2インスタンス、  ECSタスク、Lambda関数などを指定可能です。

4. CloudformationでALBを作成する。

本講座で利用するDockerfileと関連するファイル、Cloudformationテンプレートファイルは、
こちらのGithubリポジトリに配置してます。
https://github.com/wat1881mayer/ecs-app-1
上記のcloudformationフォルダから「ecs-template.yml」を利用します。
以前の講座で使用したCloudformationテンプレートに追加した形なので
変更箇所となる部分のみを抜粋して説明します。

ECSService:
    Type: "AWS::ECS::Service"
    DependsOn: ALBListener
    Properties:
      ServiceName: ecs-learning-service
      Cluster: !Ref ECSCluster
      DesiredCount: 1
      LaunchType: FARGATE
      NetworkConfiguration:
        AwsvpcConfiguration:
          AssignPublicIp: ENABLED
          SecurityGroups:
            - your-security-group-id
          Subnets:
            - your-subnet-id
            - your-subnet-id
      TaskDefinition: !Ref ECSTaskDefinition
      LoadBalancers:
        - ContainerName: my-ecs-learning-container
          ContainerPort: 80
          TargetGroupArn: !Ref ALBTargetGroup
  ALBSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Enable HTTP access via port 80
      GroupName: ECS-Learning-ALB-sgs
      VpcId: your-vpc-id
  ALBIngressRule:
    Type: AWS::EC2::SecurityGroupIngress
    Properties:
      GroupId: !GetAtt ALBSecurityGroup.GroupId
      IpProtocol: tcp
      FromPort: 80
      ToPort: 80
      CidrIp: 0.0.0.0/0
  ECSApplicationLoadBalancer:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      IpAddressType: ipv4
      Name: ECS-Learning-Alb
      Scheme: internet-facing
      SecurityGroups:
        - !GetAtt ALBSecurityGroup.GroupId
      Subnets:
        - your-public-subnet-id
        - your-public-subnet-id
  ALBTargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      Name: ECS-Learning-TargetGroup
      Port: 80
      Protocol: HTTP
      TargetType: ip
      VpcId: your-vpc-id
      HealthCheckPath: /
      HealthCheckIntervalSeconds: 30
      HealthCheckTimeoutSeconds: 5
      HealthyThresholdCount: 3
      UnhealthyThresholdCount: 2

  ALBListener:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      DefaultActions:
        - Type: forward
          TargetGroupArn: !Ref ALBTargetGroup
      LoadBalancerArn: !Ref ECSApplicationLoadBalancer
      Port: 80
      Protocol: HTTP

以前のECS編で作成した箇所からの変更としては、ECSServiceにDependsOn属性がついているのと、
LoadBalancersプロパティが設定されていることです。
Depends OnはCloudformationがスタックを作成する際に、明示的にDependsOnで指定したスタックより後に作成するように指示できます。これによりある要素が作成される前に値を参照してERRORとなるような状況を回避できます。

LoadBalancers欄にて後述で作成するALBのターゲットグループをコンテナのポートを繋ぎます。
これによりALBがターゲットグループに送った通信が、ECSコンテナ内に入るようになります。

実際に正常にALBとリスナー、ターゲットグループ、セキュリティグループが作成されましたら
ALBのDNS名から目的のECSタスクで動作するWebサーバーにアクセスできます。

5. HTTPS利用のためのSSL/TLS証明書のALBリスナーへの登録

1. ローカルでのopensslを利用した自己署名での証明書の作成手順

前提としてローカルPCにopensslをインストールします。

  1. 証明書に利用するPrivate Keyの作成
 openssl genrsa 2048 > my-private-key
  1. 自己署名証明書の作成
 openssl req -new -x509 -nodes -sha256 -days 365 -key my-private-key.pem -outform PEM - out my-certificate.pem
  1. 作成した証明書のACMへのアップロード
    ACMから証明書をインポートでインポートします。
    証明書本文に作成した証明書本体を、証明書のプライベートキーに手順1で作成したpemファイルの中身を貼り付けます。インポート実施することでAWS上に証明書をアップロード完了です。

  2. HTTPSでの接続を実施するためALBとECSのセキュリティグループIgressルールを設定する。
    ↓HTTPSの許可ルールをIgressに追加

  3. ALBのリスナーに「HTTPS」ルールを追加する。

  4. プロトコルHTTPSとターゲットグループを指定する。

  5. 証明書としてACMにアップロードした自己署名証明書を設定する

  6. これでHTTPSでのリスナールールへの証明書自体の追加作業は、終わりですが自己署名証明書なのでブラウザでのHTTPS通信時にエラー出ます..正式にCAで署名したものであればエラーなくアクセスできます。

作成者以外のコメントは許可されていません