Slide 1

Slide 1 text

株式会社Relic エンジニア 保 龍児(エイミ/amixedcolor) CloudFormationコンソールから、 実際に作られたリソースを辿れるように なろう!

Slide 2

Slide 2 text

2 • CDKをこれから使いたい • CloudFormationを使ったことはない 想定聴衆

Slide 3

Slide 3 text

3 今日のゴール CloudFormationコンソールから 実際に作られたリソースを 辿れるようになる

Slide 4

Slide 4 text

4 今日のゴール CloudFormation コンソールから 実際に作られた リソースを 辿れるようになる

Slide 5

Slide 5 text

5 おまけ CDKによる簡便な記法を体感する

Slide 6

Slide 6 text

6 自己紹介 保 龍児(エイミ/amixedcolor) 2025 Japan AWS Jr. Champion 業務内容 : 自社新規事業SaaS開発リーダー エンジニア(WebアプリFE/BE/インフラ) 好きなトピック : アジャイル、スクラム、新規事業開発、 AWS、完全没入型仮想現実 よくいるコミュニティ : AWSコミュニティ、アジャイルコミュニティ @amixedcolor

Slide 7

Slide 7 text

7 • 「コンソールからリソースを辿れるようになる」に焦点を当てて いるため、周辺の説明はざっくりとしたものです 留意事項

Slide 8

Slide 8 text

8 CDKでVPCをデプロイした!

Slide 9

Slide 9 text

9 デプロイしたVPCを見てみよう!

Slide 10

Slide 10 text

10 わっ!?

Slide 11

Slide 11 text

11 「どれだ…?」

Slide 12

Slide 12 text

12 そんなあなたに聞いて欲しい!

Slide 13

Slide 13 text

13 そもそも・・・

Slide 14

Slide 14 text

14 Q: CDKはどうやってリソースを 構築する?

Slide 15

Slide 15 text

15 Q: CDKはどうやってリソースを 構築する?

Slide 16

Slide 16 text

16 A: CloudFormationテンプレートを 介して構築する

Slide 17

Slide 17 text

17 A: CloudFormationテンプレートを 介して構築する

Slide 18

Slide 18 text

18 A: CloudFormationテンプレート を 介して構築する

Slide 19

Slide 19 text

19 構築されたリソースは CloudFormationコンソール から辿れる!

Slide 20

Slide 20 text

20 今回デプロイするリソースの説明

Slide 21

Slide 21 text

21 構成図 AWS Cloud Virtual private cloud (VPC) Internet gateway Public subnet Public subnet Amazon Elastic Compute Cloud (Amazon EC2) Role Permissions AmazonSSMManagedInstanceCore Internet

Slide 22

Slide 22 text

22 構成図 AWS Cloud Virtual private cloud (VPC) Internet gateway Public subnet Public subnet Amazon Elastic Compute Cloud (Amazon EC2) Role Permissions AmazonSSMManagedInstanceCore Internet

Slide 23

Slide 23 text

23 構成図 AWS Cloud Virtual private cloud (VPC) Internet gateway Public subnet Public subnet Amazon Elastic Compute Cloud (Amazon EC2) Role Permissions AmazonSSMManagedInstanceCore Internet

Slide 24

Slide 24 text

24 構成図 AWS Cloud Virtual private cloud (VPC) Internet gateway Public subnet Public subnet Amazon Elastic Compute Cloud (Amazon EC2) Role Permissions AmazonSSMManagedInstanceCore Internet

Slide 25

Slide 25 text

25 構成図 AWS Cloud Virtual private cloud (VPC) Internet gateway Public subnet Public subnet Amazon Elastic Compute Cloud (Amazon EC2) Role Permissions AmazonSSMManagedInstanceCore Internet

Slide 26

Slide 26 text

26 構成図 AWS Cloud Virtual private cloud (VPC) Internet gateway Public subnet Public subnet Amazon Elastic Compute Cloud (Amazon EC2) Role Permissions AmazonSSMManagedInstanceCore Internet

Slide 27

Slide 27 text

27 構成図 AWS Cloud Virtual private cloud (VPC) Internet gateway Public subnet Public subnet Amazon Elastic Compute Cloud (Amazon EC2) Role Permissions AmazonSSMManagedInstanceCore Internet

Slide 28

Slide 28 text

28 構成図 AWS Cloud Virtual private cloud (VPC) Internet gateway Public subnet Public subnet Amazon Elastic Compute Cloud (Amazon EC2) Role Permissions AmazonSSMManagedInstanceCore Internet

Slide 29

