👋
【初心者向け】ALB・ECS連携 をCloudFormationで作ってみる
はじめに
こちらの記事で紹介しているアプリケーション内の
ALBとECSの連携をCloudFormationで作成したので、まとめてみます。
なかなかドキュメントを読んでいても必要なパラメータが理解しづらかったので、
同じようなことを実装している人のサポートになれば嬉しいです。
赤枠の内容になります
対象読者
- ALB・ECS連携に興味がある方
- CloudFormationの基礎的な構文が理解できる方
- ECSについての基礎的な知識がある方
- ALBについての基礎的な知識がある方
手順
下記の内容のCloudFormationテンプレートの全文はこちらのGitHubリポジトリに
保管しているので、気になる方は是非ご覧ください。
IAMロールの作成
ECSタスクで利用するIAMロールを作成します。
今回のアプリケーションでは、ECSからDynamoDBとBedrockにアクセスするので、
アクションを許可します。
Resources:
# --------------------------------------------------#
# IAM Role
# --------------------------------------------------#
ECSTaskRole:
Type: AWS::IAM::Role
Properties:
# IAMロールの信頼ポリシーの定義
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- sts:AssumeRole
Principal:
Service: ecs-tasks.amazonaws.com # ECSタスクに引き渡すように指定
Policies:
- PolicyName: BedrockECRTaskPolicy
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- bedrock:*
- dynamodb:*
Resource: '*'
RoleName: bsc-task-role
ECSクラスターの作成
EcsCluster:
Type: AWS::ECS::Cluster
Properties:
ClusterName: ecs-cls
ECSタスク定義の作成
ECSタスク定義では、コンテナの構成を定義するものです。
-
ecsTaskExecutionRole
というロールは、ECRからDockerイメージを取得したり、ログを送信したりなどのコンテナの実行に必要な権限を提供する。 -
awsvpc
はVPCを利用するNWモードで、Fargetタスクで利用する。専用のENIを付与され、他のVPC内のリソースと通信できる
# タスク定義
EcsTaskDefinition:
Type: AWS::ECS::TaskDefinition
Properties:
ContainerDefinitions: # コンテナ設定
- Name: bedrock-container # コンテナ名
Image: !Ref DockerImageURL # DockerイメージURL
PortMappings:
- ContainerPort: 80
HostPort: 80
Protocol: tcp
ExecutionRoleArn: !Sub "arn:aws:iam::${AWS::AccountId}:role/ecsTaskExecutionRole" # タスク実行時に使用されるIAMロールのARN
TaskRoleArn: !Ref ECSTaskRole # タスクがアクセスするAWSリソースの権限を定義するIAMロールのARN
Family: bedrock-container
NetworkMode: awsvpc # VPCを利用したNWモードであり、Fargateの場合必須
RequiresCompatibilities: ["FARGATE"] # このタスクがFargateを使用して実行される
Cpu: 1024 # 1vCPU
Memory: 2048 # 2GB
RuntimePlatform:
OperatingSystemFamily: LINUX
ECSサービスの作成
ECSサービスはECSタスクを維持し、ロードバランサなどの機能を設定する。
# サービス
EcsService:
Type: AWS::ECS::Service
DependsOn: # ALBリスナーが作成されてからECSサービスが作成されることを指定
- ALBListenerHTTPS
Properties:
Cluster: !Ref EcsCluster # サービスが属するクラスター
ServiceName: EcsService
TaskDefinition: !Ref EcsTaskDefinition # ECSタスク定義
DesiredCount: 1 # 起動するタスクのデフォルト数
EnableExecuteCommand: false # ECS Exec機能を無効
LaunchType: FARGATE # Fargateを使用してタスクがサーバレスに実行される
NetworkConfiguration:
AwsvpcConfiguration:
AssignPublicIp: DISABLED
SecurityGroups:
- { Fn::ImportValue: ecs-sg-id }
Subnets:
- { Fn::ImportValue: private-subnet-a-id }
- { Fn::ImportValue: private-subnet-c-id }
# ロードバランサとの連携
LoadBalancers:
- ContainerName: bedrock-container # タスク定義で指定したコンテナをALBに関連付ける
ContainerPort: 80
TargetGroupArn: !Ref TargetGroupResource # サービスがトラフィックを転送するターゲットグループの指定
Tags:
- Key: Name
Value: bedrock-ecs-service
ターゲットグループの作成
Fargateを使用する場合、TargetType
はip
を指定する。
# --------------------------------------------------#
# TargetGroup
# --------------------------------------------------#
TargetGroupResource:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
VpcId: { Fn::ImportValue: rag-vpc-id }
Name: bedrock-target-group
Protocol: HTTP
Port: 80
TargetType: ip
HealthCheckProtocol: HTTP
HealthCheckPath: "/"
HealthyThresholdCount: 2
UnhealthyThresholdCount: 2
HealthCheckTimeoutSeconds: 20
HealthCheckIntervalSeconds: 30
Matcher:
HttpCode: 200
Tags:
- Key: Name
Value: bedrock-tg
ALBの作成
ALBを作成する場合、ALBとリスナーの2つを作成する必要がある。
リスナールールでターゲットグループへのルーティングやACMで発行した証明書などを設定する。
# --------------------------------------------------#
# ALB
# --------------------------------------------------#
ALB:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Name: bedrock-alb
# パブリックサブネットのみ配置可という意味
Scheme: internet-facing
# ALBを指定
Type: application
Subnets:
- { Fn::ImportValue: public-subnet-a-id }
- { Fn::ImportValue: public-subnet-c-id }
SecurityGroups:
- { Fn::ImportValue: alb-sg-id }
IpAddressType: ipv4
Tags:
- Key: Name
Value: bedrock-alb
# Listener
ALBListenerHTTPS:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
LoadBalancerArn: !Ref ALB
Port: 443
Protocol: HTTPS
Certificates:
- CertificateArn: !Ref ACMCertificateArn
SslPolicy: !Ref ELBSecurityPolicy
DefaultActions:
# Cognitoへのルーティング
- AuthenticateCognitoConfig:
UserPoolArn: { Fn::ImportValue: user-pool-arn }
UserPoolClientId: { Fn::ImportValue: user-pool-client-id }
UserPoolDomain: bedrock-1234
OnUnauthenticatedRequest: authenticate
Order: 1
Type: "authenticate-cognito"
# ターゲットグループへのルーティング
- TargetGroupArn: !Ref TargetGroupResource
Order: 2
Type: forward
まとめ
以上がALBとECSの連携をCloudFormationで実装する場合の記述内容になります。
これまでマネジメントコンソール画面で設定していた内容をCloudFormationで定義すると
結構複雑になるので、作成が大変な印象です。
今後は最近流行っているDify.aiもCloudFormationあるいはTerraformでセキュアな構成で
実装してみたいです。
Discussion