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

Secure source manager #2569

Merged
merged 3 commits into from
Sep 19, 2024
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Currently available modules:
- **networking** - [DNS](./modules/dns), [DNS Response Policy](./modules/dns-response-policy/), [Cloud Endpoints](./modules/endpoints), [address reservation](./modules/net-address), [NAT](./modules/net-cloudnat), [VLAN Attachment](./modules/net-vlan-attachment/), [External Application LB](./modules/net-lb-app-ext/), [External Passthrough Network LB](./modules/net-lb-ext), [External Regional Application Load Balancer](./modules/net-lb-app-ext-regional/), [Firewall policy](./modules/net-firewall-policy), [Internal Application LB](./modules/net-lb-app-int), [Cross-region Internal Application LB](./modules/net-lb-app-int-cross-region), [Internal Passthrough Network LB](./modules/net-lb-int), [Internal Proxy Network LB](./modules/net-lb-proxy-int), [IPSec over Interconnect](./modules/net-ipsec-over-interconnect), [VPC](./modules/net-vpc), [VPC firewall](./modules/net-vpc-firewall), [VPC peering](./modules/net-vpc-peering), [VPN dynamic](./modules/net-vpn-dynamic), [HA VPN](./modules/net-vpn-ha), [VPN static](./modules/net-vpn-static), [Service Directory](./modules/service-directory), [Secure Web Proxy](./modules/net-swp)
- **compute** - [VM/VM group](./modules/compute-vm), [MIG](./modules/compute-mig), [COS container](./modules/cloud-config-container/cos-generic-metadata/) (coredns, mysql, onprem, squid), [GKE cluster](./modules/gke-cluster-standard), [GKE hub](./modules/gke-hub), [GKE nodepool](./modules/gke-nodepool), [GCVE private cloud](./modules/gcve-private-cloud)
- **data** - <!-- [AlloyDB instance](./modules/alloydb-instance), --> [Analytics Hub](./modules/analytics-hub), [BigQuery dataset](./modules/bigquery-dataset), [Bigtable instance](./modules/bigtable-instance), [Dataplex](./modules/dataplex), [Dataplex DataScan](./modules/dataplex-datascan), [Cloud SQL instance](./modules/cloudsql-instance), [Spanner instance](./modules/spanner-instance), [Firestore](./modules/firestore), [Data Catalog Policy Tag](./modules/data-catalog-policy-tag), [Data Catalog Tag](./modules/data-catalog-tag), [Data Catalog Tag Template](./modules/data-catalog-tag-template), [Datafusion](./modules/datafusion), [Dataproc](./modules/dataproc), [GCS](./modules/gcs), [Pub/Sub](./modules/pubsub), [Dataform Repository](./modules/dataform-repository/)
- **development** - [API Gateway](./modules/api-gateway), [Apigee](./modules/apigee), [Artifact Registry](./modules/artifact-registry), [Container Registry](./modules/container-registry), [Cloud Source Repository](./modules/source-repository), [Workstation cluster](./modules/workstation-cluster)
- **development** - [API Gateway](./modules/api-gateway), [Apigee](./modules/apigee), [Artifact Registry](./modules/artifact-registry), [Container Registry](./modules/container-registry), [Cloud Source Repository](./modules/source-repository), [Secure Source Manager instance](./modules/secure-source-manager-instance), [Workstation cluster](./modules/workstation-cluster)
- **security** - [Binauthz](./modules/binauthz/), [Certificate Authority Service (CAS)](./modules/certificate-authority-service), [KMS](./modules/kms), [SecretManager](./modules/secret-manager), [VPC Service Control](./modules/vpc-sc), [Certificate Manager](./modules/certificate-manager/)
- **serverless** - [Cloud Function v1](./modules/cloud-function-v1), [Cloud Function v2](./modules/cloud-function-v2), [Cloud Run](./modules/cloud-run), [Cloud Run v2](./modules/cloud-run-v2)

Expand Down
1 change: 1 addition & 0 deletions modules/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ These modules are used in the examples included in this repository. If you are u
- [Artifact Registry](./artifact-registry)
- [Container Registry](./container-registry)
- [Cloud Source Repository](./source-repository)
- [Secure Source Manager instance](./secure-source-manager-instance)
- [Workstation cluster](./workstation-cluster)

## Security
Expand Down
179 changes: 179 additions & 0 deletions modules/secure-source-manager-instance/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
# Secure Source Manager

This module allows to create a Secure Source Manager instance and repositories in it. Additionally it allows creating instance IAM bindings and repository IAM bindings.

## Examples

