目次
1.はじめに
2.テンプレート作成前準備
3.テンプレート例
4.テンプレートの構成説明
5.関数
6.AWS公式マニュアルの見方
7.ちなみに
8.おわりに
はじめに
前回はAIによるCloudFormationテンプレートの作成方法を邪道編としてアップしました。
しかし、AIにテンプレートを作成してもらう場合でも、作成物の真偽を人間側で判断する必要があります。
今回は真偽判断や作成物を手直しをできるよう構成や組み込み関数などの基礎をまとめました。
テンプレート作成前準備
コードエディターをインストール
今回はVisual Studio Codeを利用します。
Visual Studio Codeのインストール方法は下記を参照。
コードチェックアプリインストール
今回はCloudFormation Linterを利用します。
CloudFormation Linterのインストール方法は下記を参照。
コード管理ツールをインストール
テンプレートを管理するためコード管理のツールが有用です。
今回は使いませんが、普段はgitを使用しています。
テンプレート例
VPC、PublicSubnet、InternetGateway、VPCFlowlogsというシンプルな構成を作成するテンプレートを例とします。
下記はアーキテクチャイメージです。
自力でテンプレート作成しました。作成するリソースはAIに依頼した内容と同様です。
この自力作成テンプレートを使い、セッションや関数について説明します。
テンプレートは下記のとおりです。
AWSTemplateFormatVersion: '2010-09-09'
Description: Create VPC,InternetGateway,PublicSubnet
# ------------------------------------------------------------#
# Meta Data
# ------------------------------------------------------------#
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
- Label:
default: VPC Settings
Parameters:
- VPCName
- VPCCIDR
- PublicSubnetCIDR
- S3BucketName
# ------------------------------------------------------------#
# Input Parameters
# ------------------------------------------------------------#
Parameters:
VPCName:
Type: String
Default: test-qiita
VPCCIDR:
Type: String
Default: 10.10.0.0/16
PublicSubnetCIDR:
Type: String
Default: 10.10.51.0/20
S3BucketName:
Type: String
Description: Please fill in the bucket name for collecting VPC Flow Logs.
Resources:
# ------------------------------------------------------------#
# VPC
# ------------------------------------------------------------#
# VPC Create
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: !Ref VPCCIDR
EnableDnsSupport: true
EnableDnsHostnames: true
InstanceTenancy: default
Tags:
- Key: Name
Value: !Ref VPCName
VPCFlowLog:
Type: AWS::EC2::FlowLog
Properties:
ResourceId: !Ref VPC
ResourceType: VPC
TrafficType: ALL
LogDestinationType: s3
LogDestination: !Sub arn:aws:s3:::${S3BucketName}
# ------------------------------------------------------------#
# InternetGateway
# ------------------------------------------------------------#
# InternetGateway Create
InternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: !Sub InternetGateway-${VPCName}
VPCGatewayAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref VPC
InternetGatewayId: !Ref InternetGateway
# ------------------------------------------------------------#
# Subnet
# ------------------------------------------------------------#
PublicSubnet:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: !Ref PublicSubnetCIDR
AvailabilityZone: !Select [ 0, !GetAZs '' ]
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: !Sub subnet-${VPCName}-public
PublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub route-${VPCName}-public
PublicRoute:
Type: AWS::EC2::Route
DependsOn: VPC
Properties:
RouteTableId: !Ref PublicRouteTable
DestinationCidrBlock: '0.0.0.0/0'
GatewayId: !Ref InternetGateway
PublicSubnetRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnet
RouteTableId: !Ref PublicRouteTable
# ------------------------------------------------------------#
# OutPut Parameters
# ------------------------------------------------------------#
Outputs:
VPC:
Description: VPC ID
Value: !Ref VPC
PublicSubnetId:
Description: Public Subnet ID
Value: !Ref PublicSubnet
InternetGatewayId:
Description: Internet Gateway ID
Value: !Ref InternetGateway
テンプレートの構成説明
テンプレートのセクションは6つ程度あります。Resourceというセクションのみ必須です。
テンプレートを元によく使う4つのセクションを説明します。
より詳しく知りたい方は下記のAWS公式ドキュメントを参照ください。
Metadata(任意)
テンプレートに関する追加情報を提供するためのセクションです。
また、"AWS::CloudFormation::Interface"を使うことでParametar(任意)のグループ化とラベル付けを行えます。
今回はVPC Settingsでひとまとめにしたかったのでセクションを作成しました。
# ------------------------------------------------------------#
# Meta Data
# ------------------------------------------------------------#
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
- Label:
default: VPC Settings
Parameters:
- VPCName
- VPCCIDR
- PublicSubnetCIDR
- S3BucketName
ちなみに下記のようなテンプレートだとキャプチャのような画面になります。
# ------------------------------------------------------------#
# Meta Data
# ------------------------------------------------------------#
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
- Label:
default: VPC Settings
Parameters:
- VPCName
- VPCCIDR
- PublicSubnetCIDR
- Label:
default: S3 Flowlogs Settings
Parameters:
- S3BucketName
Parametar(任意)
Parametarセクションは、スタックの作成時にユーザーが入力できる値を定義します。
今回の場合だとVPC名とCIDRを任意に設定できるようにし、VPCフローログの保存先のバケット名を登録するようにしました。
ここで入力された値は、のちのResourcesセクションで!Refや!Subなどの組み込み関数を使って参照します。
# ------------------------------------------------------------#
# Input Parameters
# ------------------------------------------------------------#
Parameters:
VPCName:
Type: String
Default: test-qiita
VPCCIDR:
Type: String
Default: 10.10.0.0/16
PublicSubnetCIDR:
Type: String
Default: 10.10.51.0/20
S3BucketName:
Type: String
Description: Please fill in the bucket name for collecting VPC Flow Logs.
Resource(必須)
Resourceのことセクションのみ必須です。
Resourceセクションでは、作成または管理したいAWSリソースをリストし、それぞれのリソースに対して設定やプロパティを指定します。
作成リソースの前に
# ------------------------------------------------------------#
# VPC
# ------------------------------------------------------------#
などと書いているのは私の好みです。
作成されたリソースはCloudFormationのリソースタブから確認できます。
Resources:
# ------------------------------------------------------------#
# VPC
# ------------------------------------------------------------#
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: !Ref VPCCIDR
EnableDnsSupport: true
EnableDnsHostnames: true
InstanceTenancy: default
Tags:
- Key: Name
Value: !Ref VPCName
VPCFlowLog:
Type: AWS::EC2::FlowLog
Properties:
ResourceId: !Ref VPC
ResourceType: VPC
TrafficType: ALL
LogDestinationType: s3
LogDestination: !Sub arn:aws:s3:::${S3BucketName}
# ------------------------------------------------------------#
# InternetGateway
# ------------------------------------------------------------#
InternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: !Sub InternetGateway-${VPCName}
VPCGatewayAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref VPC
InternetGatewayId: !Ref InternetGateway
# ------------------------------------------------------------#
# Subnet
# ------------------------------------------------------------#
PublicSubnet:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: !Ref PublicSubnetCIDR
AvailabilityZone: !Select [ 0, !GetAZs '' ]
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: !Sub subnet-${VPCName}-public
PublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub route-${VPCName}-public
PublicRoute:
Type: AWS::EC2::Route
DependsOn: VPC
Properties:
RouteTableId: !Ref PublicRouteTable
DestinationCidrBlock: '0.0.0.0/0'
GatewayId: !Ref InternetGateway
PublicSubnetRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnet
RouteTableId: !Ref PublicRouteTable
Outputs(任意)
Outputsセクションでは、リソースの属性や他の重要な情報をユーザーや他のスタックに渡すことができます。
例えば、作成されたリソースのID、エンドポイント、またはURIなどを出力するのに使われます。
# ------------------------------------------------------------#
# OutPut Parameters
# ------------------------------------------------------------#
Outputs:
VPC:
Description: VPC ID
Value: !Ref VPC
PublicSubnetId:
Description: Public Subnet ID
Value: !Ref PublicSubnet
InternetGatewayId:
Description: Internet Gateway ID
Value: !Ref InternetGateway
Outputsセクションで指定された値はスタック作成後の出力タブで確認できます。
組み込み関数
!Ref
同テンプレート内で定義されたリソースを参照します。
例えば下記テンプレート内の!Ref VPCCIDRにはParametarセクションで入力した値が参照されます。
Resources:
# ------------------------------------------------------------#
# VPC
# ------------------------------------------------------------#
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: !Ref VPCCIDR
EnableDnsSupport: true
EnableDnsHostnames: true
InstanceTenancy: default
Tags:
- Key: Name
Value: !Ref VPCName
下記Outputsセクションの!Ref VPCだとResourceセクションで定義されたVPC IDが参照されます。
# ------------------------------------------------------------#
# OutPut Parameters
# ------------------------------------------------------------#
Outputs:
VPC:
Description: VPC ID
Value: !Ref VPC
!Sub
同テンプレート内で定義されたリソースやパラメーターや疑似パラメーター(AWS::Region) などが参照されます。
!Refと違い、文字列の内の一部分のみ参照するときに使用します。
例えば下記パートだと !Sub InternetGateway-${VPCName} として使っています。
これはインターネットゲートウェイ名を個別で命名するのではなく、VPC名と紐づく名前をつけたかったためこのようにしました。
# ------------------------------------------------------------#
# InternetGateway
# ------------------------------------------------------------#
InternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: !Sub InternetGateway-${VPCName}
!GetAZs・!Select
!GetAZsは、指定したリージョンにおける利用可能なアベイラビリティゾーンのリストを取得するために使用します。
たとえば、us-east-1 リージョンであれば、!GetAZs '' は ['us-east-1a', 'us-east-1b', 'us-east-1c'] のようなリストを返します。
!Selectは、リストの中から特定のインデックスに基づいて1つの要素を取得するために使用します。
今回使われた !Select [ 0, !GetAZs '' ] は現在のリージョンで利用可能なアベイラビリティゾーンのリストを取得し、そのリストの最初の AZ(通常、最初のAZは us-east-1a など)を選択できます。
# ------------------------------------------------------------#
# Subnet
# ------------------------------------------------------------#
PublicSubnet:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: !Ref PublicSubnetCIDR
AvailabilityZone: !Select [ 0, !GetAZs '' ]
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: !Sub subnet-${VPCName}-public
AWS公式マニュアル
ここまでテンプレートの構成について説明してきました。
テンプレート内の文については定型文が決まっており、CloudFormationの公式ユーザーガイドに説明があります。
AWS リソースタイプおよびプロパティタイプのリファレンス情報(Resourceセクションにおいての設定値)についても下記にあります。
なぜかVPC関連はAmazon EC2のページ内にあります。
ちなみに
生成AIテンプレートと見比べたところ、Meta DataとInput ParametersあとVPCフローログ設定以外はほとんど同じでした。
生成AIなかなかやりますね。
おわりに
自分が初めてAWS Cloudformationテンプレート作成を始めた時につまずいたことをまとめました。
コードばかりで冗長気味となってしまいましたが、少しでも参考になると嬉しいです。