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

インフラ高級言語としてのAWS CDK〜"設定"より1段階ハイレベルな抽象化〜

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
Avatar for Yoda Keisuke Yoda Keisuke
February 18, 2024
130

インフラ高級言語としてのAWS CDK〜"設定"より1段階ハイレベルな抽象化〜

Avatar for Yoda Keisuke

Yoda Keisuke

February 18, 2024
Tweet

Transcript

  1. インフラ構築の領域は、 ノーコードから「コード」へと進化を遂げてきた IaC以前と以後の対⽐ ノーコード(GUI)管理 ⼿動操作、` 設計書` のメンテ ⾮⼀貫性の問題 スケーラビリティの制限 コード(Iac)管理

    ⾃動化、バージョン管理の利便性 ⼀貫性があり、再現可能なデプロイ 迅速かつ確実な変更 「コードレビュー」が可能 GenAI との対話性
  2. まずは実コードを概観 プロンプト : { 各 IaC} で、以下の要件を満たすインフラコードを書いて # 要件 ALB

    を通じて、 Aurora をデータストアとした ECS/Fargate のアプリケーションを公 開する。
  3. Cloud formation ( 62 ⾏) Resources: MyVPC: Type: 'AWS::EC2::VPC' Properties:

    CidrBlock: '10.0.0.0/16' ECSCluster: Type: 'AWS::ECS::Cluster' TaskDefinition: Type: 'AWS::ECS::TaskDefinition' Properties: Cpu: '256' Memory: '512' NetworkMode: 'awsvpc' RequiresCompatibilities: - FARGATE ContainerDefinitions: - Name: 'sample-app' Image: 'my-docker-image:latest' PortMappings: - ContainerPort: 80 ApplicationLoadBalancer: Type: 'AWS::ElasticLoadBalancingV2::LoadBalancer' Properties: Subnets: - 'subnet-12345678' Type: 'application' ALBListener: Type: 'AWS::ElasticLoadBalancingV2::Listener' Properties: DefaultActions: - Type: 'forward' TargetGroupArn: Ref: 'TargetGroup' LoadBalancerArn: Ref: 'ApplicationLoadBalancer' Port: 80 Protocol: 'HTTP' TargetGroup: Type: 'AWS::ElasticLoadBalancingV2::TargetGroup' Properties: Port: 80 Protocol: 'HTTP' VpcId: Ref: 'MyVPC' AuroraDBCluster: Type: 'AWS::RDS::DBCluster' Properties: Engine: 'aurora' MasterUsername: 'username' MasterUserPassword: 'password' AuroraDBInstance: Type: 'AWS::RDS::DBInstance' Properties: DBInstanceClass: 'db.r4.large' Engine: 'aurora' DBClusterIdentifier: Ref: 'AuroraDBCluster' EcsToAuroraSGRule: Type: 'AWS::EC2::SecurityGroupIngress' Properties: GroupId: !Ref AuroraSecurityGroup SourceSecurityGroupId: !Ref ECSTasksSecurityGroup IpProtocol: tcp FromPort: '3306' ToPort: '3306'
  4. Terraform(69⾏) resource "aws_vpc" "my_vpc" { cidr_block = "10.0.0.0/16" } resource

    "aws_ecs_cluster" "cluster" { name = "my-cluster" } resource "aws_ecs_task_definition" "task" { family = "my-family" network_mode = "awsvpc" requires_compatibilities = ["FARGATE"] cpu = "256" memory = "512" container_definitions = jsonencode([{ name = "sample-app" image = "my-docker-image:latest" portMappings = [{ containerPort = 80 }] }]) } resource "aws_lb" "lb" { name = "my-lb" internal = false load_balancer_type = "application" security_groups = ["sg-12345678"] subnets = ["subnet-12345678"] } resource "aws_lb_listener" "listener" { load_balancer_arn = aws_lb.lb.arn port = "80" protocol = "HTTP" default_action { type = "forward" target_group_arn = aws_lb_target_group.target_group.arn } } resource "aws_lb_target_group" "target_group" { port = 80 protocol = "HTTP" vpc_id = aws_vpc.my_vpc.id } resource "aws_rds_cluster" "aurora" { engine = "aurora" master_username = "username" master_password = "password" skip_final_snapshot = true } resource "aws_rds_cluster_instance" "aurora_instance" { engine = "aurora" instance_class = "db.r4.large" cluster_identifier = aws_rds_cluster.aurora.id } resource "aws_security_group_rule" "ecs_to_aurora" { type = "ingress" from_port = 3306 to_port = 3306 protocol = "tcp" security_group_id = aws_security_group.aurora_sg.id source_security_group_id = aws_security_group.ecs_tasks_sg.id }
  5. CDK(22⾏) const vpc = new ec2.Vpc(this, 'MyVpc'); const auroraCluster =

    new rds.DatabaseCluster(this, 'Database', { engine: rds.DatabaseClusterEngine.auroraMysql({ version: rds.AuroraMysqlEngineVersion.VER_2_09_1 }), instanceProps: { vpc, instanceType: ec2.InstanceType.of(ec2.InstanceClass.R5, ec2.InstanceSize.LARGE), }, defaultDatabaseName: 'MyDatabase', masterUser: { username: 'adminuser', password: cdk.SecretValue.plainText('password1234'), }, }); const cluster = new ecs.Cluster(this, 'EcsCluster', { vpc }); const loadBalancedFargateService = new ecsPatterns.ApplicationLoadBalancedFargateService(this, 'Service', { cluster, memoryLimitMiB: 1024, cpu: 512, taskImageOptions: { image: ecs.ContainerImage.fromRegistry("amazon/amazon-ecs-sample"), }, }); auroraCluster.connections.allowFrom(loadBalancedFargateService.service, ec2.Port.tcp(3306));
  6. 抽象化が更に進んだ CDK は、 その⽣産性から組織の競争⼒を加速する CDK のビジネスメリット ⼯数削減 コーディング量が少ない ヒューマンエラー削減 ⾞輪の再発明の防⽌

    競争⼒の増加 新サービスや機能の早期提供 デプロイまでの学習曲線が緩やか ë なぜそのようなメリットが⽣まれるのか?
  7. ⾼級⾔語であることのメリットを IaC に持ち込める ⾼⽔準でプログラマブルであることのメリット 1 モデリング可能 プロジェクトのインフラコードを構造化 コンポーネント同⼠の依存関係を記述可能 taskDef.json や`buildspec.yaml`

    のようなファイルをCDK コードに統合できる 2 低⽔準 / 冗⻑な作業の排除 「賢明なデフォルト」という特性をもつ 例えば… VPC 作成時: ベストプラクティスに従う( サブネットの分割、NAT ゲートウェイの配置、セキュリティ設定) lamda とdynamoDB を作成し、関連づける: それぞれにそれ⽤のSG を作成、lambda からdynamoDB を使⽤する最⼩限の権限のIAM ロールを作成、アタッチ 差別化に繋がらない重労働の排除、とも⾔い換えられる。(かつカスタマイズ性は犠牲になら ない) 3 パッケージング可能 ⾼いコンポーザビリティ 決まったパターンをライブラリのように共有/ 再利⽤が可能 公式のL3 コンストラクト( 後述) を使⽤ 4 ⾔語の機能を継承 繰り返しや条件分岐が使⽤可能 型チェック 、IDE によるAPI 仕様のサジェスト、(Typescript) プログラマのインフラ⼊⾨として、ゆるやかな学習曲線 5 Cloud formation の機能を継承 AWS 管理のロールバック、削除保護が使える CFn で使える機能は使える
  8. プログラミングの関⼼事と、 それに対する CDK のソリューションを紹介する 1 モデリング / パッケージング é Construct

    L1~3 の粒度があるConstruct による階層化 デプロイの単位はStack Construct で管理 2 DI / Configuration é environment / context / secret manager 実⾏時変数やクレデンシャル の扱い⽅、DI のやり⽅ 3 CD / CI é CDK pipeline
  9. Construct はその名の通り CDK を構成す る種々のビルディングブロックである - 1. 「モデリング」について construct の分類

    App Construct Stack Construct Construct 標準のAWS construct library 。抽象度により3つの種類が存在 L1 コンストラクト: 最も低レベルで、CFn のリソースと同じプロパティ。これがあるた め、CFn で出来ることはCDK で出来る、と⾔える L2 コンストラクト: 最も基本となるCDK らしいコンストラクト。特定のリソースを表す クラスであり、便利メソッドがたくさん⽣えている。 L3 コンストラクト( 別名 パターン): ハイレベルなコンストラクトで、よくあるパターンが事前定義され たパッケージ。独特な要件がなく、これを使⽤するとコード⾏数が ⼤幅に減る。 カスタムコンストラクト 上記の標準コンストラクトを元に独⾃作成するコンストラクト サードパーティのコンストラクト 個⼈や団体が配布しているものもある。プロダクションで使⽤する 場合は要確認。 App とStack は「特 殊な役割のコンスト ラクト」 https://docs.aws. amazon.com/cdk/ api/v2/docs/aws- construct- library.html construc… Construct Hub Construct Hub helps develope…
  10. 環境毎の実⾏時変数や設定値の DI も容易に可能 - 2. 「 DI / Configuration 」について

    値の種類とそれを適⽤する⽅法⼀覧 パラメータ種別 CDK の設定⽅法 備考 アカウント情報 CLI のプロファイルから取 得する コードに直接記述する 複数同時に開発する場合、誤 デプロイを避けるため、コー ドに直接書くのが無難 ⼀般的なパラメータ ex) ⾮機密的な環境変数 環境毎に指定する既存リ ソースが異なるなど cdk.json に記述 → 使⽤するコンストラクト 内で取得 → 必要とするコンストラク トに渡す。 parameter.ts に記述 → 環境毎のパラメータが多 い場合、別の設定ファイル に切り出すと良い( 型が効 くことからTypescript での み実質可能) 既存のparameter store から取 得してくることも可能 クレデンシャル ex) DB のパスワードや各種ア クセスキーなど secret manager を作成 → 使⽤するコンストラクト 内で取得し、必要とするコ ンストラクトに渡す。 既存のsecret manager をARN を指定して取得することも可 能。(既存のものを使⽤でき るのは全リソースがそう)
  11. CD CI パイプライン⾃体をモデリング ( コ ード表現 ) する 「CD CI

    」について 1. `stage` により表現されたパイプラインの⼀例 1 Source Stage リポジトリからソースコードを取得 2 Install Stage 依存ライブラリの取得 ソースのコンパイル Unit テスト実⾏ 3 Synth Stage インフラの同期 4 Assets Stage S3 にアセット配置 ECR にコンテナ配置 5 Dev Deploy Stage dev 環境にデプロイ Integration テスト実⾏ Load テスト実⾏ 6 Approval Stage コンソールからの⼿動承認をフロー に⼊れる 7 Prod Deploy Stage 本番デプロイ
  12. 今後の動向について pulumi やInfrastructure from Code (IfC) などという発展的概念がどんどん出てきている https://tmokmss.hatenablog.com/entry/survey_on_infrastructure_from_code 定義が曖昧なマーケティング⽤語 ひとつは、「アプリケーションコードを書けば、決まったインフラコードは書かずに⾃動⽣成すれ

    ば良い」ということ? https://infrastructurefromcode.com/ あるいは、「インフラリソースは第⼀級市⺠である」と⾔うこと? https://www.winglang.io/ インフラコードとアプリコードが同⼀⾔語で、同⼀ファイルに混ざって書かれてきている。 bring cloud; let queue = new cloud.Queue(timeout: 2m); let bucket = new cloud.Bucket(); let counter = new cloud.Counter(initial: 100); queue.setConsumer(inflight (body: str): str => { let next = counter.inc(); let key = "myfile-${next}.txt"; bucket.put(key, body); }); (inflight 以降の) 関数をコンシューマに登録したSQS ですよ。関数とは、受け取った⽂字列を元にバケ ットにデータを書き込む。その際にアトミックなカウンターとしてDynamoDB を使いますよ。という サービスが作成される。 クラスメソッド株式会社 【アプリもインフラも1 つの⾔語で書ける】Wingのチュート… 最近Infrastructure from Code ( IfC) という概念を知りました。 とり あえず、触って雰囲気を掴みたいと思いWingのチュートリアルをや…
  13. 追加のリソース集 1. ⼊⾨ /API リファレンス CDK ワークショップ https://cdkworkshop.com/ja/20-typescript.html ⽇本語あり。紹介しなかったgetting start

    的な⽅法がわかる。 ⾔語はCDK やるなら基本typescript が 良い。 公式doc https://docs.aws.amazon.com/cdk/ ⾔わずもがな 2. コンセプトのさらなる理解 The CDK Book https://www.thecdkbook.com/ 書籍ならこれかな?と⾔う感じ。公式doc を読み込めばこちらは不要かも。 3. サンプルコード系 Baseline Environment on AWS (BLEA) https://github.com/aws-samples/baseline-environment-on-aws AWS Japan の⼈が公開している、ベースラインとしてのセキュアな構成が実現されているテンプレ ート。複数のワークロードが公開されている。 現状、ここからパクってカスタマイズしていくのが良いのではないか。 初学者向けにコメントが⼊っていることもあり、勉強にもなる。 Servreless land https://serverlessland.com/ イベント駆動やサーバレスアーキテクチャの学習/ パターン集サイト。CDK 関係なくおすすめ。 EDA を構築するサンプルにCDK コードも含まれる ECS blue print https://github.com/aws-ia/ecs-blueprints/tree/main/cdk ECS 使⽤パターンのテンプレとして参考に aws-samples https://github.com/aws-samples/aws-cdk-examples
  14. Infrastructure as Code é Infrastructure is Code 54:47 YouTube AWS

    re:Invent 2018: Infrastructure Is Code with the AW… The AWS Cloud Development Kit ( AWS CDK) is a new open- source framework from AWS that enables developers to harnes…