Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/marcbuch/terraform-azurerm-reference
This repo can be used for refence to design Terraform projects
https://github.com/marcbuch/terraform-azurerm-reference
Last synced: 10 days ago
JSON representation
This repo can be used for refence to design Terraform projects
- Host: GitHub
- URL: https://github.com/marcbuch/terraform-azurerm-reference
- Owner: MarcBuch
- License: gpl-3.0
- Created: 2022-04-30T20:50:37.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2022-04-30T20:59:47.000Z (over 2 years ago)
- Last Synced: 2023-10-06T12:40:13.708Z (about 1 year ago)
- Language: Go
- Size: 41 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# terraform-azurerm-reference
> "Infrastructure as Code should be fully treated as code." - Some guy on reddit
This repo is intended to display a approach to Terraform project design with the recommendations given in the [12factor App](https://12factor.net/).
## Goals of this project
The 12 factor app recommends that configuration has to be separated from the application code. To externalize this, I decided to wrap the module with a YAML wrapper. This allows me to use a YAML file for the configuration.
- YAML is easier to read.
- Typed variables offer input validation.
- YAML can be generated by other tools.You can also use JSON for input, but this helps more on the automation side. For example, REST requests could be made to deploy Terraform.
### Why implement a YAML wrapper?
There are multiple ways to provide values to Terraform:
1. Hardcode them.
2. Using variables and default values.
3. Using variables and passing a `.tfvars` file.
4. On the command line using `-var`.
5. Through environment variables `TF_VAR_`.Each of these different ways can override the others. This can result in configuration living in various locations and makes code reviews painful.
### One step further with an immutable artifact
Why on earth would you wrap Terraform into a container?
- Provide a single way to set variables for Terraform.
- Can be promoted through the stages (dev, qa, prod).
- Everything needed for the deployment is inside the container. Only docker is required.
- The artifact can be used in other pipelines. For example, the pipeline in the application repo can pull this artifact and create a new deployment.My implementation also includes a provider mirror [Terraform Docs - Provider Installation](https://www.terraform.io/cli/config/config-file#provider-installation) meaning the providers are baked into the docker image.
### Integrating tests
I've included a compiled version of the Terratest file in the container image. Configuration for this test is read from the same YAML file as the deployment uses.
## How to build a new image
```Shell
# Build the docker image
docker build -t terraform-azurerm-reference .
```## How to run a Terratest tests
- YAML config can be passed into `/config/input.yaml` location.
```Shell
docker run -it -e "ARM_SUBSCRIPTION_ID=${ARM_SUBSCRIPTION_ID}" -e "ARM_TENANT_ID=${ARM_TENANT_ID}" \
-e "ARM_CLIENT_ID=${ARM_CLIENT_ID}" -e "ARM_CLIENT_SECRET=${ARM_CLIENT_SECRET}" \
-e "STORAGE_ACCOUNT_NAME=${storage_account_name}" -e "STORAGE_ACCOUNT_KEY=${storage_account_key}" \
-e "CONTAINER_NAME=${container_name}" -e "STATE_FILE_NAME=${state_file_name}" \
-v $PWD/input.yaml:/config/input.yaml:ro \
terraform-azurerm-reference /tests/integration_test
```## How to run a Terraform deployment
- A docker volume will be used to hold the initialized Terraform as well as the plan file.
Terraform init
```Shell
docker run -it -e "ARM_SUBSCRIPTION_ID=${ARM_SUBSCRIPTION_ID}" -e "ARM_TENANT_ID=${ARM_TENANT_ID}" \
-e "ARM_CLIENT_ID=${ARM_CLIENT_ID}" -e "ARM_CLIENT_SECRET=${ARM_CLIENT_SECRET}" \
-v tf-wd:/working_dir \
terraform-azurerm-reference terraform init -from-module=/tf \
-backend-config="storage_account_name=${storage_account_name}" -backend-config="container_name=${container_name}" \
-backend-config="access_key=${storage_account_key}" -backend-config="key=${state_file_name}"
```Terraform plan
```Shell
docker run -it -e "ARM_SUBSCRIPTION_ID=${ARM_SUBSCRIPTION_ID}" -e "ARM_TENANT_ID=${ARM_TENANT_ID}" \
-e "ARM_CLIENT_ID=${ARM_CLIENT_ID}" -e "ARM_CLIENT_SECRET=${ARM_CLIENT_SECRET}" \
-v tf-wd:/working_dir -v $PWD/input.yaml:/config/input.yaml:ro \
terraform-azurerm-reference terraform plan -out /working_dir/plan
```Terraform apply
```Shell
docker run -it -e "ARM_SUBSCRIPTION_ID=${ARM_SUBSCRIPTION_ID}" -e "ARM_TENANT_ID=${ARM_TENANT_ID}" \
-e "ARM_CLIENT_ID=${ARM_CLIENT_ID}" -e "ARM_CLIENT_SECRET=${ARM_CLIENT_SECRET}" \
-v tf-wd:/working_dir -v $PWD/input.yaml:/config/input.yaml:ro \
terraform-azurerm-reference terraform apply /working_dir/plan
```Terraform destroy
```Shell
docker run -it -e "ARM_SUBSCRIPTION_ID=${ARM_SUBSCRIPTION_ID}" -e "ARM_TENANT_ID=${ARM_TENANT_ID}" \
-e "ARM_CLIENT_ID=${ARM_CLIENT_ID}" -e "ARM_CLIENT_SECRET=${ARM_CLIENT_SECRET}" \
-v tf-wd:/working_dir -v $PWD/input.yaml:/config/input.yaml:ro \
terraform-azurerm-reference terraform destroy
```## References
Based on the [YT Video Series by Antonio Masucci](https://www.youtube.com/watch?v=FHDkxk9odLA)