In this article, I will guide you through the process of configuring a Terraform module hosted on GitHub.com as a source for the use inside Terraform module projects. In my previous blog (Part 1), I demonstrated how to set up a GitHub.com repository and branch using HashiCorp Terraform code.
To Start, I will initialize a Git repository and push a module folder to store our Terraform module. This will enable me to version control my module and easily share it with others.
Here's a step-by-step overview of what we'll cover:
- Initializing a Git repository for our Terraform module
- Creating a module folder and adding our Terraform files
- Configuring the module to be used as a source in myTerraform projects
- Best practices for managing and versioning our Terraform modules
- By the end of this article, you'll have a fully configured Terraform module hosted on GitHub.com, ready to be used in your infrastructure-as-code projects.
Before starting configuration make sure you are creating Environment Variable with GITHUB_TOKEN As shows in the below Part 1 URL article to authenticate to GitHub .
$env:GITHUB_TOKEN = 'ghp_pqsfaVFd3gp2iJ'
Check this Series of Articles:
Part 1: Create GitHub repository and branches using Terraform
Part 2 Terraform modules using a github.com repository as a source
Part 3 Automating and Planning Azure Resources with Terraform and GitHub Actions
Part 4 GitHub Actions deploy azure resources with Terraform backend
Part 4.1 GitHub Actions deploy azure resources with PowerShell
Part 4.2 GitHub Actions manage Microsoft Azure Cloud with az CLI
I have below main.tf file which I kept under ./modules folder. This folder and files I will push to GitHub repository.
# ./module/main.tf Child module file contents variable "name" { type = string description = "Provide Azure Resource Group name info" } variable "location" { type = string description = "Provide Azure Resource Group location info" } variable "tags" { type = map(string) description = "Provide Azure Resource Group tags info" } ########################################### resource "azurerm_resource_group" "rg" { name = var.name location = var.location tags = var.tags }
In this below command git init initializes a new Git repository in the current working directory. It creates a .git folder locally that contains all the necessary files for Git to track changes to your code.
Parameter --initial-branch=main specifies the name of the initial branch. In this case, it configures the first branch to be named main instead of the default master.
To summarize, git init --initial-branch=main creates a new Git repository with the first branch named main. Note: This command is typically used when you want to start a new Git repository from scratch, and you want to use a branch name other than the default master.
git init --initial-branch=main
Below are the contents of file .gitignore file. Which is stored in the local directory. This .gitignore is a file that tells Git which files or directories to ignore in a repository while pushing to GitHub.com. Below is the structure of my terraform module folder and .gitignore file. These files and folders I will push to github repository
# .gitignore file contents # Local .terraform directories **/.terraform/* **\.terraform\* # .tfstate files *.tfstate *.tfstate.* # .tfvars files *.tfvars # .tfplan files *.tfplan # .pem files *.pem # .exe files *.exe
This command will stages all changes in the current directory and subdirectories.
git add .
It creates a new commit with the staged changes and assigns a brief description ("First commit") to the commit, storing the changes in the local Git repository. Changes are not yet pushed to remote Github.com repo with this command.
git commit -m "First Commit"
This line connects local Git repository to a remote repository on GitHub.com, allowing to push and pull changes between the two.
git remote add origin https://github.com/janviudapi/vcloud-lab.com.git
Below command updates local repository with the latest changes from the remote repository on GitHub.com (Download and sync), allowing to review and merge them manually.
git fetch
In the Following command, sets the upstream tracking information for the local main branch to track the remote origin/main branch, linking local and remote branches for easy pushing and pulling.
git branch --set-upstream-to="origin/main" main
After setting git remote add / git fetch, if you haven't setup authentication to github, as shown in earlier article Create GitHub repository and branches using Terraform. You will see below popup form asking to connect to GitHub account either through Browser/Device using username and password or Token (Personal Access Token) for authentication/authorization.
This command forcefully pushes your local changes to the remote repository, overwriting any existing changes on the remote branch. And it is last command to configure GitHub and git in this article. With this command I have pushed my Terraform module and .gitignore file to GitHub repo. Check the Github portal
git push origin --force
Next in this final configuration, below is the configuration code of Terraform parent module. Note how the source attribute specifies the location of the module's source code. In this case I am using github.com URL as source. By specifying the source attribute with GitHub.com URL path, Teams can centrally manage your modules and Terraform can automatically download and use the module from the GitHub repository.
Just to be noted names mentioned after double forward slash // is folder on the GitHub repository. Also if you want to use branch in the URL use this format github.com/repo.git?ref=BranchName.
provider "azurerm" { features {} subscription_id = "9exxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx" } module "dev_git" { source = "github.com/janviudapi/vcloud-lab.com//module" name = "dev1" location = "East US" tags = { environment = "dev" } }
After running terraform init command in the terminal output, you can view that it is downloading terraform modules from remote github repository. After this I ran terraform plan and it is also successful.
Below are the command output from executed git and terraform. For more on other Terraform module sources check https://developer.hashicorp.com/terraform/language/modules/sources.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
PS D:\Projects\Terraform\\extreme_examples\061-github_configuration> git init --initial-branch=main Initialized empty Git repository in D:/Projects/Terraform//extreme_examples/061-github_configuration/.git/ PS D:\Projects\Terraform\\extreme_examples\061-github_configuration> PS D:\Projects\Terraform\\extreme_examples\061-github_configuration> Get-Content .\.gitignore # Local .terraform directories **/.terraform/* **\.terraform\* # .tfstate files *.tfstate *.tfstate.* # .tfvars files *.tfvars # .tfplan files *.tfplan # .pem files *.pem # .exe files *.exe PS D:\Projects\Terraform\\extreme_examples\061-github_configuration> PS D:\Projects\Terraform\\extreme_examples\061-github_configuration> git add . PS D:\Projects\Terraform\\extreme_examples\061-github_configuration> PS D:\Projects\Terraform\\extreme_examples\061-github_configuration> git commit -m "First commit" [main (root-commit) 5e2810a] First commit 3 files changed, 54 insertions(+) create mode 100644 .gitignore create mode 100644 main.tf create mode 100644 module/main.tf PS D:\Projects\Terraform\\extreme_examples\061-github_configuration> PS D:\Projects\Terraform\\extreme_examples\061-github_configuration> git remote add origin https://github.com/janviudapi/vcloud-lab.com.git PS D:\Projects\Terraform\\extreme_examples\061-github_configuration> PS D:\Projects\Terraform\\extreme_examples\061-github_configuration> git fetch remote: Enumerating objects: 4, done. remote: Counting objects: 100% (4/4), done. remote: Compressing objects: 100% (4/4), done. remote: Total 4 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0) Unpacking objects: 100% (4/4), 1.38 KiB | 176.00 KiB/s, done. From https://github.com/janviudapi/vcloud-lab.com * [new branch] main -> origin/main PS D:\Projects\Terraform\\extreme_examples\061-github_configuration> PS D:\Projects\Terraform\\extreme_examples\061-github_configuration> git branch --set-upstream-to="origin/main" main branch 'main' set up to track 'origin/main'. PS D:\Projects\Terraform\\extreme_examples\061-github_configuration> PS D:\Projects\Terraform\\extreme_examples\061-github_configuration> git push origin --force Enumerating objects: 6, done. Counting objects: 100% (6/6), done. Delta compression using up to 8 threads Compressing objects: 100% (5/5), done. Writing objects: 100% (6/6), 783 bytes | 783.00 KiB/s, done. Total 6 (delta 0), reused 0 (delta 0), pack-reused 0 To https://github.com/janviudapi/vcloud-lab.com.git + e307b4e...5e2810a main -> main (forced update) PS D:\Projects\Terraform\\extreme_examples\061-github_configuration> PS D:\Projects\Terraform\\extreme_examples\061-github_configuration> PS D:\Projects\Terraform\\extreme_examples\061-github_configuration> terraform init Initializing the backend... Initializing modules... Downloading git::https://github.com/janviudapi/vcloud-lab.com.git for dev_git... - dev_git in .terraform\modules\dev_git\module Initializing provider plugins... - Finding latest version of hashicorp/azurerm... - Installing hashicorp/azurerm v4.0.1... - Installed hashicorp/azurerm v4.0.1 (signed by HashiCorp) Terraform has created a lock file .terraform.lock.hcl to record the provider selections it made above. Include this file in your version control repository so that Terraform can guarantee to make the same selections by default when you run "terraform init" in the future. Terraform has been successfully initialized! You may now begin working with Terraform. Try running "terraform plan" to see any changes that are required for your infrastructure. All Terraform commands should now work. If you ever set or change modules or backend configuration for Terraform, rerun this command to reinitialize your working directory. If you forget, other commands will detect it and remind you to do so if necessary. PS D:\Projects\Terraform\\extreme_examples\061-github_configuration> PS D:\Projects\Terraform\\extreme_examples\061-github_configuration> PS D:\Projects\Terraform\\extreme_examples\061-github_configuration> terraform plan Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # module.dev_git.azurerm_resource_group.rg will be created + resource "azurerm_resource_group" "rg" { + id = (known after apply) + location = "eastus" + name = "dev1" + tags = { + "environment" = "dev" } } Plan: 1 to add, 0 to change, 0 to destroy. ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now. PS D:\Projects\Terraform\\extreme_examples\061-github_configuration> |
Useful Articles
Terraform using for loop in attribute value without for_each
Terraform variable multiple validation advanced blocks example
Terraform variable type list with for_each for loop examples
Terraform convert single string to list or set
Terraform workspaces with example
Terraform map of object for loop with if condition example
Terraform for_each for loop list of object without count example
Hashicorp Terraform map and object inside module and variable example
Terraform one module deploy null or multiple resources based on input
Terraform A reference to a resource type must be followed by at least one attribute access, specifying the resource name
Terraform fore_each for loop filter with if condition example
Terraform remote-exec provisioner with ssh connection in null_resource
Terraform count vs for_each for examples with map of objects
Terraform one module deploy null or multiple resources based on input (nested for loop) Example of Terraform functions flatten() and coalesce()
Terraform Azure Create Private Endpoint to existing Storage Account with Custom Private DNS zone record link
Creating a Private Endpoint for Azure Storage Account with required sub services using Terraform Example Terraform functions of lookup() and lower()
Using element function with count meta argument example Terraform Azure subnets Example Terraform functions of element(), count() and sum()
Terraform create Azure Virtual Network subnets from map of object and show name in the header Header name change in the output
Creating a Private Endpoint for Azure Storage Account with Terraform example 2 Example of for_each with toset() function
Creating a Private Endpoint for Azure Storage Account with Terraform example 3