Skip to content

Commit

Permalink
feat: extended the postgresql module to accept IAM users and services…
Browse files Browse the repository at this point in the history
… accounts (#218)

* feat: extended the postgresql module to accept IAM
users and services accounts.

* feat: extended the postgresql module to accept IAM
users and services accounts.
  • Loading branch information
g-awmalik committed May 19, 2021
1 parent b81ff73 commit 4c0472e
Show file tree
Hide file tree
Showing 18 changed files with 571 additions and 1 deletion.
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
}

0 comments on commit 4c0472e

Please sign in to comment.