Day 2 of 5
⏱ ~60 minutes
Terraform in 5 Days — Day 2

Variables, Outputs, and State

Parameterize configurations with variables, expose values with outputs, and understand what Terraform state is.

Variables

variables.tf
variable "region" {
  description = "AWS region"
  type        = string
  default     = "us-east-1"
}

variable "environment" {
  description = "Deployment environment"
  type        = string
  # No default = required. Must be supplied.
}

variable "allowed_ips" {
  description = "IPs allowed to access the server"
  type        = list(string)
  default     = ["0.0.0.0/0"]
}
Using variables
# In main.tf
provider "aws" {
  region = var.region
}

resource "aws_s3_bucket" "main" {
  bucket = "my-bucket-${var.environment}"
}
terraform.tfvars
# Values for required variables
environment = "staging"
allowed_ips = ["192.168.1.0/24", "10.0.0.0/8"]

# Never commit sensitive values — use env vars instead:
# TF_VAR_environment=staging terraform apply
outputs.tf
output "bucket_name" {
  description = "Name of the created bucket"
  value       = aws_s3_bucket.main.bucket
}

output "bucket_arn" {
  value = aws_s3_bucket.main.arn
}

# After apply:
# Outputs:
# bucket_name = "my-bucket-staging"
# bucket_arn = "arn:aws:s3:::my-bucket-staging"
Terraform State
# terraform.tfstate is created after first apply
# It maps your config to real resources
# NEVER edit it manually
# NEVER commit it to git (may contain secrets)
# Add to .gitignore:
echo 'terraform.tfstate*' >> .gitignore
echo '.terraform/' >> .gitignore

# Remote state (team-friendly)
# terraform { backend "s3" { bucket = "my-tf-state" ... } }
⚠️
Terraform state is the source of truth. If you manually delete a resource in the console, Terraform doesn't know until the next plan. It will try to recreate it. Always use Terraform to manage resources that Terraform created.
📝 Day 2 Exercise
Parameterize Your Config
  1. A
  2. d
  3. d
  4. v
  5. a
  6. r
  7. i
  8. a
  9. b
  10. l
  11. e
  12. s
  13. f
  14. o
  15. r
  16. r
  17. e
  18. g
  19. i
  20. o
  21. n
  22. ,
  23. e
  24. n
  25. v
  26. i
  27. r
  28. o
  29. n
  30. m
  31. e
  32. n
  33. t
  34. ,
  35. a
  36. n
  37. d
  38. a
  39. l
  40. i
  41. s
  42. t
  43. o
  44. f
  45. t
  46. a
  47. g
  48. s
  49. .
  50. C
  51. r
  52. e
  53. a
  54. t
  55. e
  56. a
  57. t
  58. e
  59. r
  60. r
  61. a
  62. f
  63. o
  64. r
  65. m
  66. .
  67. t
  68. f
  69. v
  70. a
  71. r
  72. s
  73. f
  74. i
  75. l
  76. e
  77. .
  78. A
  79. d
  80. d
  81. o
  82. u
  83. t
  84. p
  85. u
  86. t
  87. s
  88. f
  89. o
  90. r
  91. a
  92. l
  93. l
  94. r
  95. e
  96. s
  97. o
  98. u
  99. r
  100. c
  101. e
  102. I
  103. D
  104. s
  105. /
  106. A
  107. R
  108. N
  109. s
  110. .
  111. R
  112. u
  113. n
  114. a
  115. p
  116. p
  117. l
  118. y
  119. a
  120. n
  121. d
  122. v
  123. e
  124. r
  125. i
  126. f
  127. y
  128. o
  129. u
  130. t
  131. p
  132. u
  133. t
  134. s
  135. a
  136. r
  137. e
  138. p
  139. r
  140. i
  141. n
  142. t
  143. e
  144. d
  145. .

Day 2 Summary

  • Variables make configs reusable. Types: string, number, bool, list, map, object.
  • terraform.tfvars supplies values. TF_VAR_name env vars work too — good for secrets.
  • Outputs expose values after apply. Use them to pass info between modules.
  • State maps config to real resources. Use remote state (S3, Terraform Cloud) for teams.
Finished this lesson?