Movatterモバイル変換


[0]ホーム

URL:


Hackers and Slackers
Hackers and Slackers Mobile

Hackers and Slackers

Sign inSubscribe
Hashicorp

Build it with Terraform

Provision Google Cloud infrastructure using Hashicorp Terraform. Spin up instances of CloudSQL, Redis, Kubernetes and more.

David Aquino
David Aquino
4 min read
Build it with Terraform

This post covers how to build Google Cloud Platform infrastructure usingTerraform.

The files you need include:

  • main.tf
  • variables.tf
  • backend.tf (Optional)

The configurations are referenced from inside modules in this implementation, but you could have everything defined in onemain.tf.

Note: Google Cloud Platform requires APIs to be enabled, and you will need account credentials with sufficient permission to build the following resources. The project will need to be linked to a billing account.

GCP Setup via CLI

Here's what you'll need to do to get set up via the CLI:

$ export PROJECT_ID=my_gcp_project$ export ACCOUNT_ID=$(gcloud beta billing accounts list | grep True | cut -d ' ' -f1)$ gcloud auth login$ gcloud projects create $PROJECT_ID$ gcloud config set compute/region us-east1$ gcloud config set project $PROJECT_ID$ gcloud beta billing projects link $PROJECT_ID --billing-account=$ACCOUNT_ID# enable apis$ gcloud services enable \    cloudapis.googleapis.com \    cloudresourcemanager.googleapis.com \    container.googleapis.com \    containerregistry.googleapis.com \    iam.googleapis.com \    redis.googleapis.com \    servicenetworking.googleapis.com \    sqladmin.googleapis.com# If you want to use gcs for remote storage$ gsutil mb -c standard -l us-east1 gs://$PROJECT_ID# Create a service account for terraform$ gcloud iam service-accounts create terraform \    --description="Terraform Service Account" \    --display-name="Terraform"$ gcloud projects add-iam-policy-binding $PROJECT_ID \  --member serviceAccount:terraform@$PROJECT_ID.iam.gserviceaccount.com \  --role roles/owner$ gcloud iam service-accounts keys create CREDENTIALS_FILE.json --iam-account=terraform@$PROJECT_ID.iam.gserviceaccount.com --project $PROJECT_ID$ mv CREDENTIALS_FILE.json terraform/
gcloud CLI setup.

Setting up Terraform

Once all the variables are set, run:

$ terraform init
Initialize modules

This will download the necessary files to./terraform/.

Next we'll create a dry-run execution plan to see what infrastructure will be built, and decide if any changes are necessary:

$ terraform plan
Create an execution plan

The following will create the infrastructure as it's been defined:

$ terraform apply
Apply changes

Configurations for GCP Infrastructure

Let's get into what our actual Terraform configurations look like. We start with some general configuration inmain.tf:

