はじめに
普段、AWSリソースを構築する際は、
①まずAWSコンソールで手動構築してみる
②公式ドキュメントを参照しながらコード化(IaC)する
③両方の差分を確認しながらコードを修正していく
といった手順でおこなっていました。
AWSにはIaCコードを作成するための便利な機能がいくつか用意されているため、今回はその中の一つである「IaCジェネレーター」を実際に使ってみました。
IaCジェネレーターとは
AWS IaC Generator(Infrastructure as Code Generator)は、既存のAWSリソース(VPC・EC2・S3など)をスキャンして、それを再現できるIaCコード(主にCloudFormationテンプレート)を自動生成する機能です。
実際に今AWS環境に存在するリソースをコードに変換してくれるツールとなります。
今回IaCジェネレートするインフラ構成図
こちらの構成をAWSコンソール上で手動構築した後、IaCジェネレーターでコード化してみようと思います。
「ベストプラクティス」かはわかりませんが、すでにCloudFormationで単一スタックとして定義したコードはこちらの記事にありますので、ぜひ比較対象としてご参照ください。
まずは手動構築する
手動で構築する手順に関してはこちらの記事をご参照ください。
後でIaCジェネレーターでリソースのフィルタリングを行いますので、手動で作成するすべてのリソースに共通のタグをつけておきます。
IaCジェネレーターを使う
①CloudFormation > IaCジェネレーターに移動します。
②「新しいスキャンを開始」タブを開きます。
③すべてのリソースをスキャンを押します。
※1日にスキャンできる回数には上限があります
しばらく待ち、スキャンが完了したらテンプレートを作成を押します。
①新しいテンプレートから開始を選択します。
②「テンプレート名」を入力します。
③④「削除ポリシー」と「置換ポリシーを更新」はどちらも削除を選択します。
(リソースを残さないため)
⑤次へを押します。
「スキャンしたリソースを追加」画面に移動したら、
①手動作成した際に設定したタグでフィルタリング検索します。
②対象のAWSリソースをすべてチェックします。
③次へを押します。
「関連リソースを追加」画面では、関連するリソースをテンプレートに含めるかを提案してくれます。必要なリソースがあればここで追加しますが、今回は先程フィルタリングしたリソースがすべてなので
①すべてのチェックを外します。
②次へを押します。
「確認して作成」画面になるので、内容に問題なければテンプレートを作成を押して完了です。
実際に作成されたテンプレート(一部***でマスクしています)
---
Metadata:
AWSToolsMetrics:
IaC_Generator: "***"
Resources:
EC2Subnet:
UpdateReplacePolicy: "Delete"
Type: "AWS::EC2::Subnet"
DeletionPolicy: "Delete"
Properties:
MapPublicIpOnLaunch: false
EnableDns64: false
VpcId: "vpc-***"
AvailabilityZoneId: "apne1-az4"
PrivateDnsNameOptionsOnLaunch:
EnableResourceNameDnsARecord: false
HostnameType: "ip-name"
EnableResourceNameDnsAAAARecord: false
AvailabilityZone: "ap-northeast-1a"
CidrBlock: "10.0.1.0/24"
Ipv6Native: false
Tags:
- Value: "IaC"
Key: "IaC"
- Value: "public-subnet-a"
Key: "Name"
EC2SecurityGroup:
UpdateReplacePolicy: "Delete"
Type: "AWS::EC2::SecurityGroup"
DeletionPolicy: "Delete"
Properties:
GroupDescription: "test-sg"
GroupName: "test-sg"
VpcId: "vpc-***"
SecurityGroupIngress:
- CidrIp: "0.0.0.0/0"
IpProtocol: "tcp"
FromPort: 80
ToPort: 80
SecurityGroupEgress:
- CidrIp: "0.0.0.0/0"
IpProtocol: "-1"
FromPort: -1
ToPort: -1
Tags:
- Value: "IaC"
Key: "IaC"
EC2Instance:
UpdateReplacePolicy: "Delete"
Type: "AWS::EC2::Instance"
DeletionPolicy: "Delete"
Properties:
Tenancy: "default"
PrivateIpAddress: "10.0.1.131"
MetadataOptions:
HttpPutResponseHopLimit: 2
HttpProtocolIpv6: "disabled"
HttpTokens: "required"
InstanceMetadataTags: "disabled"
HttpEndpoint: "enabled"
UserData: "***"
InstanceInitiatedShutdownBehavior: "stop"
BlockDeviceMappings:
- Ebs:
SnapshotId: "snap-***"
VolumeType: "gp3"
Iops: 3000
VolumeSize: 8
Encrypted: false
DeleteOnTermination: true
DeviceName: "/dev/xvda"
PrivateDnsNameOptions:
EnableResourceNameDnsARecord: false
HostnameType: "ip-name"
EnableResourceNameDnsAAAARecord: false
SecurityGroupIds:
- "sg-***"
EbsOptimized: false
DisableApiTermination: false
SourceDestCheck: true
PlacementGroupName: ""
NetworkInterfaces:
- Ipv6Addresses: []
SecondaryPrivateIpAddressCount: 0
NetworkInterfaceId: "eni-***"
DeviceIndex: "0"
ImageId: "ami-***"
InstanceType: "t2.micro"
Monitoring: false
Tags:
- Value: "IaC"
Key: "IaC"
- Value: "test-server"
Key: "Name"
CreditSpecification:
CPUCredits: "standard"
EC2VPC:
UpdateReplacePolicy: "Delete"
Type: "AWS::EC2::VPC"
DeletionPolicy: "Delete"
Properties:
CidrBlock: "10.0.0.0/16"
EnableDnsSupport: true
InstanceTenancy: "default"
EnableDnsHostnames: false
Tags:
- Value: "test-vpc"
Key: "Name"
- Value: "IaC"
Key: "IaC"
EC2RouteTable:
UpdateReplacePolicy: "Delete"
Type: "AWS::EC2::RouteTable"
DeletionPolicy: "Delete"
Properties:
VpcId: "vpc-***"
Tags:
- Value: "test-rt-a"
Key: "Name"
- Value: "IaC"
Key: "IaC"
EC2InternetGateway:
UpdateReplacePolicy: "Delete"
Type: "AWS::EC2::InternetGateway"
DeletionPolicy: "Delete"
Properties:
Tags:
- Value: "test-igw"
Key: "Name"
- Value: "IaC"
Key: "IaC"
使ってみた感想と注意点
勉強になる
いきなり公式ドキュメントを参照しながらコードを書くのは大変です。
そんなときに、IaCジェネレーターが作成したこのコードをパラメータなどの参考に使うのはありだと思いました。
完全なIaC/ベストプラクティスではない
IaCジェネレーターは「現在の状態をそのまま写す」ため、既存リソースIDが直書きされています。
生成されたコードはそのまま使えるとは限らないので、必ずレビューをし、修正を加えることを前提に使用すると良さそうです。
また、「ベストプラクティス」の定義は使用目的やチームにより変わりますが、「命名」や「構成」も修正していく必要がありそうです。
サポート外リソースあり
すべてのAWSサービスに対応しているわけではないようです。
完全に頼りきるのではなく、一部のAWSリソースだけでもコード化して参考にする、といった使い方をするのが良さそうです。





