From ca9016452053d6312753e528e6b882de0f659db3 Mon Sep 17 00:00:00 2001 From: Andriy Kopachevskyy Date: Fri, 27 Dec 2019 16:15:14 +0200 Subject: [PATCH] Added IAM member submodule * Fix #75 --- .kitchen.yml | 13 +++++ build/int.cloudbuild.yaml | 20 ++++++++ examples/member_iam/README.md | 26 ++++++++++ examples/member_iam/main.tf | 39 +++++++++++++++ examples/member_iam/outputs.tf | 30 +++++++++++ examples/member_iam/variables.tf | 20 ++++++++ examples/member_iam/versions.tf | 19 +++++++ modules/member_iam/README.md | 32 ++++++++++++ modules/member_iam/main.tf | 22 ++++++++ modules/member_iam/outputs.tf | 25 ++++++++++ modules/member_iam/variables.tf | 30 +++++++++++ test/fixtures/member-iam/main.tf | 20 ++++++++ test/fixtures/member-iam/outputs.tf | 25 ++++++++++ test/fixtures/member-iam/variables.tf | 20 ++++++++ test/fixtures/member-iam/versions.tf | 19 +++++++ test/integration/member-iam/controls/roles.rb | 50 +++++++++++++++++++ test/integration/member-iam/inspec.yml | 27 ++++++++++ test/setup/versions.tf | 4 +- 18 files changed, 439 insertions(+), 2 deletions(-) create mode 100644 examples/member_iam/README.md create mode 100644 examples/member_iam/main.tf create mode 100644 examples/member_iam/outputs.tf create mode 100644 examples/member_iam/variables.tf create mode 100644 examples/member_iam/versions.tf create mode 100644 modules/member_iam/README.md create mode 100644 modules/member_iam/main.tf create mode 100644 modules/member_iam/outputs.tf create mode 100644 modules/member_iam/variables.tf create mode 100644 test/fixtures/member-iam/main.tf create mode 100644 test/fixtures/member-iam/outputs.tf create mode 100644 test/fixtures/member-iam/variables.tf create mode 100644 test/fixtures/member-iam/versions.tf create mode 100644 test/integration/member-iam/controls/roles.rb create mode 100644 test/integration/member-iam/inspec.yml diff --git a/.kitchen.yml b/.kitchen.yml index 61fa6569..4b61fa30 100644 --- a/.kitchen.yml +++ b/.kitchen.yml @@ -71,3 +71,16 @@ suites: backend: local provisioner: name: terraform + + - name: member-iam + driver: + name: terraform + command_timeout: 1800 + root_module_directory: test/fixtures/member-iam + verifier: + name: terraform + systems: + - name: member-iam + backend: local + provisioner: + name: terraform diff --git a/build/int.cloudbuild.yaml b/build/int.cloudbuild.yaml index 80c876eb..0e4e0537 100644 --- a/build/int.cloudbuild.yaml +++ b/build/int.cloudbuild.yaml @@ -22,6 +22,26 @@ steps: - 'TF_VAR_folder_id=$_FOLDER_ID' - 'TF_VAR_billing_account=$_BILLING_ACCOUNT' +- id: create member-iam-local + waitFor: + - prepare + name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' + args: ['/bin/bash', '-c', 'source /usr/local/bin/task_helper_functions.sh && kitchen_do create member-iam-local'] +- id: converge member-iam-local + waitFor: + - create member-iam-local + name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' + args: ['/bin/bash', '-c', 'source /usr/local/bin/task_helper_functions.sh && kitchen_do converge member-iam-local'] +- id: verify member-iam-local + waitFor: + - converge member-iam-local + name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' + args: ['/bin/bash', '-c', 'source /usr/local/bin/task_helper_functions.sh && kitchen_do verify member-iam-local'] +- id: destroy member-iam-local + waitFor: + - verify member-iam-local + name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' + args: ['/bin/bash', '-c', 'source /usr/local/bin/task_helper_functions.sh && kitchen_do destroy member-iam-local'] # ----- SUITE additive-local diff --git a/examples/member_iam/README.md b/examples/member_iam/README.md new file mode 100644 index 00000000..17928d41 --- /dev/null +++ b/examples/member_iam/README.md @@ -0,0 +1,26 @@ +# Member iam Module Example + +This example illustrates how to use the `member_iam` submodule + +## Requirements +### Installed Software +- [Terraform](https://www.terraform.io/downloads.html) ~> 0.12.6 +- [Terraform Provider for GCP](https://github.com/terraform-providers/terraform-provider-google) ~> 2.19 +- [Terraform Provider for GCP Beta](https://github.com/terraform-providers/terraform-provider-google-beta) ~> 2.19 + + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|:----:|:-----:|:-----:| +| project\_id | Project id | string | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| project\_id | Project id. | +| roles | Project roles. | +| service\_account\_address | Member which was bound to projects. | + + diff --git a/examples/member_iam/main.tf b/examples/member_iam/main.tf new file mode 100644 index 00000000..390cedcf --- /dev/null +++ b/examples/member_iam/main.tf @@ -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. + */ + +/****************************************** + Provider configuration + *****************************************/ +provider "google" { + version = "~> 2.19" +} + +provider "google-beta" { + version = "~> 2.19" +} + +resource "google_service_account" "member_iam_test" { + project = var.project_id + account_id = "member-iam-test" + display_name = "member-iam-test" +} + +module "member_roles" { + source = "../../modules/member_iam" + service_account_address = google_service_account.member_iam_test.email + project_id = var.project_id + project_roles = ["roles/compute.networkAdmin", "roles/appengine.appAdmin"] +} diff --git a/examples/member_iam/outputs.tf b/examples/member_iam/outputs.tf new file mode 100644 index 00000000..acb37799 --- /dev/null +++ b/examples/member_iam/outputs.tf @@ -0,0 +1,30 @@ +/** + * 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 "roles" { + value = module.member_roles.roles + description = "Project roles." +} + +output "project_id" { + value = var.project_id + description = "Project id." +} + +output "service_account_address" { + value = google_service_account.member_iam_test.email + description = "Member which was bound to projects." +} diff --git a/examples/member_iam/variables.tf b/examples/member_iam/variables.tf new file mode 100644 index 00000000..56e204c0 --- /dev/null +++ b/examples/member_iam/variables.tf @@ -0,0 +1,20 @@ +/** + * 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 = "Project id" + type = string +} diff --git a/examples/member_iam/versions.tf b/examples/member_iam/versions.tf new file mode 100644 index 00000000..27ba8fc1 --- /dev/null +++ b/examples/member_iam/versions.tf @@ -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" +} diff --git a/modules/member_iam/README.md b/modules/member_iam/README.md new file mode 100644 index 00000000..fb758fac --- /dev/null +++ b/modules/member_iam/README.md @@ -0,0 +1,32 @@ +# Module Member IAM + +This optional module is used to assign service account roles + +## Example Usage +``` +module "member_roles" { + source = "terraform-google-modules/iam/google//modules/member_iam" + service_account = "my-sa@my-project.iam.gserviceaccount.com" + project = "my-project-one" + project_roles = ["roles/compute.networkAdmin", "roles/appengine.appAdmin"] +} + +``` + + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|:----:|:-----:|:-----:| +| project\_id | Project id | string | n/a | yes | +| project\_roles | List of IAM roles | list(string) | n/a | yes | +| service\_account\_address | Service account address | string | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| project\_id | Project id. | +| roles | Project roles. | + + diff --git a/modules/member_iam/main.tf b/modules/member_iam/main.tf new file mode 100644 index 00000000..a9b3f69c --- /dev/null +++ b/modules/member_iam/main.tf @@ -0,0 +1,22 @@ +/** + * 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. + */ + +resource "google_project_iam_member" "project_iam_member" { + for_each = toset(var.project_roles) + project = var.project_id + role = each.key + member = "serviceAccount:${var.service_account_address}" +} diff --git a/modules/member_iam/outputs.tf b/modules/member_iam/outputs.tf new file mode 100644 index 00000000..7840f357 --- /dev/null +++ b/modules/member_iam/outputs.tf @@ -0,0 +1,25 @@ +/** + * 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 "roles" { + value = google_project_iam_member.project_iam_member + description = "Project roles." +} + +output "project_id" { + value = var.project_id + description = "Project id." +} diff --git a/modules/member_iam/variables.tf b/modules/member_iam/variables.tf new file mode 100644 index 00000000..72f7b8df --- /dev/null +++ b/modules/member_iam/variables.tf @@ -0,0 +1,30 @@ +/** + * 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 "service_account_address" { + description = "Service account address" + type = string +} + +variable "project_id" { + description = "Project id" + type = string +} + +variable "project_roles" { + description = "List of IAM roles" + type = list(string) +} diff --git a/test/fixtures/member-iam/main.tf b/test/fixtures/member-iam/main.tf new file mode 100644 index 00000000..41fc7f44 --- /dev/null +++ b/test/fixtures/member-iam/main.tf @@ -0,0 +1,20 @@ +/** + * 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 "member_roles" { + source = "../../../examples/member_iam" + project_id = var.project_id +} diff --git a/test/fixtures/member-iam/outputs.tf b/test/fixtures/member-iam/outputs.tf new file mode 100644 index 00000000..1fe8440f --- /dev/null +++ b/test/fixtures/member-iam/outputs.tf @@ -0,0 +1,25 @@ +/** + * 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 = "Project id." +} + +output "service_account_email" { + value = module.member_roles.service_account_address + description = "Member which was bound to projects." +} diff --git a/test/fixtures/member-iam/variables.tf b/test/fixtures/member-iam/variables.tf new file mode 100644 index 00000000..56e204c0 --- /dev/null +++ b/test/fixtures/member-iam/variables.tf @@ -0,0 +1,20 @@ +/** + * 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 = "Project id" + type = string +} diff --git a/test/fixtures/member-iam/versions.tf b/test/fixtures/member-iam/versions.tf new file mode 100644 index 00000000..29704272 --- /dev/null +++ b/test/fixtures/member-iam/versions.tf @@ -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" +} diff --git a/test/integration/member-iam/controls/roles.rb b/test/integration/member-iam/controls/roles.rb new file mode 100644 index 00000000..b7487743 --- /dev/null +++ b/test/integration/member-iam/controls/roles.rb @@ -0,0 +1,50 @@ +# 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 +# +# https://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. + +project_id = attribute('project_id') +service_account_email = attribute('service_account_email') + +control 'Member IAM check' do + title "Member IAM check" + + describe command("gcloud projects get-iam-policy #{project_id} --format=json") do + its('exit_status') { should eq 0 } + its('stderr') { should eq '' } + + let(:bindings) do + if subject.exit_status == 0 + JSON.parse(subject.stdout, symbolize_names: true)[:bindings] + else + [] + end + end + + describe "roles/compute.networkUser" do + it "includes the project service account in the roles/compute.networkAdmin IAM binding" do + expect(bindings).to include( + members: including("serviceAccount:#{service_account_email}"), + role: "roles/compute.networkAdmin", + ) + end + + it "includes the group email in the roles/appengine.appAdmin IAM binding" do + expect(bindings).to include( + members: including("serviceAccount:#{service_account_email}"), + role: "roles/appengine.appAdmin", + ) + end + + end + end +end diff --git a/test/integration/member-iam/inspec.yml b/test/integration/member-iam/inspec.yml new file mode 100644 index 00000000..2eeb9e78 --- /dev/null +++ b/test/integration/member-iam/inspec.yml @@ -0,0 +1,27 @@ +# 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. + +name: member-iam +depends: + - name: inspec-gcp + git: https://github.com/inspec/inspec-gcp.git + tag: v0.10.0 +attributes: + - name: project_id + required: true + type: string + - name: service_account_email + required: true + type: string + diff --git a/test/setup/versions.tf b/test/setup/versions.tf index 753832a9..d3897c37 100644 --- a/test/setup/versions.tf +++ b/test/setup/versions.tf @@ -19,11 +19,11 @@ terraform { } provider "google" { - version = "~> 2.13.0" + version = "~> 2.12.0" } provider "google-beta" { - version = "~> 2.13.0" + version = "~> 2.12.0" }