This folder contains several helper scripts for working with Terraform. The scripts are:
terraform-update-variable: This script can automatically update a variable in a terraform.tfvars or
terragrunt.hcl file and commit and push the changes to Git. It's common practice to store the version number of the
currently deployed app in a variable and this script comes in handy for updating those variables automatically, such
as in a CI job after building a new AMI or Docker image.
git-updated-folders: This script can be used to detect all the folders that have have been updated between two git
refs (branch, tag, sha, etc). This can be used in a CI pipeline to find the terraform and terragrunt modules that
have changed, and only run plan or apply on the modules that has been affected.
Imagine you have a set of Terragrunt config in the live folder to deploy an app called rails-app. You create
Amazon Machine Images (AMIs) for each new version of the app using Packer and the currently
deployed version of the app is defined in a variable called rails_app_version, set to ami-12345 in
live/rails-app/terragrunt.hcl.
If you just build a new version of the AMI, ami-67890, you could deploy it automatically, perhaps in a CI job,
as follows:
cd live/rails-app
# Due to the existence of types in terragrunt.hcl, we need to be explicit about how the variable values are quoted.terraform-update-variable --name rails_app_version --value "\"ami-67890\""
terragrunt apply
Running the commands above would:
Set the rails_app_version variable in the inputs map to the ID of the new AMI, ami-67890 in terragrunt.hcl.
commit and push the changes to terragrunt.hcl to Git.
Deploy the changes using Terragrunt.
Terraform
Imagine you have a set of Terraform templates in the templates folder to deploy an app called rails-app. You create
Amazon Machine Images (AMIs) for each new version of the app using Packer and the currently
deployed version of the app is defined in a variable called rails_app_version, set to ami-12345 in
templates/terraform.tfvars.
If you just build a new version of the AMI, ami-67890, you could deploy it automatically, perhaps in a CI job,
as follows:
cd templates
terraform-update-variable --vars-path terraform.tfvars --name rails_app_version --value "\"ami-67890\""terraform apply
Running the commands above would:
Set the rails_app_version variable to the ID of the new AMI, ami-67890 in terraform.tfvars.
commit and push the changes to terraform.tfvars to Git.
Deploy the changes using Terraform.
git-updated-folders
Terragrunt
Consider the following typical terragrunt folder structure:
Here we use * to indicate files that have been modified between the git refs development and master. To get the
terragrunt modules that have changed:
$ terraform-git-updated-modules --source-ref development --target-ref master --terragrunt
non-prod/us-east-1/qa/mysql
non-prod/us-east-1/stage/mysql
prod/us-east-1/prod/mysql
Each of these folders were detected as terragrunt modules (because they contain a terragrunt.hcl file), and were
marked as changed because the underlying terragrunt config was updated.
Note that this will only detect terragrunt.hcl files that have changed. For example, in the following scenario where
the root terragrunt.hcl file and a few yaml files were changed (the files denoted with * are those that changed),
only the root folder is returned:
Here we use * to indicate files that have been modified between the git refs development and master. To get the
terraform modules that have changed:
$ terraform-git-updated-modules --source-ref development --target-ref master --terraform
modules/mysql
live/us-east-1/prod
live/us-east-1/non-prod
Each of these were detected as terraform modules (because they contain .tf files), and were marked as changed because
one of the underlying .tf or .tfvars files have changed. Specifically:
modules/mysql <= modules/mysql/outputs.tf
live/us-east-1/prod <= live/us-east-1/prod/main.tf and live/us-east-1/prod/outputs.tf
{"treedata":{"name":"root","toggled":true,"children":[{"name":".circleci","children":[{"name":"config.yml","path":".circleci/config.yml","sha":"39a21f4f15394416888317f9eb003e5e9760176d"}]},{"name":".gitignore","path":".gitignore","sha":"1cd2e7ca72e5102b6b85a0c1de82d28c99d4287e"},{"name":".pre-commit-config.yaml","path":".pre-commit-config.yaml","sha":"47826a6fca6c68c6e0f0e9ac88988c2830ed4ef1"},{"name":"CODEOWNERS","path":"CODEOWNERS","sha":"a834dbe979d6fb551a71156abfb7e22771115e48"},{"name":"LICENSE.txt","path":"LICENSE.txt","sha":"f4e3d9bd4717a044ed31ad847a300eee74371a78"},{"name":"README-CircleCI.adoc","path":"README-CircleCI.adoc","sha":"046b030ed6e15023530d4a29a3dcf60ac7982d27"},{"name":"README-Jenkins.adoc","path":"README-Jenkins.adoc","sha":"2587e3b59001ed39eaac88468202afdcbc2332af"},{"name":"README-Terraform-Terragrunt-Pipeline.adoc","path":"README-Terraform-Terragrunt-Pipeline.adoc","sha":"1ad99530c6cf984aa638e7c2fcd0bf4d4987ce12"},{"name":"README-TravisCI.adoc","path":"README-TravisCI.adoc","sha":"45e0d32aae5d971ee7e7670dc0da94d364c14457"},{"name":"README.adoc","path":"README.adoc","sha":"47cb10253af3b2e514678434a61ad681c02a88f2"},{"name":"_ci","children":[{"name":"output-debug-values.sh","path":"_ci/output-debug-values.sh","sha":"fa613638c76c2031b1427c2daa1d66f71fedad68"}]},{"name":"_docs","children":[{"name":"circleci-cicd-architecture.png","path":"_docs/circleci-cicd-architecture.png","sha":"06f8a55b7c123b6e589333a1ff1c3d90c43222d6"},{"name":"circleci-icon.png","path":"_docs/circleci-icon.png","sha":"d4e8df17858e6f230ff9e8d90ea388b3ff340b79"},{"name":"jenkins-architecture.png","path":"_docs/jenkins-architecture.png","sha":"a35a534eb7f13547e232635262d6b1c1506e9230"},{"name":"jenkins-icon.png","path":"_docs/jenkins-icon.png","sha":"cfb474486acb167b655c22a400fe5cc999959164"},{"name":"terraform-icon.png","path":"_docs/terraform-icon.png","sha":"85602f11c76fd989788112ba40c08d979ddb1164"},{"name":"tftg-pipeline-architecture.png","path":"_docs/tftg-pipeline-architecture.png","sha":"c016f9263be935e933db832e6e5047d6d656339c"},{"name":"travisci-cicd-architecture.png","path":"_docs/travisci-cicd-architecture.png","sha":"c7da609e901de1baba84918893af9016c3da78ed"},{"name":"travisci-icon.png","path":"_docs/travisci-icon.png","sha":"57116e900f797c8f35399929fb3a24b2cf0e7181"}]},{"name":"examples","children":[{"name":"ecs-deploy-runner","children":[{"name":"README.md","path":"examples/ecs-deploy-runner/README.md","sha":"f7dbc2c05f78cdeaff779eecfef93594f7a9c175"},{"name":"main.tf","path":"examples/ecs-deploy-runner/main.tf","sha":"ba5f23421fb1e4da5a44f12ba3b750ea56ac56e1"},{"name":"outputs.tf","path":"examples/ecs-deploy-runner/outputs.tf","sha":"0d39cc204673e2e92f0b6e32464ac8080fda59c2"},{"name":"variables.tf","path":"examples/ecs-deploy-runner/variables.tf","sha":"569c2a38d743951b63d72e61caeac4071d7bbd92"}]},{"name":"iam-policies","children":[{"name":"README.md","path":"examples/iam-policies/README.md","sha":"4eaf42cd7b4bc254ac9aabfaa8d6c1b4b8cc4281"},{"name":"main.tf","path":"examples/iam-policies/main.tf","sha":"29ed07d00498d2964f2850a49cb9b28cce541333"},{"name":"vars.tf","path":"examples/iam-policies/vars.tf","sha":"ffd4eed9234a389e6809cbb1c149efdbe778578e"}]},{"name":"jenkins","children":[{"name":"README.md","path":"examples/jenkins/README.md","sha":"5c76af2853297fa24f0ab44dc1cdcdf6ba8e1a55"},{"name":"docker-compose.yml","path":"examples/jenkins/docker-compose.yml","sha":"cdbb01e4c39d6ad67656d7997355b03027f2358e"},{"name":"main.tf","path":"examples/jenkins/main.tf","sha":"1881a2126a139b44718e4fd54aaa8a087206b8da"},{"name":"mock","children":[{"name":"mock-user-data.sh","path":"examples/jenkins/mock/mock-user-data.sh","sha":"610ba8091622d0bbec4301093b63c4263b5939ae"},{"name":"mount-ebs-volume","path":"examples/jenkins/mock/mount-ebs-volume","sha":"faa2394ad8a7a35657fb7f34b2014c7f05224e56"},{"name":"systemctl","path":"examples/jenkins/mock/systemctl","sha":"c656c65a7fd2b411548adb7865bc9c065333ad2e"}]},{"name":"outputs.tf","path":"examples/jenkins/outputs.tf","sha":"0be347ef2da711389da6e9ab98e7717e3dfa1a02"},{"name":"packer","children":[{"name":"jenkins.json","path":"examples/jenkins/packer/jenkins.json","sha":"d35f1c232b6d5cc2f35b37eb4bac1409a4c4c391"}]},{"name":"user-data","children":[{"name":"user-data.sh","path":"examples/jenkins/user-data/user-data.sh","sha":"19a4ccc9a1f8cb264d6995473ece0c2b02a0091a"}]},{"name":"vars.tf","path":"examples/jenkins/vars.tf","sha":"880057af01bab8502d9c786cf2827b3f8134cc69"}]}]},{"name":"modules","children":[{"name":"aws-helpers","children":[{"name":"README.md","path":"modules/aws-helpers/README.md","sha":"2fc74c09e7880238a4c049022f455809549d2ee1"},{"name":"bin","children":[{"name":"publish-ami","path":"modules/aws-helpers/bin/publish-ami","sha":"1d5697d411cbeed05734fb356ffbf598f7e4eeeb"}]},{"name":"install.sh","path":"modules/aws-helpers/install.sh","sha":"2700711d6a80c6f6c218e4b3d5b1b0cfe4d7609b"}]},{"name":"build-helpers","children":[{"name":"README.md","path":"modules/build-helpers/README.md","sha":"6816ecb1ffd0810892df24343366667a2a4ba66a"},{"name":"bin","children":[{"name":"build-docker-image","path":"modules/build-helpers/bin/build-docker-image","sha":"0fde55c7e1985925fe00d2d399b190ae6b2edd26"},{"name":"build-packer-artifact","path":"modules/build-helpers/bin/build-packer-artifact","sha":"70f860fd8dab2178c9a89a2ced7c548d1cc5d562"}]},{"name":"install.sh","path":"modules/build-helpers/install.sh","sha":"a132488127b88ef8268399a0b3852aa5e0967a20"}]},{"name":"check-url","children":[{"name":"README.md","path":"modules/check-url/README.md","sha":"070d26ac5f4cf136fc28a69d97df6710a341cf24"},{"name":"bin","children":[{"name":"check-url","path":"modules/check-url/bin/check-url","sha":"4e6c57dd70e0a385fb23814619dc917b7c527e57"}]},{"name":"install.sh","path":"modules/check-url/install.sh","sha":"488fad728f75e4ffb6d7156b7cc9ee9682d60183"}]},{"name":"circleci-helpers","children":[{"name":"README.md","path":"modules/circleci-helpers/README.md","sha":"3e58d0856dd6ae04bbd22814d6243b0225a689d9"},{"name":"bin","children":[{"name":"install-go-version","path":"modules/circleci-helpers/bin/install-go-version","sha":"8a0121205f24358a00af129e729795013ebf7edb"},{"name":"place-repo-in-gopath","path":"modules/circleci-helpers/bin/place-repo-in-gopath","sha":"ac7085bb304a2004050e676bea658f039493fdcc"}]},{"name":"install.sh","path":"modules/circleci-helpers/install.sh","sha":"313288f93c55678a883f53106471a21f8ebbb2fa"}]},{"name":"ec2-backup","children":[{"name":"README.md","path":"modules/ec2-backup/README.md","sha":"d9ef51b6b9a83f8e5bf15a582d5b18d48091f3de"},{"name":"backup-lambda-function","children":[{"name":"ec2-snapper_linux_amd64-v0.5.2","path":"modules/ec2-backup/backup-lambda-function/ec2-snapper_linux_amd64-v0.5.2","sha":"11f872d3dde35b44c160eccf3f0adf49cc5bd72f"},{"name":"index.js","path":"modules/ec2-backup/backup-lambda-function/index.js","sha":"555ea9666346d7d57588452a5a9642ff73bcf25e"}]},{"name":"main.tf","path":"modules/ec2-backup/main.tf","sha":"78ed3754120c76cb150f6b858bc7cfdbddaa1466"},{"name":"outputs.tf","path":"modules/ec2-backup/outputs.tf","sha":"770744637fcd7cafd98991397b26a82d01524192"},{"name":"vars.tf","path":"modules/ec2-backup/vars.tf","sha":"dd8d61875d9f68596d05bf677a51119750f512e8"}]},{"name":"ecs-deploy-runner-invoke-iam-policy","children":[{"name":"README.md","path":"modules/ecs-deploy-runner-invoke-iam-policy/README.md","sha":"66152227a29ea201358ced76a359bb5f2cfd7c9d"},{"name":"main.tf","path":"modules/ecs-deploy-runner-invoke-iam-policy/main.tf","sha":"42b23973668008665974e714e1ca077ea96a9b9d"},{"name":"outputs.tf","path":"modules/ecs-deploy-runner-invoke-iam-policy/outputs.tf","sha":"8703d962acdf4584375558aa59831c1c873fe606"},{"name":"variables.tf","path":"modules/ecs-deploy-runner-invoke-iam-policy/variables.tf","sha":"566d414f7ef8621e8c7613847d92b77c3e08cbb6"}]},{"name":"ecs-deploy-runner-standard-configuration","children":[{"name":"README.md","path":"modules/ecs-deploy-runner-standard-configuration/README.md","sha":"f4c49c30bd8f1675ac907077b2e59a946ee96315"},{"name":"main.tf","path":"modules/ecs-deploy-runner-standard-configuration/main.tf","sha":"000a97b59512ee87ae1afea3e091723b262befdc"},{"name":"outputs.tf","path":"modules/ecs-deploy-runner-standard-configuration/outputs.tf","sha":"8a49694a66a0914299b1fb73e4b9576d32ec001e"},{"name":"variables.tf","path":"modules/ecs-deploy-runner-standard-configuration/variables.tf","sha":"f1475315eae8b7b3954400cf5abaa60855d1ee45"}]},{"name":"ecs-deploy-runner","children":[{"name":"README.adoc","path":"modules/ecs-deploy-runner/README.adoc","sha":"1857addf7729b043a1353863402b12b8cfb7ee4a"},{"name":"_docs","children":[{"name":"images","children":[{"name":"sequence-diagram.png","path":"modules/ecs-deploy-runner/_docs/images/sequence-diagram.png","sha":"15c9ea45ff27d20fdc23cf918f8c9ba64c0601a3"}]}]},{"name":"core-concepts.md","path":"modules/ecs-deploy-runner/core-concepts.md","sha":"849b1db4b083d1ba6a9f4d009ae767ad4651d458"},{"name":"docker","children":[{"name":"deploy-runner","children":[{"name":"Dockerfile","path":"modules/ecs-deploy-runner/docker/deploy-runner/Dockerfile","sha":"54f947afbeeda22d76ba630f4ecd84065468764e"},{"name":"known_hosts","path":"modules/ecs-deploy-runner/docker/deploy-runner/known_hosts","sha":"0dd0a16cd905887f363c0ba4effb5e88a8c4afac"}]},{"name":"kaniko","children":[{"name":"Dockerfile","path":"modules/ecs-deploy-runner/docker/kaniko/Dockerfile","sha":"d613a7380265e94d592ec61b9935bfede120fde7"},{"name":"build_docker_image.go","path":"modules/ecs-deploy-runner/docker/kaniko/build_docker_image.go","sha":"8051d59a7a8cc839a61f860d38a68c34957feafb"},{"name":"config.json","path":"modules/ecs-deploy-runner/docker/kaniko/config.json","sha":"34798d807bda1825a3285dd3ac4436eab0905d9d"},{"name":"go.mod","path":"modules/ecs-deploy-runner/docker/kaniko/go.mod","sha":"2915250c36924f1bbfb58a7485d58e3ce386efed"},{"name":"go.sum","path":"modules/ecs-deploy-runner/docker/kaniko/go.sum","sha":"cd278d67681ad9401f9de5d3ac258b9df24ed173"}]}]},{"name":"entrypoint","children":[{"name":"deploy_runner_entrypoint.go","path":"modules/ecs-deploy-runner/entrypoint/deploy_runner_entrypoint.go","sha":"f71a662ec5653f4c3f569d0606e05058c6130cd9"},{"name":"go.mod","path":"modules/ecs-deploy-runner/entrypoint/go.mod","sha":"eeca92d303d02287f5d4b1db8e0c10e5afa7e54f"},{"name":"go.sum","path":"modules/ecs-deploy-runner/entrypoint/go.sum","sha":"a114c9668062acd899c6a833fd7c09ebd4563146"},{"name":"install.sh","path":"modules/ecs-deploy-runner/entrypoint/install.sh","sha":"08c92e1e908e330112adff47b4da225658f4369e"}]},{"name":"invoker-lambda","children":[{"name":"dev_requirements.txt","path":"modules/ecs-deploy-runner/invoker-lambda/dev_requirements.txt","sha":"e5c3080c5b1785d0bcbb0a0c0751ae3adef55c54"},{"name":"invoker","children":[{"name":"__init__.py","path":"modules/ecs-deploy-runner/invoker-lambda/invoker/__init__.py","sha":"e69de29bb2d1d6434b8b29ae775ad8c2e48c5391"},{"name":"assertions.py","path":"modules/ecs-deploy-runner/invoker-lambda/invoker/assertions.py","sha":"53d74960da2cd9088992f4d1e8d62297709e4e3c"},{"name":"exceptions.py","path":"modules/ecs-deploy-runner/invoker-lambda/invoker/exceptions.py","sha":"bd0ae2c664b6242323c4f19e2bf4ebdd64262009"},{"name":"index.py","path":"modules/ecs-deploy-runner/invoker-lambda/invoker/index.py","sha":"fc432c8beacbb0275e0dda086781e5eda24ee266"},{"name":"project_logging.py","path":"modules/ecs-deploy-runner/invoker-lambda/invoker/project_logging.py","sha":"7073c22d7c70ee8940a3ab194a2edc3aef554055"},{"name":"types.py","path":"modules/ecs-deploy-runner/invoker-lambda/invoker/types.py","sha":"75f4262982bfbd5f751654b35e903be5279b7d98"}]},{"name":"test","children":[{"name":"test_assertions.py","path":"modules/ecs-deploy-runner/invoker-lambda/test/test_assertions.py","sha":"8f52d353ab727bd0e34922cfac7e98924302af65"},{"name":"test_invoker.py","path":"modules/ecs-deploy-runner/invoker-lambda/test/test_invoker.py","sha":"e99f8ee3c1314716100a1378b0d50c58c83988f3"}]}]},{"name":"main.tf","path":"modules/ecs-deploy-runner/main.tf","sha":"8af4dc91ff4e02ec58d0d7980f5a79f51542dca7"},{"name":"main_ecs.tf","path":"modules/ecs-deploy-runner/main_ecs.tf","sha":"9b3702c41b5194cd75b8b5764be111efbcc844bc"},{"name":"main_lambda.tf","path":"modules/ecs-deploy-runner/main_lambda.tf","sha":"d6d9836f72482c041841667465a3cd09e328b888"},{"name":"outputs.tf","path":"modules/ecs-deploy-runner/outputs.tf","sha":"a78322a16476d579a9f1d92846cd252a6eb8755a"},{"name":"variables.tf","path":"modules/ecs-deploy-runner/variables.tf","sha":"374b3cbcd42da8b5ed1a10e189567451ca035241"}]},{"name":"git-helpers","children":[{"name":"README.md","path":"modules/git-helpers/README.md","sha":"86803f51a9bdcca05dfd13756fe16088a6363ff4"},{"name":"bin","children":[{"name":"git-add-commit-push","path":"modules/git-helpers/bin/git-add-commit-push","sha":"f270bc4da9ee46bc7754c0ce8bf8f5a6c6c38c0a"},{"name":"git-rebase","path":"modules/git-helpers/bin/git-rebase","sha":"887dd90ba36adc5c0362cbadca79707756535b24"}]},{"name":"install.sh","path":"modules/git-helpers/install.sh","sha":"f22ede2f2f085af0a065dd43ed1279c69dd5a00b"}]},{"name":"gruntwork-module-circleci-helpers","children":[{"name":"README.md","path":"modules/gruntwork-module-circleci-helpers/README.md","sha":"074bc610447d27206bc50ba1a7b06fc95226d369"},{"name":"bin","children":[{"name":"build-go-binaries","path":"modules/gruntwork-module-circleci-helpers/bin/build-go-binaries","sha":"8aca966ed857b2d6d50a7c72c09e9181ae125e3c"},{"name":"configure-environment-for-gruntwork-module","path":"modules/gruntwork-module-circleci-helpers/bin/configure-environment-for-gruntwork-module","sha":"66538721d100ad93eac0784ab0603ddf508c6265"},{"name":"run-go-tests","path":"modules/gruntwork-module-circleci-helpers/bin/run-go-tests","sha":"d5406bdd61dae657ded161cf6f2ca66b17cd5b81"},{"name":"upload-github-release-assets","path":"modules/gruntwork-module-circleci-helpers/bin/upload-github-release-assets","sha":"b86a2f1049b1be58179569ea7fed641d960d1f05"}]},{"name":"install.sh","path":"modules/gruntwork-module-circleci-helpers/install.sh","sha":"a9cc16c05a73cf6c40097608838758a8de64daab"}]},{"name":"iam-policies","children":[{"name":"README.md","path":"modules/iam-policies/README.md","sha":"da28056c8749bc2c46dc99ed16286e14b7c55511"},{"name":"ecr-docker-push","children":[{"name":"README.md","path":"modules/iam-policies/ecr-docker-push/README.md","sha":"6a0a84157fe573f2c7ac1e0bd6e2169b2814f1c0"},{"name":"main.tf","path":"modules/iam-policies/ecr-docker-push/main.tf","sha":"f42bf07dbc968788e3afca42528ebf5f581ac7c8"},{"name":"outputs.tf","path":"modules/iam-policies/ecr-docker-push/outputs.tf","sha":"ba3177631efce4651f499e457cc9aa0b1afb338d"},{"name":"vars.tf","path":"modules/iam-policies/ecr-docker-push/vars.tf","sha":"d8aaeae6205750961e3deaba741ee68180a32ca7"}]},{"name":"ecs-service-deployment","children":[{"name":"README.md","path":"modules/iam-policies/ecs-service-deployment/README.md","sha":"77bb1df6db0d7cd886ee665f1d6566944521b00c"},{"name":"main.tf","path":"modules/iam-policies/ecs-service-deployment/main.tf","sha":"01c7f850e862dc36c1930b8deb767388c631eda7"},{"name":"outputs.tf","path":"modules/iam-policies/ecs-service-deployment/outputs.tf","sha":"4bf7dcb16326113889318ee8da63dadfc1ce35e9"},{"name":"vars.tf","path":"modules/iam-policies/ecs-service-deployment/vars.tf","sha":"78c2705c906b853f0e4b18b6c8f2c05e164109bf"}]},{"name":"terraform-remote-state-s3","children":[{"name":"README.md","path":"modules/iam-policies/terraform-remote-state-s3/README.md","sha":"b7892fd6dabecb66909706dbb8941e63e2c56954"},{"name":"main.tf","path":"modules/iam-policies/terraform-remote-state-s3/main.tf","sha":"76eb7e37989dc731b4e304303d2a46f9f17e2779"},{"name":"outputs.tf","path":"modules/iam-policies/terraform-remote-state-s3/outputs.tf","sha":"07cabd2ad56a78ea31e2bf59f1cb938fdf3b9664"},{"name":"vars.tf","path":"modules/iam-policies/terraform-remote-state-s3/vars.tf","sha":"720084fa0f9cf944b19ba30f59e78efc2e7b96b9"}]},{"name":"terragrunt","children":[{"name":"README.md","path":"modules/iam-policies/terragrunt/README.md","sha":"eccacc553810fa838b23d24718ffb8f70a9a39e5"},{"name":"main.tf","path":"modules/iam-policies/terragrunt/main.tf","sha":"e479890f7c37ce794c61022ab08e3febb91441ef"},{"name":"outputs.tf","path":"modules/iam-policies/terragrunt/outputs.tf","sha":"2b948005b8a1322f408e999226ac7b66629759cd"},{"name":"vars.tf","path":"modules/iam-policies/terragrunt/vars.tf","sha":"52f0480b69a57d0ff43e76ae26cb17d77dab5069"}]}]},{"name":"infrastructure-deploy-script","children":[{"name":"README.adoc","path":"modules/infrastructure-deploy-script/README.adoc","sha":"28e1366b934ff07de913455a42ca96555f6a8165"},{"name":"core-concepts.md","path":"modules/infrastructure-deploy-script/core-concepts.md","sha":"e617d3dd528507993c8162811cb6de16328e9ed3"},{"name":"dev_requirements.txt","path":"modules/infrastructure-deploy-script/dev_requirements.txt","sha":"6059bddb829b89421c7e1fba8a6e330de33e1a75"},{"name":"infrastructure_deploy_script","children":[{"name":"__init__.py","path":"modules/infrastructure-deploy-script/infrastructure_deploy_script/__init__.py","sha":"e69de29bb2d1d6434b8b29ae775ad8c2e48c5391"},{"name":"deploy.py","path":"modules/infrastructure-deploy-script/infrastructure_deploy_script/deploy.py","sha":"1f204faa3579919b19067c7face5af56a2aa3785"},{"name":"exceptions.py","path":"modules/infrastructure-deploy-script/infrastructure_deploy_script/exceptions.py","sha":"087c7ad70e8077121d24d775af578aa238995dca"},{"name":"git.py","path":"modules/infrastructure-deploy-script/infrastructure_deploy_script/git.py","sha":"749ace8d9812e8a906eba2d14b6eef4f90c97e02"},{"name":"project_logging.py","path":"modules/infrastructure-deploy-script/infrastructure_deploy_script/project_logging.py","sha":"a72c2a19962838f3375390380dcf444b73e1fcef"},{"name":"py.typed","path":"modules/infrastructure-deploy-script/infrastructure_deploy_script/py.typed","sha":"e69de29bb2d1d6434b8b29ae775ad8c2e48c5391"},{"name":"shell.py","path":"modules/infrastructure-deploy-script/infrastructure_deploy_script/shell.py","sha":"f9b98a99686b214a68c8c99d23fd8019a9f68213"},{"name":"ssh.py","path":"modules/infrastructure-deploy-script/infrastructure_deploy_script/ssh.py","sha":"3db8994be058bfa590bbbbdd0476128c44ad5979"},{"name":"terra.py","path":"modules/infrastructure-deploy-script/infrastructure_deploy_script/terra.py","sha":"67b1bc0f598d253e9b9ba13f54b9ca875f23f84f"}]},{"name":"install.sh","path":"modules/infrastructure-deploy-script/install.sh","sha":"c958f1065315b16e9f0474ee39728a4556c18247"},{"name":"requirements.txt","path":"modules/infrastructure-deploy-script/requirements.txt","sha":"ebe0f49e006828d7147c8ee540a278142e44e618"},{"name":"scripts","children":[{"name":"infrastructure-deploy-script","path":"modules/infrastructure-deploy-script/scripts/infrastructure-deploy-script","sha":"9f6b9fd7774de6892e9fdbb77f3200c1b1d698ae"}]},{"name":"setup.py","path":"modules/infrastructure-deploy-script/setup.py","sha":"0885421ba85af260d5e2d97ebc75e26c76fb25da"},{"name":"test","children":[{"name":"conftest.py","path":"modules/infrastructure-deploy-script/test/conftest.py","sha":"ebae81d85a6ce4997c9d6f4a3d833c617822a0a0"},{"name":"fixtures","children":[{"name":"terraform-with-inputs","children":[{"name":"input.tfvars","path":"modules/infrastructure-deploy-script/test/fixtures/terraform-with-inputs/input.tfvars","sha":"68468ad2c7a8319c2674d572eec058660cddfdfb"},{"name":"main.tf","path":"modules/infrastructure-deploy-script/test/fixtures/terraform-with-inputs/main.tf","sha":"de3e20f9744dc757b7ea2620ebdbc2e8aa7a3ec1"},{"name":"terragrunt.hcl","path":"modules/infrastructure-deploy-script/test/fixtures/terraform-with-inputs/terragrunt.hcl","sha":"e69de29bb2d1d6434b8b29ae775ad8c2e48c5391"}]},{"name":"terraform","children":[{"name":"main.tf","path":"modules/infrastructure-deploy-script/test/fixtures/terraform/main.tf","sha":"362851fda16747e2a39abba071646933e51fbbdf"}]},{"name":"terragrunt","children":[{"name":"terragrunt.hcl","path":"modules/infrastructure-deploy-script/test/fixtures/terragrunt/terragrunt.hcl","sha":"2359b15bc6a698e481a8e99fdb352e174203b925"}]}]},{"name":"test_deploy.py","path":"modules/infrastructure-deploy-script/test/test_deploy.py","sha":"f41e53648f0c9df3c55692380ab02133f5bcde12"},{"name":"test_git.py","path":"modules/infrastructure-deploy-script/test/test_git.py","sha":"862852a92b7a7edb7276cdd3cf212e500ca3c8d9"},{"name":"test_shell.py","path":"modules/infrastructure-deploy-script/test/test_shell.py","sha":"fa0f984c4ce6218303d7f9c38c4c20d018411318"}]}]},{"name":"infrastructure-deployer","children":[{"name":"README.adoc","path":"modules/infrastructure-deployer/README.adoc","sha":"ccb8ddacbca1f403e2f7487fee8da11adfff0e03"},{"name":"core-concepts.md","path":"modules/infrastructure-deployer/core-concepts.md","sha":"8b4f541bbb9986cd1ad3b27fb6896dff0f4a3b90"},{"name":"deploy","children":[{"name":"aws.go","path":"modules/infrastructure-deployer/deploy/aws.go","sha":"935179ae7f0a82af9600d2552e9c43ee48dedc77"},{"name":"aws_ecs.go","path":"modules/infrastructure-deployer/deploy/aws_ecs.go","sha":"267b65065c505ea0649a29d49f14152729258c74"},{"name":"deploy.go","path":"modules/infrastructure-deployer/deploy/deploy.go","sha":"f85db6e4e21c77103925dea13c202c2d76770d40"},{"name":"errors.go","path":"modules/infrastructure-deployer/deploy/errors.go","sha":"74d73d20144cbbac68ebe4a7c50a53b204151fb4"}]},{"name":"go.mod","path":"modules/infrastructure-deployer/go.mod","sha":"6235897ee1c45ed4259089ae217684c91946adf5"},{"name":"go.sum","path":"modules/infrastructure-deployer/go.sum","sha":"803f46872f55922e3c888dd4aff5236717352ddc"},{"name":"logging","children":[{"name":"logging.go","path":"modules/infrastructure-deployer/logging/logging.go","sha":"9a7a2aa73ff0dc233bdb5b48ddfdf1d14423f011"}]},{"name":"main.go","path":"modules/infrastructure-deployer/main.go","sha":"72ee953990c0a57554312feac5b3b733b2c03b5c"},{"name":"revshlex","children":[{"name":"revshlex.go","path":"modules/infrastructure-deployer/revshlex/revshlex.go","sha":"965c2960b0d9a0ba56e7b1868def546556167c3b"},{"name":"revshlex_test.go","path":"modules/infrastructure-deployer/revshlex/revshlex_test.go","sha":"f25d5a84e38fb4fb44930477ad999431f323f5d7"}]}]},{"name":"install-jenkins","children":[{"name":"README.md","path":"modules/install-jenkins/README.md","sha":"f3c33b9c09257522281a7be9687a53b343bc1fd8"},{"name":"install.sh","path":"modules/install-jenkins/install.sh","sha":"e9ccf35e247fc5de353f0a02e187c35246ec5655"},{"name":"run-jenkins","path":"modules/install-jenkins/run-jenkins","sha":"4f66dcc9b68b4623231de09d87c76cce40fc914e"}]},{"name":"jenkins-server","children":[{"name":"README.md","path":"modules/jenkins-server/README.md","sha":"49ecb595ff9883d9a77ddfebe1369e25f1692890"},{"name":"main.tf","path":"modules/jenkins-server/main.tf","sha":"cbecb0617d71fa5905a0fafbdf0e88892185bb35"},{"name":"outputs.tf","path":"modules/jenkins-server/outputs.tf","sha":"5670bd47368b97e5eeedcca805a28a337230e9e2"},{"name":"vars.tf","path":"modules/jenkins-server/vars.tf","sha":"c1f7433e5d2422435c256d9927eacc81db405fa3"}]},{"name":"kubernetes-circleci-helpers","children":[{"name":"README.md","path":"modules/kubernetes-circleci-helpers/README.md","sha":"833fef8b04c17c43b10c680fad7db3aa7da2e8ad"},{"name":"bin","children":[{"name":"setup-minikube","path":"modules/kubernetes-circleci-helpers/bin/setup-minikube","sha":"9a6dd7b530cdb65c314b7ca5f60c656ee6b4bbc8"}]},{"name":"install.sh","path":"modules/kubernetes-circleci-helpers/install.sh","sha":"2ae8670872407ceb2c434dc5b117ae14073af9a2"}]},{"name":"terraform-helpers","children":[{"name":"README.md","path":"modules/terraform-helpers/README.md","sha":"d6004df66f3b9684ea901f0d41592fca2aceb874","toggled":true},{"name":"bin","children":[{"name":"git-updated-folders","path":"modules/terraform-helpers/bin/git-updated-folders","sha":"d1325e85a5922d482dc8a4474fe8ef547bf51589"},{"name":"terraform-update-variable","path":"modules/terraform-helpers/bin/terraform-update-variable","sha":"44fb722fa9745668b343ca85329b003a24f650f6"}]},{"name":"install.sh","path":"modules/terraform-helpers/install.sh","sha":"6b7e40c382ec391f64e54efab3367d202b123883"}],"toggled":true}],"toggled":true},{"name":"setup.cfg","path":"setup.cfg","sha":"dbcd773df9356e74782ad58e0a2255ffa188df49"},{"name":"test","children":[{"name":"README.md","path":"test/README.md","sha":"a5996d6e678f1d454c380b7c1722843886028589"},{"name":"build_docker_image_test.go","path":"test/build_docker_image_test.go","sha":"1c3c70c8e7ae97c05acb50fdfda9c14a2762392e"},{"name":"build_helpers.go","path":"test/build_helpers.go","sha":"0e77ed869d6406431209fdbf405745dce7a7cc26"},{"name":"build_packer_artifact_test.go","path":"test/build_packer_artifact_test.go","sha":"e5a185070f7249f7ab84367f68a9af016b2b892c"},{"name":"build_packer_artifact_unit_test.go","path":"test/build_packer_artifact_unit_test.go","sha":"ae89bece3fa432e3b5e9c4c917bdf00a6f358c15"},{"name":"check_url_test.go","path":"test/check_url_test.go","sha":"bd3419bcb07624923777c14619eba17c7edc8c64"},{"name":"ecs_deploy_runner_docker_test.go","path":"test/ecs_deploy_runner_docker_test.go","sha":"be41be9e908257499a9b0487a8cec36c1a98b923"},{"name":"ecs_deploy_runner_ec2_test.go","path":"test/ecs_deploy_runner_ec2_test.go","sha":"99b17f4a1c69cdc25165b18e29497f04afde237d"},{"name":"ecs_deploy_runner_kaniko_test.go","path":"test/ecs_deploy_runner_kaniko_test.go","sha":"383e5c3ed6eda4fc3a1169f2f66b29baac4de516"},{"name":"ecs_deploy_runner_security_test.go","path":"test/ecs_deploy_runner_security_test.go","sha":"9ae42634a2bd561004d393fd969f2aad07454c2f"},{"name":"ecs_deploy_runner_standard_configuration_test.go","path":"test/ecs_deploy_runner_standard_configuration_test.go","sha":"b1ae7b1b051397409d6a54e72049c21fc78d7678"},{"name":"ecs_deploy_runner_test.go","path":"test/ecs_deploy_runner_test.go","sha":"d8feacfc2ed21631b470bd6660fe4191b1997f66"},{"name":"ecs_deploy_runner_test_helpers.go","path":"test/ecs_deploy_runner_test_helpers.go","sha":"e5b0b03e0db4ee754aeee0e5cf5f32b74ac1481a"},{"name":"ecs_deploy_runner_workflow_test.go","path":"test/ecs_deploy_runner_workflow_test.go","sha":"122bb8888a3364dd34c87e6aaf8aff4c93c8b3f2"},{"name":"edrhelpers","children":[{"name":"edrhelpers.go","path":"test/edrhelpers/edrhelpers.go","sha":"d07d2f6de7ef7eaecba18bae75ffa92751abdb9a"},{"name":"edrhelpers_test.go","path":"test/edrhelpers/edrhelpers_test.go","sha":"5b34ed2f7d5ea1f8290b354b045554db143069f9"},{"name":"fixtures","children":[{"name":"docker","children":[{"name":"Dockerfile","path":"test/edrhelpers/fixtures/docker/Dockerfile","sha":"09bd120286de9d94d1340b658e66088f6f8ae28b"}]}]},{"name":"go.mod","path":"test/edrhelpers/go.mod","sha":"dbd47ade4dfa1a18d5e97992f373775e7b62d2a8"},{"name":"go.sum","path":"test/edrhelpers/go.sum","sha":"5c7ba66f33aa2c50f25dc66c190ed7fc9aa0e892"}]},{"name":"fixtures","children":[{"name":"build-packer-image-unit","children":[{"name":"ami-name","children":[{"name":"clean-resource-name.json","path":"test/fixtures/build-packer-image-unit/ami-name/clean-resource-name.json","sha":"2601caa0afd10705ba4c023f31dd03c1b2c10417"},{"name":"isotime-ami-name.json","path":"test/fixtures/build-packer-image-unit/ami-name/isotime-ami-name.json","sha":"29fa01b7f32d374cca8549b2bda8b18b69953373"},{"name":"multiple.json","path":"test/fixtures/build-packer-image-unit/ami-name/multiple.json","sha":"436b13dd54866f8926ce24c7766a043ff6d1e223"},{"name":"timestamp-ami-name.json","path":"test/fixtures/build-packer-image-unit/ami-name/timestamp-ami-name.json","sha":"17bb05e841d46f41900e3f647acaec28c58a34cc"},{"name":"uuid-ami-name.json","path":"test/fixtures/build-packer-image-unit/ami-name/uuid-ami-name.json","sha":"834762f57e84d3a3b62ae2afb04ac56aa145ad00"},{"name":"variables.json","path":"test/fixtures/build-packer-image-unit/ami-name/variables.json","sha":"5743df9f17cf8056f9c553196dc49afac1dbb59d"},{"name":"whitespace.json","path":"test/fixtures/build-packer-image-unit/ami-name/whitespace.json","sha":"35cfd5200bbd124689868f115cb1b5498a8dfbbe"}]},{"name":"ami-region","children":[{"name":"variable.json","path":"test/fixtures/build-packer-image-unit/ami-region/variable.json","sha":"2601caa0afd10705ba4c023f31dd03c1b2c10417"}]},{"name":"ami-tags","children":[{"name":"multiple-tags-variable.json","path":"test/fixtures/build-packer-image-unit/ami-tags/multiple-tags-variable.json","sha":"a546cb645b151da0156251a2e40c0599945f605b"},{"name":"no-tags.json","path":"test/fixtures/build-packer-image-unit/ami-tags/no-tags.json","sha":"d160046152b90e840fe08650cb9fb4ae8273ab40"},{"name":"single-tag.json","path":"test/fixtures/build-packer-image-unit/ami-tags/single-tag.json","sha":"c2770e7139805962dfa1eab83e5d02dde42a7b95"}]},{"name":"assert-build-amazon","children":[{"name":"amazon-ebs.json","path":"test/fixtures/build-packer-image-unit/assert-build-amazon/amazon-ebs.json","sha":"d160046152b90e840fe08650cb9fb4ae8273ab40"},{"name":"ambiguous.json","path":"test/fixtures/build-packer-image-unit/assert-build-amazon/ambiguous.json","sha":"b516d4fd64b4fae25af1582d2a9236266740333c"},{"name":"docker.json","path":"test/fixtures/build-packer-image-unit/assert-build-amazon/docker.json","sha":"65adc353ebf9bda1f6821d42ec0b2f6f8d5fc125"}]},{"name":"scripts","children":[{"name":"ami-name-test.sh","path":"test/fixtures/build-packer-image-unit/scripts/ami-name-test.sh","sha":"07137cff13ec18cc3bb6c3b31e706f8a0b754882"},{"name":"ami-region-test.sh","path":"test/fixtures/build-packer-image-unit/scripts/ami-region-test.sh","sha":"7211f8d2e27f00395b2355eed780aa7e0c245196"},{"name":"ami-tags-test.sh","path":"test/fixtures/build-packer-image-unit/scripts/ami-tags-test.sh","sha":"2848b4aa11df09e8aed559a9e0b9119cdee10468"},{"name":"assert-builder-amazon-test.sh","path":"test/fixtures/build-packer-image-unit/scripts/assert-builder-amazon-test.sh","sha":"ff33aabd963e7971017901988f408c628c0dabb9"}]}]},{"name":"git-add-commit-push","children":[{"name":"auto-committed.txt","path":"test/fixtures/git-add-commit-push/auto-committed.txt","sha":"5a1b0487943a6bb6645e502dc2c550c3c043f52a"}]},{"name":"hello-world-go-app","children":[{"name":"main.go","path":"test/fixtures/hello-world-go-app/main.go","sha":"3e0c7643f51386747f1b85656a0c797f282aed04"}]},{"name":"infra-pipeline-workflow","children":[{"name":"deploy-ami","children":[{"name":"main.tf","path":"test/fixtures/infra-pipeline-workflow/deploy-ami/main.tf","sha":"ce71c0fc94842687489f9423d9983cd831c79751"},{"name":"terragrunt.hcl","path":"test/fixtures/infra-pipeline-workflow/deploy-ami/terragrunt.hcl","sha":"726d218ced39781cf10699baf05283fbfcfb22df"}]},{"name":"deploy-docker","children":[{"name":"main.tf","path":"test/fixtures/infra-pipeline-workflow/deploy-docker/main.tf","sha":"4c5b2f8e767ab37cdedc43910ee91c6e181feb6b"},{"name":"terragrunt.hcl","path":"test/fixtures/infra-pipeline-workflow/deploy-docker/terragrunt.hcl","sha":"6d6be2748d15d39b736ebdf7b9621ed001b1da09"}]}]},{"name":"test-docker-image","children":[{"name":"Dockerfile","path":"test/fixtures/test-docker-image/Dockerfile","sha":"5de35bbecce145045ae22fbc5fb97c133568a1ff"},{"name":"test.sh","path":"test/fixtures/test-docker-image/test.sh","sha":"ef3083cf7f3436ac7d01acfa33e4dab143fbcafd"}]},{"name":"test-go-test-files","children":[{"name":"simple_test.go","path":"test/fixtures/test-go-test-files/simple_test.go","sha":"53007ca88996e540ddfc503ce42982bdd5e785d2"},{"name":"test.sh","path":"test/fixtures/test-go-test-files/test.sh","sha":"25b8ef156d589c8d088d026b422e3b9c751c4b53"}]},{"name":"test-packer-image","children":[{"name":"hello-world-multiple-builders.json","path":"test/fixtures/test-packer-image/hello-world-multiple-builders.json","sha":"1c3e101f8965041b7aef0f5c4cddb14e1011d520"},{"name":"hello-world-no-tags-builder.json","path":"test/fixtures/test-packer-image/hello-world-no-tags-builder.json","sha":"d160046152b90e840fe08650cb9fb4ae8273ab40"},{"name":"hello-world-one-builder.json","path":"test/fixtures/test-packer-image/hello-world-one-builder.json","sha":"44a88c43721e45e9f5d921d8c04d08fa62c26748"}]},{"name":"test-tfvars-files","children":[{"name":"multiple-similar-variables.tfvars","path":"test/fixtures/test-tfvars-files/multiple-similar-variables.tfvars","sha":"8147977dee3d9a196177c575cd664354c601e68f"},{"name":"multiple-variables-and-comments.tfvars","path":"test/fixtures/test-tfvars-files/multiple-variables-and-comments.tfvars","sha":"8b757cfa5ed1d5049c478ed9180b9e9a5743335e"},{"name":"one-variable-extra-whitespace.tfvars","path":"test/fixtures/test-tfvars-files/one-variable-extra-whitespace.tfvars","sha":"743b02f7015bd51232f9c40564c654f424cbb523"},{"name":"one-variable-no-whitespace.tfvars","path":"test/fixtures/test-tfvars-files/one-variable-no-whitespace.tfvars","sha":"39ddb49aa78f683e3e45384d2440a904d0ad7ec9"},{"name":"one-variable.tfvars","path":"test/fixtures/test-tfvars-files/one-variable.tfvars","sha":"82a0cea8ac06d9534dd2549c73ae70afd47336bb"}]},{"name":"test-tghcl-files","children":[{"name":"multiple-similar-variables.hcl","path":"test/fixtures/test-tghcl-files/multiple-similar-variables.hcl","sha":"8224297de9667b6887136c897b473977f7013fc0"},{"name":"multiple-variables-and-comments.hcl","path":"test/fixtures/test-tghcl-files/multiple-variables-and-comments.hcl","sha":"1905719b9208e53d78a9bced9792194f6955f928"},{"name":"one-variable-extra-whitespace.hcl","path":"test/fixtures/test-tghcl-files/one-variable-extra-whitespace.hcl","sha":"aa09bc5beacd10b66660e71173d16f3b093e9415"},{"name":"one-variable-no-whitespace.hcl","path":"test/fixtures/test-tghcl-files/one-variable-no-whitespace.hcl","sha":"8e77e4baf099fdb7f1e1d1571725c835ac92093a"},{"name":"one-variable.hcl","path":"test/fixtures/test-tghcl-files/one-variable.hcl","sha":"0afe11b72b3635feb75d71d7aff4cc28806a7f67"}]},{"name":"tfpipeline","children":[{"name":"failure","children":[{"name":"terraform","children":[{"name":"main.tf","path":"test/fixtures/tfpipeline/failure/terraform/main.tf","sha":"5488bde3fbd03a58398aeeb904cfef74d7200aae"}]},{"name":"terragrunt","children":[{"name":"terragrunt.hcl","path":"test/fixtures/tfpipeline/failure/terragrunt/terragrunt.hcl","sha":"2359b15bc6a698e481a8e99fdb352e174203b925"}]}]},{"name":"nested","children":[{"name":"terraform","children":[{"name":"main.tf","path":"test/fixtures/tfpipeline/nested/terraform/main.tf","sha":"19538a8d8cb3820ffc99138ecf3b19004e7afa8f"}]},{"name":"terragrunt","children":[{"name":"terragrunt.hcl","path":"test/fixtures/tfpipeline/nested/terragrunt/terragrunt.hcl","sha":"2359b15bc6a698e481a8e99fdb352e174203b925"}]}]},{"name":"root","children":[{"name":"terraform","children":[{"name":"main.tf","path":"test/fixtures/tfpipeline/root/terraform/main.tf","sha":"4c38ad94d4d10a46cb1acd012f9b3e5513757ac2"}]},{"name":"terragrunt","children":[{"name":"terragrunt.hcl","path":"test/fixtures/tfpipeline/root/terragrunt/terragrunt.hcl","sha":"2359b15bc6a698e481a8e99fdb352e174203b925"}]}]}]}]},{"name":"git_updated_folders_test.go","path":"test/git_updated_folders_test.go","sha":"365224f7ed12aa3ccf6df765af3669d844274726"},{"name":"github_helpers.go","path":"test/github_helpers.go","sha":"56e54040790227aab12ae1b2f43991b9f00f87f6"},{"name":"go.mod","path":"test/go.mod","sha":"5cba1f1d742d8e433c44a513d43f79c06ae36126"},{"name":"go.sum","path":"test/go.sum","sha":"eeeb026c64c831e119900a51d8d12d3d9a96c455"},{"name":"gruntwork_module_circleci_helpers_integration_test.go","path":"test/gruntwork_module_circleci_helpers_integration_test.go","sha":"b6962168427fd2bae16cd6b5cca6f27afd9a0808"},{"name":"iam_policies_test.go","path":"test/iam_policies_test.go","sha":"75daff44988b41977dcfd064c868f038f77ffbb0"},{"name":"infrastructure_deploy_script_test.go","path":"test/infrastructure_deploy_script_test.go","sha":"1f4c3698ade167ba793813c2326e8aa7eb04ee6a"},{"name":"jenkins_test.go","path":"test/jenkins_test.go","sha":"d2cdf692eec0d4344ea052028d9a80155b1f9bcd"},{"name":"kubernetes_circleci_helpers_test.go","path":"test/kubernetes_circleci_helpers_test.go","sha":"76a87d2854c2c7cf0a57c56582796b9cdb533c1b"},{"name":"publish_ami_test.go","path":"test/publish_ami_test.go","sha":"04f7667c39445fe5d6a336641c110e2c6c1744a3"},{"name":"terraform_update_variable_unit_test.go","path":"test/terraform_update_variable_unit_test.go","sha":"5b405d87a457c0983d1bc804d1b78bc86c6e82f3"},{"name":"terragrunt_update_variable_unit_test.go","path":"test/terragrunt_update_variable_unit_test.go","sha":"69aee2044f92db0a42acde9d9f8ee5217a840796"},{"name":"test-git-add-commit-push.sh","path":"test/test-git-add-commit-push.sh","sha":"95fd142ed3d26e85c2873ee55c0e2718f0927ffd"},{"name":"test_helpers.go","path":"test/test_helpers.go","sha":"d4eb5b752450f221e5d615ffd1e470edbf7adfa0"}]},{"name":"testdep","children":[{"name":"Gopkg.lock","path":"testdep/Gopkg.lock","sha":"f12dfa4652085a0043d69d1b3bff7cc16b64551f"},{"name":"Gopkg.toml","path":"testdep/Gopkg.toml","sha":"092de38583d1bb2aff2b194753b7cc18aecddd87"},{"name":"dep_test.go","path":"testdep/dep_test.go","sha":"b87facc135093c5258a5f2da43e5f9177bc008b7"},{"name":"fixtures","children":[{"name":"hello-world-godep-app","children":[{"name":"Gopkg.lock","path":"testdep/fixtures/hello-world-godep-app/Gopkg.lock","sha":"623c785ee006b1ff3c524d18935ebdeb45395d55"},{"name":"Gopkg.toml","path":"testdep/fixtures/hello-world-godep-app/Gopkg.toml","sha":"26f5a8f783bb942cf6fba93c10b6a09017329526"},{"name":"main.go","path":"testdep/fixtures/hello-world-godep-app/main.go","sha":"0a09ad54ada955edd8e8ae731e0c113cc708766c"}]}]}]}]},"detailsContent":"<h1 class=\"preview__body--title\" id=\"terraform-helpers\">Terraform Helpers</h1><div class=\"preview__body--border\"></div><p>This folder contains several helper scripts for working with <a href=\"https://www.terraform.io/\" class=\"preview__body--description--blue\" target=\"_blank\">Terraform</a>. The scripts are:</p>\n<ol>\n<li><code>terraform-update-variable</code>: This script can automatically update a variable in a <code>terraform.tfvars</code> or\n<code>terragrunt.hcl</code> file and commit and push the changes to Git. It's common practice to store the version number of the\ncurrently deployed app in a variable and this script comes in handy for updating those variables automatically, such\nas in a CI job after building a new AMI or Docker image.</li>\n<li><code>git-updated-folders</code>: This script can be used to detect all the folders that have have been updated between two git\nrefs (branch, tag, sha, etc). This can be used in a CI pipeline to find the terraform and terragrunt modules that\nhave changed, and only run <code>plan</code> or <code>apply</code> on the modules that has been affected.</li>\n</ol>\n<h2 class=\"preview__body--subtitle\" id=\"using-the-helper-scripts-in-your-code\">Using the helper scripts in your code</h2>\n<p>You can install these scripts using the <a href=\"/repos/gruntwork-installer\" class=\"preview__body--description--blue\">Gruntwork Installer</a>:</p>\n<pre><span class=\"hljs-string\">gruntwork-install </span><span class=\"hljs-built_in\">--module-name</span> <span class=\"hljs-string\">\"terraform-helpers\"</span> <span class=\"hljs-built_in\">--repo</span> <span class=\"hljs-string\">\"https://github.com/gruntwork-io/module-ci\"</span> <span class=\"hljs-built_in\">--tag</span> <span class=\"hljs-string\">\"0.0.1\"</span>\n</pre>\n<p>Note that <code>terraform-update-variable</code> depends on the <a href=\"/repos/v0.20.1/module-ci/modules/git-helpers\" class=\"preview__body--description--blue\">git-helpers module</a> being installed!</p>\n<p>See the examples in the next section for how to use them.</p>\n<h2 class=\"preview__body--subtitle\" id=\"examples\">Examples</h2>\n<p>The examples below should give you an idea of how to use the scripts. Run the scripts above with the <code>--help</code> flag to\nsee full documentation.</p>\n<ul>\n<li><a href=\"#terraform-update-variable\" class=\"preview__body--description--blue\">terraform-update-variable</a></li>\n<li><a href=\"#git-updated-folders\" class=\"preview__body--description--blue\">git-updated-folders</a></li>\n</ul>\n<h2 class=\"preview__body--subtitle\" id=\"terraform-update-variable\">terraform-update-variable</h2>\n<h3 class=\"preview__body--subtitle\" id=\"terragrunt\">Terragrunt</h3>\n<p>Imagine you have a set of Terragrunt config in the <code>live</code> folder to deploy an app called <code>rails-app</code>. You create\nAmazon Machine Images (AMIs) for each new version of the app using <a href=\"https://www.packer.io/\" class=\"preview__body--description--blue\" target=\"_blank\">Packer</a> and the currently\ndeployed version of the app is defined in a variable called <code>rails_app_version</code>, set to <code>ami-12345</code> in\n<code>live/rails-app/terragrunt.hcl</code>.</p>\n<p>If you just build a new version of the AMI, <code>ami-67890</code>, you could deploy it automatically, perhaps in a CI job,\nas follows:</p>\n<pre>cd live/rails-app\n<span class=\"hljs-comment\"># Due to the existence of types in terragrunt.hcl, we need to be explicit about how the variable values are quoted.</span>\n<span class=\"hljs-keyword\">terraform</span>-update-<span class=\"hljs-keyword\">variable</span> --name rails_app_version --value <span class=\"hljs-string\">\"\\\"</span>ami-<span class=\"hljs-number\">67890</span>\\<span class=\"hljs-string\">\"\"</span>\nterragrunt apply\n</pre>\n<p>Running the commands above would:</p>\n<ol>\n<li>Set the <code>rails_app_version</code> variable in the inputs map to the ID of the new AMI, <code>ami-67890</code> in <code>terragrunt.hcl</code>.</li>\n<li><code>commit</code> and <code>push</code> the changes to <code>terragrunt.hcl</code> to Git.</li>\n<li>Deploy the changes using Terragrunt.</li>\n</ol>\n<h3 class=\"preview__body--subtitle\" id=\"terraform\">Terraform</h3>\n<p>Imagine you have a set of Terraform templates in the <code>templates</code> folder to deploy an app called <code>rails-app</code>. You create\nAmazon Machine Images (AMIs) for each new version of the app using <a href=\"https://www.packer.io/\" class=\"preview__body--description--blue\" target=\"_blank\">Packer</a> and the currently\ndeployed version of the app is defined in a variable called <code>rails_app_version</code>, set to <code>ami-12345</code> in\n<code>templates/terraform.tfvars</code>.</p>\n<p>If you just build a new version of the AMI, <code>ami-67890</code>, you could deploy it automatically, perhaps in a CI job,\nas follows:</p>\n<pre>cd templates\n<span class=\"hljs-keyword\">terraform</span>-update-<span class=\"hljs-keyword\">variable</span> --vars-path <span class=\"hljs-keyword\">terraform</span>.tfvars --name rails_app_version --value <span class=\"hljs-string\">\"\\\"</span>ami-<span class=\"hljs-number\">67890</span>\\<span class=\"hljs-string\">\"\"</span>\n<span class=\"hljs-keyword\">terraform</span> apply\n</pre>\n<p>Running the commands above would:</p>\n<ol>\n<li>Set the <code>rails_app_version</code> variable to the ID of the new AMI, <code>ami-67890</code> in <code>terraform.tfvars</code>.</li>\n<li><code>commit</code> and <code>push</code> the changes to <code>terraform.tfvars</code> to Git.</li>\n<li>Deploy the changes using Terraform.</li>\n</ol>\n<h2 class=\"preview__body--subtitle\" id=\"git-updated-folders\">git-updated-folders</h2>\n<h3 class=\"preview__body--subtitle\" id=\"terragrunt\">Terragrunt</h3>\n<p>Consider the following typical terragrunt folder structure:</p>\n<pre>.\n├── <span class=\"hljs-selector-tag\">non-prod</span>\n│ ├── <span class=\"hljs-selector-tag\">terragrunt</span><span class=\"hljs-selector-class\">.hcl</span>\n│ └── <span class=\"hljs-selector-tag\">us-east-1</span>\n│ ├── <span class=\"hljs-selector-tag\">qa</span>\n│ │ ├── <span class=\"hljs-selector-tag\">env</span><span class=\"hljs-selector-class\">.yaml</span>\n│ │ ├── <span class=\"hljs-selector-tag\">mysql</span>\n│ │ │ └── <span class=\"hljs-selector-tag\">terragrunt</span><span class=\"hljs-selector-class\">.hcl</span>*\n│ │ └── <span class=\"hljs-selector-tag\">webserver-cluster</span>\n│ │ └── <span class=\"hljs-selector-tag\">terragrunt</span><span class=\"hljs-selector-class\">.hcl</span>\n│ ├── <span class=\"hljs-selector-tag\">region</span><span class=\"hljs-selector-class\">.yaml</span>\n│ └── <span class=\"hljs-selector-tag\">stage</span>\n│ ├── <span class=\"hljs-selector-tag\">env</span><span class=\"hljs-selector-class\">.yaml</span>\n│ ├── <span class=\"hljs-selector-tag\">mysql</span>\n│ │ └── <span class=\"hljs-selector-tag\">terragrunt</span><span class=\"hljs-selector-class\">.hcl</span>*\n│ └── <span class=\"hljs-selector-tag\">webserver-cluster</span>\n│ └── <span class=\"hljs-selector-tag\">terragrunt</span><span class=\"hljs-selector-class\">.hcl</span>\n└── <span class=\"hljs-selector-tag\">prod</span>\n ├── <span class=\"hljs-selector-tag\">terragrunt</span><span class=\"hljs-selector-class\">.hcl</span>\n └── <span class=\"hljs-selector-tag\">us-east-1</span>\n ├── <span class=\"hljs-selector-tag\">prod</span>\n │ ├── <span class=\"hljs-selector-tag\">env</span><span class=\"hljs-selector-class\">.yaml</span>\n │ ├── <span class=\"hljs-selector-tag\">mysql</span>\n │ │ └── <span class=\"hljs-selector-tag\">terragrunt</span><span class=\"hljs-selector-class\">.hcl</span>*\n │ └── <span class=\"hljs-selector-tag\">webserver-cluster</span>\n │ └── <span class=\"hljs-selector-tag\">terragrunt</span><span class=\"hljs-selector-class\">.hcl</span>\n └── <span class=\"hljs-selector-tag\">region</span><span class=\"hljs-selector-class\">.yaml</span>\n</pre>\n<p>Here we use <code>*</code> to indicate files that have been modified between the git refs <code>development</code> and <code>master</code>. To get the\nterragrunt modules that have changed:</p>\n<pre>$ <span class=\"hljs-keyword\">terraform</span>-git-updated-modules --source-ref development --target-ref master --terragrunt\nnon-prod/us-east-<span class=\"hljs-number\">1</span>/qa/mysql\nnon-prod/us-east-<span class=\"hljs-number\">1</span>/stage/mysql\nprod/us-east-<span class=\"hljs-number\">1</span>/prod/mysql\n</pre>\n<p>Each of these folders were detected as terragrunt modules (because they contain a <code>terragrunt.hcl</code> file), and were\nmarked as changed because the underlying terragrunt config was updated.</p>\n<p>Note that this will only detect <code>terragrunt.hcl</code> files that have changed. For example, in the following scenario where\nthe root <code>terragrunt.hcl</code> file and a few yaml files were changed (the files denoted with <code>*</code> are those that changed),\nonly the root folder is returned:</p>\n<pre>.\n├── <span class=\"hljs-selector-tag\">non-prod</span>\n│ ├── <span class=\"hljs-selector-tag\">terragrunt</span><span class=\"hljs-selector-class\">.hcl</span>*\n│ └── <span class=\"hljs-selector-tag\">us-east-1</span>\n│ ├── <span class=\"hljs-selector-tag\">qa</span>\n│ │ ├── <span class=\"hljs-selector-tag\">env</span><span class=\"hljs-selector-class\">.yaml</span>\n│ │ ├── <span class=\"hljs-selector-tag\">mysql</span>\n│ │ │ └── <span class=\"hljs-selector-tag\">terragrunt</span><span class=\"hljs-selector-class\">.hcl</span>\n│ │ └── <span class=\"hljs-selector-tag\">webserver-cluster</span>\n│ │ └── <span class=\"hljs-selector-tag\">terragrunt</span><span class=\"hljs-selector-class\">.hcl</span>\n│ ├── <span class=\"hljs-selector-tag\">region</span><span class=\"hljs-selector-class\">.yaml</span>*\n│ └── <span class=\"hljs-selector-tag\">stage</span>\n│ ├── <span class=\"hljs-selector-tag\">env</span><span class=\"hljs-selector-class\">.yaml</span>\n│ ├── <span class=\"hljs-selector-tag\">mysql</span>\n│ │ └── <span class=\"hljs-selector-tag\">terragrunt</span><span class=\"hljs-selector-class\">.hcl</span>\n│ └── <span class=\"hljs-selector-tag\">webserver-cluster</span>\n│ └── <span class=\"hljs-selector-tag\">terragrunt</span><span class=\"hljs-selector-class\">.hcl</span>\n└── <span class=\"hljs-selector-tag\">prod</span>\n ├── <span class=\"hljs-selector-tag\">terragrunt</span><span class=\"hljs-selector-class\">.hcl</span>\n └── <span class=\"hljs-selector-tag\">us-east-1</span>\n ├── <span class=\"hljs-selector-tag\">prod</span>\n │ ├── <span class=\"hljs-selector-tag\">env</span><span class=\"hljs-selector-class\">.yaml</span>\n │ ├── <span class=\"hljs-selector-tag\">mysql</span>\n │ │ └── <span class=\"hljs-selector-tag\">terragrunt</span><span class=\"hljs-selector-class\">.hcl</span>\n │ └── <span class=\"hljs-selector-tag\">webserver-cluster</span>\n │ └── <span class=\"hljs-selector-tag\">terragrunt</span><span class=\"hljs-selector-class\">.hcl</span>\n └── <span class=\"hljs-selector-tag\">region</span><span class=\"hljs-selector-class\">.yaml</span>*\n</pre>\n<pre>$ <span class=\"hljs-keyword\">terraform</span>-git-updated-modules --source-ref development --target-ref master --terragrunt\nnon-prod\n</pre>\n<p>If you want to additionally pull in the folders with the <code>yaml</code> files that changed, you can pass in <code>--ext .yaml</code>:</p>\n<pre>$ <span class=\"hljs-keyword\">terraform</span>-git-updated-modules --source-ref development --target-ref master --terragrunt --ext .yaml\nnon-prod\nnon-prod/us-east-<span class=\"hljs-number\">1</span>\nprod/us-east-<span class=\"hljs-number\">1</span>\n</pre>\n<h3 class=\"preview__body--subtitle\" id=\"terraform\">Terraform</h3>\n<p>Consider the following project structure for a monorepo terraform project:</p>\n<pre>.\n├── modules\n│ ├── mysql\n│ │ ├── main.tf\n│ │ ├── outputs.tf*\n│ │ └── variables.tf\n│ └── webserver-cluster\n│ ├── main.tf\n│ ├── outputs.tf\n│ └── variables.tf\n└── live\n └── us-east-<span class=\"hljs-number\">1</span>\n ├── prod\n │ ├── <span class=\"hljs-keyword\">terraform</span>.tfvars\n │ ├── main.tf*\n │ ├── outputs.tf*\n │ └── variables.tf\n └── non-prod\n ├── <span class=\"hljs-keyword\">terraform</span>.tfvars*\n ├── main.tf\n ├── outputs.tf\n └── variables.tf\n</pre>\n<p>Here we use <code>*</code> to indicate files that have been modified between the git refs <code>development</code> and <code>master</code>. To get the\nterraform modules that have changed:</p>\n<pre>$ <span class=\"hljs-keyword\">terraform</span>-git-updated-modules --source-ref development --target-ref master --<span class=\"hljs-keyword\">terraform</span>\nmodules/mysql\nlive/us-east-<span class=\"hljs-number\">1</span>/prod\nlive/us-east-<span class=\"hljs-number\">1</span>/non-prod\n</pre>\n<p>Each of these were detected as terraform modules (because they contain <code>.tf</code> files), and were marked as changed because\none of the underlying <code>.tf</code> or <code>.tfvars</code> files have changed. Specifically:</p>\n<ul>\n<li><code>modules/mysql</code> <= <code>modules/mysql/outputs.tf</code></li>\n<li><code>live/us-east-1/prod</code> <= <code>live/us-east-1/prod/main.tf</code> and <code>live/us-east-1/prod/outputs.tf</code></li>\n<li><code>live/us-east-1/non-prod</code> <= <code>live/us-east-1/non-prod/terraform.tfvars</code></li>\n</ul>\n","repoName":"module-ci","repoRef":"v0.29.2","serviceDescriptor":{"serviceName":"EC2 backup","serviceRepoName":"module-ci","serviceRepoOrg":"gruntwork-io","serviceMainReadmePath":"/modules/ec2-backup","cloudProviders":["aws"],"description":"Snapshot your EC2 instances on a scheduled basis.","imageUrl":"grunt.png","licenseType":"subscriber","technologies":["Terraform","JavaScript","Lambda"],"compliance":[],"tags":[""]},"serviceCategoryName":"Backup & recovery","fileName":"README.md","filePath":"/modules/terraform-helpers/README.md","title":"Repo Browser: EC2 backup","description":"Browse the repos in the Gruntwork Infrastructure as Code Library."}