- a logical ID (the template-local name you reference),
- a resource Type (for example, AWS::S3::Bucket or AWS::EC2::Instance),
- and optional Properties that configure how CloudFormation should create the resource.
A CloudFormation resource block generally contains:
- A logical ID (the template identifier you use with intrinsic functions),
- Type (the AWS resource type),
- Properties (resource-specific configuration),
- Optional fields like DependsOn, Metadata, DeletionPolicy, UpdatePolicy, and Condition.
Resource anatomy (YAML example)
This concise example shows an S3 bucket and a bucket policy that depends on the bucket. It demonstrates logical IDs, the Type field, Properties, intrinsic functions (!Ref and !Sub), and an explicit DependsOn to control creation order.- MyS3Bucket is the logical ID used elsewhere in the template (for example, with !Ref or !GetAtt).
- Type identifies the AWS resource type (here AWS::S3::Bucket and AWS::S3::BucketPolicy).
- Properties contains the resource-specific configuration.
- DependsOn ensures CloudFormation creates MyS3Bucket before MyBucketPolicy.
- !Ref returns the referenced resource value (often the resource name or ID). !Sub composes ARNs or other strings with variables.
Creation order, dependencies, and references
CloudFormation automatically orders operations when it can detect implicit references (e.g., when one resource property references another). Use DependsOn for explicit ordering when:- implicit references are not detected, or
- you need strict control over resource creation order.
| Intrinsic Function | Use Case | Example |
|---|---|---|
| !Ref | Returns a resource’s reference value (name or ID) | Bucket: !Ref MyS3Bucket |
| !GetAtt (Fn::GetAtt) | Retrieves a specific attribute (ARN, endpoint, etc.) | Endpoint: !GetAtt MyLoadBalancer.DNSName |
| !Sub | Substitutes variables into strings (useful for ARNs) | Resource: !Sub "arn:aws:s3:::${MyS3Bucket}/*" |
Optional resource fields worth noting
These fields help control lifecycle behavior, attach metadata, or gate resource creation. Use them to fine-tune how CloudFormation manages resources.| Field | Purpose | Common Values / Notes |
|---|---|---|
| DependsOn | Explicit creation order | Name or list of logical IDs |
| Metadata | Arbitrary structured data attached to the resource | Useful for tooling or configuration data |
| DeletionPolicy | Control behavior on stack deletion | Delete, Retain, Snapshot (for RDS/EBS) |
| UpdatePolicy | Rolling update / replacement behavior | Used with AutoScaling/EC2/ELB updates |
| Condition | Create resource only if condition is true | References Conditions defined at template top |
Be cautious when renaming a resource’s logical ID. CloudFormation treats a renamed logical ID as a new resource and will create a replacement and delete the original (unless a DeletionPolicy prevents deletion), which can result in data loss or downtime.
Best practices and tips
- Always use meaningful logical IDs — they’re referenced by other resources and appear in change sets.
- Favor intrinsic functions over hard-coded values to keep templates reusable.
- Use Conditions to create environment-specific resources (dev vs prod).
- Apply DeletionPolicy for stateful resources (S3, RDS) to avoid accidental data loss.
- Test changes using Change Sets to preview resource replacements and deletions.
Summary
- Resources are the core building blocks of a CloudFormation template.
- Each resource requires a logical ID, a Type, and typically a Properties block.
- Connect resources with intrinsic functions (!Ref, !GetAtt, !Sub) so CloudFormation can determine dependency order.
- Use DependsOn for explicit ordering, and DeletionPolicy/UpdatePolicy/Metadata/Condition to manage lifecycle and behavior.
Links and references
- AWS CloudFormation User Guide
- Amazon S3 Documentation
- AWS RDS Documentation
- Amazon DynamoDB Developer Guide