Create K8S cluster with Terraform and GitlabCI
In this post I will show you how how you can create a K8S cluster with Terraform and GitlabCI.
create service account on GCP
gcloud config set project gke-terraform-test
gcloud iam service-accounts create gitlab-terraform \
--display-name="gitlab-terraform" \
--project=gke-terraform-test
gcloud iam service-accounts add-iam-policy-binding \
gitlab-terraform@gke-terraform-test.iam.gserviceaccount.com \
--member="serviceAccount:gitlab-terraform@gke-terraform-test.iam.gserviceaccount.com" \
--role='roles/compute.networkAdmin'
gcloud iam service-accounts add-iam-policy-binding \
gitlab-terraform@gke-terraform-test.iam.gserviceaccount.com \
--member="serviceAccount:gitlab-terraform@gke-terraform-test.iam.gserviceaccount.com" \
--role='roles/container.admin' \
--project=gke-terraform-test
gcloud iam service-accounts add-iam-policy-binding \
gitlab-terraform@gke-terraform-test.iam.gserviceaccount.com \
--member="serviceAccount:gitlab-terraform@gke-terraform-test.iam.gserviceaccount.com" \
--role='roles/iam.serviceAccountUser' \
--project=gke-terraform-test
gcloud iam service-accounts add-iam-policy-binding \
gitlab-terraform@gke-terraform-test.iam.gserviceaccount.com \
--member="serviceAccount:gitlab-terraform@gke-terraform-test.iam.gserviceaccount.com" \
--role='roles/iam.serviceAccountAdmin' \
--project=gke-terraform-test
gcloud iam service-accounts keys create serviceaccount.json \
--iam-account "gitlab-terraform@gke-terraform-test.iam.gserviceaccount.com"
Store the content of the serviceaccount.json
as base64 encoded value in gitlab variable called BASE64_GOOGLE_CREDENTIALS
base64 serviceaccount.json | tr -d \\n
Create gitlab-ci.yaml
Create CI environment variable:
TF_VAR_gitlab_token
: GitLab personal access token with api scope to add the provisioned cluster to your GitLab group.
TF_ROOT
: terraform
TF_VAR_gcp_project
: gke-terraform-test
nano gitlab-ci.yaml
include:
- template: Terraform.gitlab-ci.yml
variables:
TF_STATE_NAME: production
TF_CACHE_KEY: production
TF_ROOT: terraform
TF_VAR_gcp_project: gke-terraform-test
before_script:
- export GOOGLE_CREDENTIALS=$(echo $BASE64_GOOGLE_CREDENTIALS | base64 -d)
Create terraform file
mkdir terraform
cd
Import the hashicorp/google
provider:
nano providers.tf
terraform {
required_providers {
google = {
source = "hashicorp/google"
version = "3.79.0"
}
}
required_version = "~> 1.0.3"
backend "http" {
}
}
provider "google" {
project = var.project_id
region = var.region
}
Generate Variables:
nano variables.tf
variable "project_id" {
description = "project id"
}
variable "region" {
description = "region"
}
variable "gke_num_nodes" {
default = 1
description = "number of gke nodes per zone"
}
variable "machine_type" {
type = string
description = "Type of the node compute engines."
}
variable "disk_size_gb" {
type = number
description = "Size of the node's disk."
}
variable "disk_type" {
type = string
description = "Type of the node's disk."
}
variable "cluster_version" {
default = "1.20"
}
Create network and GKE Cluster:
nano main.json
resource "google_compute_network" "vpc" {
name = "gke-test-vpc"
auto_create_subnetworks = "false"
}
resource "google_compute_subnetwork" "gke-test-network" {
name = "gke-test-network"
region = var.region
network = google_compute_network.vpc.name
ip_cidr_range = "10.10.10.0/24"
}
resource "google_service_account" "default" {
account_id = "service-account-id"
display_name = "Service Account"
}
resource "google_container_cluster" "primary" {
name = "gke-test"
location = var.region
min_master_version = var.cluster_version
remove_default_node_pool = true
initial_node_count = 1
network = google_compute_network.vpc.name
subnetwork = "gke-test-network"
}
resource "google_container_node_pool" "primary_nodes" {
name = "${google_container_cluster.primary.name}-node-pool"
location = var.region
cluster = google_container_cluster.primary.name
node_count = var.gke_num_nodes
version = var.cluster_version
management {
auto_repair = "true"
auto_upgrade = "true"
}
node_config {
oauth_scopes = [
"https://www.googleapis.com/auth/cloud-platform",
]
labels = {
env = var.project_id
}
service_account = google_service_account.default.email
image_type = "COS"
machine_type = var.machine_type
disk_size_gb = var.disk_size_gb
disk_type = var.disk_type
preemptible = false
tags = [
"gke-node",
]
metadata = {
disable-legacy-endpoints = "true"
}
}
}
Add value for the variables:
nano terraform.tfvars
project_id = "gke-terraform-test"
region = "europe-west1"
gke_num_nodes = 1
machine_type = "g1-small"
disk_type = "pd-standard"
disk_size_gb = 10
Configure what data will print in the end of the deploy:
nano outputs.tf
output "region" {
value = var.region
description = "GCloud Region"
}
output "project_id" {
value = var.project_id
description = "GCloud Project ID"
}
output "kubernetes_cluster_name" {
value = google_container_cluster.primary.name
description = "GKE Cluster Name"
}
If you created all the fles it looks like this:
cd ..
tree .
.
├── README.md
└── terraform
├── providers.tf
├── main.tf
├── outputs.tf
├── terraform.tfvars
├── variables.tf
1 directory, 5 files
Now you can push to the gitlab project:
git add -A
git commit -m "base terraform commit"
git push