<!-- BEGIN TOC -->
- [Examples](#examples)
- [Public instance](#public-instance)
- [Public instance with CMEK](#public-instance-with-cmek)
- [Private instance](#private-instance)
- [IAM](#iam)
- [Variables](#variables)
- [Outputs](#outputs)
<!-- END TOC -->

### Public instance

```hcl
module "ssm_instance" {
source = "./fabric/modules/secure-source-manager-instance"
project_id = var.project_id
instance_id = "my-instance"
location = var.region
repositories = {
my-repository = {
location = var.region
}
}
}
# tftest modules=1 resources=2 inventory=public-instance.yaml
```

### Public instance with CMEK

```hcl
module "ssm_instance" {
source = "./fabric/modules/secure-source-manager-instance"
project_id = var.project_id
instance_id = "my-instance"
location = var.region
kms_key = "projects/another-project-id/locations/${var.region}/keyRings/my-key-ring/cryptoKeys/my-key"
repositories = {
my-repository = {
location = var.region
}
}
}
# tftest modules=1 resources=2 inventory=public-instance-with-cmek.yaml
```

### Private instance

```hcl
module "ssm_instance" {
source = "./fabric/modules/secure-source-manager-instance"
project_id = var.project_id
instance_id = "my-instance"
location = var.region
ca_pool = "projects/another-project/locations/${var.region}/caPools/my-ca-pool"
repositories = {
my-repository = {
location = var.region
}
}
}
# tftest modules=1 resources=2 inventory=private-instance.yaml
```

### IAM

```hcl
module "ssm_instance" {
source = "./fabric/modules/secure-source-manager-instance"
project_id = var.project_id
instance_id = "my-instance"
location = var.region
iam = {
"roles/securesourcemanager.instanceOwner" = [
"group:[email protected]"
]
}
repositories = {
my-repository = {
location = var.region
iam = {
"roles/securesourcemanager.repoAdmin" = [
"group:[email protected]"
]
}
}
}
}
# tftest modules=1 resources=4 inventory=iam.yaml
```

```hcl

module "ssm_instance" {
source = "./fabric/modules/secure-source-manager-instance"
project_id = var.project_id
instance_id = "my-instance"
location = var.region
iam_bindings_additive = {
my-instance-admin = {
role = "roles/securesourcemanager.instanceOwner"
member = "group:[email protected]"
}
}
repositories = {
my-repository = {
location = var.region
iam_bindings_additive = {
my-repository-admin = {
role = "roles/securesourcemanager.repoAdmin"
member = "group:[email protected]"
}
}
}
}
}
# tftest modules=1 resources=4 inventory=iam-bindings.yaml
```

```hcl
module "ssm_instance" {
source = "./fabric/modules/secure-source-manager-instance"
project_id = var.project_id
instance_id = "my-instance"
location = var.region
iam_bindings = {
my-instance-admin = {
role = "roles/securesourcemanager.instanceOwner"
members = [
"group:[email protected]"
]
}
}
repositories = {
my-repository = {
location = var.region
iam_bindings = {
my-repository-admin = {
role = "roles/securesourcemanager.repoAdmin"
members = [
"group:[email protected]"
]
}
}
}
}
}
# tftest modules=1 resources=4 inventory=iam-bindings-additive.yaml
```
<!-- BEGIN TFDOC -->
## Variables

| name | description | type | required | default |
|---|---|:---:|:---:|:---:|
| [instance_id](variables.tf#L23) | Instance ID. | <code>string</code> | ✓ | |
| [location](variables.tf#L40) | Location. | <code>string</code> | ✓ | |
| [project_id](variables.tf#L45) | Project ID. | <code>string</code> | ✓ | |
| [repositories](variables.tf#L50) | Repositories. | <code title="map&#40;object&#40;&#123;&#10; description &#61; optional&#40;string&#41;&#10; iam &#61; optional&#40;map&#40;list&#40;string&#41;&#41;, &#123;&#125;&#41;&#10; iam_bindings &#61; optional&#40;map&#40;object&#40;&#123;&#10; role &#61; string&#10; members &#61; list&#40;string&#41;&#10; &#125;&#41;&#41;, &#123;&#125;&#41;&#10; iam_bindings_additive &#61; optional&#40;map&#40;object&#40;&#123;&#10; role &#61; string&#10; member &#61; string&#10; &#125;&#41;&#41;, &#123;&#125;&#41;&#10; initial_config &#61; optional&#40;object&#40;&#123;&#10; default_branch &#61; optional&#40;string&#41;&#10; gitignores &#61; optional&#40;string&#41;&#10; license &#61; optional&#40;string&#41;&#10; readme &#61; optional&#40;string&#41;&#10; &#125;&#41;&#41;&#10; location &#61; string&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | ✓ | |
| [ca_pool](variables.tf#L17) | CA pool. | <code>string</code> | | <code>null</code> |
| [iam](variables-iam.tf#L17) | IAM bindings. | <code>map&#40;list&#40;string&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [iam_bindings](variables-iam.tf#L23) | IAM bindings. | <code title="map&#40;object&#40;&#123;&#10; role &#61; string&#10; members &#61; list&#40;string&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [iam_bindings_additive](variables-iam.tf#L32) | IAM bindings. | <code title="map&#40;object&#40;&#123;&#10; role &#61; string&#10; member &#61; string&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [kms_key](variables.tf#L28) | KMS key. | <code>string</code> | | <code>null</code> |
| [labels](variables.tf#L34) | Instance labels. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> |

## Outputs

| name | description | sensitive |
|---|---|:---:|
| [instance](outputs.tf#L17) | Instance. | |
| [instance_id](outputs.tf#L22) | Instance id. | |
| [repositories](outputs.tf#L27) | Repositories. | |
| [repository_ids](outputs.tf#L32) | Repository ids. | |
<!-- END TFDOC -->
80 changes: 80 additions & 0 deletions modules/secure-source-manager-instance/iam.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/**
* Copyright 2024 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 {
repository_iam = merge([for k1, v1 in var.repositories : { for k2, v2 in v1.iam :
"${k1}.${k2}" => {
repository = k1
role = k2
members = v2
} }]...)
repository_iam_bindings = merge([for k1, v1 in var.repositories : { for k2, v2 in v1.iam_bindings :
"${k1}.${k2}" => merge(v2, {
repository = k1
}) }]...)
repository_iam_bindings_additive = merge([for k1, v1 in var.repositories : { for k2, v2 in v1.iam_bindings_additive :
"${k1}.${k2}" => merge(v2, {
repository = k1
}) }]...)
}

resource "google_secure_source_manager_instance_iam_binding" "authoritative" {
for_each = var.iam
project = google_secure_source_manager_instance.instance.project
instance_id = google_secure_source_manager_instance.instance.instance_id
role = each.key
members = each.value
}

resource "google_secure_source_manager_instance_iam_binding" "bindings" {
for_each = var.iam_bindings
project = google_secure_source_manager_instance.instance.project
instance_id = google_secure_source_manager_instance.instance.instance_id
role = each.value.role
members = each.value.members
}

resource "google_secure_source_manager_instance_iam_member" "bindings" {
for_each = var.iam_bindings_additive
project = google_secure_source_manager_instance.instance.project
instance_id = google_secure_source_manager_instance.instance.instance_id
role = each.value.role
member = each.value.member
}

resource "google_secure_source_manager_repository_iam_binding" "authoritative" {
for_each = local.repository_iam
project = google_secure_source_manager_repository.repositories[each.value.repository].project
repository_id = google_secure_source_manager_repository.repositories[each.value.repository].repository_id
role = each.value.role
members = each.value.members
}

resource "google_secure_source_manager_repository_iam_binding" "bindings" {
for_each = local.repository_iam_bindings
project = google_secure_source_manager_repository.repositories[each.value.repository].project
repository_id = google_secure_source_manager_repository.repositories[each.value.repository].repository_id
role = each.value.role
members = each.value.members
}

resource "google_secure_source_manager_repository_iam_member" "bindings" {
for_each = local.repository_iam_bindings_additive
project = google_secure_source_manager_repository.repositories[each.value.repository].project
repository_id = google_secure_source_manager_repository.repositories[each.value.repository].repository_id
role = each.value.role
member = each.value.member
}
47 changes: 47 additions & 0 deletions modules/secure-source-manager-instance/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**
* Copyright 2024 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_secure_source_manager_instance" "instance" {
instance_id = var.instance_id
project = var.project_id
location = var.location
labels = var.labels
kms_key = var.kms_key
dynamic "private_config" {
for_each = var.ca_pool == null ? [] : [""]
content {
is_private = true
ca_pool = var.ca_pool
}
}
}

resource "google_secure_source_manager_repository" "repositories" {
for_each = var.repositories
repository_id = each.key
instance = google_secure_source_manager_instance.instance.name
project = var.project_id
location = each.value.location
dynamic "initial_config" {
for_each = each.value.initial_config == null ? [] : [""]
content {
default_branch = each.value.initial_config.default_branch
gitignores = each.value.initial_config.gitignores
license = each.value.initial_config.license
readme = each.value.initial_config.readme
}
}
}
35 changes: 35 additions & 0 deletions modules/secure-source-manager-instance/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* Copyright 2024 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 "instance" {
description = "Instance."
value = google_secure_source_manager_instance.instance
}

output "instance_id" {
description = "Instance id."
value = google_secure_source_manager_instance.instance.id
}

output "repositories" {
description = "Repositories."
value = google_secure_source_manager_repository.repositories
}

output "repository_ids" {
description = "Repository ids."
value = { for k, v in google_secure_source_manager_repository.repositories : k => v.id }
}
Loading