locals {  database_version = "" # "POSTGRES_11"  network          = "" # Network name  region           = "" # us-east1  project_id       = "" # GCP Project ID  subnetwork       = "" # Subnetwork name}// Configure the Google Cloud providerprovider "google" { credentials = file("CREDENTIALS_FILE.json") project     = local.project_id region      = local.region}provider "google-beta" {  credentials = file("CREDENTIALS_FILE.json")  project     = local.project_id  region      = local.region}module "cloudsql" {  source           = "./modules/cloudsql"  network          = local.network  private_ip_name  = "" # Private IP Name  project          = local.project_id  region           = local.region}module "gke" {  source           = "./modules/gke"  cluster          = "" # Cluster Name  network          = local.network  project          = local.project_id  region           = local.region  subnetwork       = local.subnetwork  zones            = "" # ["us-east1-b", "us-east1-c", "us-east1-d"]}module "memorystore" {  source         = "./modules/memorystore"  display_name   = "" # Display Name  ip_range       = "" #  location       = "" # Zone  name           = "" # Instance name  network        = local.network  project        = local.project_id  redis_version  = "" # 5.0  region         = local.region  size           = "" # 1  tier           = "" # STANDARD}module "vpc" {  source           = "./modules/vpc"  project          = local.project_id  network          = local.network  region           = local.region  subnetwork       = local.subnetwork}
main.tf

Next we need to make Terraform aware of our credentials file inbackend.tf:

data "terraform_remote_state" "backend" {  backend = "gcs"  config = {    bucket  = ""    prefix  = "terraform"    credentials = file("CREDENTIALS_FILE.json")  }}
backend.tf
# GCP variables
variables.tf

CloudSQL Configuration

locals {  network          = join("/", ["projects", var.project, "global", "networks", var.network])}resource "google_compute_global_address" "private_ip_address" {  provider = google-beta  name          = var.private_ip_name  purpose       = "VPC_PEERING"  address_type  = "INTERNAL"  prefix_length = 16  network       = local.network  depends_on    = [local.network]}resource "google_service_networking_connection" "private_vpc_connection" {  provider = google-beta  network                 = local.network  service                 = "servicenetworking.googleapis.com"  reserved_peering_ranges = [google_compute_global_address.private_ip_address.name]  depends_on              = [local.network]}resource "random_id" "db_name_suffix" {  byte_length = 4}resource "google_sql_database_instance" "instance" {  provider = google-beta  name   = "private-instance-${random_id.db_name_suffix.hex}"  database_version = var.database_version  region = var.region  depends_on = [google_service_networking_connection.private_vpc_connection]  settings {    tier = "db-custom-1-3840"    ip_configuration {      ipv4_enabled    = false      private_network = local.network    }  }}resource "google_sql_user" "users" {  name     = var.user_name  instance = google_sql_database_instance.instance.name  password = var.user_password}
modules/cloudsql/main.tf
variable "database_version" {  description = "The database version"}variable "network" {  description = "The name of the network being created"}variable "private_ip_name" {  description = "The name of the private ip address being created"}variable "project" {  description = "Project ID"}variable "region" {  description = "Region"}variable "user_name" {  default     = "DB_USER"}variable "user_password" {  default     = "DB_PASSWORD"}
modules/cloudsql/variables.tf

Kubernetes Configuration

module "gke" {  source                     = "terraform-google-modules/kubernetes-engine/google"  project_id                 = var.project  name                       = var.cluster  region                     = var.region  zones                      = var.zones  network                    = var.network  subnetwork                 = var.subnetwork  ip_range_pods              = join("-",[var.subnetwork,"pods"])  ip_range_services          = join("-",[var.subnetwork,"services"])  http_load_balancing        = "true"  horizontal_pod_autoscaling = "true"  network_policy             = "true"  maintenance_start_time     = "05:00"  remove_default_node_pool   = "true"  node_pools = [    {      name               = "pool-1"      machine_type       = "n1-standard-2"      min_count          = 1      max_count          = 10      local_ssd_count    = 0      disk_size_gb       = 100      disk_type          = "pd-standard"      image_type         = "COS"      auto_repair        = "true"      auto_upgrade       = "true"      preemptible        = "true"      initial_node_count = 1    }  ]  node_pools_oauth_scopes = {    all = [      "https://www.googleapis.com/auth/cloud-platform",    ]  }  node_pools_labels = {    all = {}  }  node_pools_metadata = {    all = {}  }  node_pools_tags = {    all = []  }}
modules/gke/main.tf
variable "cluster" {  description = "Cluster name"}variable "kubernetes_version" {  description = "The Kubernetes version of the masters. If set to 'latest' it will pull latest available version in the selected region."  type        = string  default     = "latest"}variable "network" {  description = "The name of the network being created"}variable "project" {  description = "Project"}variable "region" {  description = "Region of resources"}variable "subnetwork" {  description = "The name of the subnetwork being created"}variable "zones" {  description = "Zones"}
modules/gke/variables.tf

Redis Configuration

resource "google_redis_instance" "cache" {  authorized_network      = var.network  display_name            = var.display_name  name                    = var.name  memory_size_gb          = var.size  location_id             = var.location  project                 = var.project  redis_version           = var.redis_version  region                  = var.region  reserved_ip_range       = var.ip_range  tier                    = var.tier}
modules/memorystore/main.tf
variable "display_name" {  description = "Instance Name"}variable "ip_range" {  description = "IP Range"}variable "location" {  description = "Zone"}variable "name" {  description = "Instance Name"}variable "network" {  description = "Authorized Network"}variable "project" {  description = "Project ID"}variable "redis_version" {  description = "Redis Version"}variable "region" {  description = "Region"}variable "size" {  description = "Memory Size in GB"}variable "tier" {  description = "Service Tier"}
modules/memorystore/variables.tf

VPC Configuration

module "vpc" {    source  = "terraform-google-modules/network/google"    version = "~> 2.3"    project_id   = var.project    network_name = var.network    routing_mode = "GLOBAL"    subnets = [        {            subnet_name              = var.subnetwork            subnet_ip                = "10.183.0.0/20"            subnet_region            = var.region            subnet_private_access    = "true"            subnet_flow_logs         = "true"            description              = var.subnet_description        }    ]    secondary_ranges = {        (var.subnetwork) = [            {                range_name    = join("-", [var.subnetwork, "pods"])                ip_cidr_range = "10.184.0.0/14"            },            {                range_name    = join("-", [var.subnetwork, "services"])                ip_cidr_range = "10.188.0.0/20"            },        ]    }}
modules/vpc/main.tf
variable "auto_create_subnetworks" {  type        = bool  description = "When set to true, the network is created in 'auto subnet mode' and it will create a subnet for each region automatically across the 10.128.0.0/9 address range. When set to false, the network is created in 'custom subnet mode' so the user can explicitly connect subnetwork resources."  default     = false}variable "description" {  type        = string  description = "An optional description of this resource. The resource must be recreated to modify this field."  default     = "Toptal VPC network"}variable "network" {  description = "The name of the network being created"}variable "project" {  description = "Toptal Project"}variable "region" {  description = "Region of resources"}variable "routing_mode" {  type        = string  default     = "GLOBAL"  description = "The network routing mode (default 'GLOBAL')"}variable "subnet_description" {  type        = string  description = "An optional description of this resource. The resource must be recreated to modify this field."  default     = "Toptal VPC subnetwork"}variable "shared_vpc_host" {  type        = bool  description = "Makes this project a Shared VPC host if 'true' (default 'false')"  default     = false}variable "subnetwork" {  description = "The name of the subnetwork being created"}
modules/vpc/variables.tf

HashicorpDevOpsAutomationGoogle CloudTerraform
David Aquino's' avatar
NYC

Spent years in the military to become a killing machine using only 2 CDJs. Automated all of life's inconveniences, including investments in the financial markets.

Monthly Newsletter
Support us

We share tutorials to help and inspire new engineers and enthusiasts. If you've found Hackers and Slackers to be helpful, we welcome donations in the form of coffee :).

Related Posts


[8]ページ先頭

©2009-2025 Movatter.jp