diff --git a/modules/audit_config/main.tf b/modules/audit_config/main.tf new file mode 100644 index 00000000..57c06bf7 --- /dev/null +++ b/modules/audit_config/main.tf @@ -0,0 +1,32 @@ +/** + * 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. + */ + +locals { + audit_log_config = { + for key, val in var.audit_log_config : + key => val + } +} + +resource "google_project_iam_audit_config" "project" { + for_each = local.audit_log_config + project = var.project + service = each.value.service + audit_log_config { + log_type = each.value.log_type + exempted_members = each.value.exempted_members + } +} diff --git a/modules/audit_config/outputs.tf b/modules/audit_config/outputs.tf new file mode 100644 index 00000000..204e7cd9 --- /dev/null +++ b/modules/audit_config/outputs.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. + */ + +output "audit_log_config" { + value = var.audit_log_config + description = "Map of log type and exempted members to be added to service" +} diff --git a/modules/audit_config/variables.tf b/modules/audit_config/variables.tf new file mode 100644 index 00000000..701ed495 --- /dev/null +++ b/modules/audit_config/variables.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. + */ + +variable "audit_log_config" { + description = "List of objects to be added to audit log config" + type = list(object({ service : string, log_type : string, exempted_members : list(string) })) +} + +variable "project" { + description = "Project to add the IAM policies/bindings" + type = string +} diff --git a/test/fixtures/authoritative/outputs.tf b/test/fixtures/authoritative/outputs.tf index 75537362..2e9a82a0 100644 --- a/test/fixtures/authoritative/outputs.tf +++ b/test/fixtures/authoritative/outputs.tf @@ -120,3 +120,8 @@ output "roles" { value = tostring(var.roles) description = "Amount of roles assigned. Useful for testing how the module behaves on updates." } + +output "audit_config" { + value = module.generic.audit_config + description = "Map of log type and exempted members to be addded to service" +} diff --git a/test/fixtures/helper/iam.tf b/test/fixtures/helper/iam.tf index 6ce14ad9..584be665 100644 --- a/test/fixtures/helper/iam.tf +++ b/test/fixtures/helper/iam.tf @@ -99,3 +99,9 @@ module "iam_binding_pubsub_topic" { project = var.project_id bindings = local.basic_bindings } + +module "audit_config" { + source = "../../../modules/audit_config" + project = var.project_id + audit_log_config = local.audit_log_config +} diff --git a/test/fixtures/helper/main.tf b/test/fixtures/helper/main.tf index 25d58bb3..e7f32269 100644 --- a/test/fixtures/helper/main.tf +++ b/test/fixtures/helper/main.tf @@ -24,6 +24,17 @@ locals { bucket_roles = ["roles/storage.legacyObjectReader", "roles/storage.legacyBucketReader"] members = [var.member1, var.member2] + audit_log_config = [{ + service = "storage.googleapis.com" + log_type = "DATA_READ" + exempted_members = ["serviceAccount:${var.member1}"] + }, { + service = "allServices" + log_type = "DATA_READ" + exempted_members = ["serviceAccount:${var.member2}"] + + }] + member_group_0 = [ "serviceAccount:${var.member1}", "serviceAccount:${var.member2}", diff --git a/test/fixtures/helper/outputs.tf b/test/fixtures/helper/outputs.tf index dafd2e87..121f563b 100644 --- a/test/fixtures/helper/outputs.tf +++ b/test/fixtures/helper/outputs.tf @@ -114,3 +114,8 @@ output "project_id" { value = var.project_id description = "Project ID of the test fixture project. Used to avoid timing issues with recently created projects." } + +output "audit_config" { + description = "Map of log type and exempted members to be addded to service" + value = module.audit_config.audit_log_config +} diff --git a/test/integration/authoritative/controls/authoritative.rb b/test/integration/authoritative/controls/authoritative.rb index 4d305dcb..ddc92016 100644 --- a/test/integration/authoritative/controls/authoritative.rb +++ b/test/integration/authoritative/controls/authoritative.rb @@ -30,6 +30,7 @@ topics = attribute('topics') subscriptions = attribute('subscriptions') region = attribute('region') +audit_config = attribute('audit_config') # Role pairs (arrays of length = 2) basic_roles = attribute('basic_roles') @@ -259,3 +260,49 @@ end end end + +# Audit config + +control 'audit-log-config' do + title 'Test if audit log config is correct' + + describe command ("gcloud projects get-iam-policy #{project_id} --format='json(auditConfigs)'") do + its(:exit_status) { should eq 0 } + its(:stderr) { should eq '' } + let!(:data) do + if subject.exit_status == 0 + JSON.parse(subject.stdout) + else + {} + end + end + describe "check auditConfigs count" do + it "has two auditConfigs" do + expect(data["auditConfigs"].length).to eq 2 + end + end + describe "check members email" do + it "has correct exemptedMembers" do + data["auditConfigs"].each do |config| + expect([audit_config[0]["exempted_members"][0], audit_config[1]["exempted_members"][0]]).to include( + config["auditLogConfigs"][0]["exemptedMembers"][0] + ) + end + end + end + describe "check log type " do + it "has correct log type" do + expect(data["auditConfigs"][0]["auditLogConfigs"][0]["logType"]).to eq audit_config[0]["log_type"] + end + end + describe "check services " do + it "has correct Services" do + data["auditConfigs"].each do |config| + expect([audit_config[0]["service"],audit_config[1]["service"]]).to include ( + config["service"] + ) + end + end + end + end +end diff --git a/test/integration/authoritative/inspec.yml b/test/integration/authoritative/inspec.yml index baf1ddde..6ec8f538 100644 --- a/test/integration/authoritative/inspec.yml +++ b/test/integration/authoritative/inspec.yml @@ -74,3 +74,6 @@ attributes: - name: roles required: true type: string + - name: audit_config + required: true + type: array