Slide 29 text

29 構成図 AWS Cloud Virtual private cloud (VPC) Internet gateway Public subnet Public subnet Amazon Elastic Compute Cloud (Amazon EC2) Role Permissions AmazonSSMManagedInstanceCore Internet

Slide 30

Slide 30 text

30 #!/usr/bin/env node import * as cdk from 'aws-cdk-lib'; import { CdkLtStack } from '../lib/cdk-lt-stack'; import { CdkLtStack as CdkLtStackPredeployed } from '../lib/cdk-lt-stack’; const app = new cdk.App(); new CdkLtStack(app, 'CdkLtDemoStack', {}); new CdkLtStackPredeployed(app, 'CdkLtDemoStackPredeployed', {}); cdk.Tags.of(app).add('Project', 'CDK-LT-Demo'); cdk.Tags.of(app).add('Deletion Policy', '202511'); cdk.Tags.of(app).add('CreatedBy', 'tatsuji.ho'); ソースコード①:bin/app.ts

Slide 31

Slide 31 text

31 import * as cdk from 'aws-cdk-lib'; import { Construct } from 'constructs'; import * as ec2 from 'aws-cdk-lib/aws-ec2'; // EC2 (VPC, Instance) import * as iam from 'aws-cdk-lib/aws-iam'; // IAM (Role) ソースコード②:cdk-lt-stack.ts(1/4)

Slide 32

Slide 32 text

32 export class CdkLtStack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); const vpc = new ec2.Vpc(this, 'MyVpc', { vpcName: 'cdk-lt-vpc', maxAzs: 2 subnetConfiguration: [ { cidrMask: 24, name: 'Public', subnetType: ec2.SubnetType.PUBLIC, }, ], }); cdk.Tags.of(vpc).add('Name', 'cdk-lt-vpc'); ソースコード②:cdk-lt-stack.ts(2/4)

Slide 33

Slide 33 text

33 const ec2Role = new iam.Role(this, 'Ec2SsmRole', { assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com'), managedPolicies: [ iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonSSMManagedInstanceCore'), ], }); const instance = new ec2.Instance(this, 'MyEc2Instance', { vpc: vpc, instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.MICRO), machineImage: ec2.MachineImage.latestAmazonLinux2023(), vpcSubnets: { subnetType: ec2.SubnetType.PUBLIC, }, associatePublicIpAddress: true, role: ec2Role, }); cdk.Tags.of(instance).add('Name', 'cdk-lt-instance'); ソースコード②:cdk-lt-stack.ts(3/4)

Slide 34

Slide 34 text

34 new cdk.CfnOutput(this, 'VpcIdOutput', { value: vpc.vpcId, description: 'Created VPC ID', exportName: 'CdkLtDemoVpcId', // 他のスタックから参照する場合の名前 }); new cdk.CfnOutput(this, 'InstanceIdOutput', { value: instance.instanceId, description: 'Created EC2 Instance ID', }); new cdk.CfnOutput(this, 'InstancePublicIpOutput', { value: instance.instancePublicIp, description: 'EC2 Instance Public IP', }); } } ソースコード②:cdk-lt-stack.ts(4/4)

Slide 35

Slide 35 text

35 実際に辿ってみる

Slide 36

Slide 36 text

36 CloudFormationコンソールにアクセス スタック名はapp.tsで渡した文字列(引数としてはid)

Slide 37

Slide 37 text

37 #!/usr/bin/env node import * as cdk from 'aws-cdk-lib'; import { CdkLtStack } from '../lib/cdk-lt-stack'; import { CdkLtStack as CdkLtStackPredeployed } from '../lib/cdk-lt-stack’; const app = new cdk.App(); new CdkLtStack(app, 'CdkLtDemoStack', {}); new CdkLtStackPredeployed(app, 'CdkLtDemoStackPredeployed', {}); cdk.Tags.of(app).add('Project', 'CDK-LT-Demo'); cdk.Tags.of(app).add('Deletion Policy', '202511'); cdk.Tags.of(app).add('CreatedBy', 'tatsuji.ho'); ソースコード①:bin/app.ts 再掲

Slide 38

Slide 38 text

38 #!/usr/bin/env node import * as cdk from 'aws-cdk-lib'; import { CdkLtStack } from '../lib/cdk-lt-stack'; import { CdkLtStack as CdkLtStackPredeployed } from '../lib/cdk-lt-stack’; const app = new cdk.App(); new CdkLtStack(app, 'CdkLtDemoStack', {}); new CdkLtStackPredeployed(app, 'CdkLtDemoStackPredeployed', {}); cdk.Tags.of(app).add('Project', 'CDK-LT-Demo'); cdk.Tags.of(app).add('Deletion Policy', '202511'); cdk.Tags.of(app).add('CreatedBy', 'tatsuji.ho'); ソースコード①:bin/app.ts 再掲

Slide 39

Slide 39 text

39 スタックを選択すると横に情報が出てくる

Slide 40

Slide 40 text

40 「リソース」タブに切り替えることでリソースを辿れる デフォルトのビューは「ツリービュー」

Slide 41

Slide 41 text

41 「フラットビュー」で一覧表示もできる

Slide 42

Slide 42 text

42 例えばMyVpcを開くと、押せそうなリンクがある その左の「論理ID」はコード上で指定した名前(id)

Slide 43

Slide 43 text

43 export class CdkLtStack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); const vpc = new ec2.Vpc(this, 'MyVpc', { vpcName: 'cdk-lt-vpc', maxAzs: 2 subnetConfiguration: [ { cidrMask: 24, name: 'Public', subnetType: ec2.SubnetType.PUBLIC, }, ], }); cdk.Tags.of(vpc).add('Name', 'cdk-lt-vpc'); ソースコード②:cdk-lt-stack.ts(2/4) 再掲

Slide 44

Slide 44 text

44 export class CdkLtStack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); const vpc = new ec2.Vpc(this, 'MyVpc', { vpcName: 'cdk-lt-vpc', maxAzs: 2 subnetConfiguration: [ { cidrMask: 24, name: 'Public', subnetType: ec2.SubnetType.PUBLIC, }, ], }); cdk.Tags.of(vpc).add('Name', 'cdk-lt-vpc'); ソースコード②:cdk-lt-stack.ts(2/4) 再掲

