Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: extended the postgresql module to accept IAM users and services accounts #218

Merged
41 changes: 41 additions & 0 deletions examples/postgresql-public-iam/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Cloud SQL Database Example

This example shows how to create the public Postgres Cloud SQL database using the Terraform module with IAM accounts.

## Run Terraform

Create resources with terraform:

```bash
terraform init
terraform plan
terraform apply
```

To remove all resources created by terraform:

```bash
terraform destroy
```

<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| authorized\_networks | List of mapped public networks authorized to access to the instances. Default - short range of GCP health-checkers IPs | `list(map(string))` | <pre>[<br> {<br> "name": "sample-gcp-health-checkers-range",<br> "value": "130.211.0.0/28"<br> }<br>]</pre> | no |
| cloudsql\_pg\_sa | IAM service account user created for Cloud SQL. | `string` | n/a | yes |
| db\_name | The name of the SQL Database instance | `string` | `"example-postgres-public"` | no |
| project\_id | The ID of the project in which resources will be provisioned. | `string` | n/a | yes |

## Outputs

| Name | Description |
|------|-------------|
| name | The name for Cloud SQL instance |
| project\_id | The project to run tests against |
| psql\_conn | The connection name of the master instance to be used in connection strings |
| psql\_user\_pass | The password for the default user. If not set, a random one will be generated and available in the generated\_user\_password output variable. |
| public\_ip\_address | The first public (PRIMARY) IPv4 address assigned for the master instance |

