# 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` ```hcl 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 ```bash 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 ```bash # 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"`.