Slide 45

Slide 45 text

45 リンク先に飛ぶと(リソースにもよるがVPCは)一覧画面で、 物理IDによるフィルタがされている状態になる

Slide 46

Slide 46 text

46 従来通りその行をクリックして詳細を見れる

Slide 47

Slide 47 text

47 タグを確認すると、アプリケーション全体につけたタグは 個別のリソースにもついている(仕組み上のものもある)

Slide 48

Slide 48 text

48 #!/usr/bin/env node import * as cdk from 'aws-cdk-lib'; import { CdkLtStack } from '../lib/cdk-lt-stack'; import { CdkLtStack as CdkLtStackPredeployed } from '../lib/cdk-lt-stack’; const app = new cdk.App(); new CdkLtStack(app, 'CdkLtDemoStack', {}); new CdkLtStackPredeployed(app, 'CdkLtDemoStackPredeployed', {}); cdk.Tags.of(app).add('Project', 'CDK-LT-Demo'); cdk.Tags.of(app).add('Deletion Policy', '202511'); cdk.Tags.of(app).add('CreatedBy', 'tatsuji.ho'); ソースコード①:bin/app.ts 再掲

Slide 49

Slide 49 text

49 #!/usr/bin/env node import * as cdk from 'aws-cdk-lib'; import { CdkLtStack } from '../lib/cdk-lt-stack'; import { CdkLtStack as CdkLtStackPredeployed } from '../lib/cdk-lt-stack’; const app = new cdk.App(); new CdkLtStack(app, 'CdkLtDemoStack', {}); new CdkLtStackPredeployed(app, 'CdkLtDemoStackPredeployed', {}); cdk.Tags.of(app).add('Project', 'CDK-LT-Demo'); cdk.Tags.of(app).add('Deletion Policy', '202511'); cdk.Tags.of(app).add('CreatedBy', 'tatsuji.ho'); ソースコード①:bin/app.ts 再掲

Slide 50

Slide 50 text

50 コードで指定した通り、サブネットは2つ作られている

Slide 51

Slide 51 text

51 export class CdkLtStack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); const vpc = new ec2.Vpc(this, 'MyVpc', { vpcName: 'cdk-lt-vpc', maxAzs: 2 subnetConfiguration: [ { cidrMask: 24, name: 'Public', subnetType: ec2.SubnetType.PUBLIC, }, ], }); cdk.Tags.of(vpc).add('Name', 'cdk-lt-vpc'); ソースコード②:cdk-lt-stack.ts(2/4) 再掲

Slide 52

Slide 52 text

