This project provisions an S3 bucket and an EC2 VM on AWS. Terraform state is stored in a shared S3 backend bucket (cybersteps-terrafom-backend) — each student writes to their own key inside that bucket so nobody overwrites anyone else's state.
Everything you should touch lives in two files: terraform.tfvars (resource inputs) and one line in backend.tf (your unique state key). You should not need to edit main.tf, ec2.tf, or providers.tf.
- Terraform ≥ 1.10 (
terraform version) - AWS CLI v2 (
aws --version) - AWS SSO access to the
cyberstepsaccount (ask the instructor)
Run the interactive wizard:
aws configure ssoAnswer the prompts as follows:
| Prompt | Answer |
|---|---|
| SSO session name | cybersteps |
| SSO start URL | https://identitycenter.amazonaws.com/ssoins-69875d4de802b000 |
| SSO region | eu-central-1 |
| SSO registration scopes | (press Enter — default is fine) |
A browser tab will open — approve the sign-in. Back in the terminal, the wizard lists the accounts/roles you have access to. Pick the cybersteps account and the OrgAdmin role.
Finish the prompts:
| Prompt | Answer |
|---|---|
| CLI default client region | eu-central-1 |
| CLI default output format | json (or leave blank) |
| CLI profile name | default (recommended — everything else in this guide assumes it) |
If you picked a name other than default, set profile = "your-name" in terraform.tfvars.
aws sts get-caller-identityYou should see your account ID and role. If the session ever expires later, re-run:
aws sso loginEdit terraform.tfvars — three required values plus a few optional ones:
owner = "<yourname>" # tagged on every resource
bucket_name = "cybersteps-<yourname>-bucket" # must be globally unique
instance_name = "<yourname>-vm" # EC2 Name tag
vpc_id = "vpc-xxxxxxxxxxxxxxxxx" # your VPC
subnet_id = "subnet-xxxxxxxxxxxxxxxxx" # a subnet inside that VPC
# Optional overrides:
# profile = "my-profile" # if you didn't use `default`
# instance_type = "t3.micro"
# ssh_allowed_cidr = "1.2.3.4/32" # restrict SSH to your IP (default: 0.0.0.0/0)Terraform will auto-generate an RSA 4096 SSH keypair for you: the public half is uploaded to AWS as <instance_name>-key, and the private half is written to ./<instance_name>-key.pem with 0600 perms. That file is gitignored — keep it safe locally.
Terraform doesn't allow variables inside a backend block, so this one line must be edited directly. Open backend.tf and change the key value — use a filename that includes your name so you don't collide with other students:
terraform {
backend "s3" {
bucket = "cybersteps-terrafom-backend"
key = "aws-sessions/<yourname>.tfstate" # <— your name here
region = "eu-central-1"
encrypt = true
use_lockfile = true
}
}Nothing else in the file changes.
terraform initterraform plan
terraform applyReview the plan before typing yes. On success, Terraform prints outputs including your instance_public_ip, bucket_name, and a ready-to-run ssh_command. To connect:
$(terraform output -raw ssh_command)or copy the value shown in the output.
terraform destroyNo valid credential sources found— your SSO session expired. Re-runaws sso login.BucketAlreadyExists— someone else took that global bucket name. Changebucket_nameinterraform.tfvars.Error acquiring the state lock— someone else (or a previous crashed run) holds the lock. Wait a moment and retry; if it persists, runterraform force-unlock <LOCK_ID>using the ID from the error message.- Backend key collision — if two students use the same
keyinbackend.tf, they'll clobber each other's state. Always use your own name in the key. Backend configuration changed— after editing thekeyinbackend.tf, re-runterraform init -reconfigure.InvalidKeyPair.Duplicate— a key pair with the same name (<instance_name>-key) already exists in AWS for your account. Either delete it in the EC2 console (Key Pairs) or changeinstance_nameinterraform.tfvars.instance_public_ipoutput is empty / SSH times out — yoursubnet_idis a private subnet (no route to an Internet Gateway). Either pick a public subnet or setassign_public_ip = falseand reach the instance another way (SSM Session Manager, bastion, VPN).