From 5c9645249c1af2220ff0d1d8a16e2c6ca3c92e44 Mon Sep 17 00:00:00 2001 From: Petri Autero Date: Tue, 26 Nov 2019 13:31:40 +0200 Subject: [PATCH 1/6] [skip ci] README updates --- README.md | 108 +++++++++++++++------------- _docs/cloud-sql-icon.png | Bin 0 -> 17067 bytes _docs/cloud-sql.png | Bin 0 -> 57816 bytes modules/cloud-sql/README.md | 110 ++++++++++++++--------------- modules/cloud-sql/core-concepts.md | 88 +++++++++++++++++++++++ 5 files changed, 200 insertions(+), 106 deletions(-) create mode 100644 _docs/cloud-sql-icon.png create mode 100644 _docs/cloud-sql.png create mode 100644 modules/cloud-sql/core-concepts.md diff --git a/README.md b/README.md index 92939c9..ac52ce2 100644 --- a/README.md +++ b/README.md @@ -1,23 +1,44 @@ + +# Cloud SQL Modules [![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 - - - This repo contains modules for running relational databases such as MySQL and PostgreSQL on [Google Cloud Platform (GCP)](https://cloud.google.com/) using [Cloud SQL](https://cloud.google.com/sql/). -## Quickstart +## Cloud SQL Architecture -If you want to quickly spin up a Cloud SQL database, you can run the example that is in the root of this repo. Check out -[postgres-private-ip example documentation](https://github.com/gruntwork-io/terraform-google-sql/blob/master/examples/postgres-private-ip) -for instructions. +![Cloud SQL Architecture](_docs/cloud-sql.png "Cloud SQL Architecture") -## What's in this repo +## Features + +- Deploy a fully-managed relational database +- Supports MySQL and PostgreSQL +- Optional failover instances +- Optional read replicas + +## Learn + +This repo is a part of [the Gruntwork Infrastructure as Code Library](https://gruntwork.io/infrastructure-as-code-library/), a collection of reusable, battle-tested, production ready infrastructure code. If you’ve never used the Infrastructure as Code Library before, make sure to read [How to use the Gruntwork Infrastructure as Code Library](https://gruntwork.io/guides/foundations/how-to-use-gruntwork-infrastructure-as-code-library/)! + +### Core concepts + +- [What is Cloud SQL](https://github.com/gruntwork-io/terraform-google-sql/blob/master/modules/cloud-sql/core-concepts.md#what-is-cloud-sql) +- [Cloud SQL documentation](https://cloud.google.com/sql/docs/) +- **[Designing Data Intensive Applications](https://dataintensive.net/)**: the best book we’ve found for understanding data systems, including relational databases, NoSQL, replication, sharding, consistency, and so on. + +### Repo organisation This repo has the following folder structure: @@ -30,68 +51,53 @@ This repo has the following folder structure: 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 - [PostgreSQL](https://cloud.google.com/sql/docs/postgres/) database. - + - [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 of how to use 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? +## Deploy -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: +### Non-production deployment (quick start for learning) -- 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. +If you just want to try this repo out for experimenting and learning, check out the following resources: -You can learn more about Cloud SQL from [the official documentation](https://cloud.google.com/sql/docs/). +- [examples folder](https://github.com/gruntwork-io/terraform-google-sql/blob/master/examples): The `examples` folder contains sample code optimized for learning, experimenting, and testing (but not production usage). -## What's a Module? +### Production deployment -A Module is a canonical, reusable, best-practices definition for how to run a single piece of infrastructure, such -as a database or server cluster. Each Module is written using a combination of [Terraform](https://www.terraform.io/) -and scripts (mostly bash) and include automated tests, documentation, and examples. It is maintained both by the open -source community and companies that provide commercial support. +If you want to deploy this repo in production, check out the following resources: -Instead of figuring out the details of how to run a piece of infrastructure from scratch, you can reuse -existing code that has been proven in production. And instead of maintaining all that infrastructure code yourself, -you can leverage the work of the Module community to pick up infrastructure improvements through -a version number bump. +- [cloud-sql module in the GCP Reference Architecture](https://github.com/gruntwork-io/infrastructure-modules-google/tree/master/data-stores/cloud-sql): Production-ready sample code from the GCP Reference Architecture. -## Who maintains this Module? +## Manage -This Module and its Submodules are maintained by [Gruntwork](http://www.gruntwork.io/). Read the [Gruntwork Philosophy](https://github.com/gruntwork-io/terraform-google-sql/blob/master/GRUNTWORK_PHILOSOPHY.md) document to learn more about how Gruntwork builds production grade infrastructure code. If you are looking for help or -commercial support, send an email to -[support@gruntwork.io](mailto:support@gruntwork.io?Subject=Google%20SQL%20Module). +### Day-to-day operations -Gruntwork can help with: +- [How to connect to a Cloud SQL instance](https://github.com/gruntwork-io/terraform-google-sql/tree/master/modules/cloud-sql/core-concepts.md#how-do-you-connect-to-the-database) +- [How to configure high availability](https://github.com/gruntwork-io/terraform-google-sql/tree/master/modules/cloud-sql/core-concepts.md#how-do-you-configure-high-availability) +- [How to secure the database instance](https://github.com/gruntwork-io/terraform-google-sql/tree/master/modules/cloud-sql/core-concepts.md#how-do-you-secure-the-database) +- [How to scale the database](https://github.com/gruntwork-io/terraform-google-sql/tree/master/modules/cloud-sql/core-concepts.md#how-do-you-secure-the-database) -- 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. +## Support -## How do I contribute to this Module? +If you need help with this repo or anything else related to infrastructure or DevOps, Gruntwork offers [Commercial Support](https://gruntwork.io/support/) via Slack, email, and phone/video. If you’re already a Gruntwork customer, hop on Slack and ask away! If not, [subscribe now](https://www.gruntwork.io/pricing/). If you’re not sure, feel free to email us at [support@gruntwork.io](mailto:support@gruntwork.io). -Contributions are very welcome! Check out the [Contribution Guidelines](https://github.com/gruntwork-io/terraform-google-sql/blob/master/CONTRIBUTING.md) for instructions. +## Contributions -## How is this Module versioned? +Contributions to this repo are very welcome and appreciated! If you find a bug or want to add a new feature or even contribute an entirely new module, we are very happy to accept pull requests, provide feedback, and run your changes through our automated test suite. -This Module follows the principles of [Semantic Versioning](http://semver.org/). You can find each new release, along -with the changelog, in the [Releases Page](https://github.com/gruntwork-io/terraform-google-sql/releases). - -During initial development, the major version will be 0 (e.g., `0.x.y`), which indicates the code does not yet have a -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. +Please see [Contributing to the Gruntwork Infrastructure as Code Library](https://gruntwork.io/guides/foundations/how-to-use-gruntwork-infrastructure-as-code-library/#contributing-to-the-gruntwork-infrastructure-as-code-library) for instructions. ## 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. +Please see [LICENSE](https://github.com/gruntwork-io/terraform-google-sql/blob/master/LICENSE.txt) for details on how the code in this repo is licensed. Copyright © 2019 Gruntwork, Inc. + + + + diff --git a/_docs/cloud-sql-icon.png b/_docs/cloud-sql-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..aafdd06deeee3ed12f6f8af567a6e24b6437be4f GIT binary patch literal 17067 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 OWAJqKb6Mw<&;$S|My&b( literal 0 HcmV?d00001 diff --git a/_docs/cloud-sql.png b/_docs/cloud-sql.png new file mode 100644 index 0000000000000000000000000000000000000000..8c55ab233e8105d61bcdfd7ef319c29447708b67 GIT binary patch literal 57816 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 @@ -9,80 +13,70 @@ The cluster is managed by Google, automating backups, replication, patches, and This module helps you run [MySQL](https://cloud.google.com/sql/docs/mysql/) and [PostgreSQL](https://cloud.google.com/sql/docs/postgres/) databases in [Google Cloud](https://cloud.google.com/). -## How do you use this module? +## Cloud SQL Architecture -See the [examples](https://github.com/gruntwork-io/terraform-google-sql/tree/master/examples) folder for an example. +![Cloud SQL Architecture](../../_docs/cloud-sql.png "Cloud SQL Architecture") -## How do you configure this module? +## Features -This module allows you to configure a number of parameters, such as high availability, backup windows, maintenance window and replicas. -For a list of all available variables and their descriptions, see [variables.tf](https://github.com/gruntwork-io/terraform-google-sql/blob/master/modules/cloud-sql/variables.tf). +- Deploy a fully-managed relational database +- Supports MySQL and PostgreSQL +- Optional failover instances +- Optional read replicas -## How do you connect to the database? +## Learn -**Cloud SQL instances are created in a producer network (a VPC network internal to Google). They are not created in your VPC network. See https://cloud.google.com/sql/docs/mysql/private-ip** - -You can use both public IP and private IP to connect to a Cloud SQL instance. -Neither connection method affects the other; you must protect the public IP connection whether the instance is configured to use private IP or not. +This repo is a part of [the Gruntwork Infrastructure as Code Library](https://gruntwork.io/infrastructure-as-code-library/), a collection of reusable, battle-tested, production ready infrastructure code. If you’ve never used the Infrastructure as Code Library before, make sure to read [How to use the Gruntwork Infrastructure as Code Library](https://gruntwork.io/guides/foundations/how-to-use-gruntwork-infrastructure-as-code-library/)! -You can also use the [Cloud SQL Proxy for MySQL](https://cloud.google.com/sql/docs/mysql/sql-proxy) and [Cloud SQL Proxy for PostgreSQL](https://cloud.google.com/sql/docs/postgres/sql-proxy) -to connect to an instance that is also configured to use private IP. The proxy can connect using either the private IP address or a public IP address. +### Core concepts -This module provides the connection details as [Terraform output -variables](https://www.terraform.io/intro/getting-started/outputs.html). Use the public / private addresses depending on your configuration: +- [What is Cloud SQL](https://github.com/gruntwork-io/terraform-google-sql/blob/master/modules/cloud-sql/core-concepts.md#what-is-cloud-sql) +- [Cloud SQL documentation](https://cloud.google.com/sql/docs/) +- **[Designing Data Intensive Applications](https://dataintensive.net/)**: the best book we’ve found for understanding data systems, including relational databases, NoSQL, replication, sharding, consistency, and so on. +### Repo organisation -1. **Master Public IP Address** `master_public_ip_address`: The public IPv4 address of the master instance. -1. **Master Private IP Address** `master_private_ip_address`: The private IPv4 address of the master instance. -1. **Master Proxy connection** `master_proxy_connection`: Instance path for connecting with Cloud SQL Proxy; see [Connecting mysql Client Using the Cloud SQL Proxy](https://cloud.google.com/sql/docs/mysql/connect-admin-proxy). -1. **Read Replica Public IP Addresses** `read_replica_public_ip_addresses`: A list of read replica public IP addresses in the cluster. Use these addresses for reads (see "How do you scale this database?" below). -1. **Read Replica Private IP Addresses** `read_replica_private_ip_addresses`: A list of read replica private IP addresses in the cluster. Use these addresses for reads (see "How do you scale this database?" below). -1. **Read Replica Proxy Connections** `read_replica_proxy_connections`: A list of instance paths for connecting with Cloud SQL Proxy; see [Connecting Using the Cloud SQL Proxy](https://cloud.google.com/sql/docs/mysql/connect-admin-proxy). +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 + 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. -You can programmatically extract these variables in your Terraform templates and pass them to other resources. -You'll also see the variables at the end of each `terraform apply` call or if you run `terraform output`. +- [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. -For full connectivity options and detailed documentation, see [Connecting to Cloud SQL MySQL from External Applications](https://cloud.google.com/sql/docs/mysql/connect-external-app) and [Connecting to Cloud SQL PostgreSQL from External Applications](https://cloud.google.com/sql/docs/postgres/external-connection-methods). + The primary module is: -## How do you configure High Availability? + - [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 of how to use the submodules. -You can enable High Availability using the `enable_failover_replica` input variable. +- [test](https://github.com/gruntwork-io/terraform-google-sql/tree/master/test): Automated tests for the submodules + and examples. -### High Availability for MySQL +## Deploy -The configuration is made up of a primary instance (master) in the primary zone (`master_zone` input variable) and a failover replica in the secondary zone (`failover_replica_zone` input variable). -The failover replica is configured with the same database flags, users and passwords, authorized applications and networks, and databases as the primary instance. +### Non-production deployment (quick start for learning) -For full details about MySQL High Availability, see https://cloud.google.com/sql/docs/mysql/high-availability +If you just want to try this repo out for experimenting and learning, check out the following resources: -### High Availability for PostgreSQL +- [examples folder](https://github.com/gruntwork-io/terraform-google-sql/blob/master/examples): The `examples` folder contains sample code optimized for learning, experimenting, and testing (but not production usage). -A Cloud SQL PostgreSQL instance configured for HA is also called a _regional instance_ and is located in a primary and secondary zone within the configured region. Within a regional instance, -the configuration is made up of a primary instance (master) and a standby instance. You control the primary zone for the master instance -with input variable `master_zone` and Google will automatically place the standby instance in another zone. +### Production deployment -For full details about PostgreSQL High Availability, see https://cloud.google.com/sql/docs/postgres/high-availability +If you want to deploy this repo in production, check out the following resources: +- [cloud-sql module in the GCP Reference Architecture](https://github.com/gruntwork-io/infrastructure-modules-google/tree/master/data-stores/cloud-sql): Production-ready sample code from the GCP Reference Architecture. -## How do you secure this database? +## Manage -Cloud SQL customer data is encrypted when stored in database tables, temporary files, and backups. -External connections can be encrypted by using SSL, or by using the Cloud SQL Proxy, which automatically encrypts traffic to and from the database. -If you do not use the proxy, you can enforce SSL for external connections using the `require_ssl` input variable. +### Day-to-day operations -For further information, see https://cloud.google.com/blog/products/gcp/best-practices-for-securing-your-google-cloud-databases and -https://cloud.google.com/sql/faq#encryption - -## How do you scale this database? - -* **Storage**: Cloud SQL manages storage for you, automatically growing cluster volume up to 10TB You can set the -initial disk size using the `disk_size` input variable. -* **Vertical scaling**: To scale vertically (i.e. bigger DB instances with more CPU and RAM), use the `machine_type` - input variable. For a list of Cloud SQL Machine Types, see [Cloud SQL Pricing](https://cloud.google.com/sql/pricing#2nd-gen-pricing). -* **Horizontal scaling**: To scale horizontally, you can add more replicas using the `num_read_replicas` and `read_replica_zones` input variables, - and the module will automatically deploy the new instances, sync them to the master, and make them available as read - replicas. +- [How to connect to a Cloud SQL instance](https://github.com/gruntwork-io/terraform-google-sql/tree/master/modules/cloud-sql/core-concepts.md#how-do-you-connect-to-the-database) +- [How to configure high availability](https://github.com/gruntwork-io/terraform-google-sql/tree/master/modules/cloud-sql/core-concepts.md#how-do-you-configure-high-availability) +- [How to secure the database instance](https://github.com/gruntwork-io/terraform-google-sql/tree/master/modules/cloud-sql/core-concepts.md#how-do-you-secure-the-database) +- [How to scale the database](https://github.com/gruntwork-io/terraform-google-sql/tree/master/modules/cloud-sql/core-concepts.md#how-do-you-secure-the-database) ## Known Issues @@ -92,12 +86,18 @@ Due to limitations on the current `terraform` provider for Google, it is not pos See https://github.com/terraform-providers/terraform-provider-google/issues/2446 -### Read Replica and IP Addresses Outputs +## Support -Retrieving and outputting distinct values from list of maps is not possible with resources using `count` prior to `terraform 0.12`. -Instead we have to output the values JSON encoded - for example `read_replica_server_ca_certs`. For full details of the outputs and -their format, see [outputs.tf](https://github.com/gruntwork-io/terraform-google-sql/blob/master/modules/cloud-sql/outputs.tf). +If you need help with this repo or anything else related to infrastructure or DevOps, Gruntwork offers [Commercial Support](https://gruntwork.io/support/) via Slack, email, and phone/video. If you’re already a Gruntwork customer, hop on Slack and ask away! If not, [subscribe now](https://www.gruntwork.io/pricing/). If you’re not sure, feel free to email us at [support@gruntwork.io](mailto:support@gruntwork.io). -See https://github.com/hashicorp/terraform/issues/17048 +## Contributions +Contributions to this repo are very welcome and appreciated! If you find a bug or want to add a new feature or even contribute an entirely new module, we are very happy to accept pull requests, provide feedback, and run your changes through our automated test suite. +Please see [Contributing to the Gruntwork Infrastructure as Code Library](https://gruntwork.io/guides/foundations/how-to-use-gruntwork-infrastructure-as-code-library/#contributing-to-the-gruntwork-infrastructure-as-code-library) for instructions. + +## License + +Please see [LICENSE](https://github.com/gruntwork-io/terraform-google-sql/blob/master/LICENSE.txt) for details on how the code in this repo is licensed. + +Copyright © 2019 Gruntwork, Inc. diff --git a/modules/cloud-sql/core-concepts.md b/modules/cloud-sql/core-concepts.md new file mode 100644 index 0000000..0631949 --- /dev/null +++ b/modules/cloud-sql/core-concepts.md @@ -0,0 +1,88 @@ +# Core Cloud SQL Concepts + +## 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: + +- 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/). + +## How do you connect to the database? + +**Cloud SQL instances are created in a producer network (a VPC network internal to Google). They are not created in your VPC network. See https://cloud.google.com/sql/docs/mysql/private-ip** + +You can use both public IP and private IP to connect to a Cloud SQL instance. +Neither connection method affects the other; you must protect the public IP connection whether the instance is configured to use private IP or not. + +You can also use the [Cloud SQL Proxy for MySQL](https://cloud.google.com/sql/docs/mysql/sql-proxy) and [Cloud SQL Proxy for PostgreSQL](https://cloud.google.com/sql/docs/postgres/sql-proxy) +to connect to an instance that is also configured to use private IP. The proxy can connect using either the private IP address or a public IP address. + +This module provides the connection details as [Terraform output +variables](https://www.terraform.io/intro/getting-started/outputs.html). Use the public / private addresses depending on your configuration: + + +1. **Master Public IP Address** `master_public_ip_address`: The public IPv4 address of the master instance. +1. **Master Private IP Address** `master_private_ip_address`: The private IPv4 address of the master instance. +1. **Master Proxy connection** `master_proxy_connection`: Instance path for connecting with Cloud SQL Proxy; see [Connecting mysql Client Using the Cloud SQL Proxy](https://cloud.google.com/sql/docs/mysql/connect-admin-proxy). +1. **Read Replica Public IP Addresses** `read_replica_public_ip_addresses`: A list of read replica public IP addresses in the cluster. Use these addresses for reads (see "How do you scale this database?" below). +1. **Read Replica Private IP Addresses** `read_replica_private_ip_addresses`: A list of read replica private IP addresses in the cluster. Use these addresses for reads (see "How do you scale this database?" below). +1. **Read Replica Proxy Connections** `read_replica_proxy_connections`: A list of instance paths for connecting with Cloud SQL Proxy; see [Connecting Using the Cloud SQL Proxy](https://cloud.google.com/sql/docs/mysql/connect-admin-proxy). + + +You can programmatically extract these variables in your Terraform templates and pass them to other resources. +You'll also see the variables at the end of each `terraform apply` call or if you run `terraform output`. + +For full connectivity options and detailed documentation, see [Connecting to Cloud SQL MySQL from External Applications](https://cloud.google.com/sql/docs/mysql/connect-external-app) and [Connecting to Cloud SQL PostgreSQL from External Applications](https://cloud.google.com/sql/docs/postgres/external-connection-methods). + +## How do you configure High Availability? + +You can enable High Availability using the `enable_failover_replica` input variable. + +### High Availability for MySQL + +The configuration is made up of a primary instance (master) in the primary zone (`master_zone` input variable) and a failover replica in the secondary zone (`failover_replica_zone` input variable). +The failover replica is configured with the same database flags, users and passwords, authorized applications and networks, and databases as the primary instance. + +For full details about MySQL High Availability, see https://cloud.google.com/sql/docs/mysql/high-availability + +### High Availability for PostgreSQL + +A Cloud SQL PostgreSQL instance configured for HA is also called a _regional instance_ and is located in a primary and secondary zone within the configured region. Within a regional instance, +the configuration is made up of a primary instance (master) and a standby instance. You control the primary zone for the master instance +with input variable `master_zone` and Google will automatically place the standby instance in another zone. + +For full details about PostgreSQL High Availability, see https://cloud.google.com/sql/docs/postgres/high-availability + + +## How do you secure the database? + +Cloud SQL customer data is encrypted when stored in database tables, temporary files, and backups. +External connections can be encrypted by using SSL, or by using the Cloud SQL Proxy, which automatically encrypts traffic to and from the database. +If you do not use the proxy, you can enforce SSL for external connections using the `require_ssl` input variable. + +For further information, see https://cloud.google.com/blog/products/gcp/best-practices-for-securing-your-google-cloud-databases and +https://cloud.google.com/sql/faq#encryption + +## How do you scale the database? + +* **Storage**: Cloud SQL manages storage for you, automatically growing cluster volume up to 10TB You can set the + initial disk size using the `disk_size` input variable. +* **Vertical scaling**: To scale vertically (i.e. bigger DB instances with more CPU and RAM), use the `machine_type` + input variable. For a list of Cloud SQL Machine Types, see [Cloud SQL Pricing](https://cloud.google.com/sql/pricing#2nd-gen-pricing). +* **Horizontal scaling**: To scale horizontally, you can add more replicas using the `num_read_replicas` and `read_replica_zones` input variables, + and the module will automatically deploy the new instances, sync them to the master, and make them available as read + replicas. + +## Known issues + +### Instance Recovery + +Due to limitations on the current `terraform` provider for Google, it is not possible to restore backups with `terraform`. + +See https://github.com/terraform-providers/terraform-provider-google/issues/2446 + From d589e4ca5b81c4c791d7e46080f32ad0bd0b8c82 Mon Sep 17 00:00:00 2001 From: Petri Autero Date: Tue, 26 Nov 2019 13:36:03 +0200 Subject: [PATCH 2/6] [skip ci] Remove know issues from core concepts --- modules/cloud-sql/core-concepts.md | 9 --------- 1 file changed, 9 deletions(-) diff --git a/modules/cloud-sql/core-concepts.md b/modules/cloud-sql/core-concepts.md index 0631949..b909947 100644 --- a/modules/cloud-sql/core-concepts.md +++ b/modules/cloud-sql/core-concepts.md @@ -77,12 +77,3 @@ https://cloud.google.com/sql/faq#encryption * **Horizontal scaling**: To scale horizontally, you can add more replicas using the `num_read_replicas` and `read_replica_zones` input variables, and the module will automatically deploy the new instances, sync them to the master, and make them available as read replicas. - -## Known issues - -### Instance Recovery - -Due to limitations on the current `terraform` provider for Google, it is not possible to restore backups with `terraform`. - -See https://github.com/terraform-providers/terraform-provider-google/issues/2446 - From fb90c4fae90b07b44b165f3f05cfa78b33c00551 Mon Sep 17 00:00:00 2001 From: Petri Autero Date: Wed, 27 Nov 2019 14:54:20 +0200 Subject: [PATCH 3/6] [skip ci] Change to open-source license --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ac52ce2..269c5bb 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ :category: database :cloud: gcp :tags: database, mysql, postgresql -:license: gruntwork +:license: open-source :built-with: terraform --> # Cloud SQL Modules From 9dcc25b36dbe5eeca2c038f89da478996824186a Mon Sep 17 00:00:00 2001 From: Petri Autero Date: Wed, 27 Nov 2019 14:55:07 +0200 Subject: [PATCH 4/6] [skip ci] Restore tag badge --- modules/cloud-sql/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/cloud-sql/README.md b/modules/cloud-sql/README.md index b41e862..477ffa6 100644 --- a/modules/cloud-sql/README.md +++ b/modules/cloud-sql/README.md @@ -1,6 +1,7 @@ # Cloud SQL Module [![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) From a1aac03fe84baabf443d4a05501b2f0739b18e06 Mon Sep 17 00:00:00 2001 From: Petri Autero Date: Wed, 27 Nov 2019 15:05:52 +0200 Subject: [PATCH 5/6] [skip ci] Absolute link --- README.md | 2 +- modules/cloud-sql/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 269c5bb..f46a31f 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ This repo contains modules for running relational databases such as MySQL and Po ## Cloud SQL Architecture -![Cloud SQL Architecture](_docs/cloud-sql.png "Cloud SQL Architecture") +![Cloud SQL Architecture](https://github.com/gruntwork-io/terraform-google-sql/blob/master/_docs/cloud-sql.png "Cloud SQL Architecture") ## Features diff --git a/modules/cloud-sql/README.md b/modules/cloud-sql/README.md index 477ffa6..a237970 100644 --- a/modules/cloud-sql/README.md +++ b/modules/cloud-sql/README.md @@ -16,7 +16,7 @@ This module helps you run [MySQL](https://cloud.google.com/sql/docs/mysql/) and ## Cloud SQL Architecture -![Cloud SQL Architecture](../../_docs/cloud-sql.png "Cloud SQL Architecture") +![Cloud SQL Architecture](https://github.com/gruntwork-io/terraform-google-sql/blob/master/_docs/cloud-sql.png "Cloud SQL Architecture") ## Features From 5d1ab21f93b672a8b94e6cefcadae7d7b1f5278a Mon Sep 17 00:00:00 2001 From: Petri Autero Date: Thu, 28 Nov 2019 13:06:32 +0200 Subject: [PATCH 6/6] [skip ci] Prod deployment notes --- README.md | 4 +++- modules/cloud-sql/README.md | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f46a31f..4cce5a2 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,9 @@ If you just want to try this repo out for experimenting and learning, check out If you want to deploy this repo in production, check out the following resources: -- [cloud-sql module in the GCP Reference Architecture](https://github.com/gruntwork-io/infrastructure-modules-google/tree/master/data-stores/cloud-sql): Production-ready sample code from the GCP Reference Architecture. +- [cloud-sql module in the GCP Reference Architecture](https://github.com/gruntwork-io/infrastructure-modules-google/tree/master/data-stores/cloud-sql): +Production-ready sample code from the GCP Reference Architecture. Note that the repository is private and accessible only with +Gruntwork subscription. To get access, [subscribe now](https://www.gruntwork.io/pricing/) or contact us at [support@gruntwork.io](mailto:support@gruntwork.io) for more information. ## Manage diff --git a/modules/cloud-sql/README.md b/modules/cloud-sql/README.md index a237970..7f4d4e4 100644 --- a/modules/cloud-sql/README.md +++ b/modules/cloud-sql/README.md @@ -68,7 +68,9 @@ If you just want to try this repo out for experimenting and learning, check out If you want to deploy this repo in production, check out the following resources: -- [cloud-sql module in the GCP Reference Architecture](https://github.com/gruntwork-io/infrastructure-modules-google/tree/master/data-stores/cloud-sql): Production-ready sample code from the GCP Reference Architecture. +- [cloud-sql module in the GCP Reference Architecture](https://github.com/gruntwork-io/infrastructure-modules-google/tree/master/data-stores/cloud-sql): +Production-ready sample code from the GCP Reference Architecture. Note that the repository is private and accessible only with +Gruntwork subscription. To get access, [subscribe now](https://www.gruntwork.io/pricing/) or contact us at [support@gruntwork.io](mailto:support@gruntwork.io) for more information. ## Manage