Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Conditions and Parameters in CloudFormation

I am trying to create a condition based on an optional parameter. The option is whether to run some additional installation from my userData script for an EC2 deployment.

The parameters and conditions look like this:

Parameters: 
  EnvType: 
    Description: Option to install New Relic Infrastructure.
    Default: apm
    Type: String
  AllowedValues: 
    - apm
    - +infra

Then my EC2 Resource with conditional startup scripts

Resources:
  Ec2Instance:
    Type: AWS::EC2::Instance
    Properties:
     InstanceType: t2.micro
     ImageId: ami-9c9443e3  #Amazon Linux AMI in Tokyo
     KeyName: tokyocloudformation
     IamInstanceProfile: 'S3EC2'
     SecurityGroupIds:
         - !Ref myNewSecurityGroup   
     UserData:
        Condition: apmOnly
        Fn::Base64:
          |
            #!/bin/bash
            installstuff
      Condition: addInfrastructureAgent
        Fn::Base64:
          |
           #!/bin/bash
           installstuff
           installsomeotherstuff

The error message I'm getting is: Template validation error: Template format error: Unresolved dependencies [EnvTyp]. Cannot reference resources in the Conditions block of the template

I get what the error is saying I believe, but it doesn't seem to fit with the examples given by AWS.

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/conditions-section-structure.html . This AWS example clearly uses a !Ref in the Conditions block.

  EnvType: 
    Description: Environment type.
    Default: test
    Type: String
    AllowedValues: 
      - prod
      - test
    ConstraintDescription: must specify prod or test.
  Conditions: 
    CreateProdResources: !Equals [ !Ref EnvType, prod ]

Can someone provide some feedback on how to implement this conditional or why this error message is being thrown for this implementation?

like image 503
Brad Ellis Avatar asked Mar 05 '23 17:03

Brad Ellis


1 Answers

According to the docs, Conditions should be used at the top level of the resource you want to conditionally create.

Putting a Condition inside the Instance UserData section isn't supported.

To use Conditions in your situation, you'd want separate Resources conditionally created based on the Parameter.

Resources:
  Ec2InstanceAPMOnly:
    Type: AWS::EC2::Instance
    Condition: apmOnly
    Properties:
     InstanceType: t2.micro
     ImageId: ami-9c9443e3  #Amazon Linux AMI in Tokyo
     KeyName: tokyocloudformation
     IamInstanceProfile: 'S3EC2'
     SecurityGroupIds:
         - !Ref myNewSecurityGroup   
     UserData:
        Fn::Base64:
          !Sub |
            #!/bin/bash
            installstuff

  Ec2InstanceWithInfrastructureAgent:
    Type: AWS::EC2::Instance
    Condition: addInfrastructureAgent
    Properties:
     InstanceType: t2.micro
     ImageId: ami-9c9443e3  #Amazon Linux AMI in Tokyo
     KeyName: tokyocloudformation
     IamInstanceProfile: 'S3EC2'
     SecurityGroupIds:
         - !Ref myNewSecurityGroup   
     UserData:
        Fn::Base64:
          !Sub |
            #!/bin/bash
            installstuff
            installsomeotherstuff
like image 95
maafk Avatar answered Mar 20 '23 13:03

maafk