Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,4 @@ yarn.lock

# tf lock file
.terraform.lock.hcl
.terraform.lock
1 change: 1 addition & 0 deletions examples/scoped_example_with_egress_rule/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ You may use the following gcloud commands:
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| access\_level\_name | Access level name of the Access Policy. | `string` | `"terraform_members_e"` | no |
| access\_level\_name\_dry\_run | Access level name of the Access Policy in Dry-run mode. | `string` | `"terraform_members_e_dry_run"` | no |
| buckets\_names | Buckets Names as list of strings | `list(string)` | <pre>[<br> "bucket1-e",<br> "bucket2-e"<br>]</pre> | no |
| buckets\_prefix | Bucket Prefix | `string` | `"test-bucket-e"` | no |
| members | An allowed list of members (users, service accounts). The signed-in identity originating the request must be a part of one of the provided members. If not specified, a request may come from any user (logged in/not logged in, etc.). Formats: user:{emailid}, serviceAccount:{emailid} | `list(string)` | n/a | yes |
Expand Down
68 changes: 62 additions & 6 deletions examples/scoped_example_with_egress_rule/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,34 @@
* limitations under the License.
*/

locals {
egress_policies_dry_run = [
{
title = "dry-run"
from = {
sources = {
access_levels = [module.access_level_members_dry_run.name]
},
identity_type = "ANY_SERVICE_ACCOUNT"
}
to = {
resources = [
"projects/${var.public_project_ids["number"]}"
]
operations = {
for service in [
"cloudresourcemanager.googleapis.com",
"cloudfunctions.googleapis.com",
] : service =>
{
methods = ["*"]
}
}
}
},
]
}

module "access_context_manager_policy" {
source = "terraform-google-modules/vpc-service-controls/google"
version = "~> 7.1"
Expand All @@ -36,24 +64,41 @@ module "access_level_members" {
regions = var.regions
}

module "access_level_members_dry_run" {
source = "terraform-google-modules/vpc-service-controls/google//modules/access_level"
version = "~> 7.1"

description = "Simple Example Access Level dry-run"
policy = module.access_context_manager_policy.policy_id
name = var.access_level_name_dry_run
members = var.members
regions = var.regions
}


resource "time_sleep" "wait_for_members" {
create_duration = "90s"
destroy_duration = "90s"

depends_on = [module.access_level_members]
depends_on = [
module.access_level_members,
module.access_level_members_dry_run
]
}

module "regular_service_perimeter_1" {
source = "terraform-google-modules/vpc-service-controls/google//modules/regular_service_perimeter"
version = "~> 7.1"

version = "~> 7.1.1"

policy = module.access_context_manager_policy.policy_id
perimeter_name = var.perimeter_name

description = "Perimeter shielding bigquery project"
resources = [var.protected_project_ids["number"]]
access_levels = [module.access_level_members.name]
description = "Perimeter shielding bigquery project"
resources = [var.protected_project_ids["number"]]
resources_dry_run = [var.protected_project_ids["number"]]
access_levels = [module.access_level_members.name]
access_levels_dry_run = [module.access_level_members_dry_run.name]


restricted_services = ["bigquery.googleapis.com", "storage.googleapis.com"]

Expand Down Expand Up @@ -109,6 +154,9 @@ module "regular_service_perimeter_1" {
},
]

egress_policies_dry_run = distinct(tolist(local.egress_policies_dry_run))
egress_policies_keys_dry_run = ["rule_one"]

shared_resources = {
all = [var.protected_project_ids["number"]]
}
Expand All @@ -119,6 +167,14 @@ module "regular_service_perimeter_1" {
]
}

resource "random_string" "pn" {
length = 8
numeric = true
special = false
upper = false
lower = false
}

