Terraform modules for provisioning cloud instances

Terraform modules are available for automating the infrastructure provisioning of virtual machines. Depending on your selected cloud provider, additional resources or services such as security groups and firewalls must also be integrated to ensure the virtual machines can communicate effectively.

Each Terraform module consists of three core files:

AWS Copied

All AWS Terraform modules available in this documentation require the following:

AWS Default VPC discovery module Copied

This module discovers existing AWS default VPC and subnet information without creating any resources. It returns the required VPC ID and subnet ID using minimal API calls. This module is also reusable for other modules requiring VPC information.

Requirements Copied

Aside from the common Terraform AWS module requirements, this module also specifically requires:

Variables Copied

This module automatically discovers the default VPC and does not require any input variables.

Usage example Copied

# Discover default VPC
module "default_vpc" {
  source = "../../modules/aws/default-vpc"
}

Outputs Copied

Name Description
vpc_id Default VPC resource ID
subnet_id First default subnet resource ID

AWS EC2 instance module Copied

This module creates AWS EC2 instances with configurable network and security settings.

Requirements Copied

Aside from the common Terraform AWS module requirements, this module also specifically requires:

Setting up an IAM instance profile Copied

Before using this module, create an IAM instance profile for EC2 instances to securely access AWS services. The IAM instance profile created must be referenced in the iam_instance_profile parameter of your module configuration.

# Create IAM role for EC2 instances
aws iam create-role --role-name EC2-S3-Access-Role --assume-role-policy-document '{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {"Service": "ec2.amazonaws.com"},
      "Action": "sts:AssumeRole"
    }
  ]
}'

# Attach S3 access policy (adjust permissions as needed)
aws iam attach-role-policy --role-name EC2-S3-Access-Role \
    --policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess

# Create instance profile
aws iam create-instance-profile --instance-profile-name EC2-S3-Access-Profile

# Associate role with instance profile
aws iam add-role-to-instance-profile \
    --instance-profile-name EC2-S3-Access-Profile \
    --role-name EC2-S3-Access-Role

Variables Copied

Configure the following variables:

Name Description Type Default Required
ami AMI ID to use for the instance string yes
instance_type EC2 instance type string yes
key_name Name of the AWS key pair string yes
subnet_id VPC subnet ID to launch instance in string yes
vpc_security_group_ids List of security group IDs list(string) yes
iam_instance_profile IAM instance profile name for AWS service access string null no
associate_public_ip_address Associate public IP address bool false no
source_dest_check Enable source/destination checking bool true no
tags Map of tags to assign to the resource map(string) {} no
Instance types Copied

The following are common EC2 instance types:

Category Type Description
General purpose t3.nano 2 vCPU, 0.5GB RAM (burstable)
General purpose t3.micro 2 vCPU, 1GB RAM (burstable, free tier eligible)
General purpose t3.small 2 vCPU, 2GB RAM (burstable)
General purpose t3.medium 2 vCPU, 4GB RAM (burstable)
Compute optimized c5.large 2 vCPU, 4GB RAM
Compute optimized c5.xlarge 4 vCPU, 8GB RAM
Memory optimized r5.large 2 vCPU, 16GB RAM
Memory optimized r5.xlarge 4 vCPU, 32GB RAM

Usage example Copied

Basic example Copied
module "web_server" {
  source = "../../modules/aws/instance"
  
  ami           = "ami-0c94855ba95b798c7"  # Ubuntu 22.04 LTS
  instance_type = "t3.micro"
  key_name      = "my-key-pair"
  subnet_id     = "subnet-12345678"
  
  vpc_security_group_ids = ["sg-87654321"]
  
  # IAM instance profile for AWS service access (optional)
  iam_instance_profile = "EC2-S3-Access-Profile"
  
  tags = {
    Name        = "web-server-01"
    Environment = "Production"
    Purpose     = "WebServer"
  }
}
Complete example with public IP Copied
module "public_instance" {
  source = "../../modules/aws/instance"
  
  ami                         = "ami-0c94855ba95b798c7"
  instance_type              = "t3.small"
  key_name                   = "my-keypair"
  subnet_id                  = module.default_vpc.subnet_id
  vpc_security_group_ids     = [module.security_group.id]
  associate_public_ip_address = true
  source_dest_check          = false  # For NAT instances
  
  # IAM instance profile for S3 access
  iam_instance_profile = "EC2-S3-Access-Profile"
  
  tags = {
    Name        = "public-instance"
    Environment = "Development"
    Owner       = "team@company.com"
    Purpose     = "Development Server"
  }
}

