docs: add Terraform certification notes and tasks
This commit is contained in:
130
terraform/task-29.md
Normal file
130
terraform/task-29.md
Normal file
@@ -0,0 +1,130 @@
|
||||
# Assignment
|
||||
|
||||
The Nautilus DevOps team is currently engaged in a cleanup process, focusing on removing unnecessary data and services from their AWS account. As part of the migration process, several resources were created for one-time use only, necessitating a cleanup effort to optimize their AWS environment.
|
||||
|
||||
A S3 bucket named devops-bck-28889 already exists.
|
||||
|
||||
1) Copy the contents of devops-bck-28889 S3 bucket to /opt/s3-backup/ directory on terraform-client host (the landing host once you load this lab).
|
||||
|
||||
2) Delete the S3 bucket devops-bck-28889.
|
||||
|
||||
3) Use the AWS CLI through Terraform to accomplish this task—for example, by running AWS CLI commands within Terraform. The Terraform working directory is /home/bob/terraform. Update the main.tf file (do not create a separate .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
|
||||
|
||||
# S3 Backup + Delete via Terraform — `devops-bck-28889`
|
||||
|
||||
This task runs **AWS CLI commands through Terraform** using a `null_resource` with a
|
||||
`local-exec` provisioner: sync the bucket's contents to a local directory on the
|
||||
`terraform-client` host, then delete the bucket.
|
||||
|
||||
## `main.tf` (append this block)
|
||||
|
||||
```hcl
|
||||
terraform {
|
||||
required_providers {
|
||||
null = {
|
||||
source = "hashicorp/null"
|
||||
version = "~> 3.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "null_resource" "s3_backup_and_delete" {
|
||||
provisioner "local-exec" {
|
||||
interpreter = ["/bin/bash", "-c"]
|
||||
command = <<-EOT
|
||||
mkdir -p /opt/s3-backup/ && \
|
||||
aws s3 sync s3://devops-bck-28889 /opt/s3-backup/ && \
|
||||
aws s3 rb s3://devops-bck-28889 --force
|
||||
EOT
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## How to run
|
||||
|
||||
```bash
|
||||
cd /home/bob/terraform
|
||||
terraform init
|
||||
terraform apply -auto-approve
|
||||
```
|
||||
|
||||
## How it works
|
||||
|
||||
### Why a `null_resource` + `local-exec`
|
||||
|
||||
Terraform has no native resource for "copy bucket contents to a local path" or for a
|
||||
force-delete of a populated bucket. When a task explicitly says *use the AWS CLI
|
||||
through Terraform*, the idiomatic pattern is a `null_resource` whose `local-exec`
|
||||
provisioner shells out to the CLI on the machine running Terraform (here, the
|
||||
`terraform-client` landing host, which already has AWS credentials configured).
|
||||
|
||||
- **`null_resource`** — a resource that does nothing itself; it exists solely to hang
|
||||
provisioners on. Creating it once (on `apply`) triggers its `local-exec` block.
|
||||
- **`interpreter = ["/bin/bash", "-c"]`** — runs the script under bash. (The default
|
||||
is `/bin/sh`; bash is set explicitly for predictable `&&` chaining and heredoc
|
||||
behavior.)
|
||||
|
||||
### The command sequence
|
||||
|
||||
The three steps are chained with `&&`, so each runs only if the previous succeeded —
|
||||
critical because step 3 is destructive:
|
||||
|
||||
1. **`mkdir -p /opt/s3-backup/`** — ensures the destination directory exists (and is a
|
||||
no-op if it already does).
|
||||
2. **`aws s3 sync s3://devops-bck-28889 /opt/s3-backup/`** — copies every object from
|
||||
the bucket into the local directory, preserving key paths. `sync` only transfers
|
||||
what's missing/changed, but on a fresh directory it pulls everything.
|
||||
3. **`aws s3 rb s3://devops-bck-28889 --force`** — removes the bucket. `rb` (remove
|
||||
bucket) normally refuses a non-empty bucket; `--force` first deletes all objects,
|
||||
then the bucket itself.
|
||||
|
||||
The `&&` chaining is the safety mechanism: if the `sync` fails (network, permissions),
|
||||
the `rb` never executes, so you don't delete data you failed to back up.
|
||||
|
||||
### Run-once semantics
|
||||
|
||||
A `null_resource` runs its provisioner when it's **created**. After a successful
|
||||
apply it's in state and won't re-run on subsequent applies. That's the desired
|
||||
behavior for a one-time cleanup. If you ever needed to run it again, you'd
|
||||
`terraform taint null_resource.s3_backup_and_delete` (or
|
||||
`terraform apply -replace=...`) to force recreation — but note the bucket is gone
|
||||
after the first run, so a re-run would fail at the sync step anyway.
|
||||
|
||||
### Modern alternative
|
||||
|
||||
Terraform 1.4+ ships a built-in `terraform_data` resource that replaces
|
||||
`null_resource` without needing the `hashicorp/null` provider. The same block written
|
||||
with it:
|
||||
|
||||
```hcl
|
||||
resource "terraform_data" "s3_backup_and_delete" {
|
||||
provisioner "local-exec" {
|
||||
interpreter = ["/bin/bash", "-c"]
|
||||
command = <<-EOT
|
||||
mkdir -p /opt/s3-backup/ && \
|
||||
aws s3 sync s3://devops-bck-28889 /opt/s3-backup/ && \
|
||||
aws s3 rb s3://devops-bck-28889 --force
|
||||
EOT
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Either works; `null_resource` is shown as the primary since it's the widely-recognized
|
||||
form.
|
||||
|
||||
## Verify
|
||||
|
||||
```bash
|
||||
# Backup landed locally
|
||||
ls -la /opt/s3-backup/
|
||||
|
||||
# Bucket is gone (this should error with "NoSuchBucket" / "Not Found")
|
||||
aws s3 ls s3://devops-bck-28889 || echo "Bucket deleted."
|
||||
```
|
||||
|
||||
Expected — `/opt/s3-backup/` contains the former bucket contents, and the `s3 ls`
|
||||
against the bucket fails because it no longer exists.
|
||||
Reference in New Issue
Block a user