Terraform Cloud Project Bootcamp with Andrew Brown — 1.8.0 Assets Upload for Each
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 8 0 Assets Upload For Each
Issue #37 Goals
- ✅ 1) Use
for each
to upload assets. - ✅ 2) Explore different data structures in terraform.
- ✅ 3)
terraform console
Workflow
- ✅ 1) Run
http-server
and check your website. - ✅ 2)
for_each
: updateresource-storage.tf
&index.html
1. Run http-server and check your website.
Install http-server
which is a convenient http server that makes your local development and testing so easy. You can run the command in the before:
section on terminal. If you are using gitpod, you can update your gitpod.yml so your environment installs and spins it up every time you launch a new Gitpod environment:
# gitpod.yml
- name: http-server
before: |
npm install --global http-server
http-server
Once thehttp-server
is running, go check your website (http://128.0.1:8080
).
2. Update index.html & resource-storage.tf
We want to make terraform update our infrastructure every time there are differences in the objects stored in the designated bucket.
resource-storage.tf
Add the resource upload_assets
to the storage definition file in the terrahouse_aws
module.
resource-storage.tf
resource "aws_s3_object" "upload_assets" {
for_each = fileset("${path.root}/public/assets", "*.{jpg.png.gif}")
bucket = aws_s3_bucket.website_bucket.bucket
key = "assets/${each.key}"
source = var.index_html_filepath
content_type = "text/html"
etag = filemd5(var.index_html_filepath)
lifecycle {
replace_triggered_by = [ terraform_data.content_version.output ]
ignore_changes = [ etag ]
}
}
- You can test if the file path works correctly by testing it on
terraform console
. Open the console by runningterraform console
. Then runfileset(“${path.root}/public/assets”, “*.{jpg.png.gif}”)
. Make sure you are running this at root, otherwise it won’t be able to locate your files and return the result.
for_each
for_each accepts a map
or a set
of strings
and creates an instance for each item in that map
or set
. In our code above, for_each
will iterate through the set of strings using fileset
, and create each file in the aws_s3_bucket.website_bucket.bucket
as destination. Each object created in the bucket will have its own etag
. As constained by the lifecycle
, however, the replacement will only be triggered by changes in content_version
.
index.html
As we have configured Terraform to take note of changes in the target path (var.assets_path
) and upload files accordingly, I added some <images>
in the index file and the corresponding image files at the local path.
+ <h1 class="fonts-head1">Do one thing
+ <br>that scares you every day.
+ </h1>
+ <p>Eleanor Roosevelt</p>
+ <img src="./assets/eleanor-roosevelt.jpg" />
Then run the following commands to test the function.
terraform plan
terraform apply
Terraform picks up the changes and correctly uploads newly added image files to the remote S3 bucket
.
Resources
Bootcamp
- Video: 1 8 0 Assets Upload For Each
- My feature branch: 35-assets-upload
- My complete Learning Journal