Create AWS Resources Conditionally

Cloud Formation is a powerful tool to create and manage AWS infrastructure. There are scenarios which may demand to create resources conditionally. For example, You may need to create a role and grant read access to bucket only if user passes bucket name as parameter. But if user does not pass bucket name as parameter, then scripts should not create the role. In a simple create role script, If user won't mention resource name then script execution will fail as resource name in policy cannot be blank. Cloud Formation Conditions are very handy in such scenarios.
In the following script, role creation is dependent on condition IfBucketName and this condition returns true only when value of s3BucketARN parameter is not blank.
{
    "Conditions": {
        "IfBucketName": {"Fn::Not": [{"Fn::Equals": ["", {"Ref": "s3BucketARN"}]}]}
    },

    "Resources": {
        "TestRole": {
          "Condition" : "IfBucketName",
          "Type": "AWS::IAM::Role",
          "Properties" : {
            "AssumeRolePolicyDocument": {
                  "Statement": [ {
                      "Effect": "Allow",
                      "Principal": { "Service": "lambda.amazonaws.com" },
                      "Action": "sts:AssumeRole"
                    } ]
            }, 
            "RoleName": "TestRole",
            "Path": "/",
            "Policies": [ {
                "PolicyName": "TestPolicy",
                "PolicyDocument": {
                  "Version": "2012-10-17",
                  "Statement": [ {
                      "Action": [ "s3:GetObject"],
                      "Resource": {"Fn::If": ["IfBucketName", {"Ref": "s3BucketARN"}, {"Ref": "AWS::NoValue"}]},
                      "Effect": "Allow"
                    } ]
                }
            } ]
          }
        }
    },
    "Parameters": {
        "s3BucketARN": {
            "Type": "String",
            "Description": "S3 Bucket ARN"
        }
    }
}

AWS::NoValue is a pseudo-parameter. Consider a scenario in which user passes value of some property and property itself is optional for resource creation. In this case, if value of parameter is blank then exception will be thrown but if AWS::NoValue is used then corresponding property will be removed (It is like Cloud Formation will ignore this property when creating resource). Since property was optional, removing it will have no effect on resource creation. (In the above script it is only used for demo purpose as 'Resource' is mandatory property of 'Policy')
For Further Reading:
CloudFormation Template Conditions
AWS::NoValue

Comments

Popular posts from this blog

Practice Questions - AWS Solutions Architect - Associate Certification

AWS Parameter Store

Continuous Integration using AWS CodePipeline (GitHub to Elastic BeanStalk)