16

I would like to populate a value in cloudformation depending on input parameter. I want to assign Name as either test-svc.abc.com or svc.abc.com depending on whether environment name is prod or not. If the environnment name is prod then the value should be svc.abc.com otherwise it should always be {env-name}-svc.abc.com.

I have the following expression:

Name: !Join [ '-', [ !Ref EnvironmentName, !Ref 'HostedZoneName' ] ]

In the above expression, HostedZoneName will be passed as svc.abc.com and the value of EnvironmentName could be test, release or prod. So the conditions should be evaluated as:

Inputs: HostedZoneName -> svc.abc.com, EnvironmentName -> test
Output: test-svc.abc.com

Inputs: HostedZoneName -> svc.abc.com, EnvironmentName -> release
Output: release-svc.abc.com

Inputs: HostedZoneName -> svc.abc.com, EnvironmentName -> 1234567
Output: 1234567-svc.abc.com

Inputs: HostedZoneName -> svc.abc.com, EnvironmentName -> prod
Output: svc.abc.com

It's basically ternary operator.

Name = EnvironmentName.equals("prod") ? HostedZoneName : EnvironmentName + "-" + HostedZoneName

Struggling with if else condition in CloudFormation.

3 Answers 3

10

Based on the answer posted by @rdas, I've implemented below expression in YAML format:

...
Conditions: 
  IsProductionEnvironment: !Equals [ !Ref EnvironmentName, prod ]
...

...
Name: !If [IsProductionEnvironment, !Ref 'HostedZoneName', !Join [ '-', [ !Ref EnvironmentName, !Ref 'HostedZoneName' ] ]]
...
9

Take a look at Cloudformation Conditions. You can use them to define if-statements using Fn::If

Then you can use this condition in the Resources section to define how to build your HostedZoneName.

Here's an example. You'll probably need to do something like this:

...
 "Conditions" : {
    "CreateProdResources" : {"Fn::Equals" : [{"Ref" : "EnvType"}, "prod"]}
  },

...

"Properties" : {
    "HostedZoneName" : {
      "Fn::If" : [
        "CreateProdResources",
        "svn.abc.com",
        {"Fn::Sub": "${Environment}-svc.abc.com"}
      ]}
  },
5

You can achieve this by using !sub in !if. below is the example where I was looking for the domain prefix (dev,qa,stage) for the non-prod environment.

your non-prod bucket name will be

dev.mydomain.xyz.com
qa.mydomain.xyz.com
stage.mydomain.xyz.com

and prod bucket name will be

mydomain.xyz.com

clouformation Yaml exm

AWSTemplateFormatVersion: 2010-09-09
Description: 'AWS cloudformation template for admin panel s3 bucket. '
Parameters:
  WebBucketName:
    Description: Enter the name of the application
    Type: String
    Default: mydomain.xyz.com
  Environment:
    Description: Enter the environmet name from allowed values
    Type: String
    AllowedValues:
      - qa
      - dev
      - prod
      - stage
Conditions:
  CreateProdResources: !Equals [!Ref Environment, prod]
  CreatedevResources: !Equals [!Ref Environment, dev]
  CreateqaResources: !Equals [!Ref Environment, qa]
  CreatestageResources: !Equals [!Ref Environment, stage]
  MultiCondition: !Or
    - !Condition CreatedevResources
    - !Condition CreateqaResources
    - !Condition CreatestageResources

Resources:
  WebS3AdminPanel:
    Type: AWS::S3::Bucket
    Properties:
      BucketName:
        !If [MultiCondition, !Sub "${Environment}.${WebBucketName}", !Sub "${WebBucketName}" ]
      Tags:
        - Key: Name
          Value: test
      WebsiteConfiguration:
        IndexDocument: index.html
        ErrorDocument: error.html
      AccessControl: PublicRead

Not the answer you're looking for? Browse other questions tagged or ask your own question.