{"id":28690814,"url":"https://github.com/prasanna7401/terraform_best_practice_examples","last_synced_at":"2026-07-08T12:31:00.243Z","repository":{"id":269516206,"uuid":"907658250","full_name":"prasanna7401/Terraform_Best_Practice_Examples","owner":"prasanna7401","description":"Contains terraform scripts for learning important topics, useful tips and production environment best practice recommendations.","archived":false,"fork":false,"pushed_at":"2026-04-15T22:59:40.000Z","size":4271,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-04-16T00:32:37.232Z","etag":null,"topics":["best-practices","infrastructure-as-code","terraform","terraform-associate"],"latest_commit_sha":null,"homepage":"","language":"HCL","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/prasanna7401.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-12-24T05:06:31.000Z","updated_at":"2026-04-15T22:59:45.000Z","dependencies_parsed_at":null,"dependency_job_id":"58bf8853-72c7-40ef-8297-7c842032d66e","html_url":"https://github.com/prasanna7401/Terraform_Best_Practice_Examples","commit_stats":null,"previous_names":["prasanna7401/learn_terraform","prasanna7401/terraform_best_practice_examples"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/prasanna7401/Terraform_Best_Practice_Examples","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/prasanna7401%2FTerraform_Best_Practice_Examples","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/prasanna7401%2FTerraform_Best_Practice_Examples/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/prasanna7401%2FTerraform_Best_Practice_Examples/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/prasanna7401%2FTerraform_Best_Practice_Examples/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/prasanna7401","download_url":"https://codeload.github.com/prasanna7401/Terraform_Best_Practice_Examples/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/prasanna7401%2FTerraform_Best_Practice_Examples/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35265380,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-08T02:00:06.796Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["best-practices","infrastructure-as-code","terraform","terraform-associate"],"created_at":"2025-06-14T06:07:47.728Z","updated_at":"2026-07-08T12:31:00.213Z","avatar_url":"https://github.com/prasanna7401.png","language":"HCL","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Learn Terraform\n\n## Useful items:\n\n1. **Statefile Backup**: \n    - If stored _**locally**_, the `tfstate.backup` file contains the previous terraform apply results. \n    - If storing in a _**remote backend**_, make sure to enable versioning to be able to roll back.\n    - If your _apply_ operation fails without saving the state file to the remote backend, terraform will save the file locally under the name `errored.tfstate`. You can set up appropriate steps to save this file from your pipeline or CI Server. Alternatively, you can push this state file to the remote backend by `terraform state push errored.tfstate`\n    - If your pipeline crashes during the process, the state file may remain locked. In this case, you can run `terraform force-unlock \u003cLOCK_ID\u003e`\n\n2. **[Import existing resources or Handle Manual changes to managed resources](https://developer.hashicorp.com/terraform/language/import)**:\n  _2.1. How to import a resource configuration for managing via terraform_\n   - Step-1: Create an empty resource block in the terraform file \n    ```hcl\n        resource \"aws_security_group\" \"to_be_imported\" {\n        # fill later after import\n        }\n    ```\n    - Step-2: Run `terraform import \u003cresource_type\u003e.\u003cresource_name\u003e \u003cresource_id\u003e` (For example, aws_security_group.example sg-12345)\n    - Step-3: After the configurations get imported into your state file, run `terraform show` or `terraform state show \u003cresource_type\u003e.\u003cresource_name\u003e`\n    - Step-4: Clean up the output-only attributes like `id`, `arn`, `timestamp`, etc., and add the code block to the terraform configuration file.\n\n- If you had made manual changes to your terraform-managed resource, you could update your statefile by running `terraform apply --refresh-only` or `terraform refresh`\n\n\u003e Other options: For bulk import of resources, you can use tools like `terraformer` \u0026 `terracognita`\n\n3. **Avoid Resource modification/deletion (useful for imported/critical resources)**:\n    - Option 1: Add a lifecycle block to your code:\n        ```hcl\n        lifecycle {\n            ignore_changes = [cidr_block] # or any specific resource config\n            prevent_destroy = true\n        }\n        ```\n    - Option 2: Manually remove the resource configuration from the state file.\n        ```sh\n            terraform state rm aws_instance.example\n        ```\n\n4. **[Schematize/Validate Input variables:](https://developer.hashicorp.com/terraform/language/values/)** \n- Basic Input Validation: Use `validation` block\n   ```hcl\n        variable \"public_ip\" { \n        description = \"Public IP address for the service\" \n        type = string \n        validation { \n            condition = can(regex(\"^(([0-9]{1,3}\\\\.){3}[0-9]{1,3})$\", var.public_ip)) \u0026\u0026 length(split(\".\", var.public_ip)) == 4 \u0026\u0026 alltrue([for octet in split(\".\", var.public_ip) : tonumber(octet) \u003c= 255]) \n            error_message = \"The Public IP address must be in the format x.x.x.x where x is a number between 0 and 255.\" \n            } \n        }\n\n   ```\n- For complex conditions on created resource: Use `condition` block under `lifecycle` block.\n- For more examples, check [here](./05%20-%20Production%20Use%20cases/1%20-%20Input%20validation/).\n\n5. **Enforce Default Tags**: You can set up default tags during the provider configuration.\n    ```hcl\n    provider \"aws\" {\n        region = \"something\"\n        default_tags {\n            tags = {\n                deployment = \"terraform\"\n            }\n        }\n    }\n    ```\n    - This adds the mentioned tag if no tag is specified in your resource or module.\n    - Alternatively, you can use policy as code like _OPA_, _terratest_ to check your code. For reference, click [here](./06%20-%20Code%20Testing%20using%20Terratest/3%20-%20OPA%20based%20testing)\n\n6. **Instructions before refactoring existing code**:\n    - Modifying the names of the existing resource/module block may trigger changes causing downtime. So, follow appropriate procedures to _move_ the state file resource configurations using one of the below-mentioned steps:\n    1. State move command: \n    ```sh\n    terraform state mv \u003cOLD_BLOCK_REFEERENCE\u003e \u003cNEW_REFERENCE\u003e\n    ```\n    2. Use `moved` block:\n    ```hcl\n    moved {\n        from = aws_instance.something\n        to = aws_instance.myserver\n    }\n    ```\n\n7. **Force Re-creation of resource**: Use either -`-replace` flag with plan or apply step. For ex: `terraform apply -replace=\"aws_something.example\"`\n\n\n8. **Troubleshooting**: Set `TF_LOG` to any debugging level (say, _DEBUG_) environment variable output. To store the logs in a persistant file, use `TF_LOG_PATH`, if not mentioned, you will see the debugging output in the terraform CLI.\n\n9. **Reference to another state file**:\n- Use case: Access outputs and resource attributes of another terraform deployment.\n- Example:\n    ```hcl\n    data \"terraform_remote_state\" \"example\" {\n        # For locally stored state files\n        # backend = \"local\"\n        # config = {\n        #     path = \"...\"\n        # }\n        # For remote backends:\n        backend = \"s3\"\n        config = {\n            bucket = \"my-bucket\"\n            key = \"example/firewalls/terraform.tfstate\"\n            region = \"us-east-1\"\n        }\n\n    }\n    ```\n\n\n---\n\nSome parts of this repository contains the codes used for learning purposes from [Terraform: Up and Running](https://github.com/brikis98/terraform-up-and-running-code), originally authored by Yevgeniy Brikman and licensed under the MIT License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprasanna7401%2Fterraform_best_practice_examples","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fprasanna7401%2Fterraform_best_practice_examples","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprasanna7401%2Fterraform_best_practice_examples/lists"}