Chapter 34: Terraform State Remote S3 Backend Locking and Workspaces
Chala mitrano, aaj Terraform chi memory — state. State harvla tar Terraform la kahi aathvat nahi. Mhanun aapan state S3 madhe thevto, versioning aani encryption sobat, aani lock lavto mhanje don lok ekach veli apply karu shakat nahit. Navin Terraform madhe use_lockfile aahe; juna DynamoDB pan samjun gheu. Shevti workspaces.
What you will learn in this chapter
- What state stores and why it stays out of Git
- An encrypted, versioned S3 backend with use_lockfile
- Reading and migrating DynamoDB locking
- Migrating local state to S3
- Workspaces for short-lived stacks
Concepts in this chapter
- 34.1State — Terraform's memory of what it built
- 34.2Remote S3 backend with native locking (use_lockfile)
- 34.3DynamoDB locking — the older pattern you will still meet
- 34.4Move local state to S3 safely
- 34.5Workspaces — several states from one folder
The chapter recap is at the end of the last concept page.
Practice Tasks
Suppose we are on the DevOps team at Duolingo, the language learning company, working from Pittsburgh. Rachel Cohen leads the team, and we look after the streak reminder service. Costs are counted in USD. In the tasks below we do real DevOps jobs on this project using what this lesson teaches. Duolingo is a real company, but this project, the people, servers, IP addresses and numbers are made up for practice.
0 / 12
Easy S3 bucket resource
Why: Buckets in code are reviewed and never forgotten.
What to do: Write a resource aws_s3_bucket named logs with bucket = "duolingo-logs" and tags { Team = "devops" }.
- Write the block type (resource, variable, output, module...) and its labels in quotes.
- Open { and write each argument as name = value.
- Put text values in double quotes; numbers and true/false without quotes.
- Close every block with } and click Check answer.
Easy Output a value
Why: Outputs hand values to scripts and other modules.
What to do: Write output "web_ip" with value = aws_instance.web.public_ip.
- Write the block type (resource, variable, output, module...) and its labels in quotes.
- Open { and write each argument as name = value.
- Put text values in double quotes; numbers and true/false without quotes.
- Close every block with } and click Check answer.
Easy Provider block
Why: The provider tells Terraform which cloud and region to talk to.
What to do: Write a provider "aws" block with region = "us-east-2".
- Write the block type (resource, variable, output, module...) and its labels in quotes.
- Open { and write each argument as name = value.
- Put text values in double quotes; numbers and true/false without quotes.
- Close every block with } and click Check answer.
Medium List resources in state
Why: state list shows what Terraform thinks it manages.
What to do: List every resource address in the state.
- Read the task and pick the tool it needs (git, docker, kubectl, terraform, ansible...).
- Write the tool name, then the sub-command (the action word).
- Add the flags the task needs, each followed by its value.
- Add names, files or paths at the end, then click Check answer.
Medium Create a workspace
Why: Workspaces keep separate state for each environment.
What to do: Create and switch to a new workspace named staging.
- Read the task and pick the tool it needs (git, docker, kubectl, terraform, ansible...).
- Write the tool name, then the sub-command (the action word).
- Add the flags the task needs, each followed by its value.
- Add names, files or paths at the end, then click Check answer.
Medium EC2 instance using a variable
Why: Referencing var.* avoids hard-coding sizes.
What to do: Write resource aws_instance "web" with ami = "ami-0abcdef1234567890", instance_type = var.instance_type and tags Name = "streak-reminder".
- Write the block type (resource, variable, output, module...) and its labels in quotes.
- Open { and write each argument as name = value.
- Put text values in double quotes; numbers and true/false without quotes.
- Close every block with } and click Check answer.
Medium Pin the provider version
Why: Pinning stops a new provider release from breaking your plan.
What to do: Write a terraform block with required_providers aws = { source = "hashicorp/aws", version = "~> 5.0" }.
- Write the block type (resource, variable, output, module...) and its labels in quotes.
- Open { and write each argument as name = value.
- Put text values in double quotes; numbers and true/false without quotes.
- Close every block with } and click Check answer.
Hard Remote state in S3
Why: Shared remote state with locking stops two people breaking each other.
What to do: Write a terraform block with backend "s3": bucket = "duolingo-tfstate", key = "prod/terraform.tfstate", region = "us-east-2", dynamodb_table = "tf-lock".
- Write the block type (resource, variable, output, module...) and its labels in quotes.
- Open { and write each argument as name = value.
- Put text values in double quotes; numbers and true/false without quotes.
- Close every block with } and click Check answer.
Hard Import an existing bucket
Why: Import brings hand-made resources under code control.
What to do: Import the existing S3 bucket duolingo-logs into the address aws_s3_bucket.logs.
- Read the task and pick the tool it needs (git, docker, kubectl, terraform, ansible...).
- Write the tool name, then the sub-command (the action word).
- Add the flags the task needs, each followed by its value.
- Add names, files or paths at the end, then click Check answer.
Hard Create several copies with count
Why: count builds N identical resources from one block.
What to do: Write resource aws_instance "worker" with count = 2, ami = "ami-0abcdef1234567890", instance_type = "t3.small" and tags Name = "worker-${count.index}".
- Write the block type (resource, variable, output, module...) and its labels in quotes.
- Open { and write each argument as name = value.
- Put text values in double quotes; numbers and true/false without quotes.
- Close every block with } and click Check answer.
Hard Call a module
Why: Modules package a tested pattern, like a VPC, for reuse.
What to do: Write module "vpc" with source = "terraform-aws-modules/vpc/aws", version = "5.8.1", name = "duolingo-vpc" and cidr = "10.0.0.0/16".
- Write the block type (resource, variable, output, module...) and its labels in quotes.
- Open { and write each argument as name = value.
- Put text values in double quotes; numbers and true/false without quotes.
- Close every block with } and click Check answer.
Hard Security group for HTTPS
Why: Opening only 443 keeps the attack surface small.
What to do: Write resource aws_security_group "web" with name = "web-sg" and one ingress block: from_port = 443, to_port = 443, protocol = "tcp", cidr_blocks = ["0.0.0.0/0"].
- Write the block type (resource, variable, output, module...) and its labels in quotes.
- Open { and write each argument as name = value.
- Put text values in double quotes; numbers and true/false without quotes.
- Close every block with } and click Check answer.
Ravi Sir's Cards: 13 revision, interview and comparison cards for this chapter · मराठी cards