Mysql
Example: mysql resource based on GCP CloudSQL
Configuration
This example configures a mysql  Resource Definition using GCP CloudSQL. A workload using the mysql resource to create database instance looks like:
containers:
  app:
    ...
    variables:
      DB_HOST: ${resources.db.host}
      DB_PORT: ${resources.db.port}
      DB_USERNAME: ${resources.db.username}
      DB_PASSWORD: ${resources.db.password}
      DB_NAME: ${resources.db.name}
resources:
  ...
  db:
    type: mysql
This example uses username and password authentication, checkout ../postgres/README.md for an example using CloudSQL IAM Authentication.
Infrastructure setup
graph TD;
  subgraph VPC
    subgraph server["MySQL CloudSQL Database Instance"]
      database["CloudSQL Database"]
      user["CloudSQL User"]
    end
    subgraph GKE Cluster
      pod[workload pod]
      pod -- CloudSQL User with password --> database
    end
  end
Orchestrator setup
graph LR;
    workload_1 --> db_1["db_1, resource_type: mysql"]
    workload_2 --> db_2["db_2, resource_type: mysql"]
    workload_2 --> shared.db_1["shared.db_1, resource_type: mysql"]
    workload_3 --> shared.db_1["shared.db_1, resource_type: mysql"]
    db_1 --> server["main-mysql, resource_type: mysql-instance"]
    db_2 --> server
    shared.db_1 --> server
Terraform docs
Requirements
| Name | Version | 
|---|---|
| terraform | >= 1.3.0 | 
| ~> 5.17 | |
| humanitec | ~> 1.0 | 
Providers
| Name | Version | 
|---|---|
| ~> 5.17 | |
| humanitec | ~> 1.0 | 
Modules
| Name | Source | Version | 
|---|---|---|
| mysql | ../../humanitec-resource-defs/mysql/basic | n/a | 
| mysql_instance | ../../humanitec-resource-defs/mysql-instance/basic | n/a | 
Resources
Inputs
| Name | Description | Type | Default | Required | 
|---|---|---|---|---|
| private_network | The VPC network from which the Cloud SQL instance is accessible for private IP. | string | 
          n/a | yes | 
| project | n/a | string | 
          n/a | yes | 
| region | GCP region | string | 
          n/a | yes | 
| name | Name of the example application | string | 
          "hum-rp-mysql-example" | 
          no | 
| prefix | Prefix of the created resources | string | 
          "hum-rp-mysql-ex-" | 
          no | 
| resource_packs_gcp_rev | n/a | string | 
          "refs/heads/main" | 
          no | 
| resource_packs_gcp_url | n/a | string | 
          "https://github.com/humanitec-architecture/resource-packs-gcp.git" | 
          no | 
