内置函数 - Intrinsic Function

本实验演示如何在模板中使用Intrinsic Function (内置函数) , 这些内置函数可以更方便地管理堆栈,如果没有它们您将只能使用非常基本的模板,类似于上一节的CloudFormation代码。

GetAtt

CloudFormation创建好某个资源后,它会有很多属性,如EC2的IP、AZ,ELB的协议、端口、DNS名称。如果其他资源想引用这些属性的值,可以使用Fn::GetAtt

例如创建完成EC2后,EBS卷要知道它所在的AZ, 调用!GetAtt EC2Instance.AvailabilityZone:

image-20221023091430982

Fn::Ref

上一节我们讲到,Parameters可以在每次创建或更新堆栈时向模板输入自定义值。 Ref就是专门为了获取Parameter的值

例如,上一个实验将AMI ID直接硬编码到EC2 Resource属性中。 现在将对此进行修改,以使模板更加灵活。 让我们将AMI ID转换为Parameter,然后在运行时将其传递给Resource部分。

首先,创建一个名为“AmiID”的新参数,并将其放在模板的“Parameters”部分中:

  AmiID:
    Type: AWS::EC2::Image::Id
    Description: 'The ID of the AMI.'

使用内置函数“Ref”将输入的AmiID参数传递给EC2资源属性:

Resources:
  WebServerInstance:
    Type: AWS::EC2::Instance
    Properties:
      # Use !Ref function in ImageId property
      ImageId: !Ref AmiID
      InstanceType: !Ref InstanceType

Fn::Join

Join将数组使用某个连接符连接成一个字符串。

例如,使用Fn::Join给实例打Tag,命名为t2.micro-webserver这种形式:

Resources:
  WebServerInstance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref AmiID
      InstanceType: !Ref InstanceType
      Tags:
        - Key: Name
          Value: !Join [ '-', [ !Ref InstanceType, webserver ] ]

Fn::Sub

Fn::Sub用指定的值替换输入字符串中的变量。 例如我们想为EC2打一个InstanceType的Tag,仅当用户选择了实例后才知道它的具体值,此时可以使用Sub来构造:

Resources:
  WebServerInstance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref AmiID
      InstanceType: !Ref InstanceType
      Tags:
        - Key: Name
          Value: !Join [ '-', [ !Ref InstanceType, webserver ] ]
        - Key: InstanceType
          Value: !Sub ${InstanceType}  # 根据用户输入的InstanceType做替换

内置函数实验

将以下代码保存为03-lab03-IntrinsicFunctions.yaml:

AWSTemplateFormatVersion: '2010-09-09'

Description: CFN 101 Workshop - Lab 03 Intrinsic Functions.

Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          default: 'Amazon EC2 Configuration'
        Parameters:
          - InstanceType

    ParameterLabels:
      InstanceType:
        default: 'Type of EC2 Instance'

Parameters:
  InstanceType:
    Type: String
    Default: t2.micro
    AllowedValues:
      - t2.micro
      - t2.small
    Description: 'Enter t2.micro or t2.small. Default is t2.micro.'

  AmiID:
    Type: AWS::EC2::Image::Id
    Description: 'The ID of the AMI.'

Resources:
  WebServerInstance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref AmiID
      InstanceType: !Ref InstanceType
      Tags:
        - Key: Name
          Value: !Join [ '-', [ !Ref InstanceType, webserver ] ]
        - Key: InstanceType
          Value: !Sub ${InstanceType}

在上一节创建的cfn-workshop-ec2 中,更新Stack:

image-20210522215336233

上传 03-lab03-IntrinsicFunctions.yaml

image-20210522215431792

EC2 实例类型保持默认,AMI ID一项填写上一节创建EC2时使用的:

image-20210522215826393

一直点击Next,直至更新完成。


如何确认更新完成呢?可以从EC2的Tags页面查看,此时EC2带有 Name : t2.micro-webserver键值对:

image-20210522220406452