前面简单的过了一遍模板的9大模块,这一节学习一下他的内置函数(Intrinsic function)。
官方文档链接 https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference.html
Fn::Base64
这个是返回一个字符串的base64格式,一般的使用场景是创建EC2 实例的时候配置 UserData使用的。注意Yaml格式2可以简写 Fn:: 为!,不要和其他语言里面的NOT操作符搞混了
JSON格式
{ "Fn::Base64" : valueToEncode }
YAML格式
*Fn::Base64: valueToEncode
YAML格式2
!Base64 valueToEncode
Fn::Cidr
这个是返回一个IP地址块
JSON格式
{ "Fn::Cidr" : [ipBlock, count, cidrBits]}
YAML格式
Fn::Cidr:
- ipBlock
- count
- cidrBits
YAML格式2
!Cidr [ ipBlock, count, cidrBits ]
例子, 创建了一个192.168.0.0/24的地址快,然后在里面创建了6个子网掩码 为/27的CIDR块
{ "Fn::Cidr" : [ "192.168.0.0/24", "6", "5"] }
Fn::FindInMap
在一个两层的map里面返回对应的value,之前看过例子通过region来查找AMI ID
JSON格式
{ "Fn::FindInMap" : [ "MapName", "TopLevelKey", "SecondLevelKey"] }
YAML格式
Fn::FindInMap: [ MapName, TopLevelKey, SecondLevelKey ]
YAML格式2
!FindInMap [ MapName, TopLevelKey, SecondLevelKey ]
Fn::GetAtt
这个是通过指定resource来返回他对应的属性值
JSON格式
{ "Fn::GetAtt" : [ "logicalNameOfResource", "attributeName" ] }
FN::GetAZs
这个指定一个region,返回他的所有的AZ的列表
JSON格式
{ "Fn::GetAZs" : "region" }
另外,当用户获取他所在的Region的时候, 这个Region的信息本身就是一个全局变量,不需要用户去指定,所以我们可以通过下面两张方式都可以获取当前用户所在的region的AZ
{ "Fn::GetAZs" : "" }
{ "Fn::GetAZs" : { "Ref" : "AWS::Region" } }
再比如这个片段, 通过Fn::GetAZs获取整个AZ的列表了,再通过Fn::select来获取第一个索引的元素
"mySubnet" : {
"Type" : "AWS::EC2::Subnet",
"Properties" : {
"VpcId" : {
"Ref" : "VPC"
},
"CidrBlock" : "10.0.0.0/24",
"AvailabilityZone" : {
"Fn::Select" : [
"0",
{
"Fn::GetAZs" : ""
}
]
}
}
}
Fn::ImportValue
这个可以从其他stack的output结果里面导入
JSON语法
{ "Fn::ImportValue" : sharedValueToImport }
Fn::Join
这个类似字符串的拼接,通过自定义的分隔符进行连接,如果分隔符是空的字符串,那么这些字符就直接连接
JSON语法
{ "Fn::Join" : [ "delimiter", [ comma-delimited list of values ] ] }
例如,我想拼接出一个arn来
{
"Fn::Join": [
"", [
"arn:",
{
"Ref": "Partition"
},
":s3:::elasticbeanstalk-*-",
{
"Ref": "AWS::AccountId"
}
]
]
}
Fn::Select
这个函数可以通过指定索引,返回一个列表里面的元素对象
JSON格式
{ "Fn::Select" : [ index, listOfObjects ] }
YAML格式
Fn::Select: [ index, listOfObjects ]
!Select [ index, listOfObjects ]
例子:
"Parameters" : {
"DbSubnetIpBlocks": {
"Description": "Comma-delimited list of three CIDR blocks",
"Type": "CommaDelimitedList",
"Default": "10.0.48.0/24, 10.0.112.0/24, 10.0.176.0/24"
}
}
"Subnet0": {
"Type": "AWS::EC2::Subnet",
"Properties": {
"VpcId": { "Ref": "VPC" },
"CidrBlock": { "Fn::Select" : [ "0", {"Ref": "DbSubnetIpBlocks"} ] }
}
}
Fn::Split
这个和join相反,是通过分隔符来分割字符串的
JSON语法
{ "Fn::Split" : [ "delimiter", "source string" ] }
YAML语法
Fn::Split: [ delimiter, source string ]
!Split [ delimiter, source string ]
例子,分割一条导入的子网记录,然后选择其中的第三个元素
{ "Fn::Select" : [ "2", { "Fn::Split": [",", {"Fn::ImportValue": "AccountSubnetIDs"}]}] }
Fn::Sub
替换字符串。他的一个常见的使用场景是在运行的时候,把实际的值传给我们自定义的变量
{ "Fn::Sub" : [ String, { Var1Name: Var1Value, Var2Name: Var2Value } ] }
如果仅仅是替换Paramter,Resource的名字,或者Resource的某个属性名称,直接用字符串替换就是了
{ "Fn::Sub" : String }
下面看几个例子
${domain}是一个我自定义的变量,然后通过Ref获取真实的域名进行替换
{ "Fn::Sub": [ "www.${Domain}", { "Domain": {"Ref" : "RootDomainName" }} ]}
另外一个例子,通过全局变量和vpc的名字进行替换
{ "Fn::Sub": "arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:vpc/${vpc}" }
第三个例子,在userdata里面使用,通过替换来配置对应的bash命令,然后通过join拼成一个合法的bash文件,再转换成对应的base64格式
"UserData": { "Fn::Base64": { "Fn::Join": ["\n", [
"#!/bin/bash -xe",
"yum update -y aws-cfn-bootstrap",
{ "Fn::Sub": "/opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource LaunchConfig --configsets wordpress_install --region ${AWS::Region}" },
{ "Fn::Sub": "/opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource WebServerGroup --region ${AWS::Region}" }]]
}}
Fn::Transform
调用宏,这个后面会有详细例子
Fn::Ref
这个命令返回Parameter或者resoruce的值
JSON语法
{ "Ref" : "logicalName" }
YAML语法
Ref: logicalName
!Ref logicalName
例如:
"MyEIP" : {
"Type" : "AWS::EC2::EIP",
"Properties" : {
"InstanceId" : { "Ref" : "MyEC2Instance" }
}
}