Terraform Cloud Project Bootcamp with Andrew Brown — 1.6.0 Terrafrom Data Content Version
This article is part of my Terraform journey with Terraform Bootcamp by Andrew Brown and Andrew Bayko with Chris Williams and Shala.
My wild career adventure into Cloud Computing continues with Andrews, and I highly, highly recommend you to come join us if you are interested. Check out Andrews’ free youtube learning contents. You can also buy some paid courses here to support their good cause.
Agenda
Video here: 1 6 0 Terraform Data Content Version
Issue #33 Goals
- ✅ 1) Only change files when we set a content version.
Workflow
- ✅ 1) Add a variable
content_version
- ✅ 2) Disable
etag
usinglifecycle
- ✅ 3) Trigger updates on
content_version
update
Troubleshooting
Previously in unit 1.5.0, we invalidated the CloudFront cache using /*
which clears all the data that’s cached in the edge locations and this is an expensive call. CloudFront copies the cache version to all the edge location servers around the world.
In this unit, we will set up the content version so we can refresh the cache with the most up-to-date data according to version updates.
1. Add a variable content_verison
Add the content_version
to the variables.tf
file. Pay attention to the file and directory level:
./modules/terrahouse_aws/varaibles.tf
variable "content_version" {
description = "The content version. Is a positive integer starting at 1."
type = number
validation {
condition = var.content_version > 0 && floor(var.content_version) == var.content_version
error_message = "The content_version must be a positive integer starting at 1."
}
}
variables.tf
(at root)
variable "content_version" {
type = number
}
2. Disable etag using lifecycle
lifecycle
is a useful meta-argument that we can use to control the behaviour of resources. There are 4 arguments — create_before_destroy
, prevent_destroy
, ignore_changes
, and replace_triggered_by
. In this step, we apply ignore_changes
on etag
to stop Terraform from updating the stack upon changes to files tagged with etag
.
⚠️Before implementing the lifecycle
on etag
, make sure that your etag
works correctly and detects file changes. I updated my index.html
file to observe its behaviour and it did apply the change set.
Add the following snippets to the resource storage definition in the module. We are disabling the etag
and placing a trigger that will help terraform pick up changes in the variable content_version
.
./modules/terrahouse_aws/resource-storage.tf
resource "aws_s3_object" "index_html" {
bucket = aws_s3_bucket.website_bucket.bucket
key = "index.html"
source = var.index_html_filepath
content_type = "text/html"
etag = filemd5("${path.root}/public/index.html")
+ lifecycle {
+ replace_triggered_by = [terraform_data.content_version.output]
+ ignore_changes = [etag]
+ }
}
...
+ resource "terraform_data" "content_version" {
+ input = var.content_version
+ }
Then terraform apply
so that the disabling etag
and the trigger on content_version
update take effect. Then, try updating the index.html
file then terraform plan
to test if etag is correctly NOT triggered.
3. Trigger updates on content_version update
Andrew tries updating the content_version
value in terraform.tfvars
. Then terraform apply
. However, nothing changes.
# terraform.tfvars
content_version = 2
Andrew figures out that the problem was the incorrect way we were referencing the variable content_version
in the module
in main.tf
at root. The version value was hard-coded. Modify it to refer to the actual variable.
module "terrahouse_aws" {
source = "./modules/terrahouse_aws"
user_uuid = var.user_uuid
bucket_name = var.bucket_name
index_html_filepath = var.index_html_filepath
error_html_filepath = var.error_html_filepath
- content_version = 1
+ content_version = var.content_version
}
Then do this:
- Change the
content_version
value invariables.tfvars
tf apply — auto-approve
Terraform correctly detected the update in the content_version
value and applied the change set accordingly.
Troubleshooting
“content_version” is required, but no definition was found.
In the main.tf
at root, add content_version
in the terrahouse_aws
module.
# ./main.tf
module "terrahouse_aws" {
source = "./modules/terrahouse_aws"
user_uuid = var.user_uuid
bucket_name = var.bucket_name
index_html_filepath = var.index_html_filepath
error_html_filepath = var.error_html_filepath
+ content_version = var.content_version
}
Resources
Bootcamp
- Video: 1.6.0 Terraform Data Content Version
- My feature branch: 32-setup-content-version
- My complete Learning Journal