Section 7: Using OpenTofu Modules from GitHub
Exercises 11 & 12
Overview
This section teaches you how to:
- Use modules from GitHub repositories
- Implement version control with Git tags and branches
- Find and use public modules from Terraform Registry
- Create reusable infrastructure code
Exercise 11: Git Versioning with Modules
Objective
Explore versioning strategies for modules using Git tags and branches.
Concepts
1. Semantic Versioning
v1.2.3
├── 1: MAJOR (breaking changes)
├── 2: MINOR (new features, backwards compatible)
└── 3: PATCH (bug fixes)
2. Module Source Patterns
Without Version:
source = "github.com/username/repo.git//modules/ec2"
# Uses: default branch (main/master)
# Risk: Code may change unexpectedly
# Use: Development onlyWith Git Tag (RECOMMENDED):
source = "github.com/username/repo.git//modules/ec2?ref=v1.2.0"
# Uses: Exact version tag
# Benefit: Reproducible, predictable
# Use: Production environmentsWith Branch:
source = "github.com/username/repo.git//modules/ec2?ref=develop"
# Uses: Specific branch
# Benefit: Latest features on branch
# Risk: Code may change
# Use: Development, active developmentWith Commit SHA:
source = "github.com/username/repo.git//modules/ec2?ref=abc123def456"
# Uses: Exact commit
# Benefit: Maximum precision
# Risk: Hard to maintain
# Use: Debugging, rollback scenariosHands-On Exercise
Step 1: Prepare Your GitHub Repository
If you don’t have a GitHub account, create one at github.com.
# Create new repository on GitHub:
# 1. Go to github.com/new
# 2. Name: "iac-modules"
# 3. Add README
# 4. Create repositoryStep 2: Push Your Local Module to GitHub
# In your workspace
cd /home/sable/devops_base/scripts/modules
# Initialize git (if not already done)
git init
# Add all files
git add -A
git commit -m "Initial module structure"
# Add remote (replace YOUR_USERNAME)
git remote add origin https://github.com/YOUR_USERNAME/iac-modules.git
# Push to main branch
git branch -M main
git push -u origin mainStep 3: Create Version Tags
# Create first release
git tag -a v1.0.0 -m "First stable release"
git push origin v1.0.0
# Create second release (with improvements)
git tag -a v1.1.0 -m "Add port parameterization"
git push origin v1.1.0
# Create development branch
git checkout -b develop
git push -u origin developStep 4: Verify Tags on GitHub
# View all tags:
git tag -l
# Output:
# v1.0.0
# v1.1.0
# View specific tag info:
git show v1.0.0Step 5: Test Different Version References
Create different modules using different versions:
cd /home/sable/devops_base/scripts/live/github-modulesFile: test-v1.0.0.tf
module "app_v1_0_0" {
source = "github.com/YOUR_USERNAME/iac-modules.git//ec2-instance?ref=v1.0.0"
ami_id = var.ami_id
name = "app-v1-0-0"
instance_type = "t3.micro"
port = 8080
}File: test-v1.1.0.tf
module "app_v1_1_0" {
source = "github.com/YOUR_USERNAME/iac-modules.git//ec2-instance?ref=v1.1.0"
ami_id = var.ami_id
name = "app-v1-1-0"
instance_type = "t3.micro"
port = 9000
}File: test-main.tf
module "app_main" {
source = "github.com/YOUR_USERNAME/iac-modules.git//ec2-instance?ref=main"
ami_id = var.ami_id
name = "app-main"
instance_type = "t3.micro"
port = 8080
}Step 6: Initialize and Deploy (Optional)
cd /home/sable/devops_base/scripts/live/github-modules
# Initialize
tofu init
# Plan (see what would be created)
tofu plan
# Apply (only if you want to deploy)
# tofu apply -auto-approve
# Test
# curl http://<PUBLIC_IP>:8080/What You Learn
✅ Semantic versioning for modules
✅ Git tagging for releases
✅ Branch-based versioning
✅ Commit SHA references
✅ Version constraints in OpenTofu
✅ Production-ready module management
Key Takeaways
- Always use version tags in production (?ref=v1.0.0)
- Use branches for development (?ref=develop)
- Document version changes in CHANGELOG.md
- Plan upgrades carefully - test in staging first
- Use semantic versioning - clear expectations for changes
Exercise 12: Using Public Modules from Terraform Registry
Objective
Find and implement production-ready modules from public repositories.
Popular Module Sources
1. Terraform Registry (registry.terraform.io)
Official registry for Terraform and OpenTofu modules.
Common modules:
- terraform-aws-modules/ec2-instance/aws - EC2 instances
- terraform-aws-modules/vpc/aws - VPC with subnets
- terraform-aws-modules/security-group/aws - Security groups
- terraform-aws-modules/ecs/aws - ECS clusters
2. GitHub Public Repositories
Well-maintained options:
- hashicorp/terraform-aws-modules
- gruntwork-io/terraform-aws-modules
- cloudposse/terraform-aws-modules
Hands-On Exercise
Option A: Use Terraform Registry Module (EASIEST)
Step 1: Find Module
Go to https://registry.terraform.io/modules and search for “security group”
Example: terraform-aws-modules/security-group/aws
Step 2: Read Documentation
The registry provides:
- Module description
- Input variables
- Output values
- Example usage
Step 3: Create Configuration
provider "aws" {
region = "us-east-2"
profile = "labs-devops_diallo"
}
module "web_security_group" {
source = "terraform-aws-modules/security-group/aws"
version = "5.0.0"
name = "web-sg"
description = "Security group for web server"
vpc_id = "vpc-xxxxxxxx" # Your VPC ID
# Ingress rules
ingress_rules = ["http-80-tcp", "https-443-tcp", "ssh-tcp"]
ingress_cidr_blocks = ["0.0.0.0/0"]
# Egress rule
egress_rules = ["all-all"]
egress_cidr_blocks = ["0.0.0.0/0"]
tags = {
Name = "web-server-sg"
}
}
output "security_group_id" {
value = module.web_security_group.security_group_id
}Option B: Use GitHub Public Module
Step 1: Find Repository
Go to https://github.com/cloudposse/terraform-aws-modules
Example: cloudposse/terraform-aws-modules
Step 2: Examine Code
# Look at:
# - README.md (usage, requirements)
# - variables.tf (input variables)
# - outputs.tf (available outputs)
# - examples/ (sample configurations)Step 3: Create Configuration
provider "aws" {
region = "us-east-2"
profile = "labs-devops_diallo"
}
module "vpc_module" {
source = "github.com/cloudposse/terraform-aws-modules.git//vpc?ref=v1.0.0"
namespace = "myapp"
environment = "dev"
cidr_block = "10.0.0.0/16"
availability_zones = ["us-east-2a", "us-east-2b"]
tags = {
Project = "Lab2"
}
}
output "vpc_id" {
value = module.vpc_module.vpc_id
}Recommended Public Modules
For EC2:
source = "terraform-aws-modules/ec2-instance/aws"
version = "5.0.0"For VPC:
source = "terraform-aws-modules/vpc/aws"
version = "5.0.0"For Security Groups:
source = "terraform-aws-modules/security-group/aws"
version = "5.0.0"For RDS:
source = "terraform-aws-modules/rds/aws"
version = "6.0.0"For Load Balancers:
source = "terraform-aws-modules/alb/aws"
version = "9.0.0"How to Use Modules from Registry
Step 1: Identify Module
Visit https://registry.terraform.io/browse/modules
Search by:
- Provider (AWS, Azure, GCP)
- Resource type (EC2, VPC, RDS)
- Keyword
Step 2: Copy Module Declaration
module "example" {
source = "terraform-aws-modules/ec2-instance/aws"
version = "5.0.0"
# Configuration
}Step 3: Fill in Required Variables
From module documentation, identify:
required_variables: Must be specifiedoptional_variables: Have defaults
Step 4: Test with tofu plan
cd /path/to/module
tofu init
tofu plan # Preview changes
tofu apply # Deploy (if approved)Best Practices for Public Modules
✅ Always pin version (version = "5.0.0")
✅ Read README carefully (requirements, limitations)
✅ Test in non-prod first (staging, dev)
✅ Check module maturity (verify, examples, usage)
✅ Review input/output variables (compatibility)
✅ Document customizations (why certain values chosen)
✅ Monitor module updates (watch for bug fixes)
Avoiding Module Pitfalls
❌ Don’t use modules without version pins
❌ Don’t assume module outputs without reading docs
❌ Don’t deploy to production without testing
❌ Don’t ignore breaking changes between versions
❌ Don’t fork modules unless necessary
Complete Exercise 11-12 Example
Here’s a complete working example combining both exercises:
Directory: /home/sable/devops_base/scripts/live/github-modules/
Files:
example1-local-module.tf- Using local moduleexample2-github-module-terraform-aws.tf- Using Terraform Registry moduleexample3-custom-github-module.tf- Using custom GitHub moduleexample4-multiple-versions.tf- Multiple versions demonstrationmain.tf- Primary configurationvariables.tf- Input variablesoutputs.tf- Output values
Deploy Section 7 Example
# Navigate to github-modules directory
cd /home/sable/devops_base/scripts/live/github-modules
# Initialize OpenTofu
tofu init
# Plan deployment
tofu plan
# Deploy
tofu apply -auto-approve
# View outputs
tofu output
# Test the deployed instance
curl http://<PUBLIC_IP>:8080/
# Cleanup
tofu destroy -auto-approveComparison: Module Sources
| Aspect | Local Module | GitHub Custom | Terraform Registry |
|---|---|---|---|
| Control | Full | Full | Limited |
| Maintenance | Self | Self | Provider |
| Discovery | Manual | Search | Built-in search |
| Versioning | Git tags | Git tags | Version pins |
| Documentation | Your docs | Your docs | Registry docs |
| Testing | Your tests | Your tests | Provider tested |
| Support | Self | Self | Provider support |
| Use Case | Internal | Shared | Standardized |
Real-World Scenarios
Scenario 1: Development Team Sharing Modules
- Team creates internal module repository
- Each project references with
?ref=v1.0.0 - Updates released as new versions
- Teams adopt at their own pace
Scenario 2: Using Open Source Modules
- Find module on Terraform Registry
- Pin specific version
- Customize via variables
- Deploy with confidence
Scenario 3: Versioning Strategy
- v1.0.0: Initial release, all projects
- v1.1.0: New feature, backwards compatible
- v2.0.0: Breaking change, update projects gradually
Resources
- Terraform Registry: https://registry.terraform.io
- OpenTofu Modules: https://opentofu.org/docs/language/modules/
- GitHub Module Syntax: https://opentofu.org/docs/language/modules/sources/#github
- Semantic Versioning: https://semver.org
Conclusion
Exercises 11-12 teach you:
✅ How to version modules with Git tags
✅ How to reference specific module versions
✅ How to find and use public modules
✅ How to create reusable infrastructure code
✅ Production-ready module management strategies
This enables infrastructure reuse across teams and projects, a key practice in enterprise IaC.
Next Steps:
- Push your module to GitHub
- Create releases with version tags
- Use public modules in your configurations
- Implement modular architecture across projects