cloud-foundation-fabric/blueprints/data-solutions/shielded-folder/README.md

212 lines
15 KiB
Markdown
Raw Normal View History

2023-01-27 01:05:19 -08:00
# Shielded folder
2023-02-06 12:34:29 -08:00
This blueprint implements an opinionated folder configuration according to GCP best practices. Configurations set at the folder level would be beneficial to host workloads inheriting constraints from the folder they belong to.
2023-01-27 01:05:19 -08:00
2023-02-06 12:33:04 -08:00
In this blueprint, a folder will be created setting following features:
2023-02-05 13:41:57 -08:00
2023-01-27 01:05:19 -08:00
- Organizational policies
2023-02-01 08:34:31 -08:00
- Hierarchical firewall rules
2023-01-30 14:32:13 -08:00
- Cloud KMS
2023-01-27 01:05:19 -08:00
- VPC-SC
2023-01-31 15:50:22 -08:00
Within the folder, the following projects will be created:
2023-02-05 13:41:57 -08:00
2023-01-30 14:32:13 -08:00
- 'audit-logs' where Audit Logs sink will be created
- 'sec-core' where Cloud KMS and Cloud Secret manager will be configured
2023-01-27 01:05:19 -08:00
2023-01-30 14:32:13 -08:00
The following diagram is a high-level reference of the resources created and managed here:
![Shielded architecture overview](./images/overview_diagram.png "Shielded architecture overview")
2023-01-31 13:35:48 -08:00
## Design overview and choices
2023-01-30 14:32:13 -08:00
Despite its simplicity, this blueprint implements the basics of a design that we've seen working well for various customers.
The approach adapts to different high-level requirements:
2023-02-05 13:41:57 -08:00
2023-01-30 14:32:13 -08:00
- IAM roles inheritance
- Organizational policies
- Audit log sink
- VPC Service Control
- Cloud KMS
2023-01-31 13:35:48 -08:00
## Project structure
2023-02-05 13:41:57 -08:00
2023-01-30 14:32:13 -08:00
The Shielded Folder blueprint is designed to rely on several projects:
2023-02-05 13:41:57 -08:00
2023-01-30 14:32:13 -08:00
- `audit-log`: to host Audit logging buckets and Audit log sync to GCS, BigQuery or PubSub
2023-01-31 15:50:22 -08:00
- `sec-core`: to host security-related resources such as Cloud KMS and Cloud Secrets Manager
2023-01-30 14:32:13 -08:00
This separation into projects allows adhering to the least-privilege principle by using project-level roles.
2023-01-31 13:35:48 -08:00
## User groups
2023-02-05 13:41:57 -08:00
2023-01-31 15:50:22 -08:00
User groups provide a stable frame of reference that allows decoupling the final set of permissions from the stage where entities and resources are created, and their IAM bindings are defined.
2023-01-30 14:32:13 -08:00
2023-02-06 12:33:04 -08:00
We use groups to control access to resources:
2023-02-05 13:41:57 -08:00
- `gcp-data-engineers`: They handle and run workloads on the `workload` subfolder. They have editor access to all resources in the `workload` folder in order to troubleshoot possible issues within the workload. This team can also impersonate any service account in the workload folder.
- `gcp-data-security`: They handle security configurations for the shielded folder. They have owner access to the `audit-log` and `sec-core` projects.
2023-01-30 14:32:13 -08:00
2023-01-31 13:35:48 -08:00
## Encryption
2023-02-05 13:41:57 -08:00
2023-01-31 15:50:22 -08:00
The blueprint supports the configuration of an instance of Cloud KMS to handle encryption on the resources. The encryption is disabled by default, but you can enable it by configuring the `enable_features.encryption` variable.
2023-01-30 14:32:13 -08:00
2023-01-31 15:50:22 -08:00
The script will create keys to encrypt log sink buckets/datasets/topics in the specified regions. Configuring the `kms_keys` variable, you can create additional KMS keys needed by your workload.
2023-01-30 14:32:13 -08:00
2023-01-31 15:26:57 -08:00
## Customizations
### Organization policy
2023-02-05 13:41:57 -08:00
You can configure the Organization policies enforced on the folder editing yaml files in the [org-policies](./data/org-policies/) folder. An opinionated list of policies that we suggest enforcing is listed.
Some additional Organization policy constraints you may want to evaluate adding:
2023-02-05 13:41:57 -08:00
- `constraints/gcp.resourceLocations`: to define the locations where location-based GCP resources can be created.
- `constraints/gcp.restrictCmekCryptoKeyProjects`: to define which projects may be used to supply Customer-Managed Encryption Keys (CMEK) when creating resources.
2023-01-31 15:26:57 -08:00
### VPC Service Control
2023-02-05 13:41:57 -08:00
2023-01-31 15:50:22 -08:00
VPC Service Control is configured to have a Perimeter containing all projects within the folder. Additional projects you may add to the folder won't be automatically added to the perimeter, and a new `terraform apply` is needed to add the project to the perimeter.
2023-01-31 15:26:57 -08:00
The VPC SC configuration is set to dry-run mode, but switching to enforced mode is a simple operation involving modifying a few lines of code highlighted by ad-hoc comments.
2023-02-05 13:41:57 -08:00
Access level rules are not defined. Before moving the configuration to enforced mode, configure access policies to continue accessing resources from outside of the perimeter.
2023-01-31 15:26:57 -08:00
2023-01-31 15:50:22 -08:00
An access level based on the network range you are using to reach the console (e.g. Proxy IP, Internet connection, ...) is suggested. Example:
2023-01-31 15:26:57 -08:00
2023-02-06 05:58:40 -08:00
```tfvars
2023-01-31 15:26:57 -08:00
vpc_sc_access_levels = {
users = {
conditions = [
{ members = ["user:user1@example.com"] }
]
}
}
```
2023-01-31 15:50:22 -08:00
Alternatively, you can configure an access level based on the identity that needs to reach resources from outside the perimeter.
2023-01-31 15:26:57 -08:00
2023-02-06 05:58:40 -08:00
```tfvars
2023-01-31 15:26:57 -08:00
vpc_sc_access_levels = {
users = {
conditions = [
{ ip_subnetworks = ["101.101.101.0/24"] }
]
}
}
```
2023-01-31 13:35:48 -08:00
## How to run this script
2023-02-05 13:41:57 -08:00
2023-01-31 15:50:22 -08:00
To deploy this blueprint in your GCP organization, you will need
2023-02-05 13:41:57 -08:00
2023-01-30 14:32:13 -08:00
- a folder or organization where resources will be created
- a billing account that will be associated with the new projects
2023-06-23 06:52:08 -07:00
The Shielded Folder blueprint is meant to be executed by a Service Account having this minimal set of permission:
2023-02-05 13:41:57 -08:00
2023-06-23 06:52:08 -07:00
- **Billing account**
2023-01-30 14:32:13 -08:00
- `roles/billing.user`
2023-06-23 06:52:08 -07:00
- **Organization level**:
- `roles/logging.configWriter`
2023-01-30 14:32:13 -08:00
- `roles/resourcemanager.folderAdmin`
2023-06-23 06:52:08 -07:00
- `roles/compute.orgFirewallPolicyAdmin`
2023-01-30 14:32:13 -08:00
- `roles/resourcemanager.projectCreator`
2023-06-23 06:52:08 -07:00
- `roles/orgpolicy.policyAdmin`
2023-01-30 14:32:13 -08:00
2023-06-23 06:52:08 -07:00
The shielded Folder blueprint assumes [groups described](#user-groups) are created in your GCP organization. Please create them from the [https://admin.google.com/][Google Admin] console.
2023-01-30 14:32:13 -08:00
2023-06-23 06:52:08 -07:00
### Variable configuration
2023-02-05 13:41:57 -08:00
2023-02-06 12:33:04 -08:00
There are several sets of variables you will need to fill in:
2023-02-05 13:41:57 -08:00
2023-02-06 12:33:04 -08:00
```tfvars
2023-02-06 05:58:40 -08:00
access_policy_config = {
access_policy_create = {
parent = "organizations/1234567890123"
title = "ShieldedMVP"
}
}
folder_config = {
folder_create = {
display_name = "ShieldedMVP"
parent = "organizations/1234567890123"
}
}
2023-01-30 14:32:13 -08:00
organization = {
domain = "example.com"
2023-02-06 05:58:40 -08:00
id = "1122334455"
2023-01-30 14:32:13 -08:00
}
prefix = "prefix"
2023-02-06 12:33:04 -08:00
project_config = {
billing_account_id = "123456-123456-123456"
2023-02-06 05:58:40 -08:00
}
2023-01-30 14:32:13 -08:00
```
2023-01-31 13:35:48 -08:00
### Deploying the blueprint
2023-02-05 13:41:57 -08:00
2023-01-30 14:32:13 -08:00
Once the configuration is complete, run the project factory by running
```bash
terraform init
terraform apply
```
<!-- BEGIN TFDOC -->
## Variables
| name | description | type | required | default |
|---|---|:---:|:---:|:---:|
2023-02-06 05:58:40 -08:00
| [access_policy_config](variables.tf#L17) | Provide 'access_policy_create' values if a folder scoped Access Policy creation is needed, uses existing 'policy_name' otherwise. Parent is in 'organizations/123456' format. Policy will be created scoped to the folder. | <code title="object&#40;&#123;&#10; policy_name &#61; optional&#40;string, null&#41;&#10; access_policy_create &#61; optional&#40;object&#40;&#123;&#10; parent &#61; string&#10; title &#61; string&#10; &#125;&#41;, null&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | |
| [folder_config](variables.tf#L49) | Provide 'folder_create' values if folder creation is needed, uses existing 'folder_id' otherwise. Parent is in 'folders/nnn' or 'organizations/nnn' format. | <code title="object&#40;&#123;&#10; folder_id &#61; optional&#40;string, null&#41;&#10; folder_create &#61; optional&#40;object&#40;&#123;&#10; display_name &#61; string&#10; parent &#61; string&#10; &#125;&#41;, null&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | |
IAM interface refactor (#1595) * IAM modules refactor proposal * policy * subheading * Update 20230816-iam-refactor.md * log Julio's +1 * data-catalog-policy-tag * dataproc * dataproc * folder * folder * folder * folder * project * better filtering in test examples * project * folder * folder * organization * fix variable descriptions * kms * net-vpc * dataplex-datascan * modules/iam-service-account * modules/source-repository/ * blueprints/cloud-operations/vm-migration/ * blueprints/third-party-solutions/wordpress * dataplex-datascan * blueprints/cloud-operations/workload-identity-federation * blueprints/data-solutions/cloudsql-multiregion/ * blueprints/data-solutions/composer-2 * Update 20230816-iam-refactor.md * Update 20230816-iam-refactor.md * capture discussion in architectural doc * update variable names and refactor proposal * project * blueprints first round * folder * organization * data-catalog-policy-tag * re-enable folder inventory * project module style fix * dataproc * source-repository * source-repository tests * dataplex-datascan * dataplex-datascan tests * net-vpc * net-vpc test examples * iam-service-account * iam-service-account test examples * kms * boilerplate * tfdoc * fix module tests * more blueprint fixes * fix typo in data blueprints * incomplete refactor of data platform foundations * tfdoc * data platform foundation * refactor data platform foundation iam locals * remove redundant example test * shielded folder fix * fix typo * project factory * project factory outputs * tfdoc * test workflow: less verbose tests, fix tf version * re-enable -vv, shorter traceback, fix action version * ignore github extension warning, re-enable action version * fast bootstrap IAM, untested * bootstrap stage IAM fixes * stage 0 tests * fast stage 1 * tenant stage 1 * minor changes to fast stage 0 and 1 * fast security stage * fast mt stage 0 * fast mt stage 0 * fast pf
2023-08-20 00:44:20 -07:00
| [organization](variables.tf#L129) | Organization details. | <code title="object&#40;&#123;&#10; domain &#61; string&#10; id &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | |
| [prefix](variables.tf#L137) | Prefix used for resources that need unique names. | <code>string</code> | ✓ | |
| [project_config](variables.tf#L142) | Provide 'billing_account_id' value if project creation is needed, uses existing 'project_ids' if null. Parent is in 'folders/nnn' or 'organizations/nnn' format. | <code title="object&#40;&#123;&#10; billing_account_id &#61; optional&#40;string, null&#41;&#10; project_ids &#61; optional&#40;object&#40;&#123;&#10; sec-core &#61; string&#10; audit-logs &#61; string&#10; &#125;&#41;, &#123;&#10; sec-core &#61; &#34;sec-core&#34;&#10; audit-logs &#61; &#34;audit-logs&#34;&#10; &#125;&#10; &#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | |
2023-02-06 05:58:40 -08:00
| [data_dir](variables.tf#L29) | Relative path for the folder storing configuration data. | <code>string</code> | | <code>&#34;data&#34;</code> |
| [enable_features](variables.tf#L35) | Flag to enable features on the solution. | <code title="object&#40;&#123;&#10; encryption &#61; optional&#40;bool, false&#41;&#10; log_sink &#61; optional&#40;bool, true&#41;&#10; vpc_sc &#61; optional&#40;bool, true&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code title="&#123;&#10; encryption &#61; false&#10; log_sink &#61; true&#10; vpc_sc &#61; true&#10;&#125;">&#123;&#8230;&#125;</code> |
2023-02-07 04:57:26 -08:00
| [groups](variables.tf#L65) | User groups. | <code title="object&#40;&#123;&#10; workload-engineers &#61; optional&#40;string, &#34;gcp-data-engineers&#34;&#41;&#10; workload-security &#61; optional&#40;string, &#34;gcp-data-security&#34;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
IAM interface refactor (#1595) * IAM modules refactor proposal * policy * subheading * Update 20230816-iam-refactor.md * log Julio's +1 * data-catalog-policy-tag * dataproc * dataproc * folder * folder * folder * folder * project * better filtering in test examples * project * folder * folder * organization * fix variable descriptions * kms * net-vpc * dataplex-datascan * modules/iam-service-account * modules/source-repository/ * blueprints/cloud-operations/vm-migration/ * blueprints/third-party-solutions/wordpress * dataplex-datascan * blueprints/cloud-operations/workload-identity-federation * blueprints/data-solutions/cloudsql-multiregion/ * blueprints/data-solutions/composer-2 * Update 20230816-iam-refactor.md * Update 20230816-iam-refactor.md * capture discussion in architectural doc * update variable names and refactor proposal * project * blueprints first round * folder * organization * data-catalog-policy-tag * re-enable folder inventory * project module style fix * dataproc * source-repository * source-repository tests * dataplex-datascan * dataplex-datascan tests * net-vpc * net-vpc test examples * iam-service-account * iam-service-account test examples * kms * boilerplate * tfdoc * fix module tests * more blueprint fixes * fix typo in data blueprints * incomplete refactor of data platform foundations * tfdoc * data platform foundation * refactor data platform foundation iam locals * remove redundant example test * shielded folder fix * fix typo * project factory * project factory outputs * tfdoc * test workflow: less verbose tests, fix tf version * re-enable -vv, shorter traceback, fix action version * ignore github extension warning, re-enable action version * fast bootstrap IAM, untested * bootstrap stage IAM fixes * stage 0 tests * fast stage 1 * tenant stage 1 * minor changes to fast stage 0 and 1 * fast security stage * fast mt stage 0 * fast mt stage 0 * fast pf
2023-08-20 00:44:20 -07:00
| [kms_keys](variables.tf#L75) | KMS keys to create, keyed by name. | <code title="map&#40;object&#40;&#123;&#10; iam &#61; optional&#40;map&#40;list&#40;string&#41;&#41;, &#123;&#125;&#41;&#10; iam_bindings_additive &#61; optional&#40;map&#40;map&#40;any&#41;&#41;, &#123;&#125;&#41;&#10; labels &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; locations &#61; optional&#40;list&#40;string&#41;, &#91;&#34;global&#34;, &#34;europe&#34;, &#34;europe-west1&#34;&#93;&#41;&#10; rotation_period &#61; optional&#40;string, &#34;7776000s&#34;&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [log_locations](variables.tf#L87) | Optional locations for GCS, BigQuery, and logging buckets created here. | <code title="object&#40;&#123;&#10; bq &#61; optional&#40;string, &#34;europe&#34;&#41;&#10; storage &#61; optional&#40;string, &#34;europe&#34;&#41;&#10; logging &#61; optional&#40;string, &#34;global&#34;&#41;&#10; pubsub &#61; optional&#40;string, &#34;global&#34;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code title="&#123;&#10; bq &#61; &#34;europe&#34;&#10; storage &#61; &#34;europe&#34;&#10; logging &#61; &#34;global&#34;&#10; pubsub &#61; null&#10;&#125;">&#123;&#8230;&#125;</code> |
| [log_sinks](variables.tf#L104) | Org-level log sinks, in name => {type, filter} format. | <code title="map&#40;object&#40;&#123;&#10; filter &#61; string&#10; type &#61; string&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code title="&#123;&#10; audit-logs &#61; &#123;&#10; filter &#61; &#34;logName:&#92;&#34;&#47;logs&#47;cloudaudit.googleapis.com&#37;2Factivity&#92;&#34; OR logName:&#92;&#34;&#47;logs&#47;cloudaudit.googleapis.com&#37;2Fsystem_event&#92;&#34;&#34;&#10; type &#61; &#34;bigquery&#34;&#10; &#125;&#10; vpc-sc &#61; &#123;&#10; filter &#61; &#34;protoPayload.metadata.&#64;type&#61;&#92;&#34;type.googleapis.com&#47;google.cloud.audit.VpcServiceControlAuditMetadata&#92;&#34;&#34;&#10; type &#61; &#34;bigquery&#34;&#10; &#125;&#10;&#125;">&#123;&#8230;&#125;</code> |
| [vpc_sc_access_levels](variables.tf#L162) | VPC SC access level definitions. | <code title="map&#40;object&#40;&#123;&#10; combining_function &#61; optional&#40;string&#41;&#10; conditions &#61; optional&#40;list&#40;object&#40;&#123;&#10; device_policy &#61; optional&#40;object&#40;&#123;&#10; allowed_device_management_levels &#61; optional&#40;list&#40;string&#41;&#41;&#10; allowed_encryption_statuses &#61; optional&#40;list&#40;string&#41;&#41;&#10; require_admin_approval &#61; bool&#10; require_corp_owned &#61; bool&#10; require_screen_lock &#61; optional&#40;bool&#41;&#10; os_constraints &#61; optional&#40;list&#40;object&#40;&#123;&#10; os_type &#61; string&#10; minimum_version &#61; optional&#40;string&#41;&#10; require_verified_chrome_os &#61; optional&#40;bool&#41;&#10; &#125;&#41;&#41;&#41;&#10; &#125;&#41;&#41;&#10; ip_subnetworks &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; members &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; negate &#61; optional&#40;bool&#41;&#10; regions &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; required_access_levels &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; &#125;&#41;&#41;, &#91;&#93;&#41;&#10; description &#61; optional&#40;string&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [vpc_sc_egress_policies](variables.tf#L191) | VPC SC egress policy definitions. | <code title="map&#40;object&#40;&#123;&#10; from &#61; object&#40;&#123;&#10; identity_type &#61; optional&#40;string, &#34;ANY_IDENTITY&#34;&#41;&#10; identities &#61; optional&#40;list&#40;string&#41;&#41;&#10; &#125;&#41;&#10; to &#61; object&#40;&#123;&#10; operations &#61; optional&#40;list&#40;object&#40;&#123;&#10; method_selectors &#61; optional&#40;list&#40;string&#41;&#41;&#10; service_name &#61; string&#10; &#125;&#41;&#41;, &#91;&#93;&#41;&#10; resources &#61; optional&#40;list&#40;string&#41;&#41;&#10; resource_type_external &#61; optional&#40;bool, false&#41;&#10; &#125;&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [vpc_sc_ingress_policies](variables.tf#L211) | VPC SC ingress policy definitions. | <code title="map&#40;object&#40;&#123;&#10; from &#61; object&#40;&#123;&#10; access_levels &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; identity_type &#61; optional&#40;string&#41;&#10; identities &#61; optional&#40;list&#40;string&#41;&#41;&#10; resources &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; &#125;&#41;&#10; to &#61; object&#40;&#123;&#10; operations &#61; optional&#40;list&#40;object&#40;&#123;&#10; method_selectors &#61; optional&#40;list&#40;string&#41;&#41;&#10; service_name &#61; string&#10; &#125;&#41;&#41;, &#91;&#93;&#41;&#10; resources &#61; optional&#40;list&#40;string&#41;&#41;&#10; &#125;&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
2023-01-30 14:32:13 -08:00
2023-01-31 15:50:22 -08:00
## Outputs
| name | description | sensitive |
|---|---|:---:|
| [folders](outputs.tf#L15) | Folders id. | |
| [folders_sink_writer_identities](outputs.tf#L23) | Folders id. | |
| [kms_keys](outputs.tf#L31) | Cloud KMS encryption keys created. | |
2023-01-30 14:32:13 -08:00
<!-- END TFDOC -->
2023-02-10 08:04:55 -08:00
## Test
```hcl
module "test" {
source = "./fabric/blueprints/data-solutions/shielded-folder"
data_dir = "./fabric/blueprints/data-solutions/shielded-folder/data"
access_policy_config = {
access_policy_create = {
parent = "organizations/1234567890123"
title = "ShieldedMVP"
}
}
folder_config = {
folder_create = {
display_name = "ShieldedMVP"
parent = "organizations/1234567890123"
}
}
organization = {
domain = "example.com"
id = "1122334455"
}
prefix = "prefix"
project_config = {
billing_account_id = "123456-123456-123456"
}
}
# tftest modules=7 resources=38
2023-02-10 08:04:55 -08:00
```