52 export class CdkLtStack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); const vpc = new ec2.Vpc(this, 'MyVpc', { vpcName: 'cdk-lt-vpc', maxAzs: 2 subnetConfiguration: [ { cidrMask: 24, name: 'Public', subnetType: ec2.SubnetType.PUBLIC, }, ], }); cdk.Tags.of(vpc).add('Name', 'cdk-lt-vpc'); ソースコード②:cdk-lt-stack.ts(2/4) 再掲

Slide 53

Slide 53 text

53 少し覗いてみると、リンクになっていない物理IDもある この場合はまず、このIDをコピーする

Slide 54

Slide 54 text

54 コピーしたIDで、対応するサービス上で検索をかける

Slide 55

Slide 55 text

55 対応するサービスは「タイプ」から大まかに把握できるが、たま にVPCのように「EC2」タイプでも「VPC」サービスになる

Slide 56

Slide 56 text

56 こちらのリソースにも同様にタグがつけられている

Slide 57

Slide 57 text

57 #!/usr/bin/env node import * as cdk from 'aws-cdk-lib'; import { CdkLtStack } from '../lib/cdk-lt-stack'; import { CdkLtStack as CdkLtStackPredeployed } from '../lib/cdk-lt-stack’; const app = new cdk.App(); new CdkLtStack(app, 'CdkLtDemoStack', {}); new CdkLtStackPredeployed(app, 'CdkLtDemoStackPredeployed', {}); cdk.Tags.of(app).add('Project', 'CDK-LT-Demo'); cdk.Tags.of(app).add('Deletion Policy', '202511'); cdk.Tags.of(app).add('CreatedBy', 'tatsuji.ho'); ソースコード①:bin/app.ts 再掲

Slide 58

Slide 58 text

58 #!/usr/bin/env node import * as cdk from 'aws-cdk-lib'; import { CdkLtStack } from '../lib/cdk-lt-stack'; import { CdkLtStack as CdkLtStackPredeployed } from '../lib/cdk-lt-stack’; const app = new cdk.App(); new CdkLtStack(app, 'CdkLtDemoStack', {}); new CdkLtStackPredeployed(app, 'CdkLtDemoStackPredeployed', {}); cdk.Tags.of(app).add('Project', 'CDK-LT-Demo'); cdk.Tags.of(app).add('Deletion Policy', '202511'); cdk.Tags.of(app).add('CreatedBy', 'tatsuji.ho'); ソースコード①:bin/app.ts 再掲

Slide 59

Slide 59 text

59 他のリソースのリンクの貼られ具合はこんな感じ

Slide 60

Slide 60 text

60 コードの「CfnOutput」で指定した出力も見れる

Slide 61

Slide 61 text

61 new cdk.CfnOutput(this, 'VpcIdOutput', { value: vpc.vpcId, description: 'Created VPC ID', exportName: 'CdkLtDemoVpcId', // 他のスタックから参照する場合の名前 }); new cdk.CfnOutput(this, 'InstanceIdOutput', { value: instance.instanceId, description: 'Created EC2 Instance ID', }); new cdk.CfnOutput(this, 'InstancePublicIpOutput', { value: instance.instancePublicIp, description: 'EC2 Instance Public IP', }); } } ソースコード②:cdk-lt-stack.ts(4/4) 再掲

Slide 62

Slide 62 text

62 new cdk.CfnOutput(this, 'VpcIdOutput', { value: vpc.vpcId, description: 'Created VPC ID', exportName: 'CdkLtDemoVpcId', // 他のスタックから参照する場合の名前 }); new cdk.CfnOutput(this, 'InstanceIdOutput', { value: instance.instanceId, description: 'Created EC2 Instance ID', }); new cdk.CfnOutput(this, 'InstancePublicIpOutput', { value: instance.instancePublicIp, description: 'EC2 Instance Public IP', }); } } ソースコード②:cdk-lt-stack.ts(4/4) 再掲

Slide 63

Slide 63 text

63 • スタック > リソース > ビューを選択 • ツリービュー:属しているツリーがわかる/ツリーを知りたい • フラットビュー:一覧でいち早く見つけたい/名称が不明 • 物理IDで辿る • リンクになっている:リンクを押下 • リンクになっていない: • まずIDをコピーする • タイプをもとに各サービスのコンソールに移動(必要に応じてWebで調べる) • 対応するリソースの検索窓にペーストし検索 • Outputもコンソールで閲覧可能 辿り方の整理

Slide 64

Slide 64 text

64 今日のゴール CloudFormationコンソールから 実際に作られたリソースを 辿れるようになる

Slide 65

Slide 65 text

大志ある挑戦を創造し、日本から世界へ 想いを持った挑戦者と共に走り、共に創る