Outputs Copied

Name Description
instance_id EC2 instance ID
external_ip Public IP address (if assigned)
internal_ip Private IP address
iam_instance_profile IAM instance profile attached to instance

AWS Security group module Copied

This module creates AWS security groups with configurable ingress and egress rules for network access control.

Requirements Copied

Aside from the common Terraform AWS module requirements, this module also specifically requires:

Variables Copied

Configure the following variables:

Name Description Type Default Required
name Name of the security group string yes
vpc_id ID of the VPC where security group will be created string yes
ingress_rules List of ingress rules list(object) [] no
egress_rules List of egress rules list(object) [] no
tags Map of tags to assign to the security group map(string) {} no
Rule object structure Copied

Each rule in ingress_rules and egress_rules should have:

{
  from_port   = number
  to_port     = number
  protocol    = string
  cidr_blocks = list(string)
  description = string
}
Protocol values Copied
Common port ranges Copied

The following are common port ranges:

Category Type Port
Web services HTTP 80
Web services HTTPS 443
Web services Alternative HTTP 8080
Web services Alternative HTTPS 8443
Database services MySQL/MariaDB 3306
Database services PostgreSQL 5432
Database services SQL Server 1433
Database services CouchDB 5984
Database services MongoDB 27017
System services SSH 22
System services RDP (Windows) 3389
System services DNS 53
System services NTP 123
Application ports Geneos Gateway communication 7000-7100

Usage example Copied

Web server security group Copied
module "web_security_group" {
  source = "../../modules/aws/security_group"
  
  name   = "web-server-sg"
  vpc_id = "vpc-12345678"
  
  ingress_rules = [
    {
      from_port   = 22
      to_port     = 22
      protocol    = "tcp"
      cidr_blocks = ["10.0.0.0/8"]
      description = "SSH from internal networks"
    },
    {
      from_port   = 80
      to_port     = 80
      protocol    = "tcp"
      cidr_blocks = ["0.0.0.0/0"]
      description = "HTTP from anywhere"
    },
    {
      from_port   = 443
      to_port     = 443
      protocol    = "tcp"
      cidr_blocks = ["0.0.0.0/0"]
      description = "HTTPS from anywhere"
    }
  ]
  
  egress_rules = [
    {
      from_port   = 0
      to_port     = 0
      protocol    = "-1"
      cidr_blocks = ["0.0.0.0/0"]
      description = "All outbound traffic"
    }
  ]
  
  tags = {
    Name        = "web-server-sg"
    Environment = "Production"
    Purpose     = "WebServer"
  }
}
Database security group Copied
module "database_security_group" {
  source = "../../modules/aws/security_group"
  
  name   = "database-sg"
  vpc_id = "vpc-12345678"
  
  ingress_rules = [
    {
      from_port   = 3306
      to_port     = 3306
      protocol    = "tcp"
      cidr_blocks = ["10.0.0.0/16"]
      description = "MySQL from application tier"
    },
    {
      from_port   = 5432
      to_port     = 5432
      protocol    = "tcp"
      cidr_blocks = ["10.0.0.0/16"]
      description = "PostgreSQL from application tier"
    }
  ]
  
  egress_rules = [
    {
      from_port   = 443
      to_port     = 443
      protocol    = "tcp"
      cidr_blocks = ["0.0.0.0/0"]
      description = "HTTPS for updates"
    }
  ]
}

Outputs Copied

Name Description
id Security group ID
name Security group name

Azure Copied

Azure Network Interface Module Copied

Creates Azure Network Interfaces with dynamic IP configuration and security group association.

Azure Network Security Group Module Copied

Creates Azure Network Security Groups with configurable TCP inbound rules for network access control.

Azure Public IP Module Copied

Creates Azure Public IP addresses with configurable SKU, allocation method, and availability zone support.

Azure Virtual Machine Module Copied

Creates Azure Virtual Machines with SSH key authentication support.

Azure Virtual Network Module Copied

Creates Azure Virtual Networks with subnets for network isolation and connectivity.

Google Cloud Platform (GCP) Copied

All Google Cloud Terraform modules available in this documentation require the following:

GCP Compute Engine instance module Copied

This module creates Google Cloud Compute Engine instances with SSH key support and flexible configuration options.

Requirements Copied

Aside from the common Terraform Google Cloud module requirements, this module also specifically requires:

Service account setup Copied

Before using this module, create a service account with the required permissions. The service account created must be referenced in the gcp_service_account_email parameter of your module configuration.