main.tf
(view on GitHub )
:
# GCP service account used by Humanitec to provision resources
resource "google_service_account" "humanitec_provisioner" {
  account_id  = var.name
  description = "Account used by Humanitec to provision resources"
}
resource "google_project_iam_member" "humanitec_provisioner" {
  project = var.project
  role    = "roles/owner"
  member  = "serviceAccount:${google_service_account.humanitec_provisioner.email}"
}
resource "google_service_account_key" "humanitec_provisioner" {
  service_account_id = google_service_account.humanitec_provisioner.name
}
resource "humanitec_resource_account" "humanitec_provisioner" {
  id   = var.name
  name = var.name
  type = "gcp"
  credentials = base64decode(google_service_account_key.humanitec_provisioner.private_key)
  depends_on = [
    # Otherwise the account looses permissions before the resources are deleted
    google_project_iam_member.humanitec_provisioner
  ]
}
# Example application and resource definition criteria
resource "humanitec_application" "example" {
  id   = var.name
  name = var.name
}
# MySQL instance
locals {
  # Define the shared mysql-instance resource id and class
  mysql_instance_res_id = "main-mysql"
  mysql_instance_class  = "default"
}
data "google_compute_network" "network" {
  name = var.private_network
}
resource "google_project_service" "servicenetworking" {
  service            = "servicenetworking.googleapis.com"
  disable_on_destroy = false
}
resource "google_compute_global_address" "private_ip_address" {
  name          = "${var.prefix}private-ip-address"
  purpose       = "VPC_PEERING"
  address_type  = "INTERNAL"
  prefix_length = 16
  network       = data.google_compute_network.network.id
}
# In case of getting "Cannot modify allocated ranges in CreateConnection. Please use UpdateConnection.",
# temporarily set `reserved_peering_ranges = []` run apply, reset afterwards and apply again.
#
# This is required due to https://github.com/hashicorp/terraform-provider-google/issues/3294
resource "google_service_networking_connection" "private_vpc_connection" {
  network                 = data.google_compute_network.network.id
  service                 = "servicenetworking.googleapis.com"
  reserved_peering_ranges = [google_compute_global_address.private_ip_address.name]
  depends_on = [google_project_service.servicenetworking]
}
module "mysql_instance" {
  source = "github.com/humanitec-architecture/resource-packs-gcp?ref=v2024-06-14//humanitec-resource-defs/mysql-instance/basic"
  prefix                 = var.prefix
  resource_packs_gcp_rev = var.resource_packs_gcp_rev
  resource_packs_gcp_url = var.resource_packs_gcp_url
  append_logs_to_error   = true
  driver_account         = humanitec_resource_account.humanitec_provisioner.id
  project                = var.project
  region                 = var.region
  database_version = "MYSQL_8_0"
  tier             = "db-f1-micro"
  private_network  = data.google_compute_network.network.id
  depends_on = [google_service_networking_connection.private_vpc_connection]
}
resource "humanitec_resource_definition_criteria" "mysql_instance" {
  resource_definition_id = module.mysql_instance.id
  app_id                 = humanitec_application.example.id
  class                  = local.mysql_instance_class
  res_id                 = local.mysql_instance_res_id
  force_delete           = true
}
module "mysql" {
  source = "github.com/humanitec-architecture/resource-packs-gcp?ref=v2024-06-14//humanitec-resource-defs/mysql/basic"
  prefix                 = var.prefix
  resource_packs_gcp_rev = var.resource_packs_gcp_rev
  resource_packs_gcp_url = var.resource_packs_gcp_url
  append_logs_to_error   = true
  driver_account         = humanitec_resource_account.humanitec_provisioner.id
  project                = var.project
  region                 = var.region
  instance_resource = "mysql-instance.${local.mysql_instance_class}#${local.mysql_instance_res_id}"
}
resource "humanitec_resource_definition_criteria" "mysql" {
  resource_definition_id = module.mysql.id
  app_id                 = humanitec_application.example.id
  force_delete           = true
}
providers.tf
(view on GitHub )
:
terraform {
  required_providers {
    google = {
      source  = "hashicorp/google"
      version = "~> 5.17"
    }
    humanitec = {
      source  = "humanitec/humanitec"
      version = "~> 1.0"
    }
  }
  required_version = ">= 1.3.0"
}
provider "humanitec" {}
provider "google" {
  project = var.project
  region  = var.region
  default_labels = {
    "managed_by" = "terraform"
    "source"     = "github.com/humanitec-architecture/resource-pack-gcp"
  }
}
terraform.tfvars.example
(view on GitHub )
:
# Name of the example application
name = "hum-rp-mysql-example"
# Prefix of the created resources
prefix = "hum-rp-mysql-ex-"
# The VPC network from which the Cloud SQL instance is accessible for private IP.
private_network = ""
project = ""
# GCP region
region = ""
resource_packs_gcp_rev = "refs/tags/v2024-06-14"
resource_packs_gcp_url = "https://github.com/humanitec-architecture/resource-packs-gcp.git"
variables.tf
(view on GitHub )
:
variable "name" {
  description = "Name of the example application"
  type        = string
  default     = "hum-rp-mysql-example"
}
variable "resource_packs_gcp_rev" {
  type    = string
  default = "refs/tags/v2024-06-14"
}
variable "resource_packs_gcp_url" {
  type    = string
  default = "https://github.com/humanitec-architecture/resource-packs-gcp.git"
}
variable "prefix" {
  description = "Prefix of the created resources"
  type        = string
  default     = "hum-rp-mysql-ex-"
}
variable "project" {
  type = string
}
variable "region" {
  description = "GCP region"
  type        = string
}
variable "private_network" {
  type        = string
  description = "The VPC network from which the Cloud SQL instance is accessible for private IP."
}