module "gcs_buckets" {
source = "terraform-google-modules/cloud-storage/google"
version = "~> 11.0"
Expand Down
7 changes: 7 additions & 0 deletions examples/scoped_example_with_egress_rule/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ variable "access_level_name" {
default = "terraform_members_e"
}

variable "access_level_name_dry_run" {
description = "Access level name of the Access Policy in Dry-run mode."
type = string
default = "terraform_members_e_dry_run"
}

variable "buckets_prefix" {
description = "Bucket Prefix"
type = string
Expand All @@ -74,3 +80,4 @@ variable "scopes" {
type = list(string)
default = []
}

1 change: 1 addition & 0 deletions examples/scoped_example_with_ingress_rule/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ You may use the following gcloud commands:
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| access\_level\_name | Access level name of the Access Policy. | `string` | `"terraform_members"` | no |
| access\_level\_name\_dry\_run | Access level name of the Access Policy in Dry-run mode. | `string` | `"terraform_members_dry_run"` | no |
| buckets\_names | Buckets Names as list of strings | `list(string)` | <pre>[<br> "bucket1",<br> "bucket2"<br>]</pre> | no |
| buckets\_prefix | Bucket Prefix | `string` | `"test-bucket"` | no |
| members | An allowed list of members (users, service accounts). The signed-in identity originating the request must be a part of one of the provided members. If not specified, a request may come from any user (logged in/not logged in, etc.). Formats: user:{emailid}, serviceAccount:{emailid} | `list(string)` | n/a | yes |
Expand Down
65 changes: 56 additions & 9 deletions examples/scoped_example_with_ingress_rule/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,33 @@
* limitations under the License.
*/

locals {
ingress_policies_dry_run = [
{
title = "dry-run"
from = {
identities = var.read_bucket_identities
sources = {
access_levels = [module.access_level_members_dry_run.name]
},
}
to = {
resources = [
"*"
]
operations = {
"storage.googleapis.com" = {
methods = [
"google.storage.objects.get",
"google.storage.objects.list"
]
}
}
}
}
]
}

module "access_context_manager_policy" {
source = "terraform-google-modules/vpc-service-controls/google"
version = "~> 7.1"
Expand All @@ -36,11 +63,25 @@ module "access_level_members" {
regions = var.regions
}

module "access_level_members_dry_run" {
source = "terraform-google-modules/vpc-service-controls/google//modules/access_level"
version = "~> 7.1"

description = "Simple Example Access Level dry-run"
policy = module.access_context_manager_policy.policy_id
name = var.access_level_name_dry_run
members = var.members
regions = var.regions
}

resource "time_sleep" "wait_for_members" {
create_duration = "90s"
destroy_duration = "90s"

depends_on = [module.access_level_members]
depends_on = [
module.access_level_members,
module.access_level_members_dry_run
]
}

module "regular_service_perimeter_1" {
Expand All @@ -50,21 +91,22 @@ module "regular_service_perimeter_1" {
policy = module.access_context_manager_policy.policy_id
perimeter_name = var.perimeter_name

description = "Perimeter shielding bigquery project"
resources = [var.protected_project_ids["number"]]
access_levels = [module.access_level_members.name]
description = "Perimeter shielding bigquery project"
resources = [var.protected_project_ids["number"]]
resources_dry_run = [var.protected_project_ids["number"]]
access_levels = [module.access_level_members.name]
access_levels_dry_run = [module.access_level_members_dry_run.name]

restricted_services = ["bigquery.googleapis.com", "storage.googleapis.com"]

ingress_policies = [
{
title = "Allow Access from everywhere"
from = {
identities = var.read_bucket_identities
sources = {
access_levels = ["*"] # Allow Access from everywhere
},
identities = var.read_bucket_identities

}
to = {
resources = [
Expand All @@ -80,8 +122,6 @@ module "regular_service_perimeter_1" {
}
}
},


{
title = "Allow Access from project"
from = {
Expand All @@ -106,9 +146,12 @@ module "regular_service_perimeter_1" {
}
},
{
title = "without from source"
title = "from bucket read identity"
from = {
identities = var.read_bucket_identities
sources = {
resources = ["projects/${var.public_project_ids["number"]}"]
}
}
to = {
resources = [
Expand All @@ -126,6 +169,10 @@ module "regular_service_perimeter_1" {
}
]

ingress_policies_dry_run = distinct(tolist(local.ingress_policies_dry_run))
ingress_policies_keys_dry_run = ["rule_one"]


shared_resources = {
all = [var.protected_project_ids["number"]]
}
Expand Down
6 changes: 6 additions & 0 deletions examples/scoped_example_with_ingress_rule/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ variable "access_level_name" {
default = "terraform_members"
}

variable "access_level_name_dry_run" {
description = "Access level name of the Access Policy in Dry-run mode."
type = string
default = "terraform_members_dry_run"
}

variable "read_bucket_identities" {
description = "List of all identities should get read access on bucket"
type = list(string)
Expand Down
6 changes: 5 additions & 1 deletion modules/regular_service_perimeter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,16 @@ module "regular_service_perimeter_1" {
| description | Description of the regular perimeter | `string` | n/a | yes |
| egress\_policies | A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference), each list object has a `from` and `to` value that describes egress\_from and egress\_to.<br><br>Example: `[{ from={ identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`<br><br>Valid Values:<br>`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`<br>`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)<br>`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) | <pre>list(object({<br> title = optional(string, null)<br> from = object({<br> sources = optional(object({<br> resources = optional(list(string), [])<br> access_levels = optional(list(string), [])<br> }), {}),<br> identity_type = optional(string, null)<br> identities = optional(list(string), null)<br> })<br> to = object({<br> operations = optional(map(object({<br> methods = optional(list(string), [])<br> permissions = optional(list(string), [])<br> })), {}),<br> roles = optional(list(string), null)<br> resources = optional(list(string), ["*"])<br> external_resources = optional(list(string), [])<br> })<br> }))</pre> | `[]` | no |
| egress\_policies\_dry\_run | A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference), each list object has a `from` and `to` value that describes egress\_from and egress\_to. Use same formatting as `egress_policies`. | <pre>list(object({<br> title = optional(string, null)<br> from = object({<br> sources = optional(object({<br> resources = optional(list(string), [])<br> access_levels = optional(list(string), [])<br> }), {}),<br> identity_type = optional(string, null)<br> identities = optional(list(string), null)<br> })<br> to = object({<br> operations = optional(map(object({<br> methods = optional(list(string), [])<br> permissions = optional(list(string), [])<br> })), {}),<br> roles = optional(list(string), null)<br> resources = optional(list(string), ["*"])<br> external_resources = optional(list(string), [])<br> })<br> }))</pre> | `[]` | no |
| egress\_policies\_keys | A list of keys to use for the Terraform state. The order should correspond to var.egress\_policies and the keys must not be dynamically computed. If `null`, var.egress\_policies will be used as keys. | `list(string)` | `null` | no |
| egress\_policies\_keys\_dry\_run | (Dry-run) A list of keys to use for the Terraform state. The order should correspond to var.egress\_policies\_dry\_run and the keys must not be dynamically computed. If `null`, var.egress\_policies\_dry\_run will be used as keys. | `list(string)` | `null` | no |
| ingress\_policies | A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference), each list object has a `from` and `to` value that describes ingress\_from and ingress\_to.<br><br>Example: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`<br><br>Valid Values:<br>`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`<br>`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)<br>`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) | <pre>list(object({<br> title = optional(string, null)<br> from = object({<br> sources = optional(object({<br> resources = optional(list(string), [])<br> access_levels = optional(list(string), [])<br> }), {}),<br> identity_type = optional(string, null)<br> identities = optional(list(string), null)<br> })<br> to = object({<br> operations = optional(map(object({<br> methods = optional(list(string), [])<br> permissions = optional(list(string), [])<br> })), {}),<br> roles = optional(list(string), null)<br> resources = optional(list(string), ["*"])<br> })<br> }))</pre> | `[]` | no |
| ingress\_policies\_dry\_run | A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference), each list object has a `from` and `to` value that describes ingress\_from and ingress\_to. Use same formatting as `ingress_policies`. | <pre>list(object({<br> title = optional(string, null)<br> from = object({<br> sources = optional(object({<br> resources = optional(list(string), [])<br> access_levels = optional(list(string), [])<br> }), {}),<br> identity_type = optional(string, null)<br> identities = optional(list(string), null)<br> })<br> to = object({<br> operations = optional(map(object({<br> methods = optional(list(string), [])<br> permissions = optional(list(string), [])<br> })), {}),<br> roles = optional(list(string), null)<br> resources = optional(list(string), ["*"])<br> })<br> }))</pre> | `[]` | no |
| ingress\_policies\_keys | A list of keys to use for the Terraform state. The order should correspond to var.ingress\_policies and the keys must not be dynamically computed. If `null`, var.ingress\_policies will be used as keys. | `list(string)` | `null` | no |
| ingress\_policies\_keys\_dry\_run | (Dry-run) A list of keys to use for the Terraform state. The order should correspond to var.ingress\_policies\_dry\_run and the keys must not be dynamically computed. If `null`, var.ingress\_policies\_dry\_run will be used as keys. | `list(string)` | `null` | no |
| perimeter\_name | Name of the perimeter. Should be one unified string. Must only be letters, numbers and underscores | `string` | n/a | yes |
| policy | Name of the parent policy | `string` | n/a | yes |
| resource\_keys | A list of keys to use for the Terraform state. The order should correspond to var.resources and the keys must not be dynamically computed. If `null`, var.resources will be used as keys. | `list(string)` | `null` | no |
| resource\_keys\_dry\_run | A list of keys to use for the Terraform state. The order should correspond to var.resources\_dry\_run and the keys must not be dynamically computed. If `null`, var.resources\_dry\_run will be used as keys. | `list(string)` | `null` | no |
| resource\_keys\_dry\_run | (Dry-run) A list of keys to use for the Terraform state. The order should correspond to var.resources\_dry\_run and the keys must not be dynamically computed. If `null`, var.resources\_dry\_run will be used as keys. | `list(string)` | `null` | no |
| resources | A list of GCP resources that are inside of the service perimeter. Currently only projects and VPC networks are allowed. | `list(string)` | `[]` | no |
| resources\_dry\_run | (Dry-run) A list of GCP resources that are inside of the service perimeter. Currently only projects and VPC networks are allowed. If set, a dry-run policy will be set. | `list(string)` | `[]` | no |
| restricted\_services | GCP services that are subject to the Service Perimeter restrictions. Must contain a list of services. For example, if storage.googleapis.com is specified, access to the storage buckets inside the perimeter must meet the perimeter's access restrictions. | `list(string)` | `[]` | no |
Expand Down
5 changes: 3 additions & 2 deletions modules/regular_service_perimeter/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/

locals {
dry_run = (length(var.restricted_services_dry_run) > 0 || length(var.resources_dry_run) > 0 || length(var.access_levels_dry_run) > 0 || !contains(var.vpc_accessible_services_dry_run, "*"))
dry_run = (length(var.restricted_services_dry_run) > 0 || length(var.resources_dry_run) > 0 || length(var.access_levels_dry_run) > 0 || length(var.egress_policies_dry_run) > 0 || length(var.ingress_policies_dry_run) > 0 || !contains(var.vpc_accessible_services_dry_run, "*"))
}

resource "google_access_context_manager_service_perimeter" "regular_service_perimeter" {
Expand Down Expand Up @@ -80,13 +80,14 @@ resource "google_access_context_manager_service_perimeter" "regular_service_peri
}

locals {
# enforced
resource_keys = var.resource_keys != null ? var.resource_keys : var.resources
resources = {
for rk in local.resource_keys :
rk => var.resources[index(local.resource_keys, rk)]
}

#dry-run
# dry-run
resource_keys_dry_run = var.resource_keys_dry_run != null ? var.resource_keys_dry_run : var.resources_dry_run
resources_dry_run = {
for rk in local.resource_keys_dry_run :
Expand Down
Loading