Files
kodekloud-engineer/terraform/task-22.md

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:

  1. Terraform creates an aws_cloudformation_stack resource.
  2. 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 <<-TEMPLATE form strips leading indentation so the YAML parses cleanly despite being nested inside HCL. You could also point at a file with template_url (S3) or file(), but inlining keeps everything in the single main.tf the 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's aws_s3_bucket_versioning resource.

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".