Upgrade to Pro — share decks privately, control downloads, hide ads and more …

20230511_AWSにおけるコンテナサービスの選択とIaC実装例.pdf

 20230511_AWSにおけるコンテナサービスの選択とIaC実装例.pdf

nezumisannn

May 11, 2023
Tweet

More Decks by nezumisannn

Other Decks in Technology

Transcript

  1. AWSにおけるコンテナサービスの
    選択とIaC実装例
    【大阪】AWS構築・開発の技術勉強会【リアル開催】
    2023/05/11 株式会社ビヨンド 寺岡 佑樹

    View Slide

  2. 自己紹介
    resource “my_profile” “nezumisannn” {
    name = “Yuki.Teraoka”
    nickname = “ねずみさん家。”
    company = “beyond Co., Ltd.”
    job = “Infra Engineer”
    twitter = “@yktr_sre”
    skills = [“Terraform”,”Packer”]
    }

    View Slide

  3. AWS × コンテナ(サービス)

    View Slide

  4. どれをどのように使いますか?
    どのツールと組み合わせて使いますか?
    迷う & 全てに当てはまる絶対解がない

    View Slide

  5. AWSのコンテナサービス
    AWS App Runner AWS EKS
    AWS ECS AWS ECR
    AWS EC2 AWS Fargate Copilot CLI AWS CloudFormation Terraform
    AWS CDK
    Orchestration
    Environment Provisioning

    View Slide

  6. サービスの選定観点
    ● コンピューティングコスト
    ○ 月々のランニングコストはどの程度か
    ● 運用負荷
    ○ スケーリング / パッチ適用などのオペレーションを如何に少なくできるか
    ● 技術習得
    ○ 選定した(コンテナ)サービスを利用するために習得する技術と期間はどの程度か
    ○ (または)過去に同様の技術を利用したことはあるか
    ● 技術制約
    ○ (コンテナ)サービスの制約を考慮した上で要件を満たせるか
    ■ ex. FargateではGPU搭載のコンピューティングリソースを利用できない

    View Slide

  7. サービスの選定
    ● ECS on EC2
    ○ AWSのみを利用 + GPU使いたいなら多分この構成
    ● ECS on Fargate + Copilot CLI
    ○ AWSのみを利用 + GPU不要で運用負荷減らしたい (この構成が最も多い印象 )
    ○ Copilot CLIを使って対話形式で必要なリソースを AWS上に構築できる
    ○ CLIの裏でCloudFormationが実行されるが自由度は低め
    ● EKS on EC2 or Fargate
    ○ Orchestrationとしてkubernetesを利用したい
    ○ オンプレからの移設 or 将来的に他クラウドも見越した構成にしたい
    ■ ECSはベンダーロックインする
    ■ AWSを使う以上少なからずベンダーロックインするのでは?説は割愛
    ● App Runner + Terraform
    ○ CloudFormationを利用しても良い

    View Slide

  8. サービスの選定
    コンピューティングコスト 運用負荷 技術習得(難易度) 技術制約
    ECS on EC2 低い 高い 低い 少ない
    ECS on Fargate
    (Copilot CLI)
    高い 低い 低い 多い
    EKS on EC2 普通 普通 高い 少ない
    EKS on Fargate 高い 低い 低い 普通
    App Runner
    (Terraform)
    高い 低い 低い 多い
    ※ サービスの規模によって変動する可能性あり

    View Slide

  9. App Runner と Terraformで
    AWSコンテナ実行環境を構築する
    【大阪】AWS構築・開発の技術勉強会【リアル開催】
    2023/05/11 株式会社ビヨンド 寺岡 佑樹

    View Slide

  10. App Runner と Terraform
    ● App Runner
    ○ コンテナ化されたアプリケーションのフルマネージドサービス
    ○ コンテナ実行に必要な機能を特別な設定をすることなく提供してくれる
    ■ ネットワーク
    ■ 負荷分散
    ■ AutoScaling
    ■ 自動デプロイ
    ■ ロギング
    ● Terraform
    ○ Hashicorpが開発するIaCを実現するツール
    ○ HCLと呼ばれる独自言語でコードを記述する
    ○ マルチプロバイダ(AWS以外のクラウドやSaaSにも対応)

    View Slide

  11. App Runner を使わない場合
    ● 例:ECS on Fargate
    ○ ネットワーク
    ■ VPC / サブネット / セキュリティグループ etc…
    ○ 負荷分散
    ■ ELB
    ○ コンテナ実行環境 + AutoScaling
    ■ ECS Cluster / ECS Service / ECS Task
    ○ 自動デプロイ
    ■ CodeCommit / CodeBuild / CodeDeploy / CodePipeline
    ○ ロギング
    ■ CloudWatch Logs

    View Slide

  12. App Runnerを使った場合の構成
    https://aws.amazon.com/jp/blogs/news/deep-dive-on-aws-app-runner-vpc-networking/

    View Slide

  13. Terraformを使ったApp Runnerの構築
    ● Provider設定とECRの作成
    ● App Runner用のIAMロールの作成
    ● App Runnerのサービスの作成
    ● カスタムドメインの設定
    ● 接続先VPCとVPC Connectorの設定

    View Slide

  14. Provider設定とECRの作成
    provider "aws" {
    region = "ap-northeast-1"
    }
    resource "aws_ecr_repository" "nginx" {
    name = "${var.project_name}-nginx"
    image_tag_mutability = "MUTABLE"
    image_scanning_configuration {
    scan_on_push = true
    }
    }
    東京リージョンを指定
    アクセスキーとシークレットキーは環境変数を参照
    AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY
    今回はNginxのコンテナを利用
    ECR作成後にビルドしたイメージを
    Pushしておく

    View Slide

  15. App Runner用のIAMロールの作成
    resource "aws_iam_role" "apprunner_service_role" {
    name = "apprunner-service-role"
    assume_role_policy = templatefile(
    "./policy/assume_role_policy.tftpl",
    {
    service = [
    "build.apprunner.amazonaws.com",
    "tasks.apprunner.amazonaws.com"
    ]
    }
    )
    }
    resource "aws_iam_role_policy_attachment" "apprunner_service_role" {
    role = aws_iam_role.apprunner_service_role.name
    policy_arn = "arn:aws:iam::aws:policy/service-role/AWSAppRunnerServicePolicyForECRAccess"
    }
    {
    "Version": "2012-10-17",
    "Statement": [
    {
    "Sid": "",
    "Action": "sts:AssumeRole",
    "Effect": "Allow",
    "Principal": {
    "Service": ${jsonencode(service)}
    }
    }
    ]
    }
    テンプレート
    テンプレート参照
    AppRunner用のAWS管理ポリシーを適用

    View Slide

  16. App Runnerのサービスの作成
    resource "aws_apprunner_service" "example" {
    service_name = var.project_name
    source_configuration {
    authentication_configuration {
    access_role_arn = aws_iam_role.apprunner_service_role.arn
    }
    image_repository {
    image_configuration {
    port = "80"
    }
    image_identifier = "${aws_ecr_repository.nginx.repository_url}:latest"
    image_repository_type = "ECR"
    }
    }
    tags = {
    Name = "${var.project_name}-service"
    }
    }
    AppRunnerのデフォルトドメインでサイト表示可能
    コンテナ側でlistenしているポートを指定
    リポジトリのタイプで
    ECRを指定
    ECRのURLとイメージのタグを指定

    View Slide

  17. カスタムドメインの設定
    AppRunnerのサービスに紐づけるドメインを指定
    ※ 値はterraform.tfvarsに記載
    resource "aws_apprunner_custom_domain_association" "example" {
    domain_name = var.apprunner_custom_domain
    service_arn = aws_apprunner_service.example.arn
    }
    ACM検証用のCNAMEレコードが発行される

    View Slide

  18. CNAMEレコードをRoute53に設定
    resource "aws_route53_record" "acm_validations" {
    for_each = { for i in aws_apprunner_custom_domain_association.example.certificate_validation_records : i.name => i }
    zone_id = data.aws_route53_zone.selected.zone_id
    name = replace(each.value.name, ".${var.route53_hosted_zone}", "")
    type = "CNAME"
    ttl = 60
    records = [each.value.value]
    }
    resource "aws_route53_record" "apprunner_custom_domain" {
    zone_id = data.aws_route53_zone.selected.zone_id
    name = var.apprunner_custom_domain
    type = "A"
    alias {
    name = aws_apprunner_service.example.service_url
    zone_id = var.apprunner_alias_host_zone_id
    evaluate_target_health = true
    }
    }
    AppRunnerのデフォルトドメインを
    Aliasレコードに設定

    View Slide

  19. 接続先VPCとVPC Connectorの設定
    同様に1a/1c/1dの3つを作成
    resource "aws_vpc" "vpc" {
    cidr_block = "10.0.0.0/16"
    enable_dns_support = true
    enable_dns_hostnames = true
    tags = {
    Name = "${var.project_name}-vpc"
    }
    }
    resource "aws_subnet" "public_1a" {
    vpc_id = aws_vpc.vpc.id
    cidr_block = "10.0.0.0/24"
    map_public_ip_on_launch = true
    availability_zone = "ap-northeast-1a"
    tags = {
    Name = "${var.project_name}-public-subnet-1a"
    }
    }

    View Slide

  20. VPC Connectorに紐づけるセキュリティグループを作成
    アウトバウンドのみ全解放しておく
    resource "aws_security_group" "apprunner" {
    name = "${var.project_name}-sg"
    description = "Security group for App Runner VPC connector"
    vpc_id = aws_vpc.vpc.id
    tags = {
    Name = "${var.project_name}-sg"
    }
    }
    resource "aws_security_group_rule" "apprunner_egress" {
    type = "egress"
    from_port = 0
    to_port = 65535
    protocol = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
    security_group_id = aws_security_group.apprunner.id
    }

    View Slide

  21. resource "aws_apprunner_service" "example" {
    service_name = var.project_name
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    network_configuration {
    egress_configuration {
    egress_type = "VPC"
    vpc_connector_arn = aws_apprunner_vpc_connector.connector.arn
    }
    }
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    }
    resource "aws_apprunner_vpc_connector" "connector" {
    vpc_connector_name = "${var.project_name}-connector"
    subnets = [
    aws_subnet.public_1a.id,
    aws_subnet.public_1c.id,
    aws_subnet.public_1d.id,
    ]
    security_groups = [aws_security_group.apprunner.id]
    }
    VPC Connectorを作成
    サブネットIDとセキュリティグループ
    IDを指定
    ServiceにVPC Connectorのarnを指定

    View Slide

  22. App Runnerの制約事項
    ● 最小起動スペックが高め = 料金が高い
    ● サイドカーコンテナを起動できない
    ○ 単一コンテナでの起動になる
    ○ (例えば)Nginx + アプリコンテナが構成として取れない
    ■ 単一コンテナ(複数プロセス) や Supervisorで起動は可能
    ■ 1コンテナ1プロセスの原則的にどうなの?
    ● 起動したコンテナに接続する手段がない
    ○ 稼働中のコンテナでデバッグしたい場合の手段がほしい (ECS Exec相当のもの)

    View Slide

  23. まとめ
    ● ベストプラクティスはあるが絶対解はない
    ○ それぞれのサービスとツールの特徴を把握しておく
    ● サービスの選定観点からどのような構成が望ましいのかを決定する
    ○ 今回はApp Runner + Terraformを例にした
    ● App Runnerはコンテナ化アプリケーションのフルマネージドサービス
    ○ Terraformと組み合わせるとコードを記述して構成管理できる
    ● フルマネージドだからこその制約事項がある
    ○ 特に問題なければ本番利用の選択肢としてアリ

    View Slide

  24. 資料とコード公開
    ● 今回利用した資料とTerraformのコードは公開します
    ○ 資料:登壇後 Speakerdeckへ公開
    ○ Terraformのコード:登壇後 GitHubのパブリックリポジトリで公開
    ■ https://github.com/nezumisannn/aws-terraform-apprunner-example
    ● Twitter(@yktr_sre)でハッシュタグ(#ビヨ勉)付きでツイートします

    View Slide

  25. 終わり

    View Slide