# Create the service account
gcloud iam service-accounts create instance-sa \
    --display-name="Instance Service Account" \
    --project=your-project-id

# Assign required storage roles
gcloud projects add-iam-policy-binding your-project-id \
    --member="serviceAccount:instance-sa@your-project-id.iam.gserviceaccount.com" \
    --role="roles/storage.objectViewer"

gcloud projects add-iam-policy-binding your-project-id \
    --member="serviceAccount:instance-sa@your-project-id.iam.gserviceaccount.com" \
    --role="roles/storage.bucketViewer"

Variables Copied

Name Description Type Default Required
gcp_project_id GCP project ID string yes
gcp_zone GCP zone for instance placement string yes
vm_name Virtual machine name string yes
vm_type Machine type specification string yes
vm_image_family Image family name string yes
vm_image_project Image project name string yes
gcp_service_account_email Service account email to attach to instance string yes
ssh_user SSH username string yes
ssh_public_key_path Path to SSH public key file string yes
gcp_service_account_scopes Access scopes for service account list(string) [“cloud-platform”] no
network_name VPC network name string “default” no
subnetwork_name Subnet name string “default” no
vm_disk_size Boot disk size in GB number 10 no
vm_disk_type Boot disk type string “pd-standard” no
vm_status Desired VM status string “RUNNING” no
vm_labels Resource labels map(string) {} no
vm_metadata Instance metadata map(string) {} no
Machine types Copied

The following are common machine types.

Category Type Description
General purpose (E2) e2-micro 1 vCPU, 1GB RAM (shared core, always free tier eligible)
General purpose (E2) e2-small 1 vCPU, 2GB RAM (shared core)
General purpose (E2) e2-medium 1 vCPU, 4GB RAM (shared core)
General purpose (E2) e2-standard-2 2 vCPU, 8GB RAM
General purpose (E2) e2-standard-4 4 vCPU, 16GB RAM
General purpose (N2) n2-standard-2 2 vCPU, 8GB RAM
General purpose (N2) n2-standard-4 4 vCPU, 16GB RAM
General purpose (N2) n2-standard-8 8 vCPU, 32GB RAM
Compute optimized (C2) c2-standard-4 4 vCPU, 16GB RAM
Compute optimized (C2) c2-standard-8 8 vCPU, 32GB RAM
Memory optimized (M2) m2-ultramem-208 208 vCPU, 5888GB RAM
Memory optimized (M2) m2-megamem-416 416 vCPU, 5888GB RAM
Image families Copied

The following are common image families.

Operating system Image Description
Ubuntu ubuntu-minimal-2204-lts Ubuntu 22.04 LTS (minimal installation)
Ubuntu ubuntu-2204-lts Ubuntu 22.04 LTS (full installation)
Ubuntu ubuntu-minimal-2004-lts Ubuntu 20.04 LTS (minimal installation)
Ubuntu ubuntu-2004-lts Ubuntu 20.04 LTS (full installation)
Debian debian-11 Debian 11 (Bullseye)
Debian debian-10 Debian 10 (Buster)
CentOS/RHEL centos-7 CentOS 7
CentOS/RHEL rhel-8 Red Hat Enterprise Linux 8
Disk types Copied

The following are common disk types.

Type Description
pd-standard Standard persistent disk (HDD, lowest cost)
pd-balanced Balanced persistent disk (SSD, good performance/cost ratio)
pd-ssd SSD persistent disk (highest performance)
Zone examples Copied

The following are common zone examples.

Region Zone Area
US regions us-central1-a, us-central1-b, us-central1-c Iowa
US regions us-east1-a, us-east1-b, us-east1-c South Carolina
US regions us-west1-a, us-west1-b, us-west1-c Oregon
Europe regions europe-west1-a, europe-west1-b, europe-west1-c Belgium
Europe regions europe-west2-a, europe-west2-b, europe-west2-c London
Asia regions asia-east1-a, asia-east1-b, asia-east1-c Taiwan
Asia regions asia-southeast1-a, asia-southeast1-b, asia-southeast1-c Singapore

Usage example Copied

Basic instance Copied
module "web_server" {
  source = "../../modules/gcp/instance"
  
  gcp_project_id      = "my-project-123"
  gcp_zone           = "us-central1-a"
  vm_name            = "web-server-01"
  vm_type            = "e2-medium"
  vm_image_family    = "ubuntu-minimal-2204-lts"
  vm_image_project   = "ubuntu-os-cloud"
  
