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

Organization module end-to-end tests #1860

Merged
merged 5 commits into from
Nov 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
45 changes: 21 additions & 24 deletions modules/organization/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,16 @@ To manage organization policies, the `orgpolicy.googleapis.com` service should b
```hcl
module "org" {
source = "./fabric/modules/organization"
organization_id = "organizations/1234567890"
organization_id = var.organization_id
group_iam = {
"cloud-owners@example.org" = ["roles/owner", "roles/projectCreator"]
(var.group_email) = ["roles/owner"]
}
iam = {
"roles/resourcemanager.projectCreator" = ["group:cloud-admins@example.org"]
"roles/resourcemanager.projectCreator" = ["group:${var.group_email}"]
}
iam_bindings_additive = {
am1-storage-admin = {
member = "user:am1@example.org"
member = "group:${var.group_email}"
role = "roles/storage.admin"
}
}
Expand All @@ -57,9 +57,6 @@ module "org" {
}
}
org_policies = {
"custom.gkeEnableAutoUpgrade" = {
rules = [{ enforce = true }]
}
"compute.disableGuestAttributesAccess" = {
rules = [{ enforce = true }]
}
Expand Down Expand Up @@ -118,7 +115,7 @@ module "org" {
}
}
}
# tftest modules=1 resources=15 inventory=basic.yaml
# tftest modules=1 resources=13 inventory=basic.yaml e2e serial
```

## IAM
Expand Down Expand Up @@ -262,7 +259,7 @@ module "org" {
policy = module.firewall-policy.id
}
}
# tftest modules=2 resources=2
# tftest modules=2 resources=2 e2e serial
```

## Log Sinks
Expand All @@ -273,6 +270,7 @@ The following example shows how to define organization-level log sinks:
module "gcs" {
source = "./fabric/modules/gcs"
project_id = var.project_id
prefix = var.prefix
name = "gcs_sink"
force_destroy = true
}
Expand All @@ -292,7 +290,7 @@ module "pubsub" {
module "bucket" {
source = "./fabric/modules/logging-bucket"
parent_type = "project"
parent = "my-project"
parent = var.project_id
id = "bucket"
}

Expand Down Expand Up @@ -330,7 +328,7 @@ module "org" {
no-gce-instances = "resource.type=gce_instance"
}
}
# tftest modules=5 resources=13 inventory=logging.yaml
# tftest modules=5 resources=13 inventory=logging.yaml e2e serial
```

## Data Access Logs
Expand All @@ -344,20 +342,20 @@ module "org" {
logging_data_access = {
allServices = {
# logs for principals listed here will be excluded
ADMIN_READ = ["group:organization-admins@example.org"]
ADMIN_READ = ["group:${var.group_email}"]
}
"storage.googleapis.com" = {
DATA_READ = []
DATA_WRITE = []
}
}
}
# tftest modules=1 resources=2 inventory=logging-data-access.yaml
# tftest modules=1 resources=2 inventory=logging-data-access.yaml e2e serial
```

## Custom Roles

Custom roles can be defined via the `custom_roles` variable, and referenced via the `custom_role_id` output:
Custom roles can be defined via the `custom_roles` variable, and referenced via the `custom_role_id` output (this also provides explicit dependency on the custom role):

```hcl
module "org" {
Expand All @@ -369,10 +367,10 @@ module "org" {
]
}
iam = {
(module.org.custom_role_id.myRole) = ["user:me@example.com"]
(module.org.custom_role_id.myRole) = ["group:${var.group_email}"]
}
}
# tftest modules=1 resources=2 inventory=roles.yaml
# tftest modules=1 resources=2 inventory=roles.yaml e2e serial
```

## Tags
Expand All @@ -387,25 +385,24 @@ module "org" {
environment = {
description = "Environment specification."
iam = {
"roles/resourcemanager.tagAdmin" = ["group:admins@example.com"]
"roles/resourcemanager.tagAdmin" = ["group:${var.group_email}"]
}
values = {
dev = {}
prod = {
description = "Environment: production."
iam = {
"roles/resourcemanager.tagViewer" = ["user:user1@example.com"]
"roles/resourcemanager.tagViewer" = ["group:${var.group_email}"]
}
}
}
}
}
tag_bindings = {
env-prod = module.org.tag_values["environment/prod"].id
foo = "tagValues/12345678"
}
}
# tftest modules=1 resources=7 inventory=tags.yaml
# tftest modules=1 resources=6 inventory=tags.yaml e2e serial
```

