Mastering AWS CloudFormation
上QQ阅读APP看书,第一时间看更新

Using conditional elements

We want to have reusable templates, but sometimes we need to create a resource in one case and don't need to create one in another, or perhaps create one with different attributes.

Conditions are handy to solve that kind of problem, and can be used in two ways: to specify the Condition under the resource or to use the conditional intrinsic function in the resource properties.

We already know that Condition is a strict Boolean variable, which is evaluated by parameters and conditional functions. We have already learned how conditions are used in resource declaration (jump to the Going through the internals of the template section if you need a refresher), so let's look at another useful example.

Say that we have an AutoScaling group that is built from a launch template. We expect to have a different load on test and production, so we want to adjust the size of the EC2 instance accordingly. For now, we are happy with t3.micro on test and m5.large on production.

Since we will only have two environments, we can stick to only one condition—ProdEnv. Why? Because, in the resource attribute, we use a condition function, Fn::If. We use Fn::If as it is quite obvious that it has three inputs: condition, value when True, and value when False. So, if it's not production, we definitely know it is a test.

Let's develop our template:

Parameters:

  Env:

    Type: String

    Default: test

    AllowedValues: [ "test", "prod" ]

      ImageId:

        Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>

        Default: '/aws/service/ami-amazon-linux-latest/amzn2-  ami-hvm-x86_64-gp2'

Conditions:

  IsProd: !Equals [ !Ref Env, "prod" ]

Resources:

  WebLt:

    Type: AWS::EC2::LaunchTemplate

    Properties:

      LaunchTemplateName: web

      LaunchTemplateData:

      ImageId: !Ref ImageId

      InstanceType: !If [ IsProd, m5.large, t3.micro ]

The long syntax format for the last line would look like this:

InstanceType:

  Fn::If:

    - IsProd

    - m5.large

    - t3.micro

The Fn::If function also supports inheritance. If we had three environments (test, staging, and production), then we would need to have different instance types on those environments, and we would need extra conditions and a slightly longer condition function:

Conditions:

  IsProd: !Equals [ !Ref Env, "prod" ]

  IsStaging: !Equals [!Ref Env, "stage" ]

Resources:

  WebLt:

    Type: AWS::EC2::LaunchTemplate

    Properties:

      LaunchTemplateName: web

      LaunchTemplateData:

        ImageId: !Ref ImageId

        InstanceType: !If [ IsProd, m5.large, !If [ IsStaging, t3.large, t3.micro ] ]

Conditions have various use cases, and most of them show up when you start building a big infrastructure on AWS. While you will often find them handy, keep in mind the limitations and usage examples from this book.

Let's now move to another important topic—deletion policies.