├── .gitignore ├── README.md ├── cloudbuild.yaml ├── environments ├── dev │ ├── c1-versions.tf │ ├── c2-variables.tf │ ├── c3-locals.tf │ ├── c4-vpc.tf │ ├── c5-firewalls.tf │ ├── c6-vminstance.tf │ ├── c7-outputs.tf │ └── terraform.tfvars └── prod │ ├── c1-versions.tf │ ├── c2-variables.tf │ ├── c3-locals.tf │ ├── c4-vpc.tf │ ├── c5-firewalls.tf │ ├── c6-vminstance.tf │ ├── c7-outputs.tf │ └── terraform.tfvars ├── git-deploy.sh └── modules └── vminstance ├── app1-webserver-install.sh ├── main.tf ├── outputs.tf ├── variables.tf └── versions.tf /.gitignore: -------------------------------------------------------------------------------- 1 | .terraform* 2 | *.tfstate* 3 | *.tfplan -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # terraform-gcp-devops 2 | Implement DevOps Pipelines for Terraform Configs on GCP (Google Cloud Platform) 3 | -------------------------------------------------------------------------------- /cloudbuild.yaml: -------------------------------------------------------------------------------- 1 | steps: 2 | - id: 'branch name' 3 | name: 'alpine' 4 | entrypoint: 'sh' 5 | args: 6 | - '-c' 7 | - | 8 | echo "***********************" 9 | echo "$BRANCH_NAME" 10 | echo "***********************" 11 | 12 | - id: 'tf init' 13 | name: 'hashicorp/terraform:1.9.0' 14 | entrypoint: 'sh' 15 | args: 16 | - '-c' 17 | - | 18 | if [ -d "environments/$BRANCH_NAME/" ]; then 19 | cd environments/$BRANCH_NAME 20 | terraform init 21 | else 22 | for dir in environments/*/ 23 | do 24 | cd ${dir} 25 | env=${dir%*/} 26 | env=${env#*/} 27 | echo "" 28 | echo "*************** TERRAFORM INIT ******************" 29 | echo "******* At environment: ${env} ********" 30 | echo "*************************************************" 31 | terraform init || exit 1 32 | cd ../../ 33 | done 34 | fi 35 | 36 | # [START tf-plan] 37 | - id: 'tf plan' 38 | name: 'hashicorp/terraform:1.9.0' 39 | entrypoint: 'sh' 40 | args: 41 | - '-c' 42 | - | 43 | if [ -d "environments/$BRANCH_NAME/" ]; then 44 | cd environments/$BRANCH_NAME 45 | terraform plan 46 | else 47 | for dir in environments/*/ 48 | do 49 | cd ${dir} 50 | env=${dir%*/} 51 | env=${env#*/} 52 | echo "" 53 | echo "*************** TERRAFORM PLAN ******************" 54 | echo "******* At environment: ${env} ********" 55 | echo "*************************************************" 56 | terraform plan || exit 1 57 | cd ../../ 58 | done 59 | fi 60 | # [END tf-plan] 61 | 62 | # [START tf-apply] 63 | - id: 'tf apply' 64 | name: 'hashicorp/terraform:1.9.0' 65 | entrypoint: 'sh' 66 | args: 67 | - '-c' 68 | - | 69 | if [ -d "environments/$BRANCH_NAME/" ]; then 70 | cd environments/$BRANCH_NAME 71 | terraform apply -auto-approve 72 | else 73 | echo "***************************** SKIPPING APPLYING *******************************" 74 | echo "Branch '$BRANCH_NAME' does not represent an official environment." 75 | echo "*******************************************************************************" 76 | fi 77 | # [END tf-apply] 78 | -------------------------------------------------------------------------------- /environments/dev/c1-versions.tf: -------------------------------------------------------------------------------- 1 | # Terraform Settings Block 2 | terraform { 3 | required_version = ">= 1.9" 4 | required_providers { 5 | google = { 6 | source = "hashicorp/google" 7 | version = ">= 5.36.0" 8 | } 9 | } 10 | backend "gcs" { 11 | bucket = "gcplearn9-tfstate" 12 | prefix = "env/dev" 13 | } 14 | } 15 | 16 | # Terraform Provider Block 17 | provider "google" { 18 | project = var.gcp_project 19 | region = var.gcp_region1 20 | } -------------------------------------------------------------------------------- /environments/dev/c2-variables.tf: -------------------------------------------------------------------------------- 1 | # Input Variables 2 | # GCP Project 3 | variable "gcp_project" { 4 | description = "Project in which GCP Resources to be created" 5 | type = string 6 | default = "kdaida123" 7 | } 8 | 9 | # GCP Region 10 | variable "gcp_region1" { 11 | description = "Region in which GCP Resources to be created" 12 | type = string 13 | default = "us-east1" 14 | } 15 | 16 | # GCP Compute Engine Machine Type 17 | variable "machine_type" { 18 | description = "Compute Engine Machine Type" 19 | type = string 20 | default = "e2-small" 21 | } 22 | 23 | # Environment Variable 24 | variable "environment" { 25 | description = "Environment Variable used as a prefix" 26 | type = string 27 | default = "dev" 28 | } 29 | 30 | # Business Division 31 | variable "business_divsion" { 32 | description = "Business Division in the large organization this Infrastructure belongs" 33 | type = string 34 | default = "sap" 35 | } 36 | 37 | -------------------------------------------------------------------------------- /environments/dev/c3-locals.tf: -------------------------------------------------------------------------------- 1 | # Define Local Values in Terraform 2 | locals { 3 | owners = var.business_divsion 4 | environment = var.environment 5 | name = "${var.business_divsion}-${var.environment}" 6 | #name = "${local.owners}-${local.environment}" 7 | common_tags = { 8 | owners = local.owners 9 | environment = local.environment 10 | } 11 | } -------------------------------------------------------------------------------- /environments/dev/c4-vpc.tf: -------------------------------------------------------------------------------- 1 | # Resource: VPC 2 | resource "google_compute_network" "myvpc" { 3 | name = "${local.name}-vpc" 4 | auto_create_subnetworks = false 5 | } 6 | 7 | # Resource: Subnet 8 | resource "google_compute_subnetwork" "mysubnet" { 9 | name = "${local.name}-${var.gcp_region1}-subnet" 10 | region = var.gcp_region1 11 | ip_cidr_range = "10.128.0.0/20" 12 | network = google_compute_network.myvpc.id 13 | } 14 | -------------------------------------------------------------------------------- /environments/dev/c5-firewalls.tf: -------------------------------------------------------------------------------- 1 | # Firewall Rule: SSH 2 | resource "google_compute_firewall" "fw_ssh" { 3 | name = "${local.name}-fwrule-allow-ssh22" 4 | allow { 5 | ports = ["22"] 6 | protocol = "tcp" 7 | } 8 | direction = "INGRESS" 9 | network = google_compute_network.myvpc.id 10 | priority = 1000 11 | source_ranges = ["0.0.0.0/0"] 12 | target_tags = ["ssh-tag"] 13 | } 14 | 15 | # Firewall Rule: HTTP Port 80 16 | resource "google_compute_firewall" "fw_http" { 17 | name = "${local.name}-fwrule-allow-http80" 18 | allow { 19 | ports = ["80"] 20 | protocol = "tcp" 21 | } 22 | direction = "INGRESS" 23 | network = google_compute_network.myvpc.id 24 | priority = 1000 25 | source_ranges = ["0.0.0.0/0"] 26 | target_tags = ["webserver-tag"] 27 | } 28 | -------------------------------------------------------------------------------- /environments/dev/c6-vminstance.tf: -------------------------------------------------------------------------------- 1 | # Module Block: Create a single Compute Engine instance 2 | module "myvminstance" { 3 | source = "../../modules/vminstance" 4 | vminstance_name = "${local.name}-myapp1" 5 | machine_type = var.machine_type 6 | zone = "us-central1-a" 7 | firewall_tags = [tolist(google_compute_firewall.fw_ssh.target_tags)[0], tolist(google_compute_firewall.fw_http.target_tags)[0]] 8 | subnetwork = google_compute_subnetwork.mysubnet.id 9 | } 10 | 11 | -------------------------------------------------------------------------------- /environments/dev/c7-outputs.tf: -------------------------------------------------------------------------------- 1 | # Terraform Output Values 2 | output "vpc_id" { 3 | description = "VPC ID" 4 | value = google_compute_network.myvpc.id 5 | } 6 | output "subnet_id" { 7 | description = "Subnet ID" 8 | value = google_compute_subnetwork.mysubnet.id 9 | } 10 | output "vm_external_ip" { 11 | description = "VM External IPs" 12 | #value = google_compute_instance.myapp1.network_interface.0.access_config.0.nat_ip 13 | value = module.myvminstance.vm_external_ip 14 | } 15 | -------------------------------------------------------------------------------- /environments/dev/terraform.tfvars: -------------------------------------------------------------------------------- 1 | gcp_project = "gcplearn9" 2 | gcp_region1 = "us-central1" 3 | machine_type = "e2-micro" 4 | environment = "dev" 5 | business_divsion = "hr" -------------------------------------------------------------------------------- /environments/prod/c1-versions.tf: -------------------------------------------------------------------------------- 1 | # Terraform Settings Block 2 | terraform { 3 | required_version = ">= 1.9" 4 | required_providers { 5 | google = { 6 | source = "hashicorp/google" 7 | version = ">= 5.35.0" 8 | } 9 | } 10 | backend "gcs" { 11 | bucket = "gcplearn9-tfstate" 12 | prefix = "env/prod" 13 | } 14 | } 15 | 16 | # Terraform Provider Block 17 | provider "google" { 18 | project = var.gcp_project 19 | region = var.gcp_region1 20 | } -------------------------------------------------------------------------------- /environments/prod/c2-variables.tf: -------------------------------------------------------------------------------- 1 | # Input Variables 2 | # GCP Project 3 | variable "gcp_project" { 4 | description = "Project in which GCP Resources to be created" 5 | type = string 6 | default = "kdaida123" 7 | } 8 | 9 | # GCP Region 10 | variable "gcp_region1" { 11 | description = "Region in which GCP Resources to be created" 12 | type = string 13 | default = "us-east1" 14 | } 15 | 16 | # GCP Compute Engine Machine Type 17 | variable "machine_type" { 18 | description = "Compute Engine Machine Type" 19 | type = string 20 | default = "e2-small" 21 | } 22 | 23 | # Environment Variable 24 | variable "environment" { 25 | description = "Environment Variable used as a prefix" 26 | type = string 27 | default = "dev" 28 | } 29 | 30 | # Business Division 31 | variable "business_divsion" { 32 | description = "Business Division in the large organization this Infrastructure belongs" 33 | type = string 34 | default = "sap" 35 | } 36 | 37 | -------------------------------------------------------------------------------- /environments/prod/c3-locals.tf: -------------------------------------------------------------------------------- 1 | # Define Local Values in Terraform 2 | locals { 3 | owners = var.business_divsion 4 | environment = var.environment 5 | name = "${var.business_divsion}-${var.environment}" 6 | #name = "${local.owners}-${local.environment}" 7 | common_tags = { 8 | owners = local.owners 9 | environment = local.environment 10 | } 11 | } -------------------------------------------------------------------------------- /environments/prod/c4-vpc.tf: -------------------------------------------------------------------------------- 1 | # Resource: VPC 2 | resource "google_compute_network" "myvpc" { 3 | name = "${local.name}-vpc" 4 | auto_create_subnetworks = false 5 | } 6 | 7 | # Resource: Subnet 8 | resource "google_compute_subnetwork" "mysubnet" { 9 | name = "${local.name}-${var.gcp_region1}-subnet" 10 | region = var.gcp_region1 11 | ip_cidr_range = "10.132.0.0/20" 12 | network = google_compute_network.myvpc.id 13 | } 14 | -------------------------------------------------------------------------------- /environments/prod/c5-firewalls.tf: -------------------------------------------------------------------------------- 1 | # Firewall Rule: SSH 2 | resource "google_compute_firewall" "fw_ssh" { 3 | name = "${local.name}-fwrule-allow-ssh22" 4 | allow { 5 | ports = ["22"] 6 | protocol = "tcp" 7 | } 8 | direction = "INGRESS" 9 | network = google_compute_network.myvpc.id 10 | priority = 1000 11 | source_ranges = ["0.0.0.0/0"] 12 | target_tags = ["ssh-tag"] 13 | } 14 | 15 | # Firewall Rule: HTTP Port 80 16 | resource "google_compute_firewall" "fw_http" { 17 | name = "${local.name}-fwrule-allow-http80" 18 | allow { 19 | ports = ["80"] 20 | protocol = "tcp" 21 | } 22 | direction = "INGRESS" 23 | network = google_compute_network.myvpc.id 24 | priority = 1000 25 | source_ranges = ["0.0.0.0/0"] 26 | target_tags = ["webserver-tag"] 27 | } 28 | -------------------------------------------------------------------------------- /environments/prod/c6-vminstance.tf: -------------------------------------------------------------------------------- 1 | # Module Block: Create a single Compute Engine instance 2 | module "myvminstance" { 3 | source = "../../modules/vminstance" 4 | vminstance_name = "${local.name}-myapp1" 5 | machine_type = var.machine_type 6 | zone = "us-central1-a" 7 | firewall_tags = [tolist(google_compute_firewall.fw_ssh.target_tags)[0], tolist(google_compute_firewall.fw_http.target_tags)[0]] 8 | subnetwork = google_compute_subnetwork.mysubnet.id 9 | } 10 | 11 | -------------------------------------------------------------------------------- /environments/prod/c7-outputs.tf: -------------------------------------------------------------------------------- 1 | # Terraform Output Values 2 | output "vpc_id" { 3 | description = "VPC ID" 4 | value = google_compute_network.myvpc.id 5 | } 6 | output "subnet_id" { 7 | description = "Subnet ID" 8 | value = google_compute_subnetwork.mysubnet.id 9 | } 10 | output "vm_external_ip" { 11 | description = "VM External IPs" 12 | #value = google_compute_instance.myapp1.network_interface.0.access_config.0.nat_ip 13 | value = module.myvminstance.vm_external_ip 14 | } 15 | -------------------------------------------------------------------------------- /environments/prod/terraform.tfvars: -------------------------------------------------------------------------------- 1 | gcp_project = "gcplearn9" 2 | gcp_region1 = "us-central1" 3 | machine_type = "e2-micro" 4 | environment = "prod" 5 | business_divsion = "hr" -------------------------------------------------------------------------------- /git-deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "Add files and do local commit" 4 | git add . 5 | git commit -am "Welcome to StackSimplify" 6 | 7 | echo "Pushing to Github Repository" 8 | git push -------------------------------------------------------------------------------- /modules/vminstance/app1-webserver-install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | sudo apt install -y telnet 3 | sudo apt install -y nginx 4 | sudo systemctl enable nginx 5 | sudo chmod -R 755 /var/www/html 6 | sudo mkdir -p /var/www/html/app1 7 | HOSTNAME=$(hostname) 8 | sudo echo "
VM Hostname: $HOSTNAME
VM IP Address: $(hostname -I)
Application Version: V1
Google Cloud Platform - Demos
" | sudo tee /var/www/html/app1/index.html 9 | sudo echo "VM Hostname: $HOSTNAME
VM IP Address: $(hostname -I)
Application Version: V1
Google Cloud Platform - Demos
" | sudo tee /var/www/html/index.html 10 | -------------------------------------------------------------------------------- /modules/vminstance/main.tf: -------------------------------------------------------------------------------- 1 | # Resource Block: Create a single Compute Engine instance 2 | resource "google_compute_instance" "myapp1" { 3 | name = var.vminstance_name 4 | machine_type = var.machine_type 5 | zone = var.zone 6 | tags = var.firewall_tags 7 | boot_disk { 8 | initialize_params { 9 | image = "debian-cloud/debian-12" 10 | size = 10 11 | #size = 20 12 | } 13 | } 14 | # Install Webserver 15 | metadata_startup_script = file("${path.module}/app1-webserver-install.sh") 16 | network_interface { 17 | subnetwork = var.subnetwork 18 | access_config { 19 | # Include this section to give the VM an external IP address 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /modules/vminstance/outputs.tf: -------------------------------------------------------------------------------- 1 | output "vm_external_ip" { 2 | description = "VM External IPs" 3 | value = google_compute_instance.myapp1.network_interface.0.access_config.0.nat_ip 4 | } 5 | -------------------------------------------------------------------------------- /modules/vminstance/variables.tf: -------------------------------------------------------------------------------- 1 | # Input Variables 2 | # GCP Project 3 | variable "gcp_project" { 4 | description = "Project in which GCP Resources to be created" 5 | type = string 6 | default = "" 7 | } 8 | 9 | # GCP Region 10 | variable "gcp_region1" { 11 | description = "Region in which GCP Resources to be created" 12 | type = string 13 | default = "" 14 | } 15 | 16 | # GCP Compute Engine Machine Type 17 | variable "machine_type" { 18 | description = "Compute Engine Machine Type" 19 | type = string 20 | default = "" 21 | } 22 | 23 | variable "network" { 24 | description = "Network to deploy to. Only one of network or subnetwork should be specified." 25 | type = string 26 | default = "" 27 | } 28 | 29 | variable "subnetwork" { 30 | description = "Subnet to deploy to. Only one of network or subnetwork should be specified." 31 | type = string 32 | default = "" 33 | } 34 | 35 | variable "zone" { 36 | type = string 37 | description = "Zone where the instances should be created. If not specified, instances will be spread across available zones in the region." 38 | default = null 39 | } 40 | 41 | variable "vminstance_name" { 42 | type = string 43 | description = "VM Instance Name" 44 | default = "" 45 | } 46 | 47 | variable "firewall_tags" { 48 | description = "List of firewall tags" 49 | type = list(string) 50 | } -------------------------------------------------------------------------------- /modules/vminstance/versions.tf: -------------------------------------------------------------------------------- 1 | # Terraform Settings Block 2 | terraform { 3 | required_version = ">= 1.9" 4 | required_providers { 5 | google = { 6 | source = "hashicorp/google" 7 | version = ">= 5.36.0" 8 | } 9 | } 10 | } --------------------------------------------------------------------------------