4.1 KiB
Assignment
The Nautilus DevOps team is working on automating infrastructure deployment using AWS CloudFormation. As part of this effort, they need to create a CloudFormation stack that provisions an S3 bucket with versioning enabled.
Create a CloudFormation stack named xfusion-stack using Terraform. This stack should contain an S3 bucket named xfusion-bucket-20270 as a resource, and the bucket must have versioning enabled. The Terraform working directory is /home/bob/terraform. Create the main.tf file (do not create a different .tf file) to accomplish this task.
Note: Right-click under the EXPLORER section in VS Code and select Open in Integrated Terminal to launch the terminal.
Solution
CloudFormation Stack — xfusion-stack (S3 bucket with versioning)
Terraform provisions a CloudFormation stack; the stack's template, in turn, creates a versioned S3 bucket. The bucket is a CloudFormation-managed resource, not a native Terraform one.
main.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 6.0"
}
}
}
provider "aws" {
region = "us-east-1"
}
resource "aws_cloudformation_stack" "xfusion" {
name = "xfusion-stack"
template_body = <<-TEMPLATE
AWSTemplateFormatVersion: "2010-09-09"
Description: S3 bucket with versioning enabled
Resources:
XfusionBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: xfusion-bucket-20270
VersioningConfiguration:
Status: Enabled
TEMPLATE
}
How to run
cd /home/bob/terraform
terraform init
terraform apply -auto-approve
How it works
Two layers of provisioning
This task is deliberately indirect. Terraform does not create the bucket
directly with aws_s3_bucket. Instead:
- Terraform creates an
aws_cloudformation_stackresource. - AWS CloudFormation reads the template embedded in that stack and creates the S3 bucket from it.
So the ownership chain is Terraform → CloudFormation stack → S3 bucket. If you
inspect the bucket afterward it will show as managed by the xfusion-stack stack,
which is exactly what the task asks for.
aws_cloudformation_stack
name = "xfusion-stack"— the stack name, exactly as required.template_body— the CloudFormation template, inlined as a YAML heredoc. The<<-TEMPLATEform strips leading indentation so the YAML parses cleanly despite being nested inside HCL. You could also point at a file withtemplate_url(S3) orfile(), but inlining keeps everything in the singlemain.tfthe task requires.
The CloudFormation template
AWSTemplateFormatVersion— the CFN schema version;"2010-09-09"is the only valid value and is effectively a constant.Resources.XfusionBucket— the logical ID (an internal name CloudFormation uses to track the resource). It's arbitrary; the actual bucket name comes from the properties below.Type: AWS::S3::Bucket— declares an S3 bucket.BucketName: xfusion-bucket-20270— sets the real, globally-unique bucket name required by the task.VersioningConfiguration.Status: Enabled— turns on object versioning, so overwritten or deleted objects are retained as prior versions. This is the CFN equivalent of Terraform'saws_s3_bucket_versioningresource.
Why versioning is inside the template
Because the bucket is owned by CloudFormation, its configuration must be expressed in
CFN syntax inside the template — not with a separate Terraform
aws_s3_bucket_versioning block. Mixing a native TF versioning resource against a
CFN-managed bucket would create two controllers fighting over the same bucket, so all
bucket config lives in the template.
Verify
# Stack created successfully
aws cloudformation describe-stacks --stack-name xfusion-stack \
--query 'Stacks[0].{Name:StackName,Status:StackStatus}'
# Bucket exists with versioning enabled
aws s3api get-bucket-versioning --bucket xfusion-bucket-20270 \
--query 'Status'
Expected — stack StackStatus: CREATE_COMPLETE, and the versioning query returning
"Enabled".