Validate a CloudFormation Template

AWS CloudFormation is the AWS-native infrastructure-as-code service that provisions and manages cloud resources by declaring their desired state in YAML or JSON templates. Like Ansible playbooks and Kubernetes manifests, CloudFormation templates are deeply nested YAML documents where formatting errors are disproportionately difficult to debug. When AWS rejects a template, the error message often references a general "template format error" without identifying the specific line that caused the problem. Validating and formatting locally before upload saves this frustrating back-and-forth. This example provisions an S3 bucket with two significant features beyond a basic bucket: versioning is enabled (preserving every version of every object uploaded, which enables point-in-time recovery), and a lifecycle rule automatically purges non-current object versions after 30 days (preventing storage costs from accumulating as old versions accumulate over time). Key CloudFormation concepts demonstrated: AWSTemplateFormatVersion is a required field that must be exactly '2010-09-09' — the date format is not actually a date, it's an identifier for the template specification version. The Parameters section defines input values that operators provide at deployment time, enabling the same template to be used for different environments by passing different BucketName values. The Resources section is the heart of the template — every AWS resource you want to provision lives here. The intrinsic functions !Ref and !GetAtt are essential CloudFormation tools: !Ref BucketName refers to the parameter's value, substituting the actual bucket name string. !GetAtt AppBucket.Arn retrieves the Amazon Resource Name attribute of the created bucket, which you can pass to IAM policies or other resources that need to reference this specific bucket. Outputs let you export stack values — the BucketArn output allows other stacks or deployment scripts to retrieve the created bucket's ARN using the aws cloudformation describe-stacks command or CloudFormation cross-stack references. Real-world scenarios: a CI/CD pipeline that creates per-branch S3 buckets for deployment artifact storage; a multi-environment setup where the same template creates dev, staging, and production buckets with parameter-controlled names and lifecycle rules; an automated disaster recovery setup that provisions backup buckets with cross-region replication enabled. Tips: run aws cloudformation validate-template --template-body file://template.yaml before deployment to catch structural errors. Use cfn-lint for deeper validation that checks resource property types and required fields against the CloudFormation specification.

Example
AWSTemplateFormatVersion: '2010-09-09'
Description: S3 bucket with versioning

Parameters:
  BucketName:
    Type: String
    Default: my-app-bucket

Resources:
  AppBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Ref BucketName
      VersioningConfiguration:
        Status: Enabled
      LifecycleConfiguration:
        Rules:
          - Id: DeleteOldVersions
            Status: Enabled
            NoncurrentVersionExpirationInDays: 30

Outputs:
  BucketArn:
    Value: !GetAtt AppBucket.Arn
[ open in YAML Validator → ]

FAQ

What is the difference between Parameters and Outputs?
Parameters accept input values when you deploy the stack, letting you reuse the same template for different environments. Outputs export values from the stack that other stacks or scripts can reference.
What does !Ref do in CloudFormation?
!Ref is a CloudFormation intrinsic function that returns the value of a Parameter or the physical ID of a Resource, letting you pass values between resource definitions.
Can I use JSON instead of YAML for CloudFormation?
Yes. CloudFormation accepts both formats. YAML is preferred because it supports comments and is easier to read, but both produce identical stacks.

Related Examples