You can also define network tags, through a dedicated variable *network_tags*:
Expand All @@ -417,23 +414,23 @@ module "org" {
network_tags = {
net-environment = {
description = "This is a network tag."
network = "my_project/my_vpc"
network = "${var.project_id}/${var.vpc.name}"
iam = {
"roles/resourcemanager.tagAdmin" = ["group:admins@example.com"]
"roles/resourcemanager.tagAdmin" = ["group:${var.group_email}"]
}
values = {
dev = null
prod = {
description = "Environment: production."
iam = {
"roles/resourcemanager.tagUser" = ["user:user1@example.com"]
"roles/resourcemanager.tagUser" = ["group:${var.group_email}"]
}
}
}
}
}
}
# tftest modules=1 resources=5 inventory=network-tags.yaml
# tftest modules=1 resources=5 inventory=network-tags.yaml e2e serial
```

<!-- TFDOC OPTS files:1 -->
Expand Down
3 changes: 3 additions & 0 deletions modules/organization/iam.tf
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ resource "google_organization_iam_binding" "authoritative" {
org_id = local.organization_id_numeric
role = each.key
members = each.value
# ensuring that custom role exists is left to the caller, by leveraging custom_role_id output
}

resource "google_organization_iam_binding" "bindings" {
Expand All @@ -61,6 +62,7 @@ resource "google_organization_iam_binding" "bindings" {
description = each.value.condition.description
}
}
# ensuring that custom role exists is left to the caller, by leveraging custom_role_id output
}

resource "google_organization_iam_member" "bindings" {
Expand All @@ -76,4 +78,5 @@ resource "google_organization_iam_member" "bindings" {
description = each.value.condition.description
}
}
# ensuring that custom role exists is left to the caller, by leveraging custom_role_id output
}
8 changes: 7 additions & 1 deletion tests/examples/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from pathlib import Path

import marko
import pytest

FABRIC_ROOT = Path(__file__).parents[2]

Expand Down Expand Up @@ -78,7 +79,12 @@ def pytest_generate_tests(metafunc, test_group='example',
if index > 1:
name += f' {index}'
ids.append(f'{path}:{last_header}:{index}')
examples.append(Example(name, code, path, files[last_header]))
# if test is marked with 'serial' in tftest line then add them to this xdist group
# this, together with `--dist loadgroup` will ensure that those tests will be run one after another
# even if multiple workers are used
# see: https://pytest-xdist.readthedocs.io/en/latest/distribution.html
marks = [pytest.mark.xdist_group("serial")] if 'serial' in tftest_tag else []
examples.append(pytest.param(Example(name, code, path, files[last_header]), marks=marks))
elif isinstance(child, marko.block.Heading):
last_header = child.children[0].children
index = 0
Expand Down
2 changes: 1 addition & 1 deletion tests/examples_e2e/setup_module/e2e_tests.tfvars.tftpl
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ kms_key = {
id = "${kms_key_id}"
}
group_email = "${group_email}"
organization_id = "${organization_id}"
organization_id = "organizations/${organization_id}"
folder_id = "folders/${folder_id}"
project_id = "${project_id}"
region = "${region}"
Expand Down
67 changes: 24 additions & 43 deletions tests/modules/organization/examples/basic.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@

values:
module.org.google_org_policy_policy.default["compute.disableGuestAttributesAccess"]:
name: organizations/1234567890/policies/compute.disableGuestAttributesAccess
parent: organizations/1234567890
name: organizations/1122334455/policies/compute.disableGuestAttributesAccess
parent: organizations/1122334455
spec:
- inherit_from_parent: null
reset: null
Expand All @@ -27,8 +27,8 @@ values:
values: []
timeouts: null
module.org.google_org_policy_policy.default["compute.skipDefaultNetworkCreation"]:
name: organizations/1234567890/policies/compute.skipDefaultNetworkCreation
parent: organizations/1234567890
name: organizations/1122334455/policies/compute.skipDefaultNetworkCreation
parent: organizations/1122334455
spec:
- inherit_from_parent: null
reset: null
Expand All @@ -40,8 +40,8 @@ values:
values: []
timeouts: null
module.org.google_org_policy_policy.default["compute.trustedImageProjects"]:
name: organizations/1234567890/policies/compute.trustedImageProjects
parent: organizations/1234567890
name: organizations/1122334455/policies/compute.trustedImageProjects
parent: organizations/1122334455
spec:
- inherit_from_parent: null
reset: null
Expand All @@ -56,8 +56,8 @@ values:
denied_values: null
timeouts: null
module.org.google_org_policy_policy.default["compute.vmExternalIpAccess"]:
name: organizations/1234567890/policies/compute.vmExternalIpAccess
parent: organizations/1234567890
name: organizations/1122334455/policies/compute.vmExternalIpAccess
parent: organizations/1122334455
spec:
- inherit_from_parent: null
reset: null
Expand All @@ -68,22 +68,9 @@ values:
enforce: null
values: []
timeouts: null
module.org.google_org_policy_policy.default["custom.gkeEnableAutoUpgrade"]:
name: organizations/1234567890/policies/custom.gkeEnableAutoUpgrade
parent: organizations/1234567890
spec:
- inherit_from_parent: null
reset: null
rules:
- allow_all: null
condition: []
deny_all: null
enforce: 'TRUE'
values: []
timeouts: null
module.org.google_org_policy_policy.default["iam.allowedPolicyMemberDomains"]:
name: organizations/1234567890/policies/iam.allowedPolicyMemberDomains
parent: organizations/1234567890
name: organizations/1122334455/policies/iam.allowedPolicyMemberDomains
parent: organizations/1122334455
spec:
- inherit_from_parent: null
reset: null
Expand Down Expand Up @@ -114,8 +101,8 @@ values:
denied_values: null
timeouts: null
module.org.google_org_policy_policy.default["iam.disableServiceAccountKeyCreation"]:
name: organizations/1234567890/policies/iam.disableServiceAccountKeyCreation
parent: organizations/1234567890
name: organizations/1122334455/policies/iam.disableServiceAccountKeyCreation
parent: organizations/1122334455
spec:
- inherit_from_parent: null
reset: null
Expand All @@ -127,8 +114,8 @@ values:
values: []
timeouts: null
module.org.google_org_policy_policy.default["iam.disableServiceAccountKeyUpload"]:
name: organizations/1234567890/policies/iam.disableServiceAccountKeyUpload
parent: organizations/1234567890
name: organizations/1122334455/policies/iam.disableServiceAccountKeyUpload
parent: organizations/1122334455
spec:
- inherit_from_parent: null
reset: null
Expand All @@ -151,29 +138,23 @@ values:
module.org.google_organization_iam_binding.authoritative["roles/owner"]:
condition: []
members:
- group:cloud-owners@example.org
org_id: '1234567890'
- group:organization-admins@example.org
org_id: '1122334455'
role: roles/owner
module.org.google_organization_iam_binding.authoritative["roles/projectCreator"]:
condition: []
members:
- group:cloud-owners@example.org
org_id: '1234567890'
role: roles/projectCreator
module.org.google_organization_iam_binding.authoritative["roles/resourcemanager.projectCreator"]:
condition: []
members:
- group:cloud-admins@example.org
org_id: '1234567890'
- group:organization-admins@example.org
org_id: '1122334455'
role: roles/resourcemanager.projectCreator
module.org.google_organization_iam_member.bindings["am1-storage-admin"]:
condition: []
member: user:am1@example.org
org_id: '1234567890'
member: group:organization-admins@example.org
org_id: '1122334455'
role: roles/storage.admin
module.org.google_tags_tag_key.default["allowexternal"]:
description: Allow external identities.
parent: organizations/1234567890
parent: organizations/1122334455
purpose: null
purpose_data: null
short_name: allowexternal
Expand All @@ -188,12 +169,12 @@ values:
timeouts: null

counts:
google_org_policy_policy: 8
google_organization_iam_binding: 3
google_org_policy_policy: 7
google_organization_iam_binding: 2
google_organization_iam_member: 1
google_tags_tag_key: 1
google_tags_tag_value: 2
modules: 1
resources: 15
resources: 13

outputs: {}
2 changes: 1 addition & 1 deletion tests/modules/organization/examples/logging.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ values:
name: notice
org_id: '1122334455'
module.org.google_logging_organization_sink.sink["warnings"]:
destination: storage.googleapis.com/gcs_sink
destination: storage.googleapis.com/test-gcs_sink
disabled: false
exclusions: []
filter: severity=WARNING
Expand Down
6 changes: 3 additions & 3 deletions tests/modules/organization/examples/network-tags.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ values:
parent: organizations/1122334455
purpose: GCE_FIREWALL
purpose_data:
network: my_project/my_vpc
network: project-id/vpc_name
short_name: net-environment
timeouts: null
module.org.google_tags_tag_key_iam_binding.default["net-environment:roles/resourcemanager.tagAdmin"]:
condition: []
members:
- group:admins@example.com
- group:organization-admins@example.org
role: roles/resourcemanager.tagAdmin
module.org.google_tags_tag_value.default["net-environment/dev"]:
description: Managed by the Terraform organization module.
Expand All @@ -37,7 +37,7 @@ values:
module.org.google_tags_tag_value_iam_binding.default["net-environment/prod:roles/resourcemanager.tagUser"]:
condition: []
members:
- user:user1@example.com
- group:organization-admins@example.org
role: roles/resourcemanager.tagUser

counts:
Expand Down