概要
AWS CloudFormation を使用するときに知りたいことを記載。
基本的なテンプレートの書き方とスタックの作り方まで。
- スタック名に
_
は使えない(記号は-
のみ使用可能)。スタック名には、英数字 (大文字と小文字が区別されます) とハイフンのみを使用できます。先頭の文字は必ずアルファベット文字とし、128 文字より長くすることはできません。
- スタック名とパラメーターの指定 - AWS CloudFormation
- テンプレートとは、CloudFormation サービスで展開するリソースを定義したテキストファイル。
- テンプレート中で使用可能な様々な組み込み関数がある。
- 対応するサービスとしないサービスがあり、内容は随時アップデートされている。
- 対応サービスは、記述時の書式(リソースタイプ)が提供されている。
- AWS リソースおよびプロパティタイプのリファレンス - AWS CloudFormation
- スタックを消すとデフォルトでは作成したリソースも削除される。
- 何らかのデータを保持するリソースは、削除の保護などで誤削除を防止する。
- 本記事では扱わないが、テンプレートはネストできる。
[公式リファレンス]
CloudFormation とは
AWS リソースをコードで記述し、展開できるサービス。
所定の書式に従いテンプレートを作成すればその内容に基づいたリソース作成が行える。
- サービス間の依存関係はサービス側で解決してくれる。
- EC2 作成の前に VPC が必要などの作成順序をユーザが気にする必要がなくなる。
- 依存関係の明示的な指定も可能。スタックをネストするなど、特定のケースで使う。
- リソースの展開、削除が簡単になる。
- スタックという単位でリソースが展開され、この単位で更新や削除が一括で行える。
- 「パラメータ」を使用することで、一部環境のみ設定を変えるなど柔軟な展開も出来る。
- コードで環境を管理できるようになる。
- 作成可能なリソースは、CloudFormation 実行ユーザの権限、またはサービスロールで与えた権限に依存する。
see also
ベストプラクティス
利用時に一読すべし。
see also
テンプレート
セクション
テンプレートの大きな構成要素。
[主な要素]
★はよく使うもの(個人的見解)。
- ★AWSTemplateFormatVersion:
- テンプレートバージョン。
2010-09-09
で固定。
- 今は必須ではない?(昔は必須だった気がする)。
- テンプレートバージョン。
- ★Description:
- テンプレートの説明。
- ★Metadata:
Parameters
の UI を整理するときによく使う。- テンプレートに関する追加情報。
一部の AWS CloudFormation 機能は、Metadata セクションで定義した設定または設定情報を取得します。この情報は、次の AWS CloudFormation 固有のメタデータキーで定義します。
- メタデータ - AWS CloudFormation
- ★Parameters:
- スタック構築時にユーザに指定させる値を指定。
- Mappings:
- キーと値のマッピング。
Fn::FindInMap
関数と組み合わせ利用する。- リソースのパラメータ設定時に設定したキーに応じた値を取得し設定する。
- Mappings - AWS CloudFormation
- Conditions:
- 条件名と条件判断内容を(ここにまとめて)記載。
- 挿入などのためのマクロを指定。
- CloudFormationの条件関数を利用する | DevelopersIO
- Transform:
- サーバーレスアプリケーションや定型コンテンツ挿入などのためのマクロを指定。
- ★Resources(必須)
- 起動するリソースのタイプやプロパティを指定。
<Logical ID>:
論理 ID(テンプレート中でユニークな名前を指定)Type: <Resource type>
=> リソースタイプ(リソースごとに規定のタイプを指定)Properties: <properties>
=> リソースごとのプロパティ(タイプごとに異なる)
- 起動するリソースのタイプやプロパティを指定。
- Outputs
- スタック構築後に作成したリソース ARN などを出力できる。
- URL を出力するなど色々使える。
Export:
を定義することで、外部参照(他のスタックからの参照)も可能。
- スタック構築後に作成したリソース ARN などを出力できる。
see also
Metadata によるパラメータの整理
AWS::CloudFormation::Interface
を使用。
ユーザがパラメータを入力する際に関連のあるものをまとめたり、
順番を揃えたりすることでパラメータ入力時の可読性が向上する。
(デフォルトは、内容に関係なく論理 ID 順でソートされるため、非常に使いづらい。)
ParameterGroups:
において Label 単位に Parameters の項目を整理できる。- 記述は
Parameters:
中の論理リソース名を使用する。
- 記述は
default:
に設定した文字列が UI 上に名前として表示される。ParameterLabels:
で Parameters の各パラメータの別名を表示できる。- デフォルトはパラメータリソース名がそのまま表示される。
[例示]
Metadata: "AWS::CloudFormation::Interface": ParameterGroups: - Label: default: "Resource Name Prefix" Parameters: - CfPrefix - EnvType #~ - Label: default: "User Configuration" Parameters: - OnpreCIDR - TagRelease ParameterLabels: CfPrefix: default: "Resource name Prefix" #...
see also
- [CloudFormation] Metadata セクションで入力パラメータを見やすく設定する
- CloudFormationを使ってVPCを構築する - Qiita
- AWS::CloudFormation::Interface - AWS CloudFormation
サンプルテンプレート
VPC を作るケースを元によく使う内容を記載。
- 実行するとサブネットを 2 つ持つ VPC が出来る。
EnvType が transit の場合のみ、VGW が作成されるよう判定を組み込んでいる。
Conditions: CreateVGW: !Equals [ !Ref EnvType, transit ] ... CfVGW: Type: AWS::EC2::VPNGateway Condition: CreateVGW
[CLI]
aws cloudformation create-stack \ --stack-name SampleCFCreateVPC \ --template-body file://sample-cf_create-vpc.yml \ --parameters ParameterKey=EnvType,ParameterValue=guest
[sample-cf_create-vpc.yml]
AWSTemplateFormatVersion: 2010-09-09 Description: Create VPC(only transit-VPC creates VGW) Metadata: "AWS::CloudFormation::Interface": ParameterGroups: - Label: default: "Resource Name Prefix" Parameters: - CfPrefix - EnvType - Label: default: "Network Configuration" Parameters: - VPCCIDR - PrivateSubnetACIDR - PrivateSubnetAName - PrivateSubnetAZone - PrivateSubnetBCIDR - PrivateSubnetBName - PrivateSubnetBZone - Label: default: "Custom Configuration" Parameters: - OnpreCidr - TagRelease Parameters: CfPrefix: Type: String Description: resource name prefix Default: SampleCF EnvType: Type: String Description: vgw create-flag Default: guest AllowedValues: - transit - guest #----------------------- # Network Configuration #----------------------- VPCCIDR: Type: String Default: 172.16.0.0/26 # SubnetA PrivateSubnetACIDR: Type: String Default: 172.16.0.0/27 PrivateSubnetAName: Type: String Default: SubnetA PrivateSubnetAZone: Default: apne1-az1 Description: Expand resource to selected AZ Type: String AllowedValues: - apne1-az1 - apne1-az2 # SubnetB PrivateSubnetBCIDR: Type: String Default: 172.16.0.32/27 PrivateSubnetBName: Type: String Default: SubnetB PrivateSubnetBZone: Default: apne1-az2 Description: Expand resource to selected AZ Type: String AllowedValues: - apne1-az1 - apne1-az2 #----------------------- # Custom Configuration #----------------------- # CustomParameters OnpreCidr: Type: String Description: use Transit VPC Only Default: 10.0.0.0/24 # Release-TAG TagRelease: Type: String Description: Rewrite by release months and years("yyyy-mm") Default: 2023-01 Conditions: CreateVGW: !Equals [ !Ref EnvType, transit ] Resources: CfVPC: Type: AWS::EC2::VPC Properties: CidrBlock: !Ref VPCCIDR EnableDnsHostnames: true EnableDnsSupport: true Tags: - Key: Name Value: !Sub ${CfPrefix}-VPC - Key: Release Value: !Sub ${TagRelease} PrivateSubnetA: Type: AWS::EC2::Subnet Properties: CidrBlock: !Ref PrivateSubnetACIDR MapPublicIpOnLaunch: false VpcId: !Ref CfVPC AvailabilityZoneId: !Ref PrivateSubnetAZone Tags: - Key: Name Value: !Sub ${CfPrefix}-VPC_subnet_${PrivateSubnetAName} - Key: Release Value: !Sub ${TagRelease} PrivateSubnetB: Type: AWS::EC2::Subnet Properties: CidrBlock: !Ref PrivateSubnetBCIDR MapPublicIpOnLaunch: false VpcId: !Ref CfVPC AvailabilityZoneId: !Ref PrivateSubnetBZone Tags: - Key: Name Value: !Sub ${CfPrefix}-VPC_subnet_${PrivateSubnetBName} - Key: Release Value: !Sub ${TagRelease} # Create Route Table CfRouteTableCommon: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref CfVPC Tags: - Key: Name Value: !Sub ${CfPrefix}-VPC_rt-tbl_common - Key: Release Value: !Sub ${TagRelease} CfAssocciateRouteTableForPrivateSubnetA: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref CfRouteTableCommon SubnetId: !Ref PrivateSubnetA CfAssocciateRouteTableForPrivateSubnetB: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref CfRouteTableCommon SubnetId: !Ref PrivateSubnetB # Create VGW(TransitVPC Only) CfVGW: Type: AWS::EC2::VPNGateway Condition: CreateVGW Properties: Type: ipsec.1 Tags: - Key: Name Value: !Sub ${CfPrefix}-VPC_VGW - Key: Release Value: !Sub ${TagRelease} CfVGWAttachment: Type: AWS::EC2::VPCGatewayAttachment Condition: CreateVGW Properties: VpcId: !Ref CfVPC VpnGatewayId: !Ref CfVGW CfRouteToOnpre: Type: AWS::EC2::Route Condition: CreateVGW Properties: RouteTableId: !Ref CfRouteTableCommon DestinationCidrBlock: !Ref OnpreCidr GatewayId: !Ref CfVGW Outputs: CreateVpnID: Value: !Ref CfVPC Export: Name: !Sub ${CfPrefix}VpnID
(CLI)構文チェック
構文チェックが可能。
あくまで構文の検査のみで実行時エラーは検出できない。
(パラメータの型不一致などは実行して初めて分かる)
[CLI]
# url aws cloudformation validate-template --template-url https:<hoge> # file aws cloudformation validate-template --template-body file://<hoge>.yml
・下記のように中身に言及されていないエラーの場合、コマンドの構文を疑ってみる。
An error occurred (ValidationError) when calling the ValidateTemplate operation: Template format error: unsupported structure.
--template-body
でfile://
が抜けやすい。
・Unable to load paramfile
のエラーは、テンプレートの文字コードを疑う(主に Windows 環境)。
- テンプレートが日本語を含む場合、UTF-8 で保存されている可能性が高い。
see also
- CloudFormation のテンプレートの検証エラーや形式エラーを解決する
- [小ネタ]Cloudformationのvalidate-template(文法チェック)におけるファイルサイズエラーの対処法 | DevelopersIO
- CloudFormationでエラーに遭遇する理由 - 蒼の王座・裏口
YAML の書き方
個人的には YAML のほうが好き(生 JSON 書けない)。
- 基本はキーと値のマッピング('Key' => value)。
key: value
の:
とvalue
の間はスペースを入れる。- 値はスカラー型(
""
の利用は任意)。- 型付けは自動。タグにより明示も可能(
!!<tag>
)。
- 型付けは自動。タグにより明示も可能(
- 数値のみの場合は数値扱い(
""
で囲むと文字列)。 - その他のデータ型
true | false
は真偽値。null
は NULL。
- データ構造はインデントで表す。
- インデントは 2 つのスペースで表現する。
- 要素は入れ子に出来る。
- インデントでネスト。
-
はシーケンス(配列)を表す。- 記号を使った表現(フロースタイル)も可能。
[PHP, Perl, Python]
角カッコ([]
) もシーケンス。{ PHP: 5.2, MySQL: 5.1, Apache: 2.2.20 }
波カッコ({}
) はマッピング。- 組み合わせも可能。
'第1章': [はじめに, イベントの種類]
#
以降の行がコメント。
[例示]
docker: - image: ubuntu:14.04 - image: mongo:2.6.8 # 2 つのマッピングを要素に持つ command: [mongod, --smallfiles] # フロースタイル - image: postgres:9.4.1
上記の JSON。
{ "docker": [ { "image": "ubuntu:14.04" }, { "image": "mongo:2.6.8", "command": [ "mongod", "--smallfiles" ] }, { "image": "postgres:9.4.1" } ] }
"mongod" の参照(たぶん)。
$.docker[1].command[0]
リテラルブロック
|>
記号を使った表現。改行を含む複数行に渡る値の記述が可能。
記号との組み合わせで末尾の改行の処理が変わる。
|
... 何もなし。以降の改行は文字列上の改行として処理(見た目通り)。|+
... 文字列中の改行は保持。更に最終行に改行が付与される。|-
... 文字列中の改行は保持。更に最終行の改行が除去される。>
... 途中の改行はスペースとみなされる。最終行のみ改行。>+
,>-
の+-
の作用は|
の場合と同じ。
abc: | 123 456 789
see also
- The Official YAML Web Site
- 知ってるようで知らない YAML のご紹介 - NTT Communications Engineers' Blog
- YAML 入門: サンプルから学べる初心者向けガイド | CircleCI
- YAML フォーマット (symfony 1.4 legacy version)
- YAML基本文法まとめ - Qiita
- YAML のハマりどころ - Qiita
- ブロックスタイルの説明がわかりやすい。
- YAMLでネストした配列を作る - Qiita
- ネストの説明がわかりやすい。
YAML オンラインパーサー
YAML を見て ?? となったときに便利(ネストが重なると思考が止まる)。
YAML Tips
よく忘れることを書く。
{ "detail": { "findings": [ { #... "Severity": { "Normalized": 50, "Label": "MEDIUM", } } ] #... } }
上記から "Label" を抜く。
コレクションに含まれる配列の参照は、findings[0]
のように書く。
"Serverity": "$.detail.findings[0].Severity.Label",
組み込み関数
[Tips]
!Ref
等の参照系の関数で返り値に何が返ってくるかはリソースタイプごとに定義されている。- 下記は
AWS::EC2::VPC
をRef
で参照した場合。When you pass the logical ID of this resource to the intrinsic Ref function, Ref returns the ID of the VPC.
- テンプレートリファレンス - AWS CloudFormation から
Return values
を調べる。
- 下記は
- リソースの
"Properties"
の各パラメータが何の値を求めるかも上記のリファレンスに定義されている。- そのため、関数の返り値が要求されているパラメータと一致するか確認が必要。
- それぞれの関数は 完全名関数 と 短縮形 の 2 つの構文がある。
- 完全名:
Fn::XX
- 短縮形:
!XX
- 完全名:
- 短縮系構文は連続して使用できない(完全名関数の構文を交互に組み合わせる必要がある)。
- ○:
Fn::GetAZs: !Ref 'AWS::Region'
- X:
!GetAZs !Ref 'AWS::Region'
!
の連続は見た目も違和感があり、なんとなく使えなそうな雰囲気はある。
- ○:
[よく出る名前]
- パラメータの論理名
Parameters
セクションで指定した名前。
- リソースの論理名
Resources
セクションで指定した名前。
see also
Fn::Ref
指定したパラメータまたはリソースの値を返す。
- パラメータの論理名を指定
- パラメータの値を返す。
Parameters
で設定した値が取得される(!Sub ${Variable}
と同じ用法}。
- パラメータの値を返す。
- リソースの論理名を指定
- リソースを参照するために通常使用できる値を返す(物理 ID)。
Resource:
で指定した各リソースの名前を指定すると該当リソースの ARN が取得される。
Ref
でほしい値が取れない場合は、GetAtt
の利用を検討。
- リソースを参照するために通常使用できる値を返す(物理 ID)。
[構文]
完全名関数の構文:
Ref: <logicalName>
短縮形の構文:
!Ref <logicalName>
<logicalName>
- 引数に関数は使用できない。リソースの論理 ID である文字列を指定する。
see also
Fn::GetAtt
リソースごとに定義された特定の属性を取得する。
- 属性を取得するリソースと取得する属性名の 2 つの引数を取る。
- 取得可能な属性(リソースごとの返り値)はリソースごとに異なるので調べて使う。
- 同じ ARN の取得でも
Arn
だけでなく、TopicArn
等リソースごとに違いがあったりする。 - AWS リソースおよびプロパティタイプのリファレンス - AWS CloudFormation
- 同じ ARN の取得でも
[構文]
完全名関数の構文:
Fn::GetAtt: [ logicalNameOfResource, attributeName ]
短縮形の構文:
!GetAtt logicalNameOfResource.attributeName
logicalNameOfResource
- 必要な属性を含むリソースの論理名 (論理 ID)。
attributeName
- リソース固有の属性の名前。
[例示]
ELB の DNS 名を取得。
# 短縮形 !GetAtt myELB.DNSName # 完全名関数 "Fn::GetAtt": [ "myELB" , "DNSName" ]
see also
Fn::Sub
変数のように使いユーザ入力値などと組み合わせた動的なパラメータ生成ができる。
- 変数を
Parameters
で入力された値に置き換える等、実行時に変数展開ができる。 Ref
との組み合わせやAWS::Region
等の疑似パラメータもよく使う。
[構文]
完全名関数の構文:
Fn::Sub: - String - Var1Name: Var1Value Var2Name: Var2Value
短縮形の構文:
!Sub - String - Var1Name: Var1Value Var2Name: Var2Value
<String>
に関数の利用は不可(文字列のみ可)。- マッピングする名前は
${}
で指定する。
- マッピングする名前は
Var1Name: Var1Value
は String 中で置き換える(マッピング)パラメータのマッピング。- 置換が必要な場合のみパラメータを与える。
[例示]
# マッピングあり - Name: !Sub - www.${Domain} - { Domain: !Ref RootDomainName } # マッピングなし(疑似パラメータのみ) !Sub 'arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:vpc/${vpc}'
see also
Fn::FindInMap
Mappings
セクションで宣言された 2 つのレベルのマッピングのキーに対応する値を返す。
- マッピング(マッピング名) in マッピング(キー) in マッピング(値)
- FindInMap は上記を特定する 3 つのパラメータを含むシーケンス(配列)を要求する。
- アップデートにより、デフォルト値の利用が可能になった(2023/1/11)。
- 後述の言語拡張が必要。デフォルト値を含むマッピングを設定する。
- これにより想定パラメータを網羅する必要がなくなった。
- AWS CloudFormation で Fn::FindInMap の言語拡張が強化され、デフォルト値や追加の組み込み関数をサポート
[構文]
完全名関数の構文:
Fn::FindInMap: [ MapName, TopLevelKey, SecondLevelKey ]
短縮形の構文:
!FindInMap [ MapName, TopLevelKey, SecondLevelKey ]
[例示]
Mappings: RegionMap: us-east-1: HVM64: "ami-0ff8a91507f77f867" HVMG2: "ami-0a584ac55a7631c0c" ap-northeast-1: HVM64: "ami-06cd52961ce9f0d85" HVMG2: "ami-053cdd503598e4a9d" Resources: myEC2Instance: Type: "AWS::EC2::Instance" Properties: ImageId: !FindInMap - RegionMap - !Ref 'AWS::Region' - HVM64 InstanceType: m1.small
see also
言語拡張の利用(FindInMap)
テンプレート中に言語拡張の記述を加えることで、拡張構文の利用が可能になる。
AWSTemplateFormatVersion: 2010-09-09 Transform: AWS::LanguageExtensions
- 前述の FindInMap のデフォルトの利用に必要。
DefaultValue: <デフォルト値>
DefaultValue:
のキー名は固定。
- これ以外にも組み合わせが可能な関数の種類が増える。
詳細はドキュメント参照。
[例示]
AWSTemplateFormatVersion: 2010-09-09 Transform: AWS::LanguageExtensions #... # Mappings では個別の値を定義 Mappings: RegionMap: us-east-1: HVM64: "ami-0ff8a91507f77f867" HVMG2: "ami-0a584ac55a7631c0c" ap-northeast-1: HVM64: "ami-06cd52961ce9f0d85" HVMG2: "ami-053cdd503598e4a9d" Resources: myEC2Instance: Type: "AWS::EC2::Instance" Properties: ImageId: !FindInMap - RegionMap - !Ref 'AWS::Region' - HVM64 # マッピング中で定義したリージョン以外の場合はこの値を設定。 - DefaultValue: "ami-XXX" InstanceType: m1.small
see also
- [アップデート] CloudFormationで言語機能を拡張するTransformがサポートされました | DevelopersIO
- [アップデート] CloudFormation の Fn::FindInMap でより簡潔なマッピング定義が可能になるように機能が拡張されました | DevelopersIO
Fn::Select
インデックスによってオブジェクトのリストから 1 つのオブジェクトを返す。
- index は 0 始まり。
[構文]
完全名関数の構文:
Fn::Select: [ index, listOfObjects ]
短縮形の構文:
!Select [ index, listOfObjects ]
index
- 0 - N-1 まで(N は
listOfObjects
の要素数)。
- 0 - N-1 まで(N は
listOfObjects
- シーケンスを指定(
[]
)。 null
は指定不可。
- シーケンスを指定(
[例示]
AWS::Region において Fn::GetAZs
が返す配列の最初の要素を選択。
Fn::Select: - 0 - Fn::GetAZs: !Ref AWS::Region
see also
Fn::ImportValue
他のスタックでエクスポートされた値をインポートして利用する。
(これにより別のスタックで作成するリソースの ARN などを連携できる。)
Outputs
セクションにおいてExport
が必要。- エクスポートされた値は、リージョン内でのみ有効。
- かつエクスポート名はリージョン内で一意である必要がある。
- 他のスタックがエクスポートされた値を利用している状態では、当該スタックは削除できなくなる。
- つまり依存関係が出来る。
他のスタックから参照されている出力が存在する場合は、スタックを削除することはできません。
[構文]
完全な関数名:
Fn::ImportValue: sharedValueToImport
短縮形:
!ImportValue sharedValueToImport
[制約]
ImportValue
はSub
関数の短縮形と組み合わせはできない。- 書き方は例示を参照。
!ImportValue が含まれている場合、!Sub の短縮形を使用することはできません。
ImportValue
はRef
やGetAtt
などリソースに依存する関数は組み合わせられない。- エクスポート名も同じ制約を持つ。
ImportValue 関数に、リソースに依存する Ref または GetAtt 関数を含むことはできません。
[例示]
(エクスポート)
Outputs: PublicSubnet: Description: The subnet ID to use for public web servers Value: Ref: PublicSubnet Export: # エクスポート名を定義してエクスポートする。 Name: 'Fn::Sub': '${AWS::StackName}-SubnetID' WebServerSecurityGroup: Description: The security group ID to use for public web servers Value: 'Fn::GetAtt': - WebServerSecurityGroup - GroupId Export: Name: 'Fn::Sub': '${AWS::StackName}-SecurityGroupID'
(インポート)
Resources: WebServerInstance: Type: 'AWS::EC2::Instance' Properties: InstanceType: t2.micro ImageId: ami-a1b23456 NetworkInterfaces: - GroupSet: # エクスポート名を参照する。 # Sub 関数は完全名関数を使用する - !ImportValue 'Fn::Sub': '${NetworkStackNameParameter}-SecurityGroupID' AssociatePublicIpAddress: 'true' DeviceIndex: '0' DeleteOnTermination: 'true' SubnetId: !ImportValue 'Fn::Sub': '${NetworkStackNameParameter}-SubnetID'
see also
文字列操作関数(Join,Split)
結合と分割、対になる文字列操作関数。
Fn::Join
- 配列の要素を指定したデリミタで結合する。
- デリミタは省略可能。その場合は配列中の要素がそのまま結合される。
- 返り値は、結合された文字列。
- 構文
- 完全名関数の構文:
Fn::Join: [ delimiter, [ comma-delimited list of values ] ]
- 短縮形の構文:
!Join [ delimiter, [ comma-delimited list of values ] ]
- 完全名関数の構文:
- 文字列結合自体は
Sub
関数でも出来る。- ex)
:
でのパラメータの結合!Sub ${Param1}:${Param2}:${Param3}
- ex)
- 配列の要素を指定したデリミタで結合する。
Fn::Split
- 文字列を指定のデリミタで分割する。
- 返り値は、分割した要素を含む配列。
- 構文
- 完全名関数の構文:
Fn::Split: [ delimiter, source string ]
- 短縮形の構文:
!Split [ delimiter, source string ]
- 完全名関数の構文:
- 主に
Select
関数と組み合わせて使う。- ex) 3番目の要素を取得。
!Select [2, !Split [",", !ImportValue AccountSubnetIDs]]
- ex) 3番目の要素を取得。
- 文字列を指定のデリミタで分割する。
see also
文字列操作の応用例
Sub、Join 及び Split の組み合わせ。
[例示1]
NamePrefix のデリミタを .
を -
に変換。
(Split で分解して得た配列をソースに、Join で結合する)。
!Sub - ${Prefix}-lambda - Prefix: !Join [ "-", !Split [".", !Ref NamePrefix]]
[例示2]
リソース名の一部を取得し、サービス名に利用する。
(命名規則がわかれば色々応用が効きそう)
ServiceName: !Sub - com.amazonaws.vpce.ap-northeast-1.vpce-svc-${vpceid} - vpceid: !Select [ "2", !Split ["-", !Ref TransitVpcEndpointService]]
see
条件関数
簡単な条件分岐が書ける。
テスト環境と本番環境でリソースを分けるなどの用途に使う。
Fn::If
条件を除くすべての条件は、テンプレートのConditions
セクションで定義します。Fn::If
条件は、テンプレートのResources
セクションとOutputs
セクションのメタデータ属性、更新ポリシー属性、およびプロパティ値で使用できます。
If
以外は、Conditons
セクションのみで使う。If
はConditions
セクションの演算結果を受けた実際の分岐処理を書くのに使う。
Conditions
セクションでは条件関数のインプットの一部となる 条件 を定義する。!Condition
で条件の結果を参照可能。- ex)
!Condition SomeOtherCondition
- ex)
- 条件式を使用した演算も条件となる。
- ex)
!Equals ["sg-mysggroup", !Ref ASecurityGroup]
- ex)
- いずれの関数も配列を引数に取るため。
[]
の記載を忘れないこと。- かつ、一部はシーケンスの順番が意味を持つ。
- 条件式はネストして組み合わせが行える。
[条件関数]
基本的にイメージ通りの挙動をする。
Fn::If
Conditions
セクションの演算結果を受けた実際の分岐処理を書く。- 構文:
!If [<条件>, 真, 偽]
<条件>
に真偽値(true |false
)を持つパラメータを与え、処理を分岐させる。- この
<条件>
は通常、Conditions
セクションで後述の条件式による演算を経て決定する。
Fn::And
- 構文:
!And [<条件>,...]
- 条件を含む配列を与える。すべて true の場合に true を返す。
Equals
など他の条件式と組み合わせて使う。<条件>
の最低数は 2 。最大数は 10 。
- 構文:
Fn::Or
- 構文:
!Or [<条件>,...]
- 条件を含む配列を与える。いずれかが true の場合に true を返す。
- 構文:
Fn::Equals
- 構文:
!Equals [値1, 値2]
- 比較を行う値を与える。文字列比較が可能。
- ex)
!Equals ["sg-mysggroup", !Ref ASecurityGroup]
- ex)
- 比較を行う値を与える。文字列比較が可能。
- 構文:
Fn::Not
- 構文:
!Not [<条件>]
<条件>
を反転した結果を返す。- ex) 本番関係以外なら true
!Not [!Equals [!Ref EnvironmentType, prod]]
- ex) 本番関係以外なら true
- 構文:
[例示]
If の条件である CreateProdResources
は本番環境でのみ true
になる。
Parameters: EnvType: Description: Environment type. Default: test Type: String AllowedValues: - prod - test ConstraintDescription: must specify prod or test. #... Conditions: CreateProdResources: !Equals #<- 条件判定(条件名: CreateProdResources の定義) - !Ref EnvType - prod Resources: #... NewVolume: Type: "AWS::EC2::Volume" Condition: CreateProdResources Properties: Size: !If [CreateLargeSize, 100, 10] #<- 分岐 AvailabilityZone: !GetAtt EC2Instance.AvailabilityZone
see also
Fn::Base64
入力文字列から Base 64 を生成する。
マニュアル記載の通り、UserData
でよく使う。
組み込み関数 Fn::Base64 は、入力文字列の Base64 表現を返します。この関数は通常、UserData プロパティを介して Amazon EC2 インスタンスにエンコードされたデータを渡すために使用されます。
- 引数はエンコードする文字列を渡すだけ。
[例示]
TestSV: Type: AWS::EC2::Instance Properties: ImageId: !Ref EC2ImageId #... UserData: !Base64 | #!/bin/bash sudo yum update -y sudo yum install -y net-snmp-utils telnet #...
see also
Fn::Cidr
指定プレフィックスから任意のホストアドレス長を持つネットワークを指定数作成する。
組み込み関数 Fn::Cidr は CIDR アドレスブロックの配列を返します。返される CIDR ブロックの数は、count パラメータによって異なります。
[例示]
プレフィックスが 「/24」 の CIDR から、内部にサブネットマスクが 「/27」 の CIDR を 6 つ 作成
!Cidr [ "192.168.0.0/24", 6, 5 ]
- /27 は 32 - 5 で、ここにはホストアドレス長を指定する
see also
Fn::GetAZs
指定したリージョンの AZ をアルファベット順で返す。
- 実行ユーザがアクセス可能な AZ を取得できる。
- パラメータを与えない場合は、
"AWS::Region"
を指定したものとなる。 - 関数の実行に下記の権限が必要。
- スタック実行ユーザが、指定する IAM ロールに権限を持たせる。
ec2:DescribeAvailabilityZones
ec2:DescribeAccountAttributes
ec2:DescribeSubnets
[例示]
mySubnet: Type: "AWS::EC2::Subnet" Properties: VpcId: !Ref VPC CidrBlock: 10.0.0.0/24 AvailabilityZone: Fn::Select: - 0 - Fn::GetAZs: ""
see also
Fn::Transform
CloudFormation の言語拡張で利用するが、これ自体は活用したことがない。
組み込み関数 Fn::Transform は、スタックテンプレートの一部に対してカスタム処理を実行するためのマクロを指定します。マクロを使用すると、検索して置換操作のような単純なアクションからテンプレート全体の広範な変換まで、テンプレートに対してカスタム処理を実行できるようになります。詳細については、「AWS CloudFormation マクロを使用したテンプレートのカスタム処理の実行」を参照してください。
see also
スタックの操作
- 作成
- テンプレートを用いたスタックの新規作成。
- S3 バケットにテンプレートをアップロードして指定する。
- 更新
- 変更セットを使用しない更新。
- 既存テンプレートを流用した、パラメータ値の更新。
- 更新したテンプレートを利用したスタックリソースの更新。
- 変更セットを使用しない更新。
- 変更セットによる更新
- 変更セットによる差分確認のステップを挟んだ更新。
- 変更セットは複数作成でき、実行時に一括実行される。
- 反映しない変更セットは削除しておく。
- 変更セットごとに差分の記録が残る。
- 変更セットは複数作成でき、実行時に一括実行される。
- 実行後の変更セットは削除できない(試した限りは)
- 実行後の変更を取り消す場合は、切り戻し用の変更セットを再度作成する。
- 変更セットによる差分確認のステップを挟んだ更新。
- 削除
see also
スタックの作成
[パラメータ例示(GUI)]
- テンプレートの準備
- 新規テンプレート or サンプル or テンプレートの作成(デザイナー)
- 新規時は、S3 バケットの URL を指定。
- 新規テンプレート or サンプル or テンプレートの作成(デザイナー)
- スタックの名前: <任意>
- ※
_
は使えない。-
か大文字小文字の使い分けで見た目を工夫する。
- ※
- スタックの詳細を指定
- パラメータ:
Parameters
にパラメータを設定した場合に入力。
- パラメータ:
- スタックオプションの設定
- レビュー
- [x] AWS CloudFormation によって IAM リソースがカスタム名で作成される場合があることを承認します。
see also
(CLI)スタックの作成
CLI での実施例。
[作成]
aws cloudformation create-stack \ --stack-name Stack-name \ --template-body file://hogehoge.yml \ --capabilities CAPABILITY_NAMED_IAM \ --parameters ParameterKey=Key,ParameterValue=value1
[確認]
aws cloudformation list-stacks --stack-status-filter CREATE_COMPLETE aws cloudformation describe-stacks --stack-name myteststack
see also
- AWS CloudFormation コンソールでのスタックの作成 - AWS CloudFormation
- AWS Command Line Interface の使用 - AWS CloudFormation
[リソースに IAM を含む場合]
CLI 実行時に引っかかることが多い。
オプションに下記を追加(GUI では意識不要)。
--capabilities CAPABILITY_NAMED_IAM
see also
スタックの更新(変更セット)
スタックを更新する場合は通常の更新ではなく「変更セット」の利用を検討する。
対象のスタックを選択後、「変更セットを作成」から操作する。
[操作の流れ]
実際の変更前に差分確認が行える。
- 変更セットの作成
- 新規作成時と概ね同じ流れ。
- 差分の確認
- テンプレートまたはパラメータ変更に伴い発生するリソース差分が表示される。
- 変更セットの実行 or 削除
- 差分が意図しない内容だった場合、変更セットの削除で対応できる。
- 実行するまで変更は反映されない。
- 追加の変更が必要な場合は、変更セットを追加で作成する。
- 問題なければ実行して差分を反映する。
- リソース作成エラーなどの実行結果はこの段階でわかる。
- 差分が意図しない内容だった場合、変更セットの削除で対応できる。
[パラメータ例示(GUI)]
- テンプレートの準備
- 現在のテンプレート or 置き換え or テンプレートの編集(デザイナー)
- スタックの詳細を指定
- 変更セット名: 自動生成される(変更可能)
- 変更セットの説明: テンプレートの
Description
がデフォルトで記載。 - パラメータ:
Parameters
にパラメータを設定した場合に入力。
- スタックオプションの設定
- レビュー
- [x] AWS CloudFormation によって IAM リソースがカスタム名で作成される場合があることを承認します。
see also
(CLI)変更セット
[変更セット名の作成]
ユニークな変更セット名を自動生成するため、ランダム文字列を取得。
#Windows(PowerShell) $UNIQUE = -join ((1..10) | %{(65..90) + (97..122) | Get-Random} | % {[char]$_}) Write-Output $UNIQUE #Linux UNIQUE=$(tr -dc 0-9A-Za-z < /dev/urandom | fold -w 10 | head -1) echo $UNIQUE
[作成]
STACK=XXX aws cloudformation create-change-set \ --stack-name ${STACK} \ --change-set-name=${STACK}-${UNIQUE} \ --template-body file://hogehoge.yml \ --capabilities CAPABILITY_IAM CAPABILITY_NAMED_IAM \ --parameters ParameterKey=Key,ParameterValue=value
[変更セットの確認]
aws cloudformation list-change-sets --stack-name ${STACK}
[変更セットの操作]
変更セット名をオプションに加える。
aws cloudformation <operation> --stack-name ${STACK} --change-set-name ${STACK}-${UNIQUE}
- \
describe-change-set
... 変更内容の確認。execute-change-set
... 実行。delete-change-set
... 削除。
(コピペ用)
aws cloudformation describe-change-set --stack-name ${STACK} --change-set-name ${STACK}-${UNIQUE} aws cloudformation execute-change-set --stack-name ${STACK} --change-set-name ${STACK}-${UNIQUE} aws cloudformation delete-change-set --stack-name ${STACK} --change-set-name ${STACK}-${UNIQUE}
see also
(CLI)スタックの削除
[CLI]
aws cloudformation delete-stack --stack-name my-stack