4.1 KiB
Assignment
The Nautilus DevOps team is strategically planning the migration of a portion of their infrastructure to the AWS cloud. Acknowledging the magnitude of this endeavor, they have chosen to tackle the migration incrementally rather than as a single, massive transition. They created some services in different regions and later found that some of those can be deleted now.
Delete a VPC named devops-vpc present in us-east-1 region using Terraform. Make sure to keep the provisioning code, as we might need to provision this instance again later.
The Terraform working directory is /home/bob/terraform.
Note: Right-click under the EXPLORER section in VS Code and select Open in Integrated Terminal to launch the terminal.
Solution
Delete VPC (Keep Code) — devops-vpc
Same "delete but keep the code" pattern: destroy the VPC while leaving its
provisioning block in main.tf for later reuse. A targeted destroy does exactly
this — it acts on the real resource and Terraform state only, never on your .tf
source.
main.tf — leave unchanged
Do not delete or comment out the block. It stays exactly as given:
resource "aws_vpc" "this" {
cidr_block = "10.0.0.0/16"
tags = {
Name = "devops-vpc"
}
}
How to run
cd /home/bob/terraform
# Destroy ONLY this VPC; leaves the code in main.tf intact.
terraform destroy -target=aws_vpc.this -auto-approve
How it works
Targeted destroy vs. the wrong approaches
| Approach | Result |
|---|---|
Delete the resource block, then apply |
VPC is destroyed, but the code is gone — violates "keep the provisioning code." |
terraform destroy (no target) |
Destroys everything in the config, not just this VPC. |
terraform destroy -target=aws_vpc.this |
Destroys only this VPC; code stays in main.tf. ✅ |
The -target flag scopes the operation to the single resource address
(aws_vpc.this — the Terraform resource name this, not the Name tag
devops-vpc). Terraform calls DeleteVpc, removes the resource from state, and
leaves your configuration untouched, because destroy operates on infrastructure and
state, never on source code.
Why the code surviving matters
Keeping the block means the VPC is trivially re-creatable later: a plain
terraform apply will see it declared in config but absent from state and recreate
it with the same 10.0.0.0/16 CIDR. That satisfies "we might need to provision this
again."
One caveat for VPCs — dependencies
DeleteVpc only succeeds if the VPC is empty of dependent resources. AWS refuses
to delete a VPC that still has subnets, internet/NAT gateways, route tables (beyond
the main one), non-default security groups, ENIs, or running instances attached — the
call fails with DependencyViolation.
- If those dependents are Terraform-managed in this same config, targeting the VPC
will normally also plan destruction of what depends on it. If not, or if the delete
errors with
DependencyViolation, remove the dependents first (or run a fullterraform destroyif the whole config is just this VPC's stack). - The default security group, default route table, and default NACL are deleted automatically with the VPC and don't block it.
For a bare VPC like this one (just the CIDR, nothing provisioned inside it), the plain targeted destroy works directly.
Expected state afterward
After the destroy, the config still declares a resource that no longer exists in
state, so terraform plan will show Terraform wants to create devops-vpc again
(+ 1 to add). That's expected — do not apply it. The task wants the VPC deleted
with the code retained, which is exactly this state.
Verify
aws ec2 describe-vpcs \
--filters Name=tag:Name,Values=devops-vpc \
--query 'Vpcs' --output text | grep -q . \
&& echo "VPC still exists." \
|| echo "VPC deleted."
# Confirm the code is still present
grep -A6 'resource "aws_vpc" "this"' /home/bob/terraform/main.tf
Expected — the describe returns nothing (VPC gone), and the resource block is still
present in main.tf.