  network_name       = "default"
  subnetwork_name    = "default"
  
  ssh_user           = "ubuntu"
  ssh_public_key_path = "./id_rsa.pub"
  
  # Service Account Configuration (Required)
  gcp_service_account_email = "web-server-sa@my-project-123.iam.gserviceaccount.com"
  gcp_service_account_scopes = ["cloud-platform"]
  
  vm_labels = {
    environment = "production"
    purpose     = "webserver"
    team        = "engineering"
  }
}
Custom configuration Copied
module "app_server" {
  source = "../../modules/gcp/instance"
  
  gcp_project_id      = var.gcp_project_id
  gcp_zone           = "us-central1-b"
  vm_name            = "app-server-01"
  vm_type            = "n2-standard-2"
  vm_image_family    = "ubuntu-2204-lts"
  vm_image_project   = "ubuntu-os-cloud"
  vm_disk_size       = 50
  vm_disk_type       = "pd-ssd"
  vm_status          = "RUNNING"
  
  network_name       = "my-custom-network"
  subnetwork_name    = "my-custom-subnet"
  
  ssh_user           = "appuser"
  ssh_public_key_path = var.ssh_public_key_path
  
  # Service Account Configuration (Required)
  gcp_service_account_email = var.gcp_service_account_email
  gcp_service_account_scopes = ["https://www.googleapis.com/auth/cloud-platform"]
  
  vm_labels = {
    environment     = "staging"
    purpose         = "application"
    team           = "development"
    cost_center    = "engineering"
  }
}

Outputs Copied

Name Description
vm_name VM instance name
external_ip External IP address
internal_ip Internal IP address
service_account_email Service account email attached to instance

GCP Firewall module Copied

This module creates Google Cloud firewall rules to control the network traffic in VPC networks.

Requirements Copied

Aside from the common Terraform Google Cloud module requirements, this module also specifically requires:

Variables Copied

Name Description Type Default Required
name Name of the firewall rule string yes
network Name of VPC network string yes
protocol Protocol (tcp, udp, icmp, all) string yes
direction Traffic direction (INGRESS, EGRESS) string “INGRESS” no
ports List of ports or port ranges list(string) [] no
source_ranges List of source IP ranges list(string) [] no
target_tags List of target network tags list(string) [] no
source_tags List of source network tags list(string) [] no
priority Rule priority (0-65534) number 1000 no
Protocol options Copied
Direction options Copied
Port format examples Copied
Type Ports
Individual ports ports = ["22", "80", "443"]
Port ranges ports = ["7000-7100", "8080-8090"]
Mixed ports and ranges ports = ["22", "80", "443", "7000-7100"]

Usage examples Copied

Basic web traffic rule Copied
module "web_firewall" {
  source = "../../modules/gcp/firewall"
  
  name     = "allow-web-traffic"
  network  = "default"
  protocol = "tcp"
  ports    = ["80", "443"]
  
  source_ranges = ["0.0.0.0/0"]
  direction     = "INGRESS"
}
SSH access rule Copied
module "ssh_firewall" {
  source = "../../modules/gcp/firewall"
  
  name     = "allow-ssh"
  network  = "default"
  protocol = "tcp"
  ports    = ["22"]
  
  source_ranges = ["10.0.0.0/8"]
  target_tags   = ["ssh-server"]
  direction     = "INGRESS"
}
Custom application rule Copied
module "app_firewall" {
  source = "../../modules/gcp/firewall"
  
  name     = "allow-geneos-gateway"
  network  = "my-custom-network"
  protocol = "tcp"
  ports    = ["7000-7100"]
  
  source_ranges = ["192.168.1.0/24"]
  target_tags   = ["geneos-gateway"]
  direction     = "INGRESS"
}

Outputs Copied

Name Description
name Firewall rule name
id Firewall rule resource ID

Priority guidelines Copied

The firewall rule priority determines which rule is evaluated first when multiple rules apply to the same network traffic. It is an integer from 0 to 65535, where lower values indicate higher priorities.

  1. 0-999 — indicates high priority, overriding lower priority rules.
  2. 1000 — the default priority, if no priority was defined during rule creation
  3. 1001-65534 — indicates lower priority.

Common Deployment Module Copied

A universal Terraform module for executing Ansible playbooks against target hosts using Terraform’s local-exec provisioner. This module provides a bridge between Terraform infrastructure provisioning and Ansible configuration management.

["Geneos"] ["Geneos > Netprobe"] ["User Guide"]

Was this topic helpful?