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

AWS Infrastructure Composerの良さを伝えたい

NaoyaYamamoto
April 21, 2025
270

AWS Infrastructure Composerの良さを伝えたい

JAWS-UG東京
ランチタイムLT会 #22
2025年4月22日 (火)

NaoyaYamamoto

April 21, 2025
Tweet

Transcript

  1. 名前:山本 直弥 (SNSでは Nao) 所属:株式会社シーイーシー 在住:名古屋、出身:京都 2025~ AWS Community Builder(DevTools)

    2025~ JAWS-UG 名古屋 運営メンバー 2023-2024 Japan AWS All Certifications Engineer 個人的コミュニティ活動のテーマ 「ツールの良さを伝えたい」(仮) ※Xのアイコン 自己紹介 今日はこれ
  2. AWS Infrastructure Composer(旧:Application Composer) とは? 2 • GUI操作でCfnテンプレートを 作成/編集/構成の視覚化 ができるツール

    アイコン (リソースの紐づけを表現?) 実際の画面 推しポイント4つ リソースを “カード”で表現 紐づけ(参照)が見える
  3. AWS Infrastructure Composerの推しポイント その1 3 • 既存CloudFormationテンプレートを構成図のように視覚化できる! <ないとき> <あるとき> {

    "Resources": { "TESTMyLambdaFunctionServiceRole6FF4D431": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { "Statement": [ { "Action": "sts:AssumeRole", "Effect": "Allow", "Principal": { "Service": "lambda.amazonaws.com" } } ], "Version": "2012-10-17" }, "ManagedPolicyArns": [ { "Fn::Join": [ "", [ "arn:", { "Ref": "AWS::Partition" }, ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" ] ] } ] }, "Metadata": { "aws:cdk:path": "CdkHelloWorldStack/TESTMyLambdaFunction/ServiceRole/Resource" } }, "TESTMyLambdaFunction8E16014C": { "Type": "AWS::Lambda::Function", "Properties": { "Code": { "S3Bucket": "cdk-hnb659fds-assets-111111111111-ap-northeast-1", "S3Key": "fe7e1908d59e783c3f2793117673f2e93c85f0ce91cd99bed0239de3d41e8d3b.zip" }, "Handler": "index.handler", "Role": { "Fn::GetAtt": [ "TESTMyLambdaFunctionServiceRole6FF4D431", "Arn" ] }, "Runtime": "nodejs20.x" }, "DependsOn": [ "TESTMyLambdaFunctionServiceRole6FF4D431" ], "Metadata": { "aws:cdk:path": "CdkHelloWorldStack/TESTMyLambdaFunction/Resource", "aws:asset:path": "asset.fe7e1908d59e783c3f2793117673f2e93c85f0ce91cd99bed0239de3d41e8d3b", "aws:asset:is-bundled": false, "aws:asset:property": "Code" } }, "MyApiGateway04A753E5": { "Type": "AWS::ApiGateway::RestApi", "Properties": { "Name": "MyApiGateway" }, "Metadata": { "aws:cdk:path": "CdkHelloWorldStack/MyApiGateway/Resource" } }, "MyApiGatewayDeployment44AAC0313efdafc08b1d170892a3a89794c0f77f": { "Type": "AWS::ApiGateway::Deployment", "Properties": { "Description": "Automatically created by the RestApi construct", "RestApiId": { "Ref": "MyApiGateway04A753E5" } }, "DependsOn": [ "MyApiGatewayitemsGETBDFA38EE", "MyApiGatewayitemsPOST3EB9C420", "MyApiGatewayitemsAC8CBE57" ], "Metadata": { "aws:cdk:path": "CdkHelloWorldStack/MyApiGateway/Deployment/Resource" } }, "MyApiGatewayDeploymentStageprodEBC77C1B": { "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { "Ref": "MyApiGatewayDeployment44AAC0313efdafc08b1d170892a3a89794c0f77f" }, "RestApiId": { "Ref": "MyApiGateway04A753E5" }, "StageName": "prod" }, "Metadata": { "aws:cdk:path": "CdkHelloWorldStack/MyApiGateway/DeploymentStage.prod/Resource" } }, "MyApiGatewayitemsAC8CBE57": { "Type": "AWS::ApiGateway::Resource", "Properties": { "ParentId": { "Fn::GetAtt": [ "MyApiGateway04A753E5", "RootResourceId" ] }, 長いコードを読んで 構成把握、参照が 壊れていないかチェック 構成が図で示されるので構成が一目でわかる 定義漏れがないかの確認も簡単 Composerで表示 VSCodeで開いた画面
  4. AWS Infrastructure Composerの推しポイント その2 4 • 穴埋め形式でリソースのプロパティ定義が可能! <ないとき> <あるとき> {

    "Resources": { "TESTMyLambdaFunctionServiceRole6FF4D431": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { "Statement": [ { "Action": "sts:AssumeRole", "Effect": "Allow", "Principal": { "Service": "lambda.amazonaws.com" } } ], "Version": "2012-10-17" }, "ManagedPolicyArns": [ { "Fn::Join": [ "", [ "arn:", { "Ref": "AWS::Partition" }, ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" ] ] } ] }, "Metadata": { "aws:cdk:path": "CdkHelloWorldStack/TESTMyLambdaFunction/ServiceRole/Resource" } }, "TESTMyLambdaFunction8E16014C": { "Type": "AWS::Lambda::Function", "Properties": { "Code": { "S3Bucket": "cdk-hnb659fds-assets-111111111111-ap-northeast-1", "S3Key": "fe7e1908d59e783c3f2793117673f2e93c85f0ce91cd99bed0239de3d41e8d3b.zip" }, "Handler": "index.handler", "Role": { "Fn::GetAtt": [ "TESTMyLambdaFunctionServiceRole6FF4D431", "Arn" ] }, "Runtime": "nodejs20.x" }, "DependsOn": [ "TESTMyLambdaFunctionServiceRole6FF4D431" ], "Metadata": { "aws:cdk:path": "CdkHelloWorldStack/TESTMyLambdaFunction/Resource", "aws:asset:path": "asset.fe7e1908d59e783c3f2793117673f2e93c85f0ce91cd99bed0239de3d41e8d3b", "aws:asset:is-bundled": false, "aws:asset:property": "Code" } }, "MyApiGateway04A753E5": { "Type": "AWS::ApiGateway::RestApi", "Properties": { "Name": "MyApiGateway" }, "Metadata": { "aws:cdk:path": "CdkHelloWorldStack/MyApiGateway/Resource" } }, "MyApiGatewayDeployment44AAC0313efdafc08b1d170892a3a89794c0f77f": { "Type": "AWS::ApiGateway::Deployment", "Properties": { "Description": "Automatically created by the RestApi construct", "RestApiId": { "Ref": "MyApiGateway04A753E5" } }, "DependsOn": [ "MyApiGatewayitemsGETBDFA38EE", "MyApiGatewayitemsPOST3EB9C420", "MyApiGatewayitemsAC8CBE57" ], "Metadata": { "aws:cdk:path": "CdkHelloWorldStack/MyApiGateway/Deployment/Resource" } }, "MyApiGatewayDeploymentStageprodEBC77C1B": { "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { "Ref": "MyApiGatewayDeployment44AAC0313efdafc08b1d170892a3a89794c0f77f" }, "RestApiId": { "Ref": "MyApiGateway04A753E5" }, "StageName": "prod" }, "Metadata": { "aws:cdk:path": "CdkHelloWorldStack/MyApiGateway/DeploymentStage.prod/Resource" } }, "MyApiGatewayitemsAC8CBE57": { "Type": "AWS::ApiGateway::Resource", "Properties": { "ParentId": { "Fn::GetAtt": [ "MyApiGateway04A753E5", "RootResourceId" ] }, プロパティ名と値を 覚えて手動で書き込む 定義する項目の順番など メンバー間で差が出るかも 穴埋め形式なので、 書き込みが必要最低限 メンバー間の差異が生じにくい 拡張コンポーネント(後述) のみ
  5. AWS Infrastructure Composerの推しポイント その3 5 • StepFunctionsワークフローStudioがローカル(VSCode上)でも動かせる! <ないとき> <あるとき> {

    "Resources": { "TESTMyLambdaFunctionServiceRole6FF4D431": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { "Statement": [ { "Action": "sts:AssumeRole", "Effect": "Allow", "Principal": { "Service": "lambda.amazonaws.com" } } ], "Version": "2012-10-17" }, "ManagedPolicyArns": [ { "Fn::Join": [ "", [ "arn:", { "Ref": "AWS::Partition" }, ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" ] ] } ] }, "Metadata": { "aws:cdk:path": "CdkHelloWorldStack/TESTMyLambdaFunction/ServiceRole/Resource" } }, "TESTMyLambdaFunction8E16014C": { "Type": "AWS::Lambda::Function", "Properties": { "Code": { "S3Bucket": "cdk-hnb659fds-assets-111111111111-ap-northeast-1", "S3Key": "fe7e1908d59e783c3f2793117673f2e93c85f0ce91cd99bed0239de3d41e8d3b.zip" }, "Handler": "index.handler", "Role": { "Fn::GetAtt": [ "TESTMyLambdaFunctionServiceRole6FF4D431", "Arn" ] }, "Runtime": "nodejs20.x" }, "DependsOn": [ "TESTMyLambdaFunctionServiceRole6FF4D431" ], "Metadata": { "aws:cdk:path": "CdkHelloWorldStack/TESTMyLambdaFunction/Resource", "aws:asset:path": "asset.fe7e1908d59e783c3f2793117673f2e93c85f0ce91cd99bed0239de3d41e8d3b", "aws:asset:is-bundled": false, "aws:asset:property": "Code" } }, "MyApiGateway04A753E5": { "Type": "AWS::ApiGateway::RestApi", "Properties": { "Name": "MyApiGateway" }, "Metadata": { "aws:cdk:path": "CdkHelloWorldStack/MyApiGateway/Resource" } }, "MyApiGatewayDeployment44AAC0313efdafc08b1d170892a3a89794c0f77f": { "Type": "AWS::ApiGateway::Deployment", "Properties": { "Description": "Automatically created by the RestApi construct", "RestApiId": { "Ref": "MyApiGateway04A753E5" } }, "DependsOn": [ "MyApiGatewayitemsGETBDFA38EE", "MyApiGatewayitemsPOST3EB9C420", "MyApiGatewayitemsAC8CBE57" ], "Metadata": { "aws:cdk:path": "CdkHelloWorldStack/MyApiGateway/Deployment/Resource" } }, "MyApiGatewayDeploymentStageprodEBC77C1B": { "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { "Ref": "MyApiGatewayDeployment44AAC0313efdafc08b1d170892a3a89794c0f77f" }, "RestApiId": { "Ref": "MyApiGateway04A753E5" }, "StageName": "prod" }, "Metadata": { "aws:cdk:path": "CdkHelloWorldStack/MyApiGateway/DeploymentStage.prod/Resource" } }, "MyApiGatewayitemsAC8CBE57": { "Type": "AWS::ApiGateway::Resource", "Properties": { "ParentId": { "Fn::GetAtt": [ "MyApiGateway04A753E5", "RootResourceId" ] }, コード手書きで ステートマシン組むの 無理ゲーすぎる マネコンのあの 便利機能が ローカルで使える
  6. AWS Infrastructure Composerの推しポイント その4 6 • 他にもいろいろ、“GUIならでは”の便利機能がたくさん 変更点も見えて安心 構成図も好みで見やすくできる リソース間の関連付けは紐をひっぱるだけ

    変更した内容はコードで差分表示 リソースをグループ化して可視性アップ (グループの中にグループを作ることもできる) 注意ポイント3つ
  7. AWS Infrastructure Composerの注意点 その1 8 • 拡張コンポーネントと標準コンポーネントの違い (楽なのは拡張の方) <拡張コンポーネント> <標準コンポーネント>

    穴埋め式定義は 拡張コンポーネント 標準コンポーネントは リソース毎のこのスペースに 手動で定義が必要 AmazonQにより、 ワンクリック定義提案 (VSCode上のみ) こりゃ楽だ これは手動定義
  8. AWS Infrastructure Composerの注意点 その3 10 • リソースをつなげると、ポリシーも作ってくれるが・・・ 無造作に2つのカードを置いただけ <自動定義される内容> ・Lambdaファンクション

    ・Lambdaファンクションロググループ ・S3バケット ・S3バケットポリシー (全部Deny) 2つのカードを つなげるとどうなるか LambdaからS3に アクセスしたい・・・
  9. AWS Infrastructure Composerの注意点 その3 11 • リソースをつなげると、ポリシーも作ってくれるが・・・作りすぎ カードを紐づけた <自動定義される内容 (追加されたポリシー)>

    Environment: Variables: BUCKET_BUCKET_NAME: !Ref Bucket BUCKET_BUCKET_ARN: !GetAtt Bucket.Arn Policies: - Statement: - Effect: Allow Action: - s3:GetObject - s3:GetObjectAcl - s3:GetObjectLegalHold - s3:GetObjectRetention - s3:GetObjectTorrent - s3:GetObjectVersion - s3:GetObjectVersionAcl - s3:GetObjectVersionForReplication - s3:GetObjectVersionTorrent - s3:ListBucket - s3:ListBucketMultipartUploads - s3:ListBucketVersions - s3:ListMultipartUploadParts - s3:AbortMultipartUpload - s3:DeleteObject - s3:DeleteObjectVersion - s3:PutObject - s3:PutObjectLegalHold - s3:PutObjectRetention - s3:RestoreObject Resource: - !Sub arn:${AWS::Partition}:s3:::${Bucket} - !Sub arn:${AWS::Partition}:s3:::${Bucket}/* 必要ないアクションも 許可されてしまっているかも 最小限にしたい場合は修正が必要 オブジェクトの取得も更新も削除も ほとんど何でもできるポリシー
  10. まとめ 12 • InfraStructure Composerは特にサーバレスな構成(SAM)の定義で有効 ※SAM (AWS Serverless Application Model

    ) IaCを使用してサーバーレスアプリケーションを構築するためのオープンソースフレームワーク • 標準コンポーネントでも既存CloudFormationテンプレートの内容を 構成図で確認することができる • ワンクリックコード提案やポリシー自動追加など便利で簡単な操作ゆえの弱みもある 自動生成コードが、ざっくり作られすぎていないか確認と修正が必要 弱みもあるけど、よろしくネ 人もツールも弱みがあるからカワイイ