A
acceptance tests 282-283
for Petstore provider 283
for provider schema 282
Petstore data source 367-368
accounts
AWS (Amazon Web Services) 353
Azure 355
GCP (Google Cloud Platform) 357
ALB (application load balancer) 94
ami attribute 212
Ansible 224
ansible-playbook command 232
application layer 76
Apply stage 304-306
approve stage 310
architecture
Blue/Green deployments 217-218
federated Nomad cluster 192-195
hybrid-cloud load balancing 184-185
multi-tiered web application 77-78
remote backend modules 131-132
self-service infrastructure provisioning 237
serverless deployments 108-112
archive_file data source 69, 73
arguments 11
ARM (Azure Resource Manager) 124-127
deploying unsupported resources 125
generating configuration code 126-127
migrating from legacy code 125-126
ARN (Amazon Resource Name) 138, 303
ASM (AWS Secrets Manager) 347
attributes 11
auto_apply 321
-auto-approve flag 41
automating Terraform 294, 319-324
beginning at root 299
custom solution for Terraform Enterprise 295-298
design details 297-298
reverse-engineering Terraform Enterprise 295-297
deploying Terraform CI/CD pipeline 315-319
configuring Terraform variables 317
connecting to GitHub 319
creating least-privileged deployment policy 316
creating source repository 315
deploying to AWS 317-318
developing Terraform CI/CD pipeline 299-312
building Plan and Apply stages 304-306
code 312
configuring environment variables 306-308
declaring input variables 300
declaring pipeline as code 309-311
IAM roles and policies 301-303
autoscaling module 93-99
cloudinit config data source 96-99
trickling down data 94
AWS (Amazon Web Services) 353-354
configuring credentials file 354
creating account 353
creating IAM user 353-354
deploying Terraform CI/CD pipeline 317-318
multi-tiered web application in 75-102
architecture 77-78
autoscaling module 93-99
database module 88-93
deploying web application 99-101
networking module 84-88
root module 81-84
Terraform modules 78-80
AWS (Amazon Web Services) provider 11-12, 354
aws configure command 354
AWS Secrets Manager (ASM) 347
Azure 355-356
configuring in Terraform 356
creating account 355
installing Azure CLI 355
obtaining credentials via CLI 355-356
serverless deployments to 122-124
Azure Functions app 111
azure.addresses.consul_ui 198
azure.addresses.nomad_ui 199
B
BACKEND variable 308
Blue/Green deployments 212, 215-222
architecture 217-218
Blue/Green cutover 221-222
code 219
considerations 222
deploy 219-220
BrowserQuest 182
browserquest_address output 202, 206
bucket 149
build command 305
C
CI/CD pipelines (continuous integration/continuous deployment) 155-180
automating Terraform 294-324
beginning at root 299
custom solution for Terraform Enterprise 295-298
deploying 319-322
deploying Terraform CI/CD pipeline 315-319
developing Terraform CI/CD pipeline 299-312
configurations and provisioners 162-171
dynamic blocks 169-171
executing scripts with provisioners 164
for_each vs. count 162-164
null resource with local-exec provisioner 166
repeating configuration blocks 167, 171
configuring serverless containers 171-173
deploying static infrastructure 173-176
Docker containers 158-159, 176-178
two-stage deployments 156-157
workspace setup 160-161
CIDR (Classless Inter-Domain Routing) 351
Cloud Build service 158
Cloud Run service 158
Cloud Source Repositories service 158
cloud-agnostic 7-8
cloudinit config data source 96-99
CM (configuration management) 223-233
application deployment 231-233
code 224-229
combining Terraform with Ansible 224
infrastructure deployment 230-231
code
Blue/Green deployments 219
CM (configuration management) 224-229
declaring pipeline as 309-311
hybrid-cloud load balancing 186-188
managed services 204
remote backend modules 134-138
root module 82-84
self-service infrastructure provisioning 238-239
serverless deployments 112-120
function app 117-118
resource groups 113-114
storage blobs 115-117
storage containers 114-115
Terraform CI/CD pipeline 312
codepipeline module 297, 299
CodeStarConnections connection 309
conditional expressions 66-67
config_path attribute 188
configuration arguments 12
configuration code 126-127
configuration drift 42-44
configuration files
modifying 20-21
writing 9-11
configuration management 3
ConfigureFunc function 273
CONFIRM_DESTROY flag 306, 321
CONFIRM_DESTROY variable 308
connection attribute 234
Container Registry service 158
content attribute 40
corrupted state 130
count argument 60, 65, 73-74, 162-163, 246
count attribute 219, 233, 236
count parameter 65
count, for_each vs. 162-164
count.index expression 68-69
cowsay tool 166
create_before_destroy 213-214
create_before_destroy flag 211, 213
create_before_destroy meta attribute 211-212
Create() function 276
Create() function hook 48, 164, 274, 277
credentials
AWS 354
Azure 355-356
credentials output 249
credentials value 250
CRUD (create, read, update, delete) 24, 267
custom providers 265-293
blueprints for 266-268
Petstore provider architecture 268
Terraform provider basics 267
creating resources 274-280
Create() 276
Delete() 279-280
Read() 277-278
Update() 278-279
implementation 285-292
deploying Petstore API 285-286
installing provider 288
pets as code 288-292
testing and building provider 286-288
writing acceptance tests 282-283
for pet resource 283
for provider schema 282
writing Petstore provider 269-273
configuring provider schema 270-273
setting up Go project 269-270
custom resources with Shell provider 359-363
implementation 360-362
installing 359-360
D
data access layer 76
data sources 364-369
acceptance tests 367-368
adding 19-23
applying changes 21-22
destroying infrastructure 22-23
modifying Terraform configuration 20-21
creating 365-366
external 337-338
registering 364
using 369
database module 88-93
generating random password 92-93
passing data from networking module 90-91
DataSourcesMap attribute 364
db_config variable 94
db_password 81
declarative programming 7
declaring, local file resource 26-27
default argument 53
default input argument 51
Delete function hook 274
Delete() function 30, 46-48, 164, 274, 279-280
deleting, local file resource 45-47
dependencies, implicit 64
depends_on argument 69, 73
depends_on attribute 233
deployment_role_arn value 303
description input argument 52
destroy operation 46, 101
destroy runs 321-322
Docker containers 158-159, 176-178
designing pipeline 158
detailed engineering 159
kicking off 178
dynamic blocks 169-171
dynamic infrastructure 157, 199-201
dynamic secrets 345-347
AWS Secrets Manager (ASM) 347
HashiCorp Vault 345-346
dynamodb_table 149
E
each object 163
each.key accessor 163
each.value accessor 163
EC2 instance 8-19
configuring AWS provider 11-12
deploying 13-17
destroying 17-19
initializing Terraform 12
writing Terraform configuration 9-11
element() function 68
enable_green_application variable 219
encryption at rest 332-333
enhanced backends 130
environment variables 306-308, 339-341
error_message 54
execution plan 28-32
expressions
conditional 66-67
for expressions 61-62
expressiveness 8
extensibility 8, 236
external data sources 337-338
F
false expression 54, 349
federated Nomad cluster 191-203
architecture 192-195
dynamic infrastructure 199-201
overview 191-192
ready for use 202-203
static infrastructure 195-199
file() function 247
files, zipping 69-70
fileset() function 68, 247
filters block 366
first-class function 50
fixtures, test 261-263
flat modules 101, 132-133
for expressions 8, 52, 61-62, 169, 247-249, 306-307
for_each, count vs. 162-164
for-each expression 156
force new attribute 40
force_destroy attribute 257-258
ForceNew 274-275, 279
free software 6-7
function app 117-118
function hooks 26
functional programming 49-74
applying changes 71-72
assigning values with variable definition file 53
conditional expressions 66-67
count parameter 65
for expressions 61-62
functions 56-57
implicit dependencies 64
input variables 51-52
local file 68-69
local values 63
output values 57
printing output 59
shuffling lists 54-57
templates 59, 67-68
validating variables 53-54
zipping files 69-70
functions 56-57
G
GCP (Google Cloud Platform) 357-358
authenticating with Google Cloud SDK 358
configuring in Terraform 358
creating account 357
creating new project 357
designing pipeline 158
detailed engineering 159
Docker containers on 158-159, 176-178
installing Google Cloud SDK 358
kicking off 178
GET request 279, 338
GitHub 140, 319
go build 287
go mod get 286
go mod init 263, 286
Go project 269-270
go test -v command 263
Google Cloud Platform. See GCP
Google Cloud SDK
authenticating with 358
installing 358
GOPATH variable 260, 269
group, sorting by 109-112
H
HashiCorp Vault 345-346
HCL (HashiCorp Configuration Language) 6
higher-order function 50
host attribute 188
HTTP providers 338-339
http_http source 338
hybrid cloud 181
hybrid-cloud load balancing 183-190
architecture 184-185
code 186-188
deploying 188-190
I
IaC (infrastructure as code) 3, 124, 236
IAM (Identity and Access Management) 93, 132, 162
IAM (Identity and Access Management) module 250-251
creating user 353-354
roles and policies 301-303
iam module 244
iam.serviceAccountUser 171
ID resource 256
Identity and Access Management. See IAM
ids attribute 364
ignore_changes flag 213
image argument 171
image tag 305
immutability 50
immutable infrastructure 6, 278
implicit dependencies 64
importing resources 255-258
infrastructure as code (IaC) 3, 124, 236
input variables
for Terraform CI/CD pipeline 300
overview 51-52
validating variables 53-54
installing
Azure CLI 355
Google Cloud SDK 358
providers 288
Shell provider 359-360
instance_type attribute 212
integration tests 236, 258
J
join() function 249
L
lb_dns_name 81, 100
least-privileged access control 331-332
least-privileged deployment policy 316
legacy code 125-126
life cycle of Terraform resource 24-48
creating local file resource 33-35
customizing 212-215
considerations 215
create_before_destroy 213-214
declaring local file resource 26-27
deleting local file resource 45-47
generating execution plan 28-32
initializing workspace 27-28
performing no-op 36-38
process overview 25-26
updating local file resource 38, 45
detecting configuration drift 42-44
Terraform refresh 44-45
lifecycle argument 213, 234
lists, shuffling 54-57
load balancing, hybrid-cloud 183-190
architecture 184-185
code 186-188
deploying 188-190
local file resource
creating 33-35
declaring 26-27
deleting 45-47
saving output to 68-69
updating 38-45
detecting configuration drift 42-44
Terraform refresh 44-45
local values 63, 247-248
local_file resource 29, 31, 35-36, 44, 46, 68, 70, 239-242, 340
local-exec provisioners 179, 214-215, 223, 230-231, 234, 266, 336-337, 344, 350, 363
blocking 350-351
dangers of 336
null resources with 166
local.default_environment 307
local.policies 248
local.policy_mapping value 246
local.uppercase_words 63
log files security 333-339
external data sources, dangers of 337-338
HTTP provider, dangers of 338-339
local-exec provisioners, dangers of 336
restricting access 339
sensitive information in 334-336
looping through multiple instances 249
M
Mad Libs stories 50-59
assigning values with variable definition file 53
functions 56-57
generating 60-72
applying changes 71-72
conditional expressions 66-67
count parameter 65
for expressions 61-62
implicit dependencies 64
local file 68-69
local values 63
templates 67-68
zipping files 69-70
input variables 51-52
output values 57
printing output 59
shuffling lists 54-57
templates 59
validating variables 53-54
main function 270
main package 270
main.tf file 82
maintainability 236
managed services 203-206
code 204
ready for use 205-206
many-staged pipelines 324
massively multiplayer online role-playing game. See MMORPG multi-cloud
migrating Terraform state 251-258
importing resources 255-258
moving resources 253-254
redeploying 254-255
state file structure 252-253
MMORPG (massively multiplayer online role-playing game), multi-cloud 181-207
hybrid-cloud load balancing 183-190
architecture 184-185
code 186-188
deploying 188-190
on federated Nomad cluster 191-203
architecture 192-195
dynamic infrastructure 199-201
overview 191-192
ready for use 202-203
static infrastructure 195-199
re-architecting to use managed services 203-206
code 204
ready for use 205-206
module expansions 246
module.iam expansion 249
modules 78-80
expansions 245-246
looping through multiple instances 249
modularizing code 243-245
root module 79-80
standard module structure 80
syntax 78-79
multi-line strings 247-248
multi-tiered web application in AWS 75-102
architecture 77-78
autoscaling module 93-99
templating cloudinit_config 96-99
trickling down data 94
database module 88-93
generating random password 92-93
passing data from networking module 90-91
deploying web application 99-101
networking module 84-88
root module 81-84
Terraform modules 78-80
root module 79-80
standard module structure 80
syntax 78-79
mutable infrastructure 6
N
name attribute 246, 275
Name label 11
name variable 250
namespace variable 81-83, 91, 112-114, 160
nested modules 132
networking module 84-88, 90-91
no-op (no-operation) 36-38
Nomad cluster, federated 191-203
architecture 192-195
dynamic infrastructure 199-201
overview 191-192
ready for use 202-203
static infrastructure 195-199
nonpure functions 85
null resources 166
null_resource provider 145-146, 153, 156, 166, 336
O
ocal-exec provisioner 340
open source software 6-7
organizing directory structure 160-161
-out flag 31
output values
overview 57
printing 59
P
package main 270
PASSWORD 329
password 327-328, 342
password, random 92-93
PATCH request 279
PENDING state 319
petsource_pet_ids data source 366
Petstore provider
architecture 268
creating resources 274-280
Create() 276
Delete() 279-280
Read() 277-278
Update() 278-279
data source 364-369
acceptance tests 367-368
creating 365-366
registering 364
using 369
implementation 285-292
deploying Petstore API 285-286
installing provider 288
pets as code 288-292
testing and building provider 286-288
writing 269-273
configuring provider schema 270-273
setting up Go project 269-270
writing acceptance tests 282-283
for pet resource 283
for provider schema 282
PETSTORE_ADDRESS variable 287
petstore_pet data source 366
petstore_pet resource 266, 272
petstore_pet_ids data source 366-367
Plan stage 304-306
policies
IAM module 301-303
least-privileged deployment policy 316
Sentinel policies as code 347-351
blocking local-exec provisioners 350-351
policies attribute 246
policies input 247
policy variable 250
PreCheck function 287
presentation layer 76
prevent_destroy flag 213
principle of least privilege 92, 331
printing output 59
production.tfvars 343
-profile flag 354
project_name variable 83
projects, GCP 357
PROVIDER 140
provider attribute 234
provider block 11, 354
Provider() function 270
providers
custom 265-293
blueprints for 266-268
creating resources 274-280
implementation 285-292
writing acceptance tests 282-283
writing Petstore provider 269-273
Shell provider 359-363
installing provider 359-360
using provider 360-362
provisioner attribute 234
provisioners
executing scripts with 164
null resources with local-exec 166
provisioning tools 6
public_ip output 227
pure functions 49, 54
Q
query constraint arguments 21
R
race conditions 130
random password 92-93
random_shuffle resource 55, 61, 63-64, 69
random_string resource 304
RDS (Relational Database Service) 241, 285, 327
Read() function 30, 36-38, 45, 48, 274, 276-278
refactoring 235-264
migrating Terraform state 251-258
importing resources 255-258
moving resources 253-254
redeploying 254-255
state file structure 252-253
self-service infrastructure provisioning 236-242
architecture 237
code 238-239
preliminary deployment 240-241
tainting and rotating access keys 241-242
Terraform configuration 242-251
Identity and Access Management (IAM) module 250-251
looping through multiple module instances 249
modularizing code 243-245
module expansions 245-246
replacing multi-line strings with local values 247-248
testing infrastructure as code 258-263
running test 263
test fixtures 261-263
writing basic Terraform test 259-260
region variable 81-83, 160
registering data source 364
registry.terraform.io 292
remote backend modules 129-154
developing 131-138
architecture 131-132
flat modules 132-133
writing code 134-138
for teams 143-146
deploying S3 backend 143-144
storing state in S3 backend 144-146
sharing 139-142
GitHub 140
Terraform Registry 140-142
standard and enhanced backends 130
Terraform Cloud 153
workspaces 148-153
cleaning up 152-153
deploying multiple environments 148-151
remote-exec provisioner 211, 234
repeating configuration blocks 167-171
required_providers block 359
resource chaining 86
resource groups 113-114
resource provisioners 156
ResourceProvider interface 270
resourcePSPet() function 272, 274
resources
creating 274-280
Create() 276
Delete() 279-280
Read() 277-278
Update() 278-279
customizing lifecycles 212-215
considerations 215
create_before_destroy 213-214
importing 255-258
moving 253-254
with Shell provider 359-363
implementation 360-362
installing 359-360
reusability 236
role_arn 149
root module 79-84, 299
rotating access keys 241-242
run.admin 171
run.invoker role 172
S
S3 remote backends 129-154
developing 131-138
architecture 131-132
flat modules 132-133
writing code 134-138
for teams 143-146
deploying S3 backend 143-144
storing state in S3 backend 144-146
sharing 139-142
GitHub 140
Terraform Registry 140-142
standard and enhanced backends 130
Terraform Cloud 153
workspaces 148-153
cleaning up 152-153
deploying multiple environments 148-151
s3backend module 298-299, 303
schema, provider
configuring 270-273
writing acceptance tests for 282
schema.EnvDefaultFunc function 271
schema.Resource interface 274
scripts, executing with provisioners 164
SECRET_ID 330
secrets.tfvars 343
security and secrets management 325-352
dynamic secrets 345-347
AWS Secrets Manager (ASM) 347
HashiCorp Vault 345-346
log files 333-339
external data sources, dangers of 337-338
HTTP provider, dangers of 338-339
local-exec provisioners, dangers of 336
restricting access to 339
sensitive information in 334-336
writing 349
environment variables 339-341
redirecting sensitive Terraform variables 343-344
Terraform variables 342-343
Terraform state 326-333
encryption at rest 332-333
least-privileged access control 331-332
removing unnecessary secrets from 326-331
self-service infrastructure provisioning 236-242
architecture 237
code 238-239
preliminary deployment 240-241
tainting and rotating access keys 241-242
writing 349
serverless deployments 105, 107-128
architecture 108-112
combining Azure Resource Manager (ARM) with Terraform 124-127
deploying unsupported resources 125
generating configuration code 126-127
migrating from legacy code 125-126
deploying to Azure 122-124
writing code 112-120
function app 117-118
resource groups 113-114
storage blobs 115-117
storage containers 114-115
sg output 88
sg variable 94
shared configuration objects 267
sharing remote backend modules 139-142
GitHub 140
Terraform Registry 140-142
Shell provider 359-363
installing provider 359-360
using provider 360-362
shell_script data source 360
shell_script resource 360
shuffle_enabled variable 67
shuffle_resource 65
shuffle() function 54
shuffling lists 54-57
size, sorting by 109-112
sleep 60 command 164
software componentization 87
source repository 315
species attribute 275
ssh_keypair variable 81
standard backends 130
standard module structure 80
state file structure 252-253
static infrastructure 173-176, 195-199
static secrets 339-344
environment variables 339-341
redirecting sensitive Terraform variables 343-344
Terraform variables 342-343
storage blobs 115-117
storage containers 114-115
strangler façade pattern 125
strings, multi-line 247-248
syntax, module 78-79
system tests 258
T
tainting access keys 241-242
teams 143-146
deploying S3 backend 143-144
storing state in S3 backend 144-146
templatefile() function 49, 56-57, 69, 73-74, 98
templates 59, 67-68
Terraform 3-23
adding data sources 19-23
applying changes 21-22
destroying infrastructure 22-23
modifying Terraform configuration 20-21
characteristics 4-8
cloud-agnostic 7-8
declarative programming 7
easy to use 6
free and open source software 6-7
provisioning tool 6
richly expressive and highly extensible 8
combining ARM with 124-127
deploying unsupported resources 125
generating configuration code 126-127
migrating from legacy code 125-126
combining with Ansible 224
configuring
AWS provider 354
Azure in 356
GCP 358
deploying virtual machine 8-19
configuring AWS provider 11-12
deploying EC2 instance 13-17
destroying EC2 instance 17-19
initializing Terraform 12
life cycle of resource 24-48
creating local file resource 33-35
declaring local file resource 26-27
deleting local file resource 45-47
generating execution plan 28-32
initializing workspace 27-28
performing no-operation (no-op) 36-38
process overview 25-26
updating local file resource 38-45
modules 78-80
root module 79-80
standard module structure 80
syntax 78-79
provider basics 267
refactoring 242-251
IAM module 250-251
looping through multiple module instances 249
modularizing code 243-245
module expansions 245-246
replacing multi-line strings with local values 247-248
security and secrets management 326-333
encryption at rest 332-333
least-privileged access control 331-332
removing unnecessary secrets from 326-331
terraform apply -auto-approve 41, 100, 123, 146
terraform apply -state 148
terraform apply command 9, 13, 19, 21, 33, 39, 44-45, 48, 71, 79, 85, 93, 116, 123, 130, 138, 143, 145, 156, 166, 189, 196, 205, 207, 212, 219, 231, 240-242, 252, 258, 260, 274, 306, 310, 317, 321-323, 336, 356
Terraform Cloud 7, 153
Terraform core 6
terraform destroy -auto-approve 101
terraform destroy command 9, 17, 19, 22, 45, 72, 124, 130, 153, 166, 178, 190, 207, 241, 258, 260, 274, 292, 306, 321, 323, 336
Terraform Enterprise 7, 295-298
design details 297-298
reverse-engineering 295-297
terraform get 116, 128
terraform graph command 31
terraform import 235-236, 252, 255-256, 264
terraform init command 9, 12, 19, 59, 71, 84, 100, 116, 122, 128, 143, 146, 148, 189, 196, 205, 219, 240, 251, 254, 270, 306, 316, 323, 360
terraform plan 29-31, 33, 36-37, 39, 42, 44, 122-123, 130, 237, 241, 251, 255, 257, 274, 296-297, 306, 309, 323, 337, 339, 356
terraform plan -destroy 306
terraform providers schema command 271
Terraform refresh 44-45
terraform refresh command 44, 48, 255, 258, 264
Terraform Registry 140-142
terraform show command 15, 19, 22, 32, 43-44, 256
terraform state command 146, 235
terraform state list command 150, 241, 254
terraform state mv command 252-253, 264
terraform state rm command 252, 255-256, 264
terraform state show 256, 291
terraform taint command 236, 241, 264
terraform validate 259
Terraform variables
redirecting sensitive 343-344
static secrets 342-343
terraform workspace list 148
terraform workspace select command 148
terraform-aws-s3backend 140
terraform-exec 235
terraform-lint 259
terraform-plugin-sdk 270
terraform.ResourceProvider interface 270
TestAccPSPet_basic() 287
testing
infrastructure as code 258-263
running test 263
test fixtures 261-263
writing basic Terraform test 259-260
writing acceptance tests 282-283
for pet resource 283
for provider schema 282
TF_IN_AUTOMATION variable 308
TF_INPUT variable 308
TF_LOG 334
tfe_workspace 365
tfe_workspace_ids 365
tia-chapter4-dev 83
timestamp() function 74
trickling down data 94
type input argument 52
U
unit tests 258
unsupported resources 125
Update function hook 274
Update() function 30, 278-279
Update() function hook 48, 274, 277
updating local file resource 38-45
detecting configuration drift 42-44
Terraform refresh 44-45
urls.app address 176
user_data attribute 212, 214
user_init data 234
USERNAME 329
username 327-328, 342
uuid() function 74
V
validating variables 53-54
var.auto_apply flag 311
var.environment variable 306-307
var.namespace 114, 160
var.num_files files 68
var.num_files variable 65
var.password 327, 344
var.production 221
var.terraform_version 305
var.username 327
var.version variable 214
var.words 61-63
variable definition files 53
variable object type 51
virtual machine 8-19
configuring AWS provider 11-12
deploying EC2 instance 13-17
destroying EC2 instance 17-19
initializing Terraform 12
vpc output 88, 91
vpc variable 94
W
web application 99-101
website_url value 112
WORKING_DIRECTORY variable 306, 308
workspaces
initializing 27-28
remote backend modules 148-153
cleaning up 152-153
deploying multiple environments 148-151
Z
ZDDs (zero-downtime deployments) 211-234
Blue/Green deployments 215-222
architecture 217-218
Blue/Green cutover 221-222
code 219
considerations 222
deploy 219-220
CM (configuration management) 223-233
application deployment 231-233
code 224-229
combining Terraform with Ansible 224
infrastructure deployment 230-231
customizing resource lifecycles 212-215
considerations 215
create_before_destroy 213-214
zipping files 69-70