Skip to main content

Documentation Index

Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt

Use this file to discover all available pages before exploring further.

This lesson demonstrates how to use AWS CloudFormation Conditions to control resource properties and conditional resource creation. We’ll build an S3 bucket whose public-access configuration and bucket policy depend on a developer name mapped to an environment. The same template can therefore apply different, environment-specific configurations at deployment time. Key concepts covered:
  • Mappings to link developer names to environment metadata
  • Parameters for runtime choices
  • Conditions with intrinsic functions (!FindInMap, !Equals, !If)
  • Conditional resource creation using the Condition attribute

Template structure — Mappings and Parameters

The template uses a Mapping named DevMap to associate each developer with a profession and an environment. Parameters accept the S3 bucket name and the developer name used to determine the environment at deploy/update time.
Mappings:
  DevMap:
    Arno:
      Field: Quality assurance
      Env: Testing/development
    Alice:
      Field: Backend developer
      Env: Production

Parameters:
  InputBucketName:
    Type: String
    Description: Please enter your desired S3 bucket name
  InputDeveloperName:
    Type: String
    AllowedValues:
      - Arno
      - Alice
    Description: Developer name used to look up environment in the mapping
When the stack is applied, the template uses these values to tag the bucket, select public-access behavior, and optionally create a public-read bucket policy.

Runtime view — bucket tags in the console

When the stack was deployed with InputDeveloperName set to Arno, the bucket tags reflect the mapping (Developer = Arno, Environment = Testing/development):
A screenshot of the AWS S3 console showing the properties/tags for a bucket (eden-kodekcloud-bncv-bkt). The table lists key-value tags such as Status: Active, aws:cloudformation:stack-name: DemoStack, Profession: Quality assurance, Developer: Arno, Environment: Testing/development, and aws:cloudformation:logical-id: MyS3Bucket.
Because Arno maps to Testing/development, the production condition evaluated to false. This resulted in two outcomes:
  • The PublicAccessBlockConfiguration used the non-production branch (blocking public access).
  • The bucket policy that would allow anonymous GetObject was not created (it is gated by the production Condition).

Conditions — detect production vs non-production

The template defines a Condition to check whether the mapped environment equals “Production”:
Conditions:
  IsProd: !Equals
    - !FindInMap [DevMap, !Ref InputDeveloperName, Env]
    - "Production"
This Condition (IsProd) becomes the switch that drives resource property selection and conditional resource creation.

Conditional resource properties — S3 bucket configuration

The S3 bucket resource sets tags from the mapping and uses !If to choose between production and non-production values for PublicAccessBlockConfiguration. When IsProd is true, public-access-block flags are set to false to allow public access. When false, the flags are set to true to block public access.
Resources:
  MyS3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Ref InputBucketName
      Tags:
        - Key: Developer
          Value: !Ref InputDeveloperName
        - Key: Profession
          Value: !FindInMap [DevMap, !Ref InputDeveloperName, Field]
        - Key: Environment
          Value: !FindInMap [DevMap, !Ref InputDeveloperName, Env]

      PublicAccessBlockConfiguration: !If
        - IsProd
        - BlockPublicAcls: false
          BlockPublicPolicy: false
          IgnorePublicAcls: false
          RestrictPublicBuckets: false
        - BlockPublicAcls: true
          BlockPublicPolicy: true
          IgnorePublicAcls: true
          RestrictPublicBuckets: true
Summary of the IsProd effect:
IsProd valuePublicAccessBlockConfigurationBucketPolicy created
true (Production)All flags false (public access allowed)Yes — public-read policy created
false (Non-prod)All flags true (public access blocked)No — bucket policy not created

Conditional resource creation — bucket policy

The bucket policy that allows public reads is created only when IsProd is true. This is implemented using the Condition attribute on the BucketPolicy resource:
  MyPublicReadPolicy:
    Condition: IsProd
    DependsOn: MyS3Bucket
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: !Ref InputBucketName
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal: "*"
            Action: "s3:GetObject"
            Resource: !Sub "arn:aws:s3:::${InputBucketName}/*"
The Condition attribute prevents the BucketPolicy resource from being created when IsProd is false. The !If intrinsic function is used to select the appropriate PublicAccessBlockConfiguration object for production and non-production branches.

Demonstration: switching the developer parameter

  • With InputDeveloperName = Arno:
    • IsProd = false
    • The template applies the branch that blocks public access
    • The public-read bucket policy is not created
  • After updating the stack with InputDeveloperName = Alice:
    • IsProd = true (Alice maps to Production)
    • PublicAccessBlockConfiguration flags are set to false (Block all public access = Off)
    • MyPublicReadPolicy is created and attaches a public-read policy to the bucket
The console after switching to Alice shows the environment tag updated to Production and “Block all public access” switched Off:
A screenshot of the AWS S3 console showing the bucket "eden-kodekloud-bncv-bkt." The "Block public access (bucket settings)" panel is displayed with "Block all public access" set to Off and an Edit button.
Because public access was allowed, the policy permitting s3:GetObject for all principals became effective. To verify public-read behavior, upload a small test object (image or file) to the bucket. Objects view before upload:
A screenshot of the Amazon S3 console opened to the bucket "eden-kodekloud-bncv-bkt" on the Objects tab. The bucket shows no objects and displays controls like Upload, Create folder, Copy URL, and Actions.
Upload a test image (e.g., Person1.jpg):
A screenshot of the AWS S3 console's Upload page showing one file (Person1.jpg, 26.2 KB) queued for upload to the bucket "eden-kodekloud-bncv-bkt", with buttons to add files or folders. The page also displays destination details and navigation/header elements for the AWS console.
After the upload, the CloudFormation-created bucket policy is visible under the bucket Permissions tab. The policy document uses !Sub to reference the bucket name and allows s3:GetObject for all principals when IsProd is true:
PolicyDocument:
  Version: "2012-10-17"
  Statement:
    - Effect: Allow
      Principal: "*"
      Action: "s3:GetObject"
      Resource: !Sub "arn:aws:s3:::${InputBucketName}/*"
Open the uploaded object’s public URL (e.g., in an incognito window) to verify it is publicly accessible — this confirms the template’s conditional logic worked as intended.

Validation and deployment tips

  • Always lint and validate your CloudFormation template before updating stacks. A quick lint step:
[cfn-lint](https://github.com/aws-cloudformation/cfn-lint) template.yaml
Validate templates and test different parameter combinations in a non-production account to ensure Conditions and !If branches behave as expected. Use the AWS CloudFormation documentation for intrinsic function details: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference.html
  • In the AWS Console to update the stack:
    1. Select the stack → Update stack
    2. Replace current template → Upload template file → Next
    3. Provide new parameter values (for example, set InputDeveloperName = Alice) → Update

Summary

This example demonstrates how to:
  • Use Mappings and Parameters to drive deployment-time decisions
  • Define Conditions with !FindInMap and !Equals
  • Use !If to select resource property values
  • Use the Condition resource attribute to create resources only for specific environments
You can extend this pattern to other resource types (EC2, IAM, RDS, etc.) to enforce environment-specific configuration and policies during automated deployments. Further reading and references:

Watch Video