25 Commits

Author SHA1 Message Date
Rob Morgan
3b18b91411 Merge pull request #38 from gruntwork-io/tf12
Upgrade to Terraform 0.12
2019-06-26 16:38:38 +02:00
Rob Morgan
cb93ed3983 reorder cleanup funcs 2019-06-26 13:30:22 +02:00
Rob Morgan
62fcb11062 fix bug caught by tests and yoris feedback 2019-06-26 12:57:15 +02:00
Rob Morgan
b8e137b0bd fix syntax 2019-06-26 12:54:00 +02:00
Rob Morgan
81b187580c improve docs 2019-06-26 11:58:17 +02:00
Rob Morgan
fd76dce436 test against tf 0.12.2 2019-06-26 10:20:22 +02:00
Rob Morgan
925924a298 fix code 2019-06-25 18:08:10 +02:00
Rob Morgan
f25a4c7c8b fix root example 2019-06-25 18:03:00 +02:00
Rob Morgan
188cdfb0d7 fix dependency chain 2019-06-25 17:36:42 +02:00
Rob Morgan
5dc807e2f3 use nulls instead of empty strings 2019-06-25 17:35:52 +02:00
Rob Morgan
2a46a70ee8 improve syntax a bit 2019-06-25 17:23:38 +02:00
Rob Morgan
edd30bcea5 use nulls 2019-06-25 17:23:28 +02:00
Rob Morgan
0dfd8e28cf fix module deps 2019-06-25 16:55:10 +02:00
Rob Morgan
bb152b218d fix a few issues from the tests. bump version in docs 2019-06-25 16:42:31 +02:00
Rob Morgan
7713a67db3 change tests to use different options for non-replica and replica tests 2019-06-25 14:23:20 +02:00
Rob Morgan
1fdb587e0b fix a few things from tests 2019-06-25 13:53:18 +02:00
Rob Morgan
d5554b29f4 bump terratest version 2019-06-25 13:20:16 +02:00
Rob Morgan
1364203502 more tf12 changes 2019-06-25 12:15:46 +02:00
Rob Morgan
213f6e2e3a start modifying code 2019-06-21 18:23:15 +02:00
Rob Morgan
11a459bba1 bump required version 2019-06-21 17:54:45 +02:00
Rob Morgan
f91123778c bump tf ver on circleci 2019-06-21 17:52:36 +02:00
Rob Morgan
d5324fdc80 clean up readme a bit and add badge 2019-06-21 17:52:17 +02:00
Riley Karson
6aebe49bb0 Bump refs, use https (#37) 2019-06-05 09:59:44 -07:00
Rob Morgan
5f896dd55a Merge pull request #35 from gruntwork-io/version-bump
Bump version to a 0.12-compatible one.
2019-05-24 09:31:13 +02:00
Riley Karson
de09c6223a Bump version to a 0.12-compatible one. 2019-05-23 13:52:41 -07:00
37 changed files with 1032 additions and 461 deletions

View File

@@ -4,7 +4,7 @@ defaults: &defaults
GRUNTWORK_INSTALLER_VERSION: v0.0.21
TERRATEST_LOG_PARSER_VERSION: v0.13.24
MODULE_CI_VERSION: v0.13.3
TERRAFORM_VERSION: 0.11.8
TERRAFORM_VERSION: 0.12.2
TERRAGRUNT_VERSION: NONE
PACKER_VERSION: NONE
GOLANG_VERSION: 1.11.2
@@ -99,4 +99,4 @@ workflows:
- build
- test:
requires:
- build
- build

View File

@@ -1,5 +1,6 @@
[![Maintained by Gruntwork.io](https://img.shields.io/badge/maintained%20by-gruntwork.io-%235849a6.svg)](https://gruntwork.io/?ref=repo_google_cloudsql)
[![GitHub tag (latest SemVer)](https://img.shields.io/github/tag/gruntwork-io/terraform-google-sql.svg?label=latest)](http://github.com/gruntwork-io/terraform-google-sql/releases/latest)
![Terraform Version](https://img.shields.io/badge/tf-%3E%3D0.12.0-blue.svg)
# Cloud SQL Modules
@@ -20,33 +21,33 @@ for instructions.
This repo has the following folder structure:
* [root](https://github.com/gruntwork-io/terraform-google-sql/tree/master): The root folder contains an example of how
- [root](https://github.com/gruntwork-io/terraform-google-sql/tree/master): The root folder contains an example of how
to deploy a private PostgreSQL instance in Cloud SQL. See [postgres-private-ip](https://github.com/gruntwork-io/terraform-google-sql/blob/master/examples/postgres-private-ip)
for the documentation.
* [modules](https://github.com/gruntwork-io/terraform-google-sql/tree/master/modules): This folder contains the
- [modules](https://github.com/gruntwork-io/terraform-google-sql/tree/master/modules): This folder contains the
main implementation code for this Module, broken down into multiple standalone submodules.
The primary module is:
* [cloud-sql](https://github.com/gruntwork-io/terraform-google-sql/tree/master/modules/cloud-sql): Deploy a Cloud SQL [MySQL](https://cloud.google.com/sql/docs/mysql/) or
- [cloud-sql](https://github.com/gruntwork-io/terraform-google-sql/tree/master/modules/cloud-sql): Deploy a Cloud SQL [MySQL](https://cloud.google.com/sql/docs/mysql/) or
[PostgreSQL](https://cloud.google.com/sql/docs/postgres/) database.
* [examples](https://github.com/gruntwork-io/terraform-google-sql/tree/master/examples): This folder contains
- [examples](https://github.com/gruntwork-io/terraform-google-sql/tree/master/examples): This folder contains
examples of how to use the submodules.
* [test](https://github.com/gruntwork-io/terraform-google-sql/tree/master/test): Automated tests for the submodules
- [test](https://github.com/gruntwork-io/terraform-google-sql/tree/master/test): Automated tests for the submodules
and examples.
## What is Cloud SQL?
Cloud SQL is Google's fully-managed database service that makes it easy to set up, maintain, manage, and administer
your relational databases on Google Cloud Platform. Cloud SQL automatically includes:
Cloud SQL is Google's fully-managed database service that makes it easy to set up, maintain, manage, and administer
your relational databases on Google Cloud Platform. Cloud SQL automatically includes:
* Data replication between multiple zones with automatic failover.
* Automated and on-demand backups, and point-in-time recovery.
* Data encryption on networks, database tables, temporary files, and backups.
* Secure external connections with the [Cloud SQL Proxy](https://cloud.google.com/sql/docs/mysql/sql-proxy) or with the SSL/TLS protocol.
- Data replication between multiple zones with automatic failover.
- Automated and on-demand backups, and point-in-time recovery.
- Data encryption on networks, database tables, temporary files, and backups.
- Secure external connections with the [Cloud SQL Proxy](https://cloud.google.com/sql/docs/mysql/sql-proxy) or with the SSL/TLS protocol.
You can learn more about Cloud SQL from [the official documentation](https://cloud.google.com/sql/docs/).
@@ -70,18 +71,16 @@ commercial support, send an email to
Gruntwork can help with:
* Setup, customization, and support for this Module.
* Modules and submodules for other types of infrastructure, such as VPCs, Docker clusters, databases, and continuous
- Setup, customization, and support for this Module.
- Modules and submodules for other types of infrastructure, such as VPCs, Docker clusters, databases, and continuous
integration.
* Modules and Submodules that meet compliance requirements, such as HIPAA.
* Consulting & Training on GCP, AWS, Terraform, and DevOps.
- Modules and Submodules that meet compliance requirements, such as HIPAA.
- Consulting & Training on GCP, AWS, Terraform, and DevOps.
## How do I contribute to this Module?
Contributions are very welcome! Check out the [Contribution Guidelines](https://github.com/gruntwork-io/terraform-google-sql/blob/master/CONTRIBUTING.md) for instructions.
## How is this Module versioned?
This Module follows the principles of [Semantic Versioning](http://semver.org/). You can find each new release, along
@@ -91,7 +90,6 @@ During initial development, the major version will be 0 (e.g., `0.x.y`), which i
stable API. Once we hit `1.0.0`, we will make every effort to maintain a backwards compatible API and use the MAJOR,
MINOR, and PATCH versions on each release to indicate any incompatibilities.
## License
Please see [LICENSE](https://github.com/gruntwork-io/terraform-google-sql/blob/master/LICENSE.txt) for how the code in this repo is licensed.

View File

@@ -7,14 +7,15 @@
# ------------------------------------------------------------------------------
provider "google-beta" {
region = "${var.region}"
project = "${var.project}"
version = "~> 2.7.0"
project = var.project
region = var.region
}
# Use Terraform 0.10.x so that we can take advantage of Terraform GCP functionality as a separate provider via
# https://github.com/terraform-providers/terraform-provider-google
terraform {
required_version = ">= 0.10.3"
# The modules used in this example have been updated with 0.12 syntax, which means the example is no longer
# compatible with any versions below 0.12.
required_version = ">= 0.12"
}
# ------------------------------------------------------------------------------
@@ -23,6 +24,6 @@ terraform {
resource "google_sql_ssl_cert" "client_cert" {
provider = "google-beta"
common_name = "${var.common_name}"
instance = "${var.database_instance_name}"
common_name = var.common_name
instance = var.database_instance_name
}

View File

@@ -4,11 +4,11 @@
output "client_ca_cert" {
description = "Certificate data for the client certificate."
value = "${google_sql_ssl_cert.client_cert.cert}"
value = google_sql_ssl_cert.client_cert.cert
}
# In real-world cases, the output for the private key should always be encrypted
output "client_private_key" {
description = "Private key associated with the client certificate."
value = "${google_sql_ssl_cert.client_cert.private_key}"
value = google_sql_ssl_cert.client_cert.private_key
}

View File

@@ -5,17 +5,21 @@
variable "project" {
description = "The project ID to host the database in."
type = string
}
variable "region" {
description = "The region to host the database in."
type = string
}
# Note, after a name db instance is used, it cannot be reused for up to one week.
variable "common_name" {
description = "The common name to be used in the certificate to identify the client. Constrained to [a-zA-Z.-_ ]+. Changing this forces a new resource to be created."
type = string
}
variable "database_instance_name" {
description = "The name of the Cloud SQL instance. Changing this forces a new resource to be created."
type = string
}

View File

@@ -7,15 +7,15 @@
# ------------------------------------------------------------------------------
provider "google-beta" {
version = "~> 2.1.0"
region = "${var.region}"
project = "${var.project}"
version = "~> 2.7.0"
project = var.project
region = var.region
}
# Use Terraform 0.10.x so that we can take advantage of Terraform GCP functionality as a separate provider via
# https://github.com/terraform-providers/terraform-provider-google
terraform {
required_version = ">= 0.10.3"
# The modules used in this example have been updated with 0.12 syntax, which means the example is no longer
# compatible with any versions below 0.12.
required_version = ">= 0.12"
}
# ------------------------------------------------------------------------------
@@ -28,7 +28,7 @@ resource "random_id" "name" {
locals {
# If name_override is specified, use that - otherwise use the name_prefix with a random string
instance_name = "${length(var.name_override) == 0 ? format("%s-%s", var.name_prefix, random_id.name.hex) : var.name_override}"
instance_name = var.name_override == null ? format("%s-%s", var.name_prefix, random_id.name.hex) : var.name_override
private_network_name = "private-network-${random_id.name.hex}"
private_ip_name = "private-ip-${random_id.name.hex}"
}
@@ -40,25 +40,25 @@ locals {
# Simple network, auto-creates subnetworks
resource "google_compute_network" "private_network" {
provider = "google-beta"
name = "${local.private_network_name}"
name = local.private_network_name
}
# Reserve global internal address range for the peering
resource "google_compute_global_address" "private_ip_address" {
provider = "google-beta"
name = "${local.private_ip_name}"
name = local.private_ip_name
purpose = "VPC_PEERING"
address_type = "INTERNAL"
prefix_length = 16
network = "${google_compute_network.private_network.self_link}"
network = google_compute_network.private_network.self_link
}
# Establish VPC network peering connection using the reserved address range
resource "google_service_networking_connection" "private_vpc_connection" {
provider = "google-beta"
network = "${google_compute_network.private_network.self_link}"
network = google_compute_network.private_network.self_link
service = "servicenetworking.googleapis.com"
reserved_peering_ranges = ["${google_compute_global_address.private_ip_address.name}"]
reserved_peering_ranges = [google_compute_global_address.private_ip_address.name]
}
# ------------------------------------------------------------------------------
@@ -68,31 +68,31 @@ resource "google_service_networking_connection" "private_vpc_connection" {
module "mysql" {
# When using these modules in your own templates, you will need to use a Git URL with a ref attribute that pins you
# to a specific version of the modules, such as the following example:
# source = "git::git@github.com:gruntwork-io/terraform-google-sql.git//modules/cloud-sql?ref=v0.1.0"
# source = "github.com/gruntwork-io/terraform-google-sql.git//modules/cloud-sql?ref=v0.2.0"
source = "../../modules/cloud-sql"
project = "${var.project}"
region = "${var.region}"
name = "${local.instance_name}"
db_name = "${var.db_name}"
project = var.project
region = var.region
name = local.instance_name
db_name = var.db_name
engine = "${var.mysql_version}"
machine_type = "${var.machine_type}"
engine = var.mysql_version
machine_type = var.machine_type
# These together will construct the master_user privileges, i.e.
# 'master_user_name'@'master_user_host' IDENTIFIED BY 'master_user_password'.
# These should typically be set as the environment variable TF_VAR_master_user_password, etc.
# so you don't check these into source control."
master_user_password = "${var.master_user_password}"
master_user_password = var.master_user_password
master_user_name = "${var.master_user_name}"
master_user_name = var.master_user_name
master_user_host = "%"
# Pass the private network link to the module
private_network = "${google_compute_network.private_network.self_link}"
private_network = google_compute_network.private_network.self_link
# Wait for the vpc connection to complete
dependencies = ["${google_service_networking_connection.private_vpc_connection.network}"]
dependencies = [google_service_networking_connection.private_vpc_connection.network]
# Set auto-increment flags to test the
# feature during automated testing

View File

@@ -4,27 +4,27 @@
output "master_instance_name" {
description = "The name of the database instance"
value = "${module.mysql.master_instance_name}"
value = module.mysql.master_instance_name
}
output "master_ip_addresses" {
description = "All IP addresses of the instance as list of maps, see https://www.terraform.io/docs/providers/google/r/sql_database_instance.html#ip_address-0-ip_address"
value = "${module.mysql.master_ip_addresses}"
value = module.mysql.master_ip_addresses
}
output "master_private_ip" {
description = "The private IPv4 address of the master instance."
value = "${module.mysql.master_private_ip_address}"
value = module.mysql.master_private_ip_address
}
output "master_instance" {
description = "Self link to the master instance"
value = "${module.mysql.master_instance}"
value = module.mysql.master_instance
}
output "master_proxy_connection" {
description = "Instance path for connecting with Cloud SQL Proxy. Read more at https://cloud.google.com/sql/docs/mysql/sql-proxy"
value = "${module.mysql.master_proxy_connection}"
value = module.mysql.master_proxy_connection
}
# ------------------------------------------------------------------------------
@@ -33,10 +33,10 @@ output "master_proxy_connection" {
output "db_name" {
description = "Name of the default database"
value = "${module.mysql.db_name}"
value = module.mysql.db_name
}
output "db" {
description = "Self link to the default database"
value = "${module.mysql.db}"
value = module.mysql.db
}

View File

@@ -5,45 +5,55 @@
variable "project" {
description = "The project ID to host the database in."
type = string
}
variable "region" {
description = "The region to host the database in."
type = string
}
# Note, after a name db instance is used, it cannot be reused for up to one week.
variable "name_prefix" {
description = "The name prefix for the database instance. Will be appended with a random string. Use lowercase letters, numbers, and hyphens. Start with a letter."
type = string
}
variable "master_user_name" {
description = "The username part for the default user credentials, i.e. 'master_user_name'@'master_user_host' IDENTIFIED BY 'master_user_password'. This should typically be set as the environment variable TF_VAR_master_user_name so you don't check it into source control."
type = string
}
variable "master_user_password" {
description = "The password part for the default user credentials, i.e. 'master_user_name'@'master_user_host' IDENTIFIED BY 'master_user_password'. This should typically be set as the environment variable TF_VAR_master_user_password so you don't check it into source control."
type = string
}
# ---------------------------------------------------------------------------------------------------------------------
# OPTIONAL PARAMETERS
# Generally, these values won't need to be changed.
# ---------------------------------------------------------------------------------------------------------------------
variable "mysql_version" {
description = "The engine version of the database, e.g. `MYSQL_5_6` or `MYSQL_5_7`. See https://cloud.google.com/sql/docs/features for supported versions."
type = string
default = "MYSQL_5_7"
}
variable "machine_type" {
description = "The machine type to use, see https://cloud.google.com/sql/pricing for more details"
type = string
default = "db-f1-micro"
}
variable "db_name" {
description = "Name for the db"
type = string
default = "default"
}
variable "name_override" {
description = "You may optionally override the name_prefix + random string by specifying an override"
default = ""
type = string
default = null
}

View File

@@ -7,15 +7,15 @@
# ------------------------------------------------------------------------------
provider "google-beta" {
version = "~> 2.1.0"
region = "${var.region}"
project = "${var.project}"
version = "~> 2.7.0"
project = var.project
region = var.region
}
# Use Terraform 0.10.x so that we can take advantage of Terraform GCP functionality as a separate provider via
# https://github.com/terraform-providers/terraform-provider-google
terraform {
required_version = ">= 0.10.3"
# The modules used in this example have been updated with 0.12 syntax, which means the example is no longer
# compatible with any versions below 0.12.
required_version = ">= 0.12"
}
# ------------------------------------------------------------------------------
@@ -28,7 +28,7 @@ resource "random_id" "name" {
locals {
# If name_override is specified, use that - otherwise use the name_prefix with a random string
instance_name = "${length(var.name_override) == 0 ? format("%s-%s", var.name_prefix, random_id.name.hex) : var.name_override}"
instance_name = var.name_override == null ? format("%s-%s", var.name_prefix, random_id.name.hex) : var.name_override
}
# ------------------------------------------------------------------------------
@@ -38,24 +38,24 @@ locals {
module "mysql" {
# When using these modules in your own templates, you will need to use a Git URL with a ref attribute that pins you
# to a specific version of the modules, such as the following example:
# source = "git::git@github.com:gruntwork-io/terraform-google-sql.git//modules/cloud-sql?ref=v0.1.0"
# source = "github.com/gruntwork-io/terraform-google-sql.git//modules/cloud-sql?ref=v0.2.0"
source = "../../modules/cloud-sql"
project = "${var.project}"
region = "${var.region}"
name = "${local.instance_name}"
db_name = "${var.db_name}"
project = var.project
region = var.region
name = local.instance_name
db_name = var.db_name
engine = "${var.mysql_version}"
machine_type = "${var.machine_type}"
engine = var.mysql_version
machine_type = var.machine_type
# These together will construct the master_user privileges, i.e.
# 'master_user_name'@'master_user_host' IDENTIFIED BY 'master_user_password'.
# These should typically be set as the environment variable TF_VAR_master_user_password, etc.
# so you don't check these into source control."
master_user_password = "${var.master_user_password}"
master_user_password = var.master_user_password
master_user_name = "${var.master_user_name}"
master_user_name = var.master_user_name
master_user_host = "%"
# To make it easier to test this example, we are giving the servers public IP addresses and allowing inbound
@@ -65,7 +65,7 @@ module "mysql" {
# Default setting for this is 'false' in 'variables.tf'
# In the test cases, we're setting this to true, to test forced SSL.
require_ssl = "${var.require_ssl}"
require_ssl = var.require_ssl
authorized_networks = [
{

View File

@@ -4,27 +4,27 @@
output "master_instance_name" {
description = "The name of the database instance"
value = "${module.mysql.master_instance_name}"
value = module.mysql.master_instance_name
}
output "master_public_ip" {
description = "The public IPv4 address of the master instance."
value = "${module.mysql.master_public_ip_address}"
value = module.mysql.master_public_ip_address
}
output "master_ca_cert" {
value = "${module.mysql.master_ca_cert}"
value = module.mysql.master_ca_cert
description = "The CA Certificate used to connect to the SQL Instance via SSL"
}
output "master_instance" {
description = "Self link to the master instance"
value = "${module.mysql.master_instance}"
value = module.mysql.master_instance
}
output "master_proxy_connection" {
description = "Instance path for connecting with Cloud SQL Proxy. Read more at https://cloud.google.com/sql/docs/mysql/sql-proxy"
value = "${module.mysql.master_proxy_connection}"
value = module.mysql.master_proxy_connection
}
# ------------------------------------------------------------------------------
@@ -33,10 +33,10 @@ output "master_proxy_connection" {
output "db_name" {
description = "Name of the default database"
value = "${module.mysql.db_name}"
value = module.mysql.db_name
}
output "db" {
description = "Self link to the default database"
value = "${module.mysql.db}"
value = module.mysql.db
}

View File

@@ -5,52 +5,63 @@
variable "project" {
description = "The project ID to host the database in."
type = string
}
variable "region" {
description = "The region to host the database in."
type = string
}
# Note, after a name db instance is used, it cannot be reused for up to one week.
variable "name_prefix" {
description = "The name prefix for the database instance. Will be appended with a random string. Use lowercase letters, numbers, and hyphens. Start with a letter."
type = string
}
variable "master_user_name" {
description = "The username part for the default user credentials, i.e. 'master_user_name'@'master_user_host' IDENTIFIED BY 'master_user_password'. This should typically be set as the environment variable TF_VAR_master_user_name so you don't check it into source control."
type = string
}
variable "master_user_password" {
description = "The password part for the default user credentials, i.e. 'master_user_name'@'master_user_host' IDENTIFIED BY 'master_user_password'. This should typically be set as the environment variable TF_VAR_master_user_password so you don't check it into source control."
type = string
}
# ---------------------------------------------------------------------------------------------------------------------
# OPTIONAL PARAMETERS
# Generally, these values won't need to be changed.
# ---------------------------------------------------------------------------------------------------------------------
variable "mysql_version" {
description = "The engine version of the database, e.g. `MYSQL_5_6` or `MYSQL_5_7`. See https://cloud.google.com/sql/docs/features for supported versions."
type = string
default = "MYSQL_5_7"
}
variable "machine_type" {
description = "The machine type to use, see https://cloud.google.com/sql/pricing for more details"
type = string
default = "db-f1-micro"
}
variable "db_name" {
description = "Name for the db"
type = string
default = "default"
}
variable "name_override" {
description = "You may optionally override the name_prefix + random string by specifying an override"
default = ""
type = string
default = null
}
# When configuring a public IP instance, you should only allow secure connections
# For testing purposes, we're initially allowing unsecured connections.
variable "require_ssl" {
description = "True if the instance should require SSL/TLS for users connecting over IP. Note: SSL/TLS is needed to provide security when you connect to Cloud SQL using IP addresses. If you are connecting to your instance only by using the Cloud SQL Proxy or the Java Socket Library, you do not need to configure your instance to use SSL/TLS."
type = bool
default = false
}

View File

@@ -7,15 +7,15 @@
# ------------------------------------------------------------------------------
provider "google-beta" {
version = "~> 2.1.0"
region = "${var.region}"
project = "${var.project}"
version = "~> 2.7.0"
project = var.project
region = var.region
}
# Use Terraform 0.10.x so that we can take advantage of Terraform GCP functionality as a separate provider via
# https://github.com/terraform-providers/terraform-provider-google
terraform {
required_version = ">= 0.10.3"
# The modules used in this example have been updated with 0.12 syntax, which means the example is no longer
# compatible with any versions below 0.12.
required_version = ">= 0.12"
}
# ------------------------------------------------------------------------------
@@ -28,7 +28,7 @@ resource "random_id" "name" {
locals {
# If name_override is specified, use that - otherwise use the name_prefix with a random string
instance_name = "${length(var.name_override) == 0 ? format("%s-%s", var.name_prefix, random_id.name.hex) : var.name_override}"
instance_name = var.name_override == null ? format("%s-%s", var.name_prefix, random_id.name.hex) : var.name_override
private_network_name = "private-network-${random_id.name.hex}"
private_ip_name = "private-ip-${random_id.name.hex}"
}
@@ -40,18 +40,18 @@ locals {
module "mysql" {
# When using these modules in your own templates, you will need to use a Git URL with a ref attribute that pins you
# to a specific version of the modules, such as the following example:
# source = "git::git@github.com:gruntwork-io/terraform-google-sql.git//modules/cloud-sql?ref=v0.1.0"
# source = "github.com/gruntwork-io/terraform-google-sql.git//modules/cloud-sql?ref=v0.2.0"
source = "../../modules/cloud-sql"
project = "${var.project}"
region = "${var.region}"
name = "${local.instance_name}"
db_name = "${var.db_name}"
project = var.project
region = var.region
name = local.instance_name
db_name = var.db_name
engine = "${var.mysql_version}"
machine_type = "${var.machine_type}"
engine = var.mysql_version
machine_type = var.machine_type
master_zone = "${var.master_zone}"
master_zone = var.master_zone
# To make it easier to test this example, we are giving the servers public IP addresses and allowing inbound
# connections from anywhere. In real-world usage, your servers should live in private subnets, only have private IP
@@ -67,19 +67,19 @@ module "mysql" {
# Indicate that we want to create a failover replica
enable_failover_replica = true
mysql_failover_replica_zone = "${var.failover_replica_zone}"
mysql_failover_replica_zone = var.failover_replica_zone
# Indicate we want read replicas to be created
num_read_replicas = "${var.num_read_replicas}"
read_replica_zones = ["${var.read_replica_zones}"]
num_read_replicas = var.num_read_replicas
read_replica_zones = var.read_replica_zones
# These together will construct the master_user privileges, i.e.
# 'master_user_name'@'master_user_host' IDENTIFIED BY 'master_user_password'.
# These should typically be set as the environment variable TF_VAR_master_user_password, etc.
# so you don't check these into source control."
master_user_password = "${var.master_user_password}"
master_user_password = var.master_user_password
master_user_name = "${var.master_user_name}"
master_user_name = var.master_user_name
master_user_host = "%"
# Set auto-increment flags to test the

View File

@@ -4,22 +4,22 @@
output "master_instance_name" {
description = "The name of the database instance"
value = "${module.mysql.master_instance_name}"
value = module.mysql.master_instance_name
}
output "master_public_ip" {
description = "The public IPv4 address of the master instance."
value = "${module.mysql.master_public_ip_address}"
value = module.mysql.master_public_ip_address
}
output "master_instance" {
description = "Self link to the master instance"
value = "${module.mysql.master_instance}"
value = module.mysql.master_instance
}
output "master_proxy_connection" {
description = "Instance path for connecting with Cloud SQL Proxy. Read more at https://cloud.google.com/sql/docs/mysql/sql-proxy"
value = "${module.mysql.master_proxy_connection}"
value = module.mysql.master_proxy_connection
}
# ------------------------------------------------------------------------------
@@ -28,12 +28,12 @@ output "master_proxy_connection" {
output "db_name" {
description = "Name of the default database"
value = "${module.mysql.db_name}"
value = module.mysql.db_name
}
output "db" {
description = "Self link to the default database"
value = "${module.mysql.db}"
value = module.mysql.db
}
# ------------------------------------------------------------------------------
@@ -42,22 +42,22 @@ output "db" {
output "failover_instance" {
description = "Self link to the failover instance"
value = "${module.mysql.failover_instance}"
value = module.mysql.failover_instance
}
output "failover_instance_name" {
description = "The name of the failover database instance"
value = "${module.mysql.failover_instance_name}"
value = module.mysql.failover_instance_name
}
output "failover_public_ip" {
description = "The public IPv4 address of the failover instance"
value = "${module.mysql.failover_public_ip_address}"
value = module.mysql.failover_public_ip_address
}
output "failover_proxy_connection" {
description = "Failover instance path for connecting with Cloud SQL Proxy. Read more at https://cloud.google.com/sql/docs/mysql/sql-proxy"
value = "${module.mysql.failover_proxy_connection}"
value = module.mysql.failover_proxy_connection
}
# ------------------------------------------------------------------------------
@@ -66,22 +66,22 @@ output "failover_proxy_connection" {
output "read_replica_instance_names" {
description = "List of names for the read replica instances"
value = ["${module.mysql.read_replica_instance_names}"]
value = module.mysql.read_replica_instance_names
}
output "read_replica_public_ips" {
description = "List of public IPv4 addresses of the read replica instances"
value = ["${module.mysql.read_replica_public_ip_addresses}"]
value = module.mysql.read_replica_public_ip_addresses
}
output "read_replica_instances" {
description = "List of self links to the read replica instances"
value = ["${module.mysql.read_replica_instances}"]
value = module.mysql.read_replica_instances
}
output "read_replica_proxy_connections" {
description = "List of read replica instance paths for connecting with Cloud SQL Proxy. Read more at https://cloud.google.com/sql/docs/mysql/sql-proxy"
value = ["${module.mysql.read_replica_proxy_connections}"]
value = module.mysql.read_replica_proxy_connections
}
# Although we don't use the values, this output highlights the JSON encoded output we use in certain
@@ -89,5 +89,5 @@ output "read_replica_proxy_connections" {
# See https://github.com/hashicorp/terraform/issues/17048
output "read_replica_server_ca_certs" {
description = "JSON encoded list of CA Certificates used to connect to the read replica instances via SSL"
value = "${module.mysql.read_replica_server_ca_certs}"
value = module.mysql.read_replica_server_ca_certs
}

View File

@@ -5,27 +5,32 @@
variable "project" {
description = "The project ID to host the database in."
type = string
}
variable "region" {
description = "The region to host the database in (e.g. 'us-central1')."
type = string
}
variable "master_zone" {
description = "The preferred zone for the master instance (e.g. 'us-central1-a'). Must be different than 'failover_replica_zone'."
type = string
}
variable "failover_replica_zone" {
description = "The preferred zone for the failover instance (e.g. 'us-central1-b'). Must be different than 'master_zone'."
type = string
}
variable "num_read_replicas" {
description = "The number of read replicas to create. Cloud SQL will replicate all data from the master to these replicas, which you can use to horizontally scale read traffic."
type = number
}
variable "read_replica_zones" {
description = "A list of compute zones where read replicas should be created. List size should match 'num_read_replicas'"
type = "list"
type = list(string)
# Example:
# default = ["us-central1-b", "us-central1-c"]
@@ -34,36 +39,44 @@ variable "read_replica_zones" {
# Note, after a name db instance is used, it cannot be reused for up to one week.
variable "name_prefix" {
description = "The name prefix for the database instance. Will be appended with a random string. Use lowercase letters, numbers, and hyphens. Start with a letter."
type = string
}
variable "master_user_name" {
description = "The username part for the default user credentials, i.e. 'master_user_name'@'master_user_host' IDENTIFIED BY 'master_user_password'. This should typically be set as the environment variable TF_VAR_master_user_name so you don't check it into source control."
type = string
}
variable "master_user_password" {
description = "The password part for the default user credentials, i.e. 'master_user_name'@'master_user_host' IDENTIFIED BY 'master_user_password'. This should typically be set as the environment variable TF_VAR_master_user_password so you don't check it into source control."
type = string
}
# ---------------------------------------------------------------------------------------------------------------------
# OPTIONAL PARAMETERS
# Generally, these values won't need to be changed.
# ---------------------------------------------------------------------------------------------------------------------
variable "mysql_version" {
description = "The engine version of the database, e.g. `MYSQL_5_6` or `MYSQL_5_7`. See https://cloud.google.com/sql/docs/features for supported versions."
type = string
default = "MYSQL_5_7"
}
variable "machine_type" {
description = "The machine type to use, see https://cloud.google.com/sql/pricing for more details"
type = string
default = "db-f1-micro"
}
variable "db_name" {
description = "Name for the db"
type = string
default = "default"
}
variable "name_override" {
description = "You may optionally override the name_prefix + random string by specifying an override"
default = ""
type = string
default = null
}

View File

@@ -7,15 +7,15 @@
# ------------------------------------------------------------------------------
provider "google-beta" {
version = "~> 2.1.0"
region = "${var.region}"
project = "${var.project}"
version = "~> 2.7.0"
project = var.project
region = var.region
}
# Use Terraform 0.10.x so that we can take advantage of Terraform GCP functionality as a separate provider via
# https://github.com/terraform-providers/terraform-provider-google
terraform {
required_version = ">= 0.10.3"
# The modules used in this example have been updated with 0.12 syntax, which means the example is no longer
# compatible with any versions below 0.12.
required_version = ">= 0.12"
}
# ------------------------------------------------------------------------------
@@ -28,7 +28,7 @@ resource "random_id" "name" {
locals {
# If name_override is specified, use that - otherwise use the name_prefix with a random string
instance_name = "${length(var.name_override) == 0 ? format("%s-%s", var.name_prefix, random_id.name.hex) : var.name_override}"
instance_name = var.name_override == null ? format("%s-%s", var.name_prefix, random_id.name.hex) : var.name_override
private_network_name = "private-network-${random_id.name.hex}"
private_ip_name = "private-ip-${random_id.name.hex}"
}
@@ -40,25 +40,25 @@ locals {
# Simple network, auto-creates subnetworks
resource "google_compute_network" "private_network" {
provider = "google-beta"
name = "${local.private_network_name}"
name = local.private_network_name
}
# Reserve global internal address range for the peering
resource "google_compute_global_address" "private_ip_address" {
provider = "google-beta"
name = "${local.private_ip_name}"
name = local.private_ip_name
purpose = "VPC_PEERING"
address_type = "INTERNAL"
prefix_length = 16
network = "${google_compute_network.private_network.self_link}"
network = google_compute_network.private_network.self_link
}
# Establish VPC network peering connection using the reserved address range
resource "google_service_networking_connection" "private_vpc_connection" {
provider = "google-beta"
network = "${google_compute_network.private_network.self_link}"
network = google_compute_network.private_network.self_link
service = "servicenetworking.googleapis.com"
reserved_peering_ranges = ["${google_compute_global_address.private_ip_address.name}"]
reserved_peering_ranges = [google_compute_global_address.private_ip_address.name]
}
# ------------------------------------------------------------------------------
@@ -68,31 +68,31 @@ resource "google_service_networking_connection" "private_vpc_connection" {
module "postgres" {
# When using these modules in your own templates, you will need to use a Git URL with a ref attribute that pins you
# to a specific version of the modules, such as the following example:
# source = "git::git@github.com:gruntwork-io/terraform-google-sql.git//modules/cloud-sql?ref=v0.1.0"
# source = "github.com/gruntwork-io/terraform-google-sql.git//modules/cloud-sql?ref=v0.2.0"
source = "../../modules/cloud-sql"
project = "${var.project}"
region = "${var.region}"
name = "${local.instance_name}"
db_name = "${var.db_name}"
project = var.project
region = var.region
name = local.instance_name
db_name = var.db_name
engine = "${var.postgres_version}"
machine_type = "${var.machine_type}"
engine = var.postgres_version
machine_type = var.machine_type
# These together will construct the master_user privileges, i.e.
# 'master_user_name'@'master_user_host' IDENTIFIED BY 'master_user_password'.
# These should typically be set as the environment variable TF_VAR_master_user_password, etc.
# so you don't check these into source control."
master_user_password = "${var.master_user_password}"
master_user_password = var.master_user_password
master_user_name = "${var.master_user_name}"
master_user_name = var.master_user_name
master_user_host = "%"
# Pass the private network link to the module
private_network = "${google_compute_network.private_network.self_link}"
private_network = google_compute_network.private_network.self_link
# Wait for the vpc connection to complete
dependencies = ["${google_service_networking_connection.private_vpc_connection.network}"]
dependencies = [google_service_networking_connection.private_vpc_connection.network]
custom_labels = {
test-id = "postgres-private-ip-example"

View File

@@ -4,27 +4,27 @@
output "master_instance_name" {
description = "The name of the database instance"
value = "${module.postgres.master_instance_name}"
value = module.postgres.master_instance_name
}
output "master_ip_addresses" {
description = "All IP addresses of the instance as list of maps, see https://www.terraform.io/docs/providers/google/r/sql_database_instance.html#ip_address-0-ip_address"
value = "${module.postgres.master_ip_addresses}"
value = module.postgres.master_ip_addresses
}
output "master_private_ip" {
description = "The private IPv4 address of the master instance"
value = "${module.postgres.master_private_ip_address}"
value = module.postgres.master_private_ip_address
}
output "master_instance" {
description = "Self link to the master instance"
value = "${module.postgres.master_instance}"
value = module.postgres.master_instance
}
output "master_proxy_connection" {
description = "Instance path for connecting with Cloud SQL Proxy. Read more at https://cloud.google.com/sql/docs/mysql/sql-proxy"
value = "${module.postgres.master_proxy_connection}"
value = module.postgres.master_proxy_connection
}
# ------------------------------------------------------------------------------
@@ -33,10 +33,10 @@ output "master_proxy_connection" {
output "db_name" {
description = "Name of the default database"
value = "${module.postgres.db_name}"
value = module.postgres.db_name
}
output "db" {
description = "Self link to the default database"
value = "${module.postgres.db}"
value = module.postgres.db
}

View File

@@ -5,45 +5,55 @@
variable "project" {
description = "The project ID to host the database in."
type = string
}
variable "region" {
description = "The region to host the database in."
type = string
}
# Note, after a name db instance is used, it cannot be reused for up to one week.
variable "name_prefix" {
description = "The name prefix for the database instance. Will be appended with a random string. Use lowercase letters, numbers, and hyphens. Start with a letter."
type = string
}
variable "master_user_name" {
description = "The username part for the default user credentials, i.e. 'master_user_name'@'master_user_host' IDENTIFIED BY 'master_user_password'. This should typically be set as the environment variable TF_VAR_master_user_name so you don't check it into source control."
type = string
}
variable "master_user_password" {
description = "The password part for the default user credentials, i.e. 'master_user_name'@'master_user_host' IDENTIFIED BY 'master_user_password'. This should typically be set as the environment variable TF_VAR_master_user_password so you don't check it into source control."
type = string
}
# ---------------------------------------------------------------------------------------------------------------------
# OPTIONAL PARAMETERS
# Generally, these values won't need to be changed.
# ---------------------------------------------------------------------------------------------------------------------
variable "postgres_version" {
description = "The engine version of the database, e.g. `POSTGRES_9_6`. See https://cloud.google.com/sql/docs/db-versions for supported versions."
type = string
default = "POSTGRES_9_6"
}
variable "machine_type" {
description = "The machine type to use, see https://cloud.google.com/sql/pricing for more details"
type = string
default = "db-f1-micro"
}
variable "db_name" {
description = "Name for the db"
type = string
default = "default"
}
variable "name_override" {
description = "You may optionally override the name_prefix + random string by specifying an override"
default = ""
type = string
default = null
}

View File

@@ -7,15 +7,15 @@
# ------------------------------------------------------------------------------
provider "google-beta" {
version = "~> 2.1.0"
region = "${var.region}"
project = "${var.project}"
version = "~> 2.7.0"
project = var.project
region = var.region
}
# Use Terraform 0.10.x so that we can take advantage of Terraform GCP functionality as a separate provider via
# https://github.com/terraform-providers/terraform-provider-google
terraform {
required_version = ">= 0.10.3"
# The modules used in this example have been updated with 0.12 syntax, which means the example is no longer
# compatible with any versions below 0.12.
required_version = ">= 0.12"
}
# ------------------------------------------------------------------------------
@@ -28,7 +28,7 @@ resource "random_id" "name" {
locals {
# If name_override is specified, use that - otherwise use the name_prefix with a random string
instance_name = "${length(var.name_override) == 0 ? format("%s-%s", var.name_prefix, random_id.name.hex) : var.name_override}"
instance_name = var.name_override == null ? format("%s-%s", var.name_prefix, random_id.name.hex) : var.name_override
}
# ------------------------------------------------------------------------------
@@ -38,25 +38,23 @@ locals {
module "postgres" {
# When using these modules in your own templates, you will need to use a Git URL with a ref attribute that pins you
# to a specific version of the modules, such as the following example:
# source = "git::git@github.com:gruntwork-io/terraform-google-sql.git//modules/cloud-sql?ref=v0.1.0"
# source = "github.com/gruntwork-io/terraform-google-sql.git//modules/cloud-sql?ref=v0.2.0"
source = "../../modules/cloud-sql"
project = "${var.project}"
region = "${var.region}"
name = "${local.instance_name}"
db_name = "${var.db_name}"
project = var.project
region = var.region
name = local.instance_name
db_name = var.db_name
engine = "${var.postgres_version}"
machine_type = "${var.machine_type}"
engine = var.postgres_version
machine_type = var.machine_type
# These together will construct the master_user privileges, i.e.
# 'master_user_name'@'master_user_host' IDENTIFIED BY 'master_user_password'.
# 'master_user_name' IDENTIFIED BY 'master_user_password'.
# These should typically be set as the environment variable TF_VAR_master_user_password, etc.
# so you don't check these into source control."
master_user_password = "${var.master_user_password}"
master_user_name = "${var.master_user_name}"
master_user_host = "%"
master_user_password = var.master_user_password
master_user_name = var.master_user_name
# To make it easier to test this example, we are giving the servers public IP addresses and allowing inbound
# connections from anywhere. In real-world usage, your servers should live in private subnets, only have private IP
@@ -65,7 +63,7 @@ module "postgres" {
# Default setting for this is 'false' in 'variables.tf'
# In the test cases, we're setting this to true, to test forced SSL.
require_ssl = "${var.require_ssl}"
require_ssl = var.require_ssl
authorized_networks = [
{

View File

@@ -4,27 +4,27 @@
output "master_instance_name" {
description = "The name of the database instance"
value = "${module.postgres.master_instance_name}"
value = module.postgres.master_instance_name
}
output "master_public_ip" {
description = "The public IPv4 address of the master instance"
value = "${module.postgres.master_public_ip_address}"
value = module.postgres.master_public_ip_address
}
output "master_ca_cert" {
description = "The CA Certificate used to connect to the SQL Instance via SSL"
value = "${module.postgres.master_ca_cert}"
value = module.postgres.master_ca_cert
}
output "master_instance" {
description = "Self link to the master instance"
value = "${module.postgres.master_instance}"
value = module.postgres.master_instance
}
output "master_proxy_connection" {
description = "Instance path for connecting with Cloud SQL Proxy. Read more at https://cloud.google.com/sql/docs/mysql/sql-proxy"
value = "${module.postgres.master_proxy_connection}"
value = module.postgres.master_proxy_connection
}
# ------------------------------------------------------------------------------
@@ -33,10 +33,10 @@ output "master_proxy_connection" {
output "db_name" {
description = "Name of the default database"
value = "${module.postgres.db_name}"
value = module.postgres.db_name
}
output "db" {
description = "Self link to the default database"
value = "${module.postgres.db}"
value = module.postgres.db
}

View File

@@ -5,52 +5,63 @@
variable "project" {
description = "The project ID to host the database in."
type = string
}
variable "region" {
description = "The region to host the database in."
type = string
}
# Note, after a name db instance is used, it cannot be reused for up to one week.
variable "name_prefix" {
description = "The name prefix for the database instance. Will be appended with a random string. Use lowercase letters, numbers, and hyphens. Start with a letter."
type = string
}
variable "master_user_name" {
description = "The username part for the default user credentials, i.e. 'master_user_name'@'master_user_host' IDENTIFIED BY 'master_user_password'. This should typically be set as the environment variable TF_VAR_master_user_name so you don't check it into source control."
type = string
}
variable "master_user_password" {
description = "The password part for the default user credentials, i.e. 'master_user_name'@'master_user_host' IDENTIFIED BY 'master_user_password'. This should typically be set as the environment variable TF_VAR_master_user_password so you don't check it into source control."
type = string
}
# ---------------------------------------------------------------------------------------------------------------------
# OPTIONAL PARAMETERS
# Generally, these values won't need to be changed.
# ---------------------------------------------------------------------------------------------------------------------
variable "postgres_version" {
description = "The engine version of the database, e.g. `POSTGRES_9_6`. See https://cloud.google.com/sql/docs/features for supported versions."
type = string
default = "POSTGRES_9_6"
}
variable "machine_type" {
description = "The machine type to use, see https://cloud.google.com/sql/pricing for more details"
type = string
default = "db-f1-micro"
}
variable "db_name" {
description = "Name for the db"
type = string
default = "default"
}
variable "name_override" {
description = "You may optionally override the name_prefix + random string by specifying an override"
default = ""
type = string
default = null
}
# When configuring a public IP instance, you should only allow secure connections
# For testing purposes, we're initially allowing unsecured connections.
variable "require_ssl" {
description = "True if the instance should require SSL/TLS for users connecting over IP. Note: SSL/TLS is needed to provide security when you connect to Cloud SQL using IP addresses. If you are connecting to your instance only by using the Cloud SQL Proxy or the Java Socket Library, you do not need to configure your instance to use SSL/TLS."
type = bool
default = false
}

View File

@@ -7,15 +7,15 @@
# ------------------------------------------------------------------------------
provider "google-beta" {
version = "~> 2.1.0"
region = "${var.region}"
project = "${var.project}"
version = "~> 2.7.0"
project = var.project
region = var.region
}
# Use Terraform 0.10.x so that we can take advantage of Terraform GCP functionality as a separate provider via
# https://github.com/terraform-providers/terraform-provider-google
terraform {
required_version = ">= 0.10.3"
# The modules used in this example have been updated with 0.12 syntax, which means the example is no longer
# compatible with any versions below 0.12.
required_version = ">= 0.12"
}
# ------------------------------------------------------------------------------
@@ -28,7 +28,7 @@ resource "random_id" "name" {
locals {
# If name_override is specified, use that - otherwise use the name_prefix with a random string
instance_name = "${length(var.name_override) == 0 ? format("%s-%s", var.name_prefix, random_id.name.hex) : var.name_override}"
instance_name = var.name_override == null ? format("%s-%s", var.name_prefix, random_id.name.hex) : var.name_override
private_network_name = "private-network-${random_id.name.hex}"
private_ip_name = "private-ip-${random_id.name.hex}"
}
@@ -40,18 +40,18 @@ locals {
module "postgres" {
# When using these modules in your own templates, you will need to use a Git URL with a ref attribute that pins you
# to a specific version of the modules, such as the following example:
# source = "git::git@github.com:gruntwork-io/terraform-google-sql.git//modules/cloud-sql?ref=v0.1.0"
# source = "github.com/gruntwork-io/terraform-google-sql.git//modules/cloud-sql?ref=v0.2.0"
source = "../../modules/cloud-sql"
project = "${var.project}"
region = "${var.region}"
name = "${local.instance_name}"
db_name = "${var.db_name}"
project = var.project
region = var.region
name = local.instance_name
db_name = var.db_name
engine = "${var.postgres_version}"
machine_type = "${var.machine_type}"
engine = var.postgres_version
machine_type = var.machine_type
master_zone = "${var.master_zone}"
master_zone = var.master_zone
# To make it easier to test this example, we are giving the servers public IP addresses and allowing inbound
# connections from anywhere. In real-world usage, your servers should live in private subnets, only have private IP
@@ -69,17 +69,15 @@ module "postgres" {
enable_failover_replica = true
# Indicate we want read replicas to be created
num_read_replicas = "${var.num_read_replicas}"
read_replica_zones = ["${var.read_replica_zones}"]
num_read_replicas = var.num_read_replicas
read_replica_zones = var.read_replica_zones
# These together will construct the master_user privileges, i.e.
# 'master_user_name'@'master_user_host' IDENTIFIED BY 'master_user_password'.
# 'master_user_name' IDENTIFIED BY 'master_user_password'.
# These should typically be set as the environment variable TF_VAR_master_user_password, etc.
# so you don't check these into source control."
master_user_password = "${var.master_user_password}"
master_user_name = "${var.master_user_name}"
master_user_host = "%"
master_user_password = var.master_user_password
master_user_name = var.master_user_name
custom_labels = {
test-id = "postgres-replicas-example"

View File

@@ -4,22 +4,22 @@
output "master_instance_name" {
description = "The name of the database instance"
value = "${module.postgres.master_instance_name}"
value = module.postgres.master_instance_name
}
output "master_public_ip" {
description = "The public IPv4 address of the master instance"
value = "${module.postgres.master_public_ip_address}"
value = module.postgres.master_public_ip_address
}
output "master_instance" {
description = "Self link to the master instance"
value = "${module.postgres.master_instance}"
value = module.postgres.master_instance
}
output "master_proxy_connection" {
description = "Instance path for connecting with Cloud SQL Proxy. Read more at https://cloud.google.com/sql/docs/mysql/sql-proxy"
value = "${module.postgres.master_proxy_connection}"
value = module.postgres.master_proxy_connection
}
# ------------------------------------------------------------------------------
@@ -28,12 +28,12 @@ output "master_proxy_connection" {
output "db_name" {
description = "Name of the default database"
value = "${module.postgres.db_name}"
value = module.postgres.db_name
}
output "db" {
description = "Self link to the default database"
value = "${module.postgres.db}"
value = module.postgres.db
}
# ------------------------------------------------------------------------------
@@ -42,22 +42,22 @@ output "db" {
output "read_replica_instance_names" {
description = "List of names for the read replica instances"
value = ["${module.postgres.read_replica_instance_names}"]
value = module.postgres.read_replica_instance_names
}
output "read_replica_public_ips" {
description = "List of public IPv4 addresses of the read replica instances"
value = ["${module.postgres.read_replica_public_ip_addresses}"]
value = module.postgres.read_replica_public_ip_addresses
}
output "read_replica_instances" {
description = "List of self links to the read replica instances"
value = ["${module.postgres.read_replica_instances}"]
value = module.postgres.read_replica_instances
}
output "read_replica_proxy_connections" {
description = "List of read replica instance paths for connecting with Cloud SQL Proxy. Read more at https://cloud.google.com/sql/docs/mysql/sql-proxy"
value = ["${module.postgres.read_replica_proxy_connections}"]
value = module.postgres.read_replica_proxy_connections
}
# Although we don't use the values, this output highlights the JSON encoded output we use in certain
@@ -65,5 +65,5 @@ output "read_replica_proxy_connections" {
# See https://github.com/hashicorp/terraform/issues/17048
output "read_replica_server_ca_certs" {
description = "JSON encoded list of CA Certificates used to connect to the read replica instances via SSL"
value = "${module.postgres.read_replica_server_ca_certs}"
value = module.postgres.read_replica_server_ca_certs
}

View File

@@ -5,27 +5,32 @@
variable "project" {
description = "The project ID to host the database in."
type = string
}
variable "region" {
description = "The region to host the database in (e.g. 'us-central1')."
type = string
}
variable "master_zone" {
description = "The preferred zone for the master instance (e.g. 'us-central1-a'). Must be different than 'failover_replica_zone'."
type = string
}
variable "failover_replica_zone" {
description = "The preferred zone for the failover instance (e.g. 'us-central1-b'). Must be different than 'master_zone'."
type = string
}
variable "num_read_replicas" {
description = "The number of read replicas to create. Cloud SQL will replicate all data from the master to these replicas, which you can use to horizontally scale read traffic."
type = number
}
variable "read_replica_zones" {
description = "A list of compute zones where read replicas should be created. List size should match 'num_read_replicas'"
type = "list"
type = list(string)
# Example:
# default = ["us-central1-b", "us-central1-c"]
@@ -34,36 +39,44 @@ variable "read_replica_zones" {
# Note, after a name db instance is used, it cannot be reused for up to one week.
variable "name_prefix" {
description = "The name prefix for the database instance. Will be appended with a random string. Use lowercase letters, numbers, and hyphens. Start with a letter."
type = string
}
variable "master_user_name" {
description = "The username part for the default user credentials, i.e. 'master_user_name'@'master_user_host' IDENTIFIED BY 'master_user_password'. This should typically be set as the environment variable TF_VAR_master_user_name so you don't check it into source control."
type = string
}
variable "master_user_password" {
description = "The password part for the default user credentials, i.e. 'master_user_name'@'master_user_host' IDENTIFIED BY 'master_user_password'. This should typically be set as the environment variable TF_VAR_master_user_password so you don't check it into source control."
type = string
}
# ---------------------------------------------------------------------------------------------------------------------
# OPTIONAL PARAMETERS
# Generally, these values won't need to be changed.
# ---------------------------------------------------------------------------------------------------------------------
variable "postgres_version" {
description = "The engine version of the database, e.g. `POSTGRES_9_6`. See https://cloud.google.com/sql/docs/features for supported versions."
type = string
default = "POSTGRES_9_6"
}
variable "machine_type" {
description = "The machine type to use, see https://cloud.google.com/sql/pricing for more details"
type = string
default = "db-f1-micro"
}
variable "db_name" {
description = "Name for the db"
type = string
default = "default"
}
variable "name_override" {
description = "You may optionally override the name_prefix + random string by specifying an override"
default = ""
type = string
default = null
}

46
main.tf
View File

@@ -7,15 +7,15 @@
# ------------------------------------------------------------------------------
provider "google-beta" {
version = "~> 2.1.0"
region = "${var.region}"
project = "${var.project}"
version = "~> 2.7.0"
project = var.project
region = var.region
}
# Use Terraform 0.10.x so that we can take advantage of Terraform GCP functionality as a separate provider via
# https://github.com/terraform-providers/terraform-provider-google
terraform {
required_version = ">= 0.10.3"
# The modules used in this example have been updated with 0.12 syntax, which means the example is no longer
# compatible with any versions below 0.12.
required_version = ">= 0.12"
}
# ------------------------------------------------------------------------------
@@ -28,7 +28,7 @@ resource "random_id" "name" {
locals {
# If name_override is specified, use that - otherwise use the name_prefix with a random string
instance_name = "${length(var.name_override) == 0 ? format("%s-%s", var.name_prefix, random_id.name.hex) : var.name_override}"
instance_name = length(var.name_override) == 0 ? format("%s-%s", var.name_prefix, random_id.name.hex) : var.name_override
private_network_name = "private-network-${random_id.name.hex}"
private_ip_name = "private-ip-${random_id.name.hex}"
}
@@ -40,25 +40,25 @@ locals {
# Simple network, auto-creates subnetworks
resource "google_compute_network" "private_network" {
provider = "google-beta"
name = "${local.private_network_name}"
name = local.private_network_name
}
# Reserve global internal address range for the peering
resource "google_compute_global_address" "private_ip_address" {
provider = "google-beta"
name = "${local.private_ip_name}"
name = local.private_ip_name
purpose = "VPC_PEERING"
address_type = "INTERNAL"
prefix_length = 16
network = "${google_compute_network.private_network.self_link}"
network = google_compute_network.private_network.self_link
}
# Establish VPC network peering connection using the reserved address range
resource "google_service_networking_connection" "private_vpc_connection" {
provider = "google-beta"
network = "${google_compute_network.private_network.self_link}"
network = google_compute_network.private_network.self_link
service = "servicenetworking.googleapis.com"
reserved_peering_ranges = ["${google_compute_global_address.private_ip_address.name}"]
reserved_peering_ranges = [google_compute_global_address.private_ip_address.name]
}
# ------------------------------------------------------------------------------
@@ -68,31 +68,31 @@ resource "google_service_networking_connection" "private_vpc_connection" {
module "postgres" {
# When using these modules in your own templates, you will need to use a Git URL with a ref attribute that pins you
# to a specific version of the modules, such as the following example:
# source = "git::git@github.com:gruntwork-io/terraform-google-sql.git//modules/cloud-sql?ref=v0.1.0"
# source = "github.com/gruntwork-io/terraform-google-sql.git//modules/cloud-sql?ref=v0.2.0"
source = "./modules/cloud-sql"
project = "${var.project}"
region = "${var.region}"
name = "${local.instance_name}"
db_name = "${var.db_name}"
project = var.project
region = var.region
name = local.instance_name
db_name = var.db_name
engine = "${var.postgres_version}"
machine_type = "${var.machine_type}"
engine = var.postgres_version
machine_type = var.machine_type
# These together will construct the master_user privileges, i.e.
# 'master_user_name'@'master_user_host' IDENTIFIED BY 'master_user_password'.
# These should typically be set as the environment variable TF_VAR_master_user_password, etc.
# so you don't check these into source control."
master_user_password = "${var.master_user_password}"
master_user_password = var.master_user_password
master_user_name = "${var.master_user_name}"
master_user_name = var.master_user_name
master_user_host = "%"
# Pass the private network link to the module
private_network = "${google_compute_network.private_network.self_link}"
private_network = google_compute_network.private_network.self_link
# Wait for the vpc connection to complete
wait_for = "${google_service_networking_connection.private_vpc_connection.network}"
dependencies = [google_service_networking_connection.private_vpc_connection.network]
custom_labels = {
test-id = "postgres-private-ip-example"

View File

@@ -8,14 +8,14 @@
locals {
# Replica proxy connection info
failover_proxy_connection = "${join("",data.template_file.failover_proxy_connection.*.rendered)}"
failover_proxy_connection = join("", data.template_file.failover_proxy_connection.*.rendered)
# Replica certificate info
failover_certificate = "${join("",data.template_file.failover_certificate.*.rendered)}"
failover_certificate_common_name = "${join("",data.template_file.failover_certificate_common_name.*.rendered)}"
failover_certificate_create_time = "${join("",data.template_file.failover_certificate_create_time.*.rendered)}"
failover_certificate_expiration_time = "${join("",data.template_file.failover_certificate_expiration_time.*.rendered)}"
failover_certificate_sha1_fingerprint = "${join("",data.template_file.failover_certificate_sha1_fingerprint.*.rendered)}"
failover_certificate = join("", data.template_file.failover_certificate.*.rendered)
failover_certificate_common_name = join("", data.template_file.failover_certificate_common_name.*.rendered)
failover_certificate_create_time = join("", data.template_file.failover_certificate_create_time.*.rendered)
failover_certificate_expiration_time = join("", data.template_file.failover_certificate_expiration_time.*.rendered)
failover_certificate_sha1_fingerprint = join("", data.template_file.failover_certificate_sha1_fingerprint.*.rendered)
}
# ------------------------------------------------------------------------------
@@ -23,7 +23,7 @@ locals {
# ------------------------------------------------------------------------------
data "template_file" "failover_proxy_connection" {
count = "${local.actual_failover_replica_count}"
count = local.actual_failover_replica_count
template = "${var.project}:${var.region}:${google_sql_database_instance.failover_replica.0.name}"
}
@@ -36,28 +36,28 @@ data "template_file" "failover_proxy_connection" {
# ------------------------------------------------------------------------------
data "template_file" "failover_certificate" {
count = "${local.actual_failover_replica_count}"
template = "${google_sql_database_instance.failover_replica.0.server_ca_cert.0.cert}"
count = local.actual_failover_replica_count
template = google_sql_database_instance.failover_replica.0.server_ca_cert.0.cert
}
data "template_file" "failover_certificate_common_name" {
count = "${local.actual_failover_replica_count}"
template = "${google_sql_database_instance.failover_replica.0.server_ca_cert.0.common_name}"
count = local.actual_failover_replica_count
template = google_sql_database_instance.failover_replica.0.server_ca_cert.0.common_name
}
data "template_file" "failover_certificate_create_time" {
count = "${local.actual_failover_replica_count}"
template = "${google_sql_database_instance.failover_replica.0.server_ca_cert.0.create_time}"
count = local.actual_failover_replica_count
template = google_sql_database_instance.failover_replica.0.server_ca_cert.0.create_time
}
data "template_file" "failover_certificate_expiration_time" {
count = "${local.actual_failover_replica_count}"
template = "${google_sql_database_instance.failover_replica.0.server_ca_cert.0.expiration_time}"
count = local.actual_failover_replica_count
template = google_sql_database_instance.failover_replica.0.server_ca_cert.0.expiration_time
}
data "template_file" "failover_certificate_sha1_fingerprint" {
count = "${local.actual_failover_replica_count}"
template = "${google_sql_database_instance.failover_replica.0.server_ca_cert.0.sha1_fingerprint}"
count = local.actual_failover_replica_count
template = google_sql_database_instance.failover_replica.0.server_ca_cert.0.sha1_fingerprint
}
# ------------------------------------------------------------------------------
@@ -65,6 +65,6 @@ data "template_file" "failover_certificate_sha1_fingerprint" {
# ------------------------------------------------------------------------------
data "template_file" "read_replica_proxy_connection" {
count = "${var.num_read_replicas}"
count = var.num_read_replicas
template = "${var.project}:${var.region}:${google_sql_database_instance.read_replica.*.name[count.index]}"
}

View File

@@ -13,13 +13,13 @@
locals {
# Determine the engine type
is_postgres = "${replace(var.engine, "POSTGRES", "") != var.engine}"
is_mysql = "${replace(var.engine, "MYSQL", "") != var.engine}"
is_postgres = replace(var.engine, "POSTGRES", "") != var.engine
is_mysql = replace(var.engine, "MYSQL", "") != var.engine
# Calculate actuals, so we get expected behavior for each engine
actual_binary_log_enabled = "${local.is_postgres ? false : var.mysql_binary_log_enabled}"
actual_availability_type = "${local.is_postgres && var.enable_failover_replica ? "REGIONAL" : "ZONAL"}"
actual_failover_replica_count = "${local.is_postgres ? 0 : var.enable_failover_replica ? 1 : 0}"
actual_binary_log_enabled = local.is_postgres ? false : var.mysql_binary_log_enabled
actual_availability_type = local.is_postgres && var.enable_failover_replica ? "REGIONAL" : "ZONAL"
actual_failover_replica_count = local.is_postgres ? 0 : var.enable_failover_replica ? 1 : 0
}
# ------------------------------------------------------------------------------
@@ -30,59 +30,73 @@ locals {
# ------------------------------------------------------------------------------
resource "google_sql_database_instance" "master" {
depends_on = ["null_resource.dependency_getter"]
depends_on = [null_resource.dependency_getter]
provider = "google-beta"
name = "${var.name}"
project = "${var.project}"
region = "${var.region}"
database_version = "${var.engine}"
name = var.name
project = var.project
region = var.region
database_version = var.engine
settings {
tier = "${var.machine_type}"
activation_policy = "${var.activation_policy}"
authorized_gae_applications = ["${var.authorized_gae_applications}"]
disk_autoresize = "${var.disk_autoresize}"
tier = var.machine_type
activation_policy = var.activation_policy
authorized_gae_applications = var.authorized_gae_applications
disk_autoresize = var.disk_autoresize
ip_configuration {
authorized_networks = ["${var.authorized_networks}"]
ipv4_enabled = "${var.enable_public_internet_access}"
private_network = "${var.private_network}"
require_ssl = "${var.require_ssl}"
dynamic "authorized_networks" {
for_each = var.authorized_networks
content {
name = lookup(authorized_networks.value, "name", null)
value = authorized_networks.value.value
}
}
ipv4_enabled = var.enable_public_internet_access
private_network = var.private_network
require_ssl = var.require_ssl
}
location_preference {
follow_gae_application = "${var.follow_gae_application}"
zone = "${var.master_zone}"
follow_gae_application = var.follow_gae_application
zone = var.master_zone
}
backup_configuration {
binary_log_enabled = "${local.actual_binary_log_enabled}"
enabled = "${var.backup_enabled}"
start_time = "${var.backup_start_time}"
binary_log_enabled = local.actual_binary_log_enabled
enabled = var.backup_enabled
start_time = var.backup_start_time
}
maintenance_window {
day = "${var.maintenance_window_day}"
hour = "${var.maintenance_window_hour}"
update_track = "${var.maintenance_track}"
day = var.maintenance_window_day
hour = var.maintenance_window_hour
update_track = var.maintenance_track
}
disk_size = "${var.disk_size}"
disk_type = "${var.disk_type}"
database_flags = ["${var.database_flags}"]
availability_type = "${local.actual_availability_type}"
disk_size = var.disk_size
disk_type = var.disk_type
availability_type = local.actual_availability_type
user_labels = "${var.custom_labels}"
dynamic "database_flags" {
for_each = var.database_flags
content {
name = database_flags.value.name
value = database_flags.value.value
}
}
user_labels = var.custom_labels
}
# Default timeouts are 10 minutes, which in most cases should be enough.
# Sometimes the database creation can, however, take longer, so we
# increase the timeouts slightly.
timeouts {
create = "${var.resource_timeout}"
delete = "${var.resource_timeout}"
update = "${var.resource_timeout}"
create = var.resource_timeout
delete = var.resource_timeout
update = var.resource_timeout
}
}
@@ -91,23 +105,26 @@ resource "google_sql_database_instance" "master" {
# ------------------------------------------------------------------------------
resource "google_sql_database" "default" {
depends_on = ["google_sql_database_instance.master"]
depends_on = [google_sql_database_instance.master]
name = "${var.db_name}"
project = "${var.project}"
instance = "${google_sql_database_instance.master.name}"
charset = "${var.db_charset}"
collation = "${var.db_collation}"
name = var.db_name
project = var.project
instance = google_sql_database_instance.master.name
charset = var.db_charset
collation = var.db_collation
}
resource "google_sql_user" "default" {
depends_on = ["google_sql_database.default"]
depends_on = [google_sql_database.default]
name = "${var.master_user_name}"
project = "${var.project}"
instance = "${google_sql_database_instance.master.name}"
host = "${var.master_user_host}"
password = "${var.master_user_password}"
project = var.project
name = var.master_user_name
instance = google_sql_database_instance.master.name
# Postgres users don't have hosts, so the API will ignore this value which causes Terraform to attempt
# to recreate the user each time.
# See https://github.com/terraform-providers/terraform-provider-google/issues/1526 for more information.
host = local.is_postgres ? null : var.master_user_host
password = var.master_user_password
}
# ------------------------------------------------------------------------------
@@ -129,22 +146,22 @@ resource "null_resource" "dependency_getter" {
# ------------------------------------------------------------------------------
resource "google_sql_database_instance" "failover_replica" {
count = "${local.actual_failover_replica_count}"
count = local.actual_failover_replica_count
depends_on = [
"google_sql_database_instance.master",
"google_sql_database.default",
"google_sql_user.default",
google_sql_database_instance.master,
google_sql_database.default,
google_sql_user.default,
]
provider = "google-beta"
name = "${var.name}-failover"
project = "${var.project}"
region = "${var.region}"
database_version = "${var.engine}"
project = var.project
region = var.region
database_version = var.engine
# The name of the instance that will act as the master in the replication setup.
master_instance_name = "${google_sql_database_instance.master.name}"
master_instance_name = google_sql_database_instance.master.name
replica_configuration {
# Specifies that the replica is the failover target.
@@ -154,36 +171,50 @@ resource "google_sql_database_instance" "failover_replica" {
settings {
crash_safe_replication = true
tier = "${var.machine_type}"
authorized_gae_applications = ["${var.authorized_gae_applications}"]
disk_autoresize = "${var.disk_autoresize}"
tier = var.machine_type
authorized_gae_applications = var.authorized_gae_applications
disk_autoresize = var.disk_autoresize
ip_configuration {
authorized_networks = ["${var.authorized_networks}"]
ipv4_enabled = "${var.enable_public_internet_access}"
private_network = "${var.private_network}"
require_ssl = "${var.require_ssl}"
dynamic "authorized_networks" {
for_each = var.authorized_networks
content {
name = authorized_networks.value.name
value = authorized_networks.value.value
}
}
ipv4_enabled = var.enable_public_internet_access
private_network = var.private_network
require_ssl = var.require_ssl
}
location_preference {
follow_gae_application = "${var.follow_gae_application}"
zone = "${var.mysql_failover_replica_zone}"
follow_gae_application = var.follow_gae_application
zone = var.mysql_failover_replica_zone
}
disk_size = "${var.disk_size}"
disk_type = "${var.disk_type}"
database_flags = ["${var.database_flags}"]
disk_size = var.disk_size
disk_type = var.disk_type
user_labels = "${var.custom_labels}"
dynamic "database_flags" {
for_each = var.database_flags
content {
name = database_flags.value.name
value = database_flags.value.value
}
}
user_labels = var.custom_labels
}
# Default timeouts are 10 minutes, which in most cases should be enough.
# Sometimes the database creation can, however, take longer, so we
# increase the timeouts slightly.
timeouts {
create = "${var.resource_timeout}"
delete = "${var.resource_timeout}"
update = "${var.resource_timeout}"
create = var.resource_timeout
delete = var.resource_timeout
update = var.resource_timeout
}
}
@@ -192,23 +223,23 @@ resource "google_sql_database_instance" "failover_replica" {
# ------------------------------------------------------------------------------
resource "google_sql_database_instance" "read_replica" {
count = "${var.num_read_replicas}"
count = var.num_read_replicas
depends_on = [
"google_sql_database_instance.master",
"google_sql_database_instance.failover_replica",
"google_sql_database.default",
"google_sql_user.default",
google_sql_database_instance.master,
google_sql_database_instance.failover_replica,
google_sql_database.default,
google_sql_user.default,
]
provider = "google-beta"
name = "${var.name}-read-${count.index}"
project = "${var.project}"
region = "${var.region}"
database_version = "${var.engine}"
project = var.project
region = var.region
database_version = var.engine
# The name of the instance that will act as the master in the replication setup.
master_instance_name = "${google_sql_database_instance.master.name}"
master_instance_name = google_sql_database_instance.master.name
replica_configuration {
# Specifies that the replica is not the failover target.
@@ -216,27 +247,41 @@ resource "google_sql_database_instance" "read_replica" {
}
settings {
tier = "${var.machine_type}"
authorized_gae_applications = ["${var.authorized_gae_applications}"]
disk_autoresize = "${var.disk_autoresize}"
tier = var.machine_type
authorized_gae_applications = var.authorized_gae_applications
disk_autoresize = var.disk_autoresize
ip_configuration {
authorized_networks = ["${var.authorized_networks}"]
ipv4_enabled = "${var.enable_public_internet_access}"
private_network = "${var.private_network}"
require_ssl = "${var.require_ssl}"
dynamic "authorized_networks" {
for_each = var.authorized_networks
content {
name = authorized_networks.value.name
value = authorized_networks.value.value
}
}
ipv4_enabled = var.enable_public_internet_access
private_network = var.private_network
require_ssl = var.require_ssl
}
location_preference {
follow_gae_application = "${var.follow_gae_application}"
zone = "${element(var.read_replica_zones, count.index)}"
follow_gae_application = var.follow_gae_application
zone = element(var.read_replica_zones, count.index)
}
disk_size = "${var.disk_size}"
disk_type = "${var.disk_type}"
database_flags = ["${var.database_flags}"]
disk_size = var.disk_size
disk_type = var.disk_type
user_labels = "${var.custom_labels}"
dynamic "database_flags" {
for_each = var.database_flags
content {
name = database_flags.value.name
value = database_flags.value.value
}
}
user_labels = var.custom_labels
}
# Read replica creation is initiated concurrently, but the provider creates
@@ -244,23 +289,24 @@ resource "google_sql_database_instance" "read_replica" {
# to allow successful creation of multiple read replicas without having to
# fear the operation timing out.
timeouts {
create = "${var.resource_timeout}"
delete = "${var.resource_timeout}"
update = "${var.resource_timeout}"
create = var.resource_timeout
delete = var.resource_timeout
update = var.resource_timeout
}
}
# ------------------------------------------------------------------------------
# CREATE A TEMPLATE FILE TO SIGNAL ALL RESOURCES HAVE BEEN CREATED
# ------------------------------------------------------------------------------
data "template_file" "complete" {
depends_on = [
"google_sql_database_instance.master",
"google_sql_database_instance.failover_replica",
"google_sql_database_instance.read_replica",
"google_sql_database.default",
"google_sql_user.default",
google_sql_database_instance.master,
google_sql_database_instance.failover_replica,
google_sql_database_instance.read_replica,
google_sql_database.default,
google_sql_user.default,
]
template = "true"
template = true
}

View File

@@ -4,27 +4,27 @@
output "master_instance_name" {
description = "The name of the master database instance"
value = "${google_sql_database_instance.master.name}"
value = google_sql_database_instance.master.name
}
output "master_public_ip_address" {
description = "The public IPv4 address of the master instance."
value = "${google_sql_database_instance.master.public_ip_address}"
value = google_sql_database_instance.master.public_ip_address
}
output "master_private_ip_address" {
description = "The public IPv4 address of the master instance."
value = "${google_sql_database_instance.master.private_ip_address}"
value = google_sql_database_instance.master.private_ip_address
}
output "master_ip_addresses" {
description = "All IP addresses of the master instance JSON encoded, see https://www.terraform.io/docs/providers/google/r/sql_database_instance.html#ip_address-0-ip_address"
value = "${jsonencode(google_sql_database_instance.master.ip_address)}"
value = jsonencode(google_sql_database_instance.master.ip_address)
}
output "master_instance" {
description = "Self link to the master instance"
value = "${google_sql_database_instance.master.self_link}"
value = google_sql_database_instance.master.self_link
}
output "master_proxy_connection" {
@@ -38,27 +38,27 @@ output "master_proxy_connection" {
output "master_ca_cert" {
description = "The CA Certificate used to connect to the master instance via SSL"
value = "${google_sql_database_instance.master.server_ca_cert.0.cert}"
value = google_sql_database_instance.master.server_ca_cert.0.cert
}
output "master_ca_cert_common_name" {
description = "The CN valid for the master instance CA Cert"
value = "${google_sql_database_instance.master.server_ca_cert.0.common_name}"
value = google_sql_database_instance.master.server_ca_cert.0.common_name
}
output "master_ca_cert_create_time" {
description = "Creation time of the master instance CA Cert"
value = "${google_sql_database_instance.master.server_ca_cert.0.create_time}"
value = google_sql_database_instance.master.server_ca_cert.0.create_time
}
output "master_ca_cert_expiration_time" {
description = "Expiration time of the master instance CA Cert"
value = "${google_sql_database_instance.master.server_ca_cert.0.expiration_time}"
value = google_sql_database_instance.master.server_ca_cert.0.expiration_time
}
output "master_ca_cert_sha1_fingerprint" {
description = "SHA Fingerprint of the master instance CA Cert"
value = "${google_sql_database_instance.master.server_ca_cert.0.sha1_fingerprint}"
value = google_sql_database_instance.master.server_ca_cert.0.sha1_fingerprint
}
# ------------------------------------------------------------------------------
@@ -67,12 +67,12 @@ output "master_ca_cert_sha1_fingerprint" {
output "db" {
description = "Self link to the default database"
value = "${google_sql_database.default.self_link}"
value = google_sql_database.default.self_link
}
output "db_name" {
description = "Name of the default database"
value = "${google_sql_database.default.name}"
value = google_sql_database.default.name
}
# ------------------------------------------------------------------------------
@@ -81,32 +81,32 @@ output "db_name" {
output "failover_instance_name" {
description = "The name of the failover database instance"
value = "${join("", google_sql_database_instance.failover_replica.*.name)}"
value = join("", google_sql_database_instance.failover_replica.*.name)
}
output "failover_public_ip_address" {
description = "The public IPv4 address of the failover instance."
value = "${join("", google_sql_database_instance.failover_replica.*.public_ip_address)}"
value = join("", google_sql_database_instance.failover_replica.*.public_ip_address)
}
output "failover_private_ip_address" {
description = "The private IPv4 address of the failover instance."
value = "${join("", google_sql_database_instance.failover_replica.*.private_ip_address)}"
value = join("", google_sql_database_instance.failover_replica.*.private_ip_address)
}
output "failover_ip_addresses" {
description = "All IP addresses of the failover instance JSON encoded, see https://www.terraform.io/docs/providers/google/r/sql_database_instance.html#ip_address-0-ip_address"
value = "${jsonencode(google_sql_database_instance.failover_replica.*.ip_address)}"
value = jsonencode(google_sql_database_instance.failover_replica.*.ip_address)
}
output "failover_instance" {
description = "Self link to the failover instance"
value = "${join("", google_sql_database_instance.failover_replica.*.self_link)}"
value = join("", google_sql_database_instance.failover_replica.*.self_link)
}
output "failover_proxy_connection" {
description = "Failover instance path for connecting with Cloud SQL Proxy. Read more at https://cloud.google.com/sql/docs/mysql/sql-proxy"
value = "${local.failover_proxy_connection}"
value = local.failover_proxy_connection
}
# ------------------------------------------------------------------------------
@@ -115,27 +115,27 @@ output "failover_proxy_connection" {
output "failover_replica_ca_cert" {
description = "The CA Certificate used to connect to the failover instance via SSL"
value = "${local.failover_certificate}"
value = local.failover_certificate
}
output "failover_replica_ca_cert_common_name" {
description = "The CN valid for the failover instance CA Cert"
value = "${local.failover_certificate_common_name}"
value = local.failover_certificate_common_name
}
output "failover_replica_ca_cert_create_time" {
description = "Creation time of the failover instance CA Cert"
value = "${local.failover_certificate_create_time}"
value = local.failover_certificate_create_time
}
output "failover_replica_ca_cert_expiration_time" {
description = "Expiration time of the failover instance CA Cert"
value = "${local.failover_certificate_expiration_time}"
value = local.failover_certificate_expiration_time
}
output "failover_replica_ca_cert_sha1_fingerprint" {
description = "SHA Fingerprint of the failover instance CA Cert"
value = "${local.failover_certificate_sha1_fingerprint}"
value = local.failover_certificate_sha1_fingerprint
}
# ------------------------------------------------------------------------------
@@ -144,37 +144,37 @@ output "failover_replica_ca_cert_sha1_fingerprint" {
output "read_replica_instance_names" {
description = "List of names for the read replica instances"
value = ["${google_sql_database_instance.read_replica.*.name}"]
value = google_sql_database_instance.read_replica.*.name
}
output "read_replica_ip_addresses" {
description = "All IP addresses of the read replica instances JSON encoded, see https://www.terraform.io/docs/providers/google/r/sql_database_instance.html#ip_address-0-ip_address"
value = "${jsonencode(google_sql_database_instance.read_replica.*.ip_address)}"
value = jsonencode(google_sql_database_instance.read_replica.*.ip_address)
}
output "read_replica_public_ip_addresses" {
description = "List of public IPv4 addresses of the read replica instances."
value = ["${google_sql_database_instance.read_replica.*.public_ip_address}"]
value = google_sql_database_instance.read_replica.*.public_ip_address
}
output "read_replica_private_ip_addresses" {
description = "List of private IPv4 addresses of the read replica instances."
value = ["${google_sql_database_instance.read_replica.*.private_ip_address}"]
value = google_sql_database_instance.read_replica.*.private_ip_address
}
output "read_replica_instances" {
description = "List of self links to the read replica instances"
value = ["${google_sql_database_instance.read_replica.*.self_link}"]
value = google_sql_database_instance.read_replica.*.self_link
}
output "read_replica_proxy_connections" {
description = "List of read replica instance paths for connecting with Cloud SQL Proxy. Read more at https://cloud.google.com/sql/docs/mysql/sql-proxy"
value = ["${data.template_file.read_replica_proxy_connection.*.rendered}"]
value = data.template_file.read_replica_proxy_connection.*.rendered
}
output "read_replica_server_ca_certs" {
description = "JSON encoded list of CA Certificates used to connect to the read replica instances via SSL"
value = "${jsonencode(google_sql_database_instance.read_replica.*.server_ca_cert)}"
value = jsonencode(google_sql_database_instance.read_replica.*.server_ca_cert)
}
# ------------------------------------------------------------------------------
@@ -183,5 +183,5 @@ output "read_replica_server_ca_certs" {
output "complete" {
description = "Output signaling that all resources have been created"
value = "${data.template_file.complete.rendered}"
value = data.template_file.complete.rendered
}

View File

@@ -5,34 +5,42 @@
variable "project" {
description = "The project ID to host the database in."
type = string
}
variable "region" {
description = "The region to host the database in."
type = string
}
variable "name" {
description = "The name of the database instance. Note, after a name is used, it cannot be reused for up to one week. Use lowercase letters, numbers, and hyphens. Start with a letter."
type = string
}
variable "engine" {
description = "The engine version of the database, e.g. `MYSQL_5_6` or `MYSQL_5_7`. See https://cloud.google.com/sql/docs/features for supported versions."
type = string
}
variable "machine_type" {
description = "The machine type for the instances. See this page for supported tiers and pricing: https://cloud.google.com/sql/pricing"
type = string
}
variable "db_name" {
description = "Name of your database. Needs to follow MySQL identifier rules: https://dev.mysql.com/doc/refman/5.7/en/identifiers.html"
type = string
}
variable "master_user_name" {
description = "The username part for the default user credentials, i.e. 'master_user_name'@'master_user_host' IDENTIFIED BY 'master_user_password'. This should typically be set as the environment variable TF_VAR_master_user_name so you don't check it into source control."
type = string
}
variable "master_user_password" {
description = "The password part for the default user credentials, i.e. 'master_user_name'@'master_user_host' IDENTIFIED BY 'master_user_password'. This should typically be set as the environment variable TF_VAR_master_user_password so you don't check it into source control."
type = string
}
# ---------------------------------------------------------------------------------------------------------------------
@@ -42,12 +50,13 @@ variable "master_user_password" {
variable "activation_policy" {
description = "This specifies when the instance should be active. Can be either `ALWAYS`, `NEVER` or `ON_DEMAND`."
type = string
default = "ALWAYS"
}
variable "authorized_networks" {
description = "A list of authorized CIDR-formatted IP address ranges that can connect to this DB. Only applies to public IP instances."
type = "list"
type = list(map(string))
default = []
# Example:
@@ -62,53 +71,61 @@ variable "authorized_networks" {
variable "authorized_gae_applications" {
description = "A list of Google App Engine (GAE) project names that are allowed to access this instance."
type = "list"
type = list(string)
default = []
}
variable "backup_enabled" {
description = "Set to false if you want to disable backup."
type = bool
default = true
}
variable "backup_start_time" {
description = "HH:MM format (e.g. 04:00) time indicating when backup configuration starts. NOTE: Start time is randomly assigned if backup is enabled and 'backup_start_time' is not set"
type = string
default = "04:00"
}
variable "mysql_binary_log_enabled" {
description = "Set to false if you want to disable binary logs - only applicable to MySQL. Note, when using failover or read replicas, master and existing backups need to have binary_log_enabled=true set."
type = bool
default = true
}
variable "maintenance_window_day" {
description = "Day of week (1-7), starting on Monday, on which system maintenance can occur. Performance may be degraded or there may even be a downtime during maintenance windows."
type = number
default = 7
}
variable "maintenance_window_hour" {
description = "Hour of day (0-23) on which system maintenance can occur. Ignored if 'maintenance_window_day' not set. Performance may be degraded or there may even be a downtime during maintenance windows."
type = number
default = 7
}
variable "maintenance_track" {
description = "Receive updates earlier (canary) or later (stable)."
type = string
default = "stable"
}
variable "db_charset" {
description = "The charset for the default database."
default = ""
type = string
default = null
}
variable "db_collation" {
description = "The collation for the default database. Example for MySQL databases: 'utf8_general_ci'."
default = ""
type = string
default = null
}
variable "database_flags" {
description = "List of Cloud SQL flags that are applied to the database server"
type = "list"
type = list(any)
default = []
# Example:
@@ -127,68 +144,80 @@ variable "database_flags" {
variable "disk_autoresize" {
description = "Second Generation only. Configuration to increase storage size automatically."
type = bool
default = true
}
variable "disk_size" {
description = "Second generation only. The size of data disk, in GB. Size of a running instance cannot be reduced but can be increased."
type = number
default = 10
}
variable "disk_type" {
description = "The type of storage to use. Must be one of `PD_SSD` or `PD_HDD`."
type = string
default = "PD_SSD"
}
variable "follow_gae_application" {
description = "A GAE application whose zone to remain in. Must be in the same region as this instance."
default = ""
type = string
default = null
}
variable "master_zone" {
description = "Preferred zone for the master instance (e.g. 'us-central1-a'). 'region'. If empty, Google will auto-assign a zone."
default = ""
description = "Preferred zone for the master instance (e.g. 'us-central1-a'). 'region'. If null, Google will auto-assign a zone."
type = string
default = null
}
variable "master_user_host" {
description = "The host part for the default user, i.e. 'master_user_name'@'master_user_host' IDENTIFIED BY 'master_user_password' "
description = "The host part for the default user, i.e. 'master_user_name'@'master_user_host' IDENTIFIED BY 'master_user_password'. Don't set this field for Postgres instances."
type = string
default = "%"
}
# In nearly all cases, databases should NOT be publicly accessible, however if you're migrating from a PAAS provider like Heroku to GCP, this needs to remain open to the internet.
variable "enable_public_internet_access" {
description = "WARNING: - In nearly all cases a database should NOT be publicly accessible. Only set this to true if you want the database open to the internet."
type = bool
default = false
}
variable "enable_failover_replica" {
description = "Set to true to enable failover replica."
type = bool
default = false
}
variable "mysql_failover_replica_zone" {
description = "The preferred zone for the failover instance (e.g. 'us-central1-b'). Must be different than 'master_zone'. Only applicable to MySQL, Postgres will determine this automatically."
default = ""
type = string
default = null
}
variable "require_ssl" {
description = "True if the instance should require SSL/TLS for users connecting over IP. Note: SSL/TLS is needed to provide security when you connect to Cloud SQL using IP addresses. If you are connecting to your instance only by using the Cloud SQL Proxy or the Java Socket Library, you do not need to configure your instance to use SSL/TLS."
type = bool
default = false
}
variable "private_network" {
description = "The resource link for the VPC network from which the Cloud SQL instance is accessible for private IP."
default = ""
type = string
default = null
}
variable "num_read_replicas" {
description = "The number of read replicas to create. Cloud SQL will replicate all data from the master to these replicas, which you can use to horizontally scale read traffic."
type = number
default = 0
}
variable "read_replica_zones" {
description = "A list of compute zones where read replicas should be created. List size should match 'num_read_replicas'"
type = "list"
type = list(string)
default = []
# Example:
@@ -197,7 +226,7 @@ variable "read_replica_zones" {
variable "custom_labels" {
description = "A map of custom labels to apply to the instance. The key is the label name and the value is the label value."
type = "map"
type = map(string)
default = {}
}
@@ -205,6 +234,7 @@ variable "custom_labels" {
# to not have the operations time out.
variable "resource_timeout" {
description = "Timeout for creating, updating and deleting database instances. Valid units of time are s, m, h."
type = string
default = "60m"
}
@@ -214,11 +244,11 @@ variable "resource_timeout" {
# See https://github.com/hashicorp/terraform/issues/1178 for more details.
# This can be used to make sure the module resources are created after other bootstrapping resources have been created.
# For example:
# dependencies = ["${google_service_networking_connection.private_vpc_connection.network}"]
# dependencies = [google_service_networking_connection.private_vpc_connection.network]
# ---------------------------------------------------------------------------------------------------------------------
variable "dependencies" {
description = "Create a dependency between the resources in this module to the interpolated values in this list (and thus the source resources). In other words, the resources in this module will now depend on the resources backing the values in this list such that those resources need to be created before the resources in this module, and the resources in this module need to be destroyed before the resources in the list."
type = "list"
type = list(string)
default = []
}

397
test/Gopkg.lock generated
View File

@@ -2,7 +2,7 @@
[[projects]]
digest = "1:8b95956b70e181b19025c7ba3578fdfd8efbec4ce916490700488afb9218972c"
digest = "1:7131fa3a68e56764067bb569886cc7b03de5523fe5e81cbe0c70368932a1c622"
name = "cloud.google.com/go"
packages = [
"compute/metadata",
@@ -14,8 +14,8 @@
"storage",
]
pruneopts = ""
revision = "64a2037ec6be8a4b0c1d1f706ed35b428b989239"
version = "v0.26.0"
revision = "28a4bc8c44b3acbcc482cff0cdf7de29a4688b61"
version = "v0.35.1"
[[projects]]
digest = "1:5204bbf2acdc60904e9ed06b4364810bd8b16e2cd48e4c5cbb242c52d6fa1d5f"
@@ -47,6 +47,7 @@
"aws/credentials/endpointcreds",
"aws/credentials/processcreds",
"aws/credentials/stscreds",
"aws/crr",
"aws/csm",
"aws/defaults",
"aws/ec2metadata",
@@ -74,7 +75,9 @@
"service/acm",
"service/autoscaling",
"service/cloudwatchlogs",
"service/dynamodb",
"service/ec2",
"service/ecs",
"service/iam",
"service/kms",
"service/rds",
@@ -83,6 +86,7 @@
"service/s3/s3manager",
"service/sns",
"service/sqs",
"service/ssm",
"service/sts",
]
pruneopts = ""
@@ -109,6 +113,33 @@
revision = "8991bc29aa16c548c550c7ff78260e27b9ab7c73"
version = "v1.1.1"
[[projects]]
branch = "master"
digest = "1:d6c13a378213e3de60445e49084b8a0a9ce582776dfc77927775dbeb3ff72a35"
name = "github.com/docker/spdystream"
packages = [
".",
"spdy",
]
pruneopts = ""
revision = "6480d4af844c189cf5dd913db24ddd339d3a4f85"
[[projects]]
digest = "1:b13707423743d41665fd23f0c36b2f37bb49c30e94adb813319c44188a51ba22"
name = "github.com/ghodss/yaml"
packages = ["."]
pruneopts = ""
revision = "0ca9ea5df5451ffdf184b4428c902747c2c11cd7"
version = "v1.0.0"
[[projects]]
branch = "master"
digest = "1:26317724ed32bcf2ef15454613d2a8fe9d670b12f073cfd20db3bcec54e069ab"
name = "github.com/go-errors/errors"
packages = ["."]
pruneopts = ""
revision = "d98b870cc4e05f1545532a80e9909be8216095b6"
[[projects]]
digest = "1:e692d16fdfbddb94e9e4886aaf6c08bdbae5cb4ac80651445de9181b371c6e46"
name = "github.com/go-sql-driver/mysql"
@@ -118,6 +149,25 @@
source = "git@github.com:go-sql-driver/mysql"
version = "v1.4.1"
[[projects]]
digest = "1:fd53b471edb4c28c7d297f617f4da0d33402755f58d6301e7ca1197ef0a90937"
name = "github.com/gogo/protobuf"
packages = [
"proto",
"sortkeys",
]
pruneopts = ""
revision = "ba06b47c162d49f2af050fb4c75bcbc86a159d5c"
version = "v1.2.1"
[[projects]]
branch = "master"
digest = "1:107b233e45174dbab5b1324201d092ea9448e58243ab9f039e4c0f332e121e3a"
name = "github.com/golang/glog"
packages = ["."]
pruneopts = ""
revision = "23def4e6c14b4da8ac2ed8007337bc5eb5007998"
[[projects]]
digest = "1:3dd078fda7500c341bc26cfbc6c6a34614f295a2457149fc1045cab767cbcf18"
name = "github.com/golang/protobuf"
@@ -133,6 +183,22 @@
revision = "aa810b61a9c79d51363740d207bb46cf8e620ed5"
version = "v1.2.0"
[[projects]]
digest = "1:1e5b1e14524ed08301977b7b8e10c719ed853cbf3f24ecb66fae783a46f207a6"
name = "github.com/google/btree"
packages = ["."]
pruneopts = ""
revision = "4030bb1f1f0c35b30ca7009e9ebd06849dd45306"
version = "v1.0.0"
[[projects]]
digest = "1:8d4a577a9643f713c25a32151c0f26af7228b4b97a219b5ddb7fd38d16f6e673"
name = "github.com/google/gofuzz"
packages = ["."]
pruneopts = ""
revision = "f140a6486e521aad38f5917de355cbf147cc0496"
version = "v1.0.0"
[[projects]]
digest = "1:c1d7e883c50a26ea34019320d8ae40fad86c9e5d56e63a1ba2cb618cef43e986"
name = "github.com/google/uuid"
@@ -144,16 +210,44 @@
[[projects]]
digest = "1:55c1b46a80db2baf4d762c1d0b5cb4946e46125baa02b8959310abab15b54aee"
name = "github.com/googleapis/gax-go"
packages = [
".",
"v2",
]
packages = ["v2"]
pruneopts = ""
revision = "c8a15bac9b9fe955bd9f900272f9a306465d28cf"
version = "v2.0.3"
[[projects]]
digest = "1:4b6c36dd91add683751cb4670cc26d63c7e7db259695ffd723670c666797c62c"
digest = "1:5facc3828b6a56f9aec988433ea33fb4407a89460952ed75be5347cec07318c0"
name = "github.com/googleapis/gnostic"
packages = [
"OpenAPIv2",
"compiler",
"extensions",
]
pruneopts = ""
revision = "e73c7ec21d36ddb0711cb36d1502d18363b5c2c9"
version = "v0.3.0"
[[projects]]
branch = "master"
digest = "1:e1fd67b5695fb12f54f979606c5d650a5aa72ef242f8e71072bfd4f7b5a141a0"
name = "github.com/gregjones/httpcache"
packages = [
".",
"diskcache",
]
pruneopts = ""
revision = "901d90724c7919163f472a9812253fb26761123d"
[[projects]]
digest = "1:f032ebac9a824af56f183e82817a79792738f3faef09b4feced2252df7b253e7"
name = "github.com/gruntwork-io/gruntwork-cli"
packages = ["errors"]
pruneopts = ""
revision = "6a2163138f3d10377f313428e7e367b0a6c0c1c9"
version = "v0.4.2"
[[projects]]
digest = "1:f4aa63932320bc30b5a0895d451eba4749e08a7fc18ba096a4bf2afcaeae9b5e"
name = "github.com/gruntwork-io/terratest"
packages = [
"modules/aws",
@@ -162,6 +256,7 @@
"modules/environment",
"modules/files",
"modules/gcp",
"modules/k8s",
"modules/logger",
"modules/packer",
"modules/random",
@@ -172,9 +267,25 @@
"modules/test-structure",
]
pruneopts = ""
revision = "425f7f1c2c72c607142c67aee02d1c14f874cf0a"
revision = "295736141a96daa369a972e1409622d702c8f40e"
source = "git@github.com:gruntwork-io/terratest"
version = "v0.13.24"
version = "v0.17.4"
[[projects]]
digest = "1:31bfd110d31505e9ffbc9478e31773bf05bf02adcaeb9b139af42684f9294c13"
name = "github.com/imdario/mergo"
packages = ["."]
pruneopts = ""
revision = "7c29201646fa3de8506f701213473dd407f19646"
version = "v0.3.7"
[[projects]]
digest = "1:870d441fe217b8e689d7949fef6e43efbc787e50f200cb1e70dbca9204a1d6be"
name = "github.com/inconshreveable/mousetrap"
packages = ["."]
pruneopts = ""
revision = "76626ae9c91c4f2a10f34cad8ce83ea42c93bb75"
version = "v1.0"
[[projects]]
digest = "1:13fe471d0ed891e8544eddfeeb0471fd3c9f2015609a1c000aefdedf52a19d40"
@@ -183,6 +294,14 @@
pruneopts = ""
revision = "c2b33e84"
[[projects]]
digest = "1:12d3de2c11e54ea37d7f00daf85088ad5e61ec4e8a1f828d6c8b657976856be7"
name = "github.com/json-iterator/go"
packages = ["."]
pruneopts = ""
revision = "0ff49de124c6f76f8494e194af75bde0f1a49a29"
version = "v1.1.6"
[[projects]]
digest = "1:29145d7af4adafd72a79df5e41456ac9e232d5a28c1cd4dacf3ff008a217fc10"
name = "github.com/lib/pq"
@@ -194,6 +313,46 @@
revision = "4ded0e9383f75c197b3a2aaa6d590ac52df6fd79"
version = "v1.0.0"
[[projects]]
digest = "1:6dbb0eb72090871f2e58d1e37973fe3cb8c0f45f49459398d3fc740cb30e13bd"
name = "github.com/mitchellh/go-homedir"
packages = ["."]
pruneopts = ""
revision = "af06845cf3004701891bf4fdb884bfe4920b3727"
version = "v1.1.0"
[[projects]]
digest = "1:0c0ff2a89c1bb0d01887e1dac043ad7efbf3ec77482ef058ac423d13497e16fd"
name = "github.com/modern-go/concurrent"
packages = ["."]
pruneopts = ""
revision = "bacd9c7ef1dd9b15be4a9909b8ac7a4e313eec94"
version = "1.0.3"
[[projects]]
digest = "1:e32bdbdb7c377a07a9a46378290059822efdce5c8d96fe71940d87cb4f918855"
name = "github.com/modern-go/reflect2"
packages = ["."]
pruneopts = ""
revision = "4b7aa43c6742a2c18fdef89dd197aaae7dac7ccd"
version = "1.0.1"
[[projects]]
branch = "master"
digest = "1:5f0faa008e8ff4221b55a1a5057c8b02cb2fd68da6a65c9e31c82b72cbc836d0"
name = "github.com/petar/GoLLRB"
packages = ["llrb"]
pruneopts = ""
revision = "33fb24c13b99c46c93183c291836c573ac382536"
[[projects]]
digest = "1:4709c61d984ef9ba99b037b047546d8a576ae984fb49486e48d99658aa750cd5"
name = "github.com/peterbourgon/diskv"
packages = ["."]
pruneopts = ""
revision = "0be1b92a6df0e4f5cb0a5d15fb7f643d0ad93ce6"
version = "v3.0.0"
[[projects]]
digest = "1:256484dbbcd271f9ecebc6795b2df8cad4c458dd0f5fd82a8c2fa0c29f233411"
name = "github.com/pmezard/go-difflib"
@@ -214,6 +373,22 @@
revision = "be78767b3e392ce45ea73444451022a6fc32ad0d"
version = "v1.1.0"
[[projects]]
digest = "1:0c63b3c7ad6d825a898f28cb854252a3b29d37700c68a117a977263f5ec94efe"
name = "github.com/spf13/cobra"
packages = ["."]
pruneopts = ""
revision = "f2b07da1e2c38d5f12845a4f607e2e1018cbb1f5"
version = "v0.0.5"
[[projects]]
digest = "1:cbaf13cdbfef0e4734ed8a7504f57fe893d471d62a35b982bf6fb3f036449a66"
name = "github.com/spf13/pflag"
packages = ["."]
pruneopts = ""
revision = "298182f68c66c05229eb03ac171abe6e309ee79a"
version = "v1.0.3"
[[projects]]
digest = "1:381bcbeb112a51493d9d998bbba207a529c73dbb49b3fd789e48c63fac1f192c"
name = "github.com/stretchr/testify"
@@ -225,6 +400,14 @@
revision = "ffdc059bfe9ce6a4e144ba849dbedead332c6053"
version = "v1.3.0"
[[projects]]
digest = "1:e85837cb04b78f61688c6eba93ea9d14f60d611e2aaf8319999b1a60d2dafbfa"
name = "github.com/urfave/cli"
packages = ["."]
pruneopts = ""
revision = "cfb38830724cc34fedffe9a2a29fb54fa9169cd1"
version = "v1.20.0"
[[projects]]
digest = "1:b1bb9332f6cb7821a730e1681819b2813340eba5e873f05381815a7c6807d172"
name = "go.opencensus.io"
@@ -261,6 +444,7 @@
"poly1305",
"ssh",
"ssh/agent",
"ssh/terminal",
]
pruneopts = ""
revision = "b8fe1690c61389d7d2a8074a507d1d40c5d30448"
@@ -299,7 +483,10 @@
branch = "master"
digest = "1:489610147902fe0c7229218c749bb25a8a9ecce0d726ae4f8662517319f32554"
name = "golang.org/x/sys"
packages = ["unix"]
packages = [
"unix",
"windows",
]
pruneopts = ""
revision = "41f3e6584952bb034a481797859f6ab34b6803bd"
@@ -326,6 +513,14 @@
revision = "f21a4dfb5e38f5895301dc265a8def02365cc3d0"
version = "v0.3.0"
[[projects]]
branch = "master"
digest = "1:9522af4be529c108010f95b05f1022cb872f2b9ff8b101080f554245673466e1"
name = "golang.org/x/time"
packages = ["rate"]
pruneopts = ""
revision = "9d24e82272b4f38b78bc8cff74fa936d31ccd8ef"
[[projects]]
branch = "master"
digest = "1:e53b3650fadc76377e90fa596a939233cff79f8606cae71e0b6c73e5e6829ecd"
@@ -339,6 +534,7 @@
"internal",
"iterator",
"option",
"oslogin/v1",
"sqladmin/v1beta4",
"storage/v1",
"transport/http",
@@ -420,6 +616,185 @@
revision = "a02b0774206b209466313a0b525d2c738fe407eb"
version = "v1.18.0"
[[projects]]
digest = "1:75fb3fcfc73a8c723efde7777b40e8e8ff9babf30d8c56160d01beffea8a95a6"
name = "gopkg.in/inf.v0"
packages = ["."]
pruneopts = ""
revision = "d2d2541c53f18d2a059457998ce2876cc8e67cbf"
version = "v0.9.1"
[[projects]]
digest = "1:cedccf16b71e86db87a24f8d4c70b0a855872eb967cb906a66b95de56aefbd0d"
name = "gopkg.in/yaml.v2"
packages = ["."]
pruneopts = ""
revision = "51d6538a90f86fe93ac480b35f37b2be17fef232"
version = "v2.2.2"
[[projects]]
branch = "release-1.12"
digest = "1:3e3e9df293bd6f9fd64effc9fa1f0edcd97e6c74145cd9ab05d35719004dc41f"
name = "k8s.io/api"
packages = [
"admissionregistration/v1alpha1",
"admissionregistration/v1beta1",
"apps/v1",
"apps/v1beta1",
"apps/v1beta2",
"authentication/v1",
"authentication/v1beta1",
"authorization/v1",
"authorization/v1beta1",
"autoscaling/v1",
"autoscaling/v2beta1",
"autoscaling/v2beta2",
"batch/v1",
"batch/v1beta1",
"batch/v2alpha1",
"certificates/v1beta1",
"coordination/v1beta1",
"core/v1",
"events/v1beta1",
"extensions/v1beta1",
"networking/v1",
"policy/v1beta1",
"rbac/v1",
"rbac/v1alpha1",
"rbac/v1beta1",
"scheduling/v1alpha1",
"scheduling/v1beta1",
"settings/v1alpha1",
"storage/v1",
"storage/v1alpha1",
"storage/v1beta1",
]
pruneopts = ""
revision = "6db15a15d2d3874a6c3ddb2140ac9f3bc7058428"
[[projects]]
branch = "release-1.12"
digest = "1:9c7ee6fe7b8b621df5a7604e9a1f752b566ae451b2cf010c9c075e5e5ff81f56"
name = "k8s.io/apimachinery"
packages = [
"pkg/api/errors",
"pkg/api/meta",
"pkg/api/resource",
"pkg/apis/meta/v1",
"pkg/apis/meta/v1/unstructured",
"pkg/apis/meta/v1beta1",
"pkg/conversion",
"pkg/conversion/queryparams",
"pkg/fields",
"pkg/labels",
"pkg/runtime",
"pkg/runtime/schema",
"pkg/runtime/serializer",
"pkg/runtime/serializer/json",
"pkg/runtime/serializer/protobuf",
"pkg/runtime/serializer/recognizer",
"pkg/runtime/serializer/streaming",
"pkg/runtime/serializer/versioning",
"pkg/selection",
"pkg/types",
"pkg/util/clock",
"pkg/util/errors",
"pkg/util/framer",
"pkg/util/httpstream",
"pkg/util/httpstream/spdy",
"pkg/util/intstr",
"pkg/util/json",
"pkg/util/naming",
"pkg/util/net",
"pkg/util/runtime",
"pkg/util/sets",
"pkg/util/validation",
"pkg/util/validation/field",
"pkg/util/yaml",
"pkg/version",
"pkg/watch",
"third_party/forked/golang/netutil",
"third_party/forked/golang/reflect",
]
pruneopts = ""
revision = "01f179d85dbce0f2e0e4351a92394b38694b7cae"
[[projects]]
branch = "release-9.0"
digest = "1:b1a32e8c431a032029c57bd211aa8b7e7de4fd7e142d4805be654da286f5efe4"
name = "k8s.io/client-go"
packages = [
"discovery",
"kubernetes",
"kubernetes/scheme",
"kubernetes/typed/admissionregistration/v1alpha1",
"kubernetes/typed/admissionregistration/v1beta1",
"kubernetes/typed/apps/v1",
"kubernetes/typed/apps/v1beta1",
"kubernetes/typed/apps/v1beta2",
"kubernetes/typed/authentication/v1",
"kubernetes/typed/authentication/v1beta1",
"kubernetes/typed/authorization/v1",
"kubernetes/typed/authorization/v1beta1",
"kubernetes/typed/autoscaling/v1",
"kubernetes/typed/autoscaling/v2beta1",
"kubernetes/typed/autoscaling/v2beta2",
"kubernetes/typed/batch/v1",
"kubernetes/typed/batch/v1beta1",
"kubernetes/typed/batch/v2alpha1",
"kubernetes/typed/certificates/v1beta1",
"kubernetes/typed/coordination/v1beta1",
"kubernetes/typed/core/v1",
"kubernetes/typed/events/v1beta1",
"kubernetes/typed/extensions/v1beta1",
"kubernetes/typed/networking/v1",
"kubernetes/typed/policy/v1beta1",
"kubernetes/typed/rbac/v1",
"kubernetes/typed/rbac/v1alpha1",
"kubernetes/typed/rbac/v1beta1",
"kubernetes/typed/scheduling/v1alpha1",
"kubernetes/typed/scheduling/v1beta1",
"kubernetes/typed/settings/v1alpha1",
"kubernetes/typed/storage/v1",
"kubernetes/typed/storage/v1alpha1",
"kubernetes/typed/storage/v1beta1",
"pkg/apis/clientauthentication",
"pkg/apis/clientauthentication/v1alpha1",
"pkg/apis/clientauthentication/v1beta1",
"pkg/version",
"plugin/pkg/client/auth/exec",
"plugin/pkg/client/auth/gcp",
"rest",
"rest/watch",
"third_party/forked/golang/template",
"tools/auth",
"tools/clientcmd",
"tools/clientcmd/api",
"tools/clientcmd/api/latest",
"tools/clientcmd/api/v1",
"tools/metrics",
"tools/portforward",
"tools/reference",
"transport",
"transport/spdy",
"util/cert",
"util/connrotation",
"util/flowcontrol",
"util/homedir",
"util/integer",
"util/jsonpath",
]
pruneopts = ""
revision = "b6aa6aafe32b0767f075245e5d391381c5449c8a"
[[projects]]
digest = "1:f27698f7ae7864893ebcfb843e44d821263ac1dcf0ba1d5c2353f9d319a2f28d"
name = "k8s.io/kubernetes"
packages = ["pkg/kubectl/generate"]
pruneopts = ""
revision = "e8462b5b5dc2584fdcd18e6bcfe9f1e4d970a529"
version = "v1.15.0"
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1

View File

@@ -22,7 +22,7 @@
[[constraint]]
name = "github.com/gruntwork-io/terratest"
source = "git@github.com:gruntwork-io/terratest"
version = "0.13.24"
version = "0.17.4"
[[constraint]]
name = "github.com/go-sql-driver/mysql"

View File

@@ -2,13 +2,14 @@ package test
import (
"fmt"
"github.com/gruntwork-io/terratest/modules/gcp"
"github.com/gruntwork-io/terratest/modules/terraform"
"github.com/gruntwork-io/terratest/modules/test-structure"
"github.com/stretchr/testify/assert"
"path/filepath"
"strings"
"testing"
"github.com/gruntwork-io/terratest/modules/gcp"
"github.com/gruntwork-io/terratest/modules/terraform"
test_structure "github.com/gruntwork-io/terratest/modules/test-structure"
"github.com/stretchr/testify/assert"
)
const NAME_PREFIX_PRIVATE = "mysql-private"
@@ -42,7 +43,7 @@ func TestMySqlPrivateIP(t *testing.T) {
test_structure.RunTestStage(t, "deploy", func() {
region := test_structure.LoadString(t, exampleDir, KEY_REGION)
projectId := test_structure.LoadString(t, exampleDir, KEY_PROJECT)
terraformOptions := createTerratestOptionsForCloudSql(projectId, region, exampleDir, NAME_PREFIX_PRIVATE, "", "", 0, "")
terraformOptions := createTerratestOptionsForCloudSql(projectId, region, exampleDir, NAME_PREFIX_PRIVATE)
test_structure.SaveTerraformOptions(t, exampleDir, terraformOptions)
terraform.InitAndApply(t, terraformOptions)

View File

@@ -5,18 +5,19 @@ import (
"crypto/x509"
"database/sql"
"fmt"
"path/filepath"
"strings"
"testing"
"time"
mydialer "github.com/GoogleCloudPlatform/cloudsql-proxy/proxy/dialers/mysql"
"github.com/go-sql-driver/mysql"
"github.com/gruntwork-io/terratest/modules/gcp"
"github.com/gruntwork-io/terratest/modules/logger"
"github.com/gruntwork-io/terratest/modules/terraform"
"github.com/gruntwork-io/terratest/modules/test-structure"
test_structure "github.com/gruntwork-io/terratest/modules/test-structure"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"path/filepath"
"strings"
"testing"
"time"
)
const NAME_PREFIX_PUBLIC = "mysql-public"
@@ -65,7 +66,7 @@ func TestMySqlPublicIP(t *testing.T) {
test_structure.RunTestStage(t, "deploy", func() {
region := test_structure.LoadString(t, exampleDir, KEY_REGION)
projectId := test_structure.LoadString(t, exampleDir, KEY_PROJECT)
terraformOptions := createTerratestOptionsForCloudSql(projectId, region, exampleDir, NAME_PREFIX_PUBLIC, "", "", 0, "")
terraformOptions := createTerratestOptionsForCloudSql(projectId, region, exampleDir, NAME_PREFIX_PUBLIC)
test_structure.SaveTerraformOptions(t, exampleDir, terraformOptions)
terraform.InitAndApply(t, terraformOptions)

View File

@@ -3,15 +3,16 @@ package test
import (
"database/sql"
"fmt"
"github.com/gruntwork-io/terratest/modules/gcp"
"github.com/gruntwork-io/terratest/modules/logger"
"github.com/gruntwork-io/terratest/modules/terraform"
"github.com/gruntwork-io/terratest/modules/test-structure"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"path/filepath"
"strings"
"testing"
"github.com/gruntwork-io/terratest/modules/gcp"
"github.com/gruntwork-io/terratest/modules/logger"
"github.com/gruntwork-io/terratest/modules/terraform"
test_structure "github.com/gruntwork-io/terratest/modules/test-structure"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
const NAME_PREFIX_REPLICAS = "mysql-replicas"
@@ -58,7 +59,7 @@ func TestMySqlReplicas(t *testing.T) {
masterZone := test_structure.LoadString(t, exampleDir, KEY_MASTER_ZONE)
failoverReplicaZone := test_structure.LoadString(t, exampleDir, KEY_FAILOVER_REPLICA_ZONE)
readReplicaZone := test_structure.LoadString(t, exampleDir, KEY_READ_REPLICA_ZONE)
terraformOptions := createTerratestOptionsForCloudSql(projectId, region, exampleDir, NAME_PREFIX_REPLICAS, masterZone, failoverReplicaZone, 1, readReplicaZone)
terraformOptions := createTerratestOptionsForCloudSqlReplicas(projectId, region, exampleDir, NAME_PREFIX_REPLICAS, masterZone, failoverReplicaZone, 1, readReplicaZone)
test_structure.SaveTerraformOptions(t, exampleDir, terraformOptions)
terraform.InitAndApply(t, terraformOptions)

View File

@@ -2,13 +2,14 @@ package test
import (
"fmt"
"github.com/gruntwork-io/terratest/modules/gcp"
"github.com/gruntwork-io/terratest/modules/terraform"
"github.com/gruntwork-io/terratest/modules/test-structure"
"github.com/stretchr/testify/assert"
"path/filepath"
"strings"
"testing"
"github.com/gruntwork-io/terratest/modules/gcp"
"github.com/gruntwork-io/terratest/modules/terraform"
test_structure "github.com/gruntwork-io/terratest/modules/test-structure"
"github.com/stretchr/testify/assert"
)
const NAME_PREFIX_POSTGRES_PRIVATE = "postgres-private"
@@ -42,7 +43,7 @@ func TestPostgresPrivateIP(t *testing.T) {
test_structure.RunTestStage(t, "deploy", func() {
region := test_structure.LoadString(t, exampleDir, KEY_REGION)
projectId := test_structure.LoadString(t, exampleDir, KEY_PROJECT)
terraformOptions := createTerratestOptionsForCloudSql(projectId, region, exampleDir, NAME_PREFIX_POSTGRES_PRIVATE, "", "", 0, "")
terraformOptions := createTerratestOptionsForCloudSql(projectId, region, exampleDir, NAME_PREFIX_POSTGRES_PRIVATE)
test_structure.SaveTerraformOptions(t, exampleDir, terraformOptions)
terraform.InitAndApply(t, terraformOptions)

View File

@@ -3,18 +3,19 @@ package test
import (
"database/sql"
"fmt"
_ "github.com/GoogleCloudPlatform/cloudsql-proxy/proxy/dialers/postgres"
"github.com/gruntwork-io/terratest/modules/gcp"
"github.com/gruntwork-io/terratest/modules/logger"
"github.com/gruntwork-io/terratest/modules/terraform"
"github.com/gruntwork-io/terratest/modules/test-structure"
_ "github.com/lib/pq"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"os"
"path/filepath"
"strings"
"testing"
_ "github.com/GoogleCloudPlatform/cloudsql-proxy/proxy/dialers/postgres"
"github.com/gruntwork-io/terratest/modules/gcp"
"github.com/gruntwork-io/terratest/modules/logger"
"github.com/gruntwork-io/terratest/modules/terraform"
test_structure "github.com/gruntwork-io/terratest/modules/test-structure"
_ "github.com/lib/pq"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
const NAME_PREFIX_POSTGRES_PUBLIC = "postgres-public"
@@ -62,7 +63,7 @@ func TestPostgresPublicIP(t *testing.T) {
test_structure.RunTestStage(t, "deploy", func() {
region := test_structure.LoadString(t, exampleDir, KEY_REGION)
projectId := test_structure.LoadString(t, exampleDir, KEY_PROJECT)
terraformOptions := createTerratestOptionsForCloudSql(projectId, region, exampleDir, NAME_PREFIX_POSTGRES_PUBLIC, "", "", 0, "")
terraformOptions := createTerratestOptionsForCloudSql(projectId, region, exampleDir, NAME_PREFIX_POSTGRES_PUBLIC)
test_structure.SaveTerraformOptions(t, exampleDir, terraformOptions)
terraform.InitAndApply(t, terraformOptions)
@@ -137,7 +138,7 @@ func TestPostgresPublicIP(t *testing.T) {
logger.Logf(t, "Connecting to: %s via Cloud SQL Proxy", proxyConn)
// Use the Cloud SQL Proxy for queries
// See https://cloud.google.com/sql/docs/mysql/sql-proxy
// See https://cloud.google.com/sql/docs/postgres/sql-proxy
// Note that sslmode=disable is required it does not mean that the connection
// is unencrypted. All connections via the proxy are completely encrypted.
@@ -245,5 +246,11 @@ func TestPostgresPublicIP(t *testing.T) {
if err = db.Ping(); err != nil {
t.Fatalf("Failed to ping DB with forced SSL: %v", err)
}
// Drop the test table if it exists
logger.Logf(t, "Drop table: %s", POSTGRES_DROP_TEST_TABLE)
if _, err = db.Exec(POSTGRES_DROP_TEST_TABLE); err != nil {
t.Fatalf("Failed to drop table: %v", err)
}
})
}

View File

@@ -3,16 +3,17 @@ package test
import (
"database/sql"
"fmt"
"github.com/gruntwork-io/terratest/modules/gcp"
"github.com/gruntwork-io/terratest/modules/logger"
"github.com/gruntwork-io/terratest/modules/terraform"
"github.com/gruntwork-io/terratest/modules/test-structure"
_ "github.com/lib/pq"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"path/filepath"
"strings"
"testing"
"github.com/gruntwork-io/terratest/modules/gcp"
"github.com/gruntwork-io/terratest/modules/logger"
"github.com/gruntwork-io/terratest/modules/terraform"
test_structure "github.com/gruntwork-io/terratest/modules/test-structure"
_ "github.com/lib/pq"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
const NAME_PREFIX_POSTGRES_REPLICAS = "postgres-replicas"
@@ -51,12 +52,35 @@ func TestPostgresReplicas(t *testing.T) {
terraform.Destroy(t, terraformOptions)
})
// AT THE END OF THE TESTS, CLEAN UP ANY POSTGRES OBJECTS THAT WERE CREATED
defer test_structure.RunTestStage(t, "cleanup_postgres_objects", func() {
terraformOptions := test_structure.LoadTerraformOptions(t, exampleDir)
publicIp := terraform.Output(t, terraformOptions, OUTPUT_MASTER_PUBLIC_IP)
connectionString := fmt.Sprintf("postgres://%s:%s@%s/%s?sslmode=disable", DB_USER, DB_PASS, publicIp, DB_NAME)
// Does not actually open up the connection - just returns a DB ref
logger.Logf(t, "Connecting to: %s", publicIp)
db, err := sql.Open("postgres", connectionString)
require.NoError(t, err, "Failed to open DB connection")
// Make sure we clean up properly
defer db.Close()
// Drop table if it exists
logger.Logf(t, "Drop table: %s", POSTGRES_DROP_TEST_TABLE)
if _, err = db.Exec(POSTGRES_DROP_TEST_TABLE); err != nil {
t.Fatalf("Failed to drop table: %v", err)
}
})
test_structure.RunTestStage(t, "deploy", func() {
region := test_structure.LoadString(t, exampleDir, KEY_REGION)
projectId := test_structure.LoadString(t, exampleDir, KEY_PROJECT)
masterZone := test_structure.LoadString(t, exampleDir, KEY_MASTER_ZONE)
readReplicaZone := test_structure.LoadString(t, exampleDir, KEY_READ_REPLICA_ZONE)
terraformOptions := createTerratestOptionsForCloudSql(projectId, region, exampleDir, NAME_PREFIX_POSTGRES_REPLICAS, masterZone, "", 1, readReplicaZone)
terraformOptions := createTerratestOptionsForCloudSqlReplicas(projectId, region, exampleDir, NAME_PREFIX_POSTGRES_REPLICAS, masterZone, "", 1, readReplicaZone)
test_structure.SaveTerraformOptions(t, exampleDir, terraformOptions)
terraform.InitAndApply(t, terraformOptions)

View File

@@ -1,12 +1,13 @@
package test
import (
"github.com/gruntwork-io/terratest/modules/gcp"
"github.com/gruntwork-io/terratest/modules/terraform"
"github.com/stretchr/testify/require"
"io/ioutil"
"os"
"testing"
"github.com/gruntwork-io/terratest/modules/gcp"
"github.com/gruntwork-io/terratest/modules/terraform"
"github.com/stretchr/testify/require"
)
const DB_NAME = "testdb"
@@ -43,6 +44,7 @@ const SQL_QUERY_ROW_COUNT = "SELECT count(*) FROM test"
const POSTGRES_CREATE_TEST_TABLE_WITH_SERIAL = "CREATE TABLE IF NOT EXISTS test (id SERIAL, name varchar(10) NOT NULL, PRIMARY KEY (ID))"
const POSTGRES_INSERT_TEST_ROW = "INSERT INTO test(name) VALUES('Grunty') RETURNING id"
const POSTGRES_DROP_TEST_TABLE = "DROP TABLE IF EXISTS test"
func getRandomRegion(t *testing.T, projectID string) string {
approvedRegions := []string{"europe-north1", "europe-west1", "europe-west2", "europe-west3", "us-central1", "us-east1", "us-west1"}
@@ -63,8 +65,24 @@ func getTwoDistinctRandomZonesForRegion(t *testing.T, projectID string, region s
return firstZone, secondZone
}
func createTerratestOptionsForCloudSql(projectId string, region string, exampleDir string, namePrefix string, masterZone string, failoverReplicaZone string, numReadReplicas int, readReplicaZone string) *terraform.Options {
func createTerratestOptionsForCloudSql(projectId string, region string, exampleDir string, namePrefix string) *terraform.Options {
terratestOptions := &terraform.Options{
// The path to where your Terraform code is located
TerraformDir: exampleDir,
Vars: map[string]interface{}{
"region": region,
"project": projectId,
"name_prefix": namePrefix,
"db_name": DB_NAME,
"master_user_name": DB_USER,
"master_user_password": DB_PASS,
},
}
return terratestOptions
}
func createTerratestOptionsForCloudSqlReplicas(projectId string, region string, exampleDir string, namePrefix string, masterZone string, failoverReplicaZone string, numReadReplicas int, readReplicaZone string) *terraform.Options {
terratestOptions := &terraform.Options{
// The path to where your Terraform code is located
TerraformDir: exampleDir,