Terraform Deployment

This project automates the deployment of infrastructure on Google Cloud Platform (GCP) using Terraform. It sets up a network, a Cloud SQL PostgreSQL database, a Kubernetes cluster with a node pool, and deploys Helm charts for Ingress Nginx and Cert Manager.

Prerequisites

Before running the Terraform script locally, ensure you have installed, created and enabled the following prerequisites

  1. Terraform installed.

  2. Google Cloud Platform (GCP) account and access to ksa region.

  3. Google Cloud service account with appropriate permissions (e.g., roles/owner)

  4. Install gcloud.

    See also

  5. Logged In GCP Project.

  6. Cloud Storage bucket to store Terraform state

  7. Google Cloud Platform (GCP) account with the following APIs enabled:

    • Cloud SQL Admin API

    • Compute Engine API

    • Artifact Registry API

    • Kubernetes Engine API

    • Cloud Resource Manager API

    • Service Networking API

    • Cloud Filestore API

Create Infrastructure

This section outlines the deployment of various infrastructure components using Terraform modules.

Note

Before running any module, make sure to set the required variables in the corresponding configuration files. Failure to do so may result in errors during deployment.

Network

Creates a Google Compute Engine (GCE) network and subnetwork. Additionally, it provisions a global static IP address to enable private access to the Cloud SQL PostgreSQL instance.

Storage

Deploys a Cloud SQL PostgreSQL instance along with a database and user. Additionally, it provides a Kubernetes secret for storing Azure Container Registry (ACR) credentials and provisioning a Redis database for caching purposes.

Cluster

Provisions a Kubernetes cluster with a node pool for running applications.

Helm

Deploys Helm charts for Ingress Nginx and Cert Manager to manage ingress and SSL certificates. Additionally, it includes an Ingress for the MEG portal web application and a ConfigMap with environment variables required by the application.

Variables

The following variables can be configured to customize the deployment:

Variable Explanations

Variable

Explanation

project

GCP project ID

region

Terraform project region

zone

Terraform project zone

network

Compute network name

subnet_gke

Subnet network for PostgreSQL

registry

Specifies the name of the Azure Container Registry (ACR) where Docker images are stored.

cluster_name

GKE cluster name

nodepool_name

GKE nodepool name

min_node_count

Minimum number of nodes per zone in the node pool

max_node_count

Maximum number of nodes per zone in the node pool

machine_type

GKE node pool machine type

postgres_name

PostgreSQL instance name

database_version

PostgreSQL version

tier

PostgreSQL tier

disk_size

PostgreSQL disk size

database_name

PostgreSQL database name

username

PostgreSQL database username

password

PostgreSQL database password

replicas

Ingress Nginx replicas

Note

You can set the necessary variables from the command line, or create a .tfvars file specifying the value of each of these variables, in order to run the plan with that set of variables with the parameter -var-file, depending on the environment.

Deploy Infrastructure with Terraform

To deploy the infrastructure using Terraform, follow these steps:

Note

All these commands need to be executed from the directory where the main.tf file is located.

Initialize Terraform

This command initializes Terraform in the current directory, downloading any required plugins and modules. This command only needs to be executed the first time the infrastructure is deployed or destroyed.

terraform init

Validate Terraform Configuration

Use the following command to validate the Terraform configuration syntax and check for any errors:

terraform validate

Plan Infrastructure Changes

Generate an execution plan for Terraform to preview the changes it will make to your infrastructure, execute only one of these commands, depending on your needs:

terraform plan -out plan.json
terraform plan -var-file ./gcp-ksa.tfvars -out plan.json

Note

The first command allows executing the plan by setting the variables from the command line (also using the default value specified for each variable), while the second one uses a .tfvars file where those variables are already defined.

Apply Infrastructure Changes

Apply the planned changes to deploy the infrastructure, execute only one of these commands, depending on your needs:

terraform apply plan.json
terraform apply -var-file ./gcp-ksa.tfvars

Note

The first command allows applying changes automatically according to the plan generated in the previous command, while the second one, on the other hand, allows approving deployment from the command line.

Destroy Deployment with Terraform

To destroy the deployment using Terraform, follow these steps:

Note

Make sure you have executed the ‘terraform init’ command previously to download all dependencies.

Plan Destroy

Generate an execution plan for Terraform to preview the destruction of the infrastructure, execute only one of these commands, depending on your needs:

terraform plan -destroy  -out plan.json
terraform plan -destroy -var-file ./gcp-ksa.tfvars -out plan.json

Note

The first command allows executing the plan by setting the variables from the command line (also using the default value specified for each variable), while the second one uses a .tfvars file where those variables are already defined.

Destroy Infrastructure

Apply the planned destruction to remove the infrastructure, execute only one of these commands, depending on your needs:

terraform apply plan.json
terraform destroy -var-file ./gcp-ksa.tfvars

Note

The first command allows applying changes automatically according to the plan generated in the previous command, while the second one, on the other hand, allows approving from the command line.

GitLab CI/CD Job

A job have been created in GitLab CI/CD to run the Terraform scripts and deploy the solution. Specifically, this job has been created in the .gitlab-ci.deploy.yml file.

k8s:ksa:deploy:production

This job is responsible for deploying all MEG pods and jobs to run the application in the production environment. It deploys pods with the Docker image that was pushed by the pipeline in the docker:build:dev job.