<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
77 changes: 77 additions & 0 deletions examples/postgresql-public-iam/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/**
* Copyright 2019 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

provider "google" {
version = "~> 3.22"
}

provider "google-beta" {
version = "~> 3.5"
}

provider "null" {
version = "~> 2.1"
}

provider "random" {
version = "~> 2.2"
}

module "postgresql-db" {
source = "../../modules/postgresql"
name = var.db_name
random_instance_name = true
database_version = "POSTGRES_9_6"
project_id = var.project_id
zone = "us-central1-c"
region = "us-central1"
tier = "db-f1-micro"

deletion_protection = false

ip_configuration = {
ipv4_enabled = true
private_network = null
require_ssl = true
authorized_networks = var.authorized_networks
}

database_flags = [
{
name = "cloudsql.iam_authentication"
value = "On"
},
]

additional_users = [
{
name = "tftest2"
password = "abcdefg"
host = "localhost"
},
{
name = "tftest3"
password = "abcdefg"
host = "localhost"
},
]

# Supports creation of both IAM Users and IAM Service Accounts with provided emails
iam_user_emails = [
var.cloudsql_pg_sa,
"dbadmin@goosecorp.org",
]
}
40 changes: 40 additions & 0 deletions examples/postgresql-public-iam/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* Copyright 2019 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

output "project_id" {
value = var.project_id
description = "The project to run tests against"
}

output "name" {
description = "The name for Cloud SQL instance"
value = module.postgresql-db.instance_name
}

output "psql_conn" {
value = module.postgresql-db.instance_connection_name
description = "The connection name of the master instance to be used in connection strings"
}

output "psql_user_pass" {
value = module.postgresql-db.generated_user_password
description = "The password for the default user. If not set, a random one will be generated and available in the generated_user_password output variable."
}

output "public_ip_address" {
description = "The first public (PRIMARY) IPv4 address assigned for the master instance"
value = module.postgresql-db.public_ip_address
}
39 changes: 39 additions & 0 deletions examples/postgresql-public-iam/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* Copyright 2019 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

variable "project_id" {
description = "The ID of the project in which resources will be provisioned."
type = string
}

variable "authorized_networks" {
default = [{
name = "sample-gcp-health-checkers-range"
value = "130.211.0.0/28"
}]
type = list(map(string))
description = "List of mapped public networks authorized to access to the instances. Default - short range of GCP health-checkers IPs"
}

variable "db_name" {
description = "The name of the SQL Database instance"
default = "example-postgres-public"
}

variable "cloudsql_pg_sa" {
type = string
description = "IAM service account user created for Cloud SQL."
}
19 changes: 19 additions & 0 deletions examples/postgresql-public-iam/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* Copyright 2019 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

terraform {
required_version = ">=0.12.6"
}
5 changes: 5 additions & 0 deletions kitchen.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ suites:
name: terraform
root_module_directory: test/fixtures/postgresql-public
command_timeout: 1800
- name: postgresql-public-iam
driver:
name: terraform
root_module_directory: test/fixtures/postgresql-public-iam
command_timeout: 1800
- name: mysql-private
driver:
name: terraform
Expand Down
1 change: 1 addition & 0 deletions modules/postgresql/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Note: CloudSQL provides [disk autoresize](https://cloud.google.com/sql/docs/mysq
| enable\_default\_db | Enable or disable the creation of the default database | `bool` | `true` | no |
| enable\_default\_user | Enable or disable the creation of the default user | `bool` | `true` | no |
| encryption\_key\_name | The full path to the encryption key used for the CMEK disk encryption | `string` | `null` | no |
| iam\_user\_emails | A list of IAM users to be created in your cluster | `list(string)` | `[]` | no |
| insights\_config | The insights\_config settings for the database. | <pre>object({<br> query_string_length = number<br> record_application_tags = bool<br> record_client_address = bool<br> })</pre> | `null` | no |
| ip\_configuration | The ip configuration for the master instances. | <pre>object({<br> authorized_networks = list(map(string))<br> ipv4_enabled = bool<br> private_network = string<br> require_ssl = bool<br> })</pre> | <pre>{<br> "authorized_networks": [],<br> "ipv4_enabled": true,<br> "private_network": null,<br> "require_ssl": null<br>}</pre> | no |
| maintenance\_window\_day | The day of week (1-7) for the master instance maintenance. | `number` | `1` | no |
Expand Down
38 changes: 38 additions & 0 deletions modules/postgresql/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ locals {

databases = { for db in var.additional_databases : db.name => db }
users = { for u in var.additional_users : u.name => u }
iam_users = [for iu in var.iam_user_emails : {
email = iu,
is_account_sa = trimsuffix(iu, "gserviceaccount.com") == iu ? false : true
}]
}

resource "random_id" "suffix" {
Expand Down Expand Up @@ -173,6 +177,40 @@ resource "google_sql_user" "additional_users" {
depends_on = [null_resource.module_depends_on, google_sql_database_instance.default]
}

resource "google_project_iam_member" "iam_binding" {
for_each = {
for iu in local.iam_users :
"${iu.email} ${iu.is_account_sa}" => iu
}
project = var.project_id
role = "roles/cloudsql.instanceUser"
member = each.value.is_account_sa ? (
"serviceAccount:${each.value.email}"
) : (
"user:${each.value.email}"
)
}

resource "google_sql_user" "iam_account" {
for_each = {
for iu in local.iam_users :
"${iu.email} ${iu.is_account_sa}" => iu
}
project = var.project_id
name = each.value.is_account_sa ? (
trimsuffix(each.value.email, ".gserviceaccount.com")
) : (
each.value.email
)
instance = google_sql_database_instance.default.name
type = each.value.is_account_sa ? "CLOUD_IAM_SERVICE_ACCOUNT" : "CLOUD_IAM_USER"

depends_on = [
null_resource.module_depends_on,
google_project_iam_member.iam_binding,
]
}

resource "null_resource" "module_depends_on" {
triggers = {
value = length(var.module_depends_on)
Expand Down
6 changes: 6 additions & 0 deletions modules/postgresql/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,12 @@ variable "additional_users" {
default = []
}

variable "iam_user_emails" {
description = "A list of IAM users to be created in your cluster"
type = list(string)
default = []
}

variable "create_timeout" {
description = "The optional timout that is applied to limit long database creates."
type = string
Expand Down
24 changes: 24 additions & 0 deletions test/fixtures/postgresql-public-iam/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* Copyright 2019 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

module "example" {
source = "../../../examples/postgresql-public-iam"

project_id = var.project_id
authorized_networks = var.authorized_networks
db_name = var.db_name
cloudsql_pg_sa = var.cloudsql_pg_sa
}
40 changes: 40 additions & 0 deletions test/fixtures/postgresql-public-iam/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* Copyright 2019 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

output "project_id" {
value = module.example.project_id
description = "The project to run tests against"
}

output "name" {
value = module.example.name
description = "The name for Cloud SQL instance"
}

output "psql_conn" {
value = module.example.psql_conn
description = "The connection name of the master instance to be used in connection strings"
}

output "psql_user_pass" {
value = module.example.psql_user_pass
description = "The password for the default user. If not set, a random one will be generated and available in the generated_user_password output variable."
}

output "public_ip_address" {
description = "The first public (PRIMARY) IPv4 address assigned for the master instance"
value = module.example.public_ip_address
}
Loading