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

Refactor outputs for 0.12, switch from maps to lists #9

Merged
merged 8 commits into from
Aug 14, 2019
Merged
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ and this project adheres to

## [Unreleased]

- Added new `service_account` and `service_accounts` outputs for single and multi user use that expose the base resources, now possible with Terraform 0.12.
- Added new `emails_list` and `iam_emails_list` outputs that return lists, and are guaranteed to keep the same ordering for resources as the map type outputs.
- Refactored the formatted list generation for the `iam_emails` and new `iam_emails_list` outputs to use the new `for` expression, fixing issues with `formatlist` and `zipmap` in Terraform 0.12.
- Refactored and simplified the `keys` template and output using the new splat syntax.

## [1.0.0] - 2019-07-26

### CHANGED
Expand Down
23 changes: 13 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,33 +37,36 @@ module "service_accounts" {
Functional examples are included in the
[examples](./examples/) directory.

[^]: (autogen_docs_start)
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|:----:|:-----:|:-----:|
| billing\_account\_id | If assigning billing role, specificy a billing account (default is to assign at the organizational level). | string | `""` | no |
| generate\_keys | Generate keys for service accounts. | string | `"false"` | no |
| grant\_billing\_role | Grant billing user role. | string | `"false"` | no |
| grant\_xpn\_roles | Grant roles for shared VPC management. | string | `"true"` | no |
| names | Names of the service accounts to create. | list | `<list>` | no |
| generate\_keys | Generate keys for service accounts. | bool | `"false"` | no |
| grant\_billing\_role | Grant billing user role. | bool | `"false"` | no |
| grant\_xpn\_roles | Grant roles for shared VPC management. | bool | `"true"` | no |
| names | Names of the service accounts to create. | list(string) | `<list>` | no |
| org\_id | Id of the organization for org-level roles. | string | `""` | no |
| prefix | Prefix applied to service account names. | string | `""` | no |
| project\_id | Project id where service account will be created. | string | n/a | yes |
| project\_roles | Common roles to apply to all service accounts, project=>role as elements. | list | `<list>` | no |
| project\_roles | Common roles to apply to all service accounts, project=>role as elements. | list(string) | `<list>` | no |

## Outputs

| Name | Description |
|------|-------------|
| email | Service account email (single-use case). |
| emails | Map of service account emails. |
| iam\_email | IAM-format service account email (single-use case). |
| email | Service account email (for single use). |
| emails | Service account emails. |
| iam\_email | IAM-format service account email (for single use). |
| iam\_emails | IAM-format service account emails. |
| key | Service account key (for single use). |
| keys | Map of service account keys. |
| service\_account | Service account resource (for single use). |
| service\_accounts | Service account resources. |

[^]: (autogen_docs_end)
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->

## Requirements

Expand Down
5 changes: 2 additions & 3 deletions examples/multiple_service_accounts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

This example illustrates how to use the `service-accounts` module to generate multiple service accounts.

[^]: (autogen_docs_start)

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

| Name | Description | Type | Default | Required |
Expand All @@ -18,7 +17,7 @@ This example illustrates how to use the `service-accounts` module to generate mu
| iam\_emails | The service account IAM-format emails. |
| keys | The service account keys. |

[^]: (autogen_docs_end)
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->

To provision this example, run the following from within this directory:
- `terraform init` to get the plugins
Expand Down
11 changes: 8 additions & 3 deletions examples/multiple_service_accounts/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,17 @@

output "emails" {
description = "The service account emails."
value = values(module.service_accounts.emails)
value = module.service_accounts.emails
}

output "emails_list" {
description = "The service account emails as a list."
value = module.service_accounts.emails_list
}

output "iam_emails" {
description = "The service account IAM-format emails."
value = values(module.service_accounts.iam_emails)
description = "The service account IAM-format emails as a map."
value = module.service_accounts.iam_emails
}

output "keys" {
Expand Down
6 changes: 3 additions & 3 deletions examples/single_service_account/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

This example illustrates how to use the `service-accounts` module to generate a single service account.

[^]: (autogen_docs_start)

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

| Name | Description | Type | Default | Required |
|------|-------------|:----:|:-----:|:-----:|
| prefix | Prefix applied to service account names. | string | `""` | no |
| project\_id | The ID of the project in which to provision resources. | string | n/a | yes |

## Outputs
Expand All @@ -17,7 +17,7 @@ This example illustrates how to use the `service-accounts` module to generate a
| email | The service account email. |
| iam\_email | The service account IAM-format email. |

[^]: (autogen_docs_end)
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->

To provision this example, run the following from within this directory:
- `terraform init` to get the plugins
Expand Down
2 changes: 1 addition & 1 deletion examples/single_service_account/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

output "email" {
description = "The service account email."
value = module.service_accounts.email
value = module.service_accounts.service_account.email
}

output "iam_email" {
Expand Down
1 change: 1 addition & 0 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ locals {
org_billing = var.grant_billing_role && var.billing_account_id == "" && var.org_id != ""
prefix = var.prefix != "" ? "${var.prefix}-" : ""
xpn = var.grant_xpn_roles && var.org_id != ""
iam_emails = [for s in google_service_account.service_accounts : "serviceAccount:${s.email}"]
}

# create service accounts
Expand Down
54 changes: 32 additions & 22 deletions outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -14,52 +14,62 @@
* limitations under the License.
*/

output "service_account" {
description = "Service account resource (for single use)."
value = google_service_account.service_accounts[0]
}

output "email" {
description = "Service account email (single-use case)."
description = "Service account email (for single use)."
value = google_service_account.service_accounts[0].email
}

output "iam_email" {
description = "IAM-format service account email (single-use case)."
description = "IAM-format service account email (for single use)."
value = "serviceAccount:${google_service_account.service_accounts[0].email}"
}

output "key" {
description = "Service account key (for single use)."
value = data.template_file.keys[0].rendered
}

output "service_accounts" {
description = "Service account resources."
value = google_service_account.service_accounts
}

output "emails" {
description = "Map of service account emails."
value = zipmap(var.names, google_service_account.service_accounts.*.email)
description = "Service account emails."
value = zipmap(var.names, google_service_account.service_accounts[*].email)
ludoo marked this conversation as resolved.
Show resolved Hide resolved
}

output "iam_emails" {
description = "IAM-format service account emails."
value = zipmap(
var.names,
formatlist(
"serviceAccount:%s",
google_service_account.service_accounts.*.email,
),
)
value = zipmap(var.names, local.iam_emails)
}

output "emails_list" {
description = "Service account emails."
value = google_service_account.service_accounts[*].email
ludoo marked this conversation as resolved.
Show resolved Hide resolved
}

output "iam_emails_list" {
description = "IAM-format service account emails."
value = [for s in google_service_account.service_accounts : "serviceAccount:${s.email}"]
}

data "template_file" "keys" {
count = length(var.names)
template = "$${key}"

vars = {
key = var.generate_keys ? base64decode(
element(
concat(google_service_account_key.keys.*.private_key, [""]),
count.index,
),
) : ""
key = var.generate_keys ? base64decode(google_service_account_key.keys[count.index].private_key) : ""
}
}

output "keys" {
description = "Map of service account keys."
sensitive = true
value = zipmap(
formatlist("%s-key.json", var.names),
data.template_file.keys.*.rendered,
)
value = zipmap(var.names, data.template_file.keys[*].rendered)
morgante marked this conversation as resolved.
Show resolved Hide resolved
}

15 changes: 15 additions & 0 deletions test/fixtures/multiple_service_accounts/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,21 @@ output "emails" {
value = module.example.emails
}

output "emails_list" {
description = "The service account emails as a list."
value = module.example.emails_list
}

output "iam_emails" {
description = "The service account IAM-format emails as a map."
value = module.example.iam_emails
}

output "keys" {
description = "The service account keys."
value = module.example.keys
}

output "project_id" {
description = "Project id variable."
value = var.project_id
Expand Down
15 changes: 9 additions & 6 deletions test/integration/multiple_service_accounts/controls/gcp.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,18 @@
control "gcp" do
title "GCP Resources"

attribute('emails').each do |email|
describe google_service_accounts(project: "#{attribute('project_id')}") do
its('service_account_emails'){ should include email }
end
attribute('iam_emails').each_value do |email|
describe google_project_iam_binding(project: "#{attribute("project_id")}", role: 'roles/viewer') do
its('members') {should include "serviceAccount:#{email}" }
morgante marked this conversation as resolved.
Show resolved Hide resolved
its('members') {should include email }
end
describe google_project_iam_binding(project: "#{attribute("project_id")}", role: 'roles/storage.objectViewer') do
its('members') {should include "serviceAccount:#{email}" }
its('members') {should include email }
end
end

attribute('emails_list').each do |email|
describe google_service_accounts(project: "#{attribute('project_id')}") do
its('service_account_emails'){ should include email }
end
end

Expand Down
6 changes: 6 additions & 0 deletions test/integration/multiple_service_accounts/inspec.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,11 @@ attributes:
required: true
type: string
- name: emails
required: true
type: hash
- name: emails_list
required: true
type: array
- name: iam_emails
required: true
type: hash