Skip to content

Commit

Permalink
Added support for the integration with Secret Manager in Cloud Run Ma…
Browse files Browse the repository at this point in the history
…naged.

The integration enables binding secret values to environment variables or
to the content of files.
  • Loading branch information
jeremiele committed Apr 23, 2021
1 parent 2bf0e12 commit 2170b50
Show file tree
Hide file tree
Showing 6 changed files with 537 additions and 0 deletions.
106 changes: 106 additions & 0 deletions mmv1/products/cloudrun/api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ versions:
- !ruby/object:Api::Product::Version
name: ga
base_url: https://{{location}}-run.googleapis.com/
- !ruby/object:Api::Product::Version
name: beta
base_url: https://{{location}}-run.googleapis.com/
scopes:
- https://www.googleapis.com/auth/cloud-platform
objects:
Expand Down Expand Up @@ -515,6 +518,37 @@ objects:
references will never be expanded, regardless of whether the variable
exists or not.
Defaults to "".
- !ruby/object:Api::Type::NestedObject
name: valueFrom
min_version: beta
description: |-
Source for the environment variable's value. Only supports secret_key_ref.
properties:
- !ruby/object:Api::Type::NestedObject
name: secretKeyRef
min_version: beta
description: |-
Selects a key (version) of a secret in Secret Manager.
properties:
- !ruby/object:Api::Type::String
name: key
min_version: beta
description: |-
A Cloud Secret Manager secret version. Must be 'latest' for the latest
version or an integer for a specific version.
- !ruby/object:Api::Type::String
name: name
min_version: beta
description: |-
The name of the secret in Cloud Secret Manager. By default, the secret
is assumed to be in the same project.
If the secret is in another project, you must define an alias.
An alias definition has the form:
<alias>:projects/<project-id|project-number>/secrets/<secret-name>.
If multiple alias definitions are needed, they must be separated by
commas.
The alias definitions must be set on the run.googleapis.com/secrets
annotation.
- !ruby/object:Api::Type::Array
name: ports
description: |-
Expand Down Expand Up @@ -554,6 +588,27 @@ objects:
explicitly specified, otherwise to an implementation-defined value.
The values of the map is string form of the 'quantity' k8s type:
https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/apimachinery/pkg/api/resource/quantity.go
- !ruby/object:Api::Type::Array
name: volumeMounts
description: |-
Volume to mount into the container's filesystem.
Only supports SecretVolumeSources.
item_type: !ruby/object:Api::Type::NestedObject
properties:
- !ruby/object:Api::Type::String
name: mountPath
description: |-
Path within the container at which the volume should be mounted. Must
not contain ':'.
- !ruby/object:Api::Type::String
name: name
description: |-
This must match the Name of a Volume.
- !ruby/object:Api::Type::Boolean
name: readOnly
description: |-
Only true is accepted.
Defaults to true.
- !ruby/object:Api::Type::Integer
name: containerConcurrency
Expand All @@ -575,6 +630,57 @@ objects:
service. The service account represents the identity of the running revision,
and determines what permissions the revision has. If not provided, the revision
will use the project's default service account.
- !ruby/object:Api::Type::Array
name: volumes
description: |-
Volume represents a named volume in a container.
item_type: !ruby/object:Api::Type::NestedObject
properties:
- !ruby/object:Api::Type::String
name: name
description: |-
Volume's name.
- !ruby/object:Api::Type::NestedObject
name: secret
description: |-
The secret's value will be presented as the content of a file whose
name is defined in the item path. If no items are defined, the name of
the file is the secret_name.
properties:
- !ruby/object:Api::Type::String
name: secretName
description: |-
The name of the secret in Cloud Secret Manager. By default, the secret
is assumed to be in the same project.
If the secret is in another project, you must define an alias.
An alias definition has the form:
<alias>:projects/<project-id|project-number>/secrets/<secret-name>.
If multiple alias definitions are needed, they must be separated by
commas.
The alias definitions must be set on the run.googleapis.com/secrets
annotation.
- !ruby/object:Api::Type::Array
name: items
description: |-
If unspecified, the volume will expose a file whose name is the
secret_name.
If specified, the key will be used as the version to fetch from Cloud
Secret Manager and the path will be the name of the file exposed in the
volume. When items are defined, they must specify a key and a path.
item_type: !ruby/object:Api::Type::NestedObject
properties:
- !ruby/object:Api::Type::String
name: key
description: |-
The Cloud Secret Manager secret version.
Can be 'latest' for the latest value or an integer for a specific version.
- !ruby/object:Api::Type::String
name: path
description: |-
The relative path of the file to map the key to.
May not be an absolute path.
May not contain the path element '..'.
May not start with the string '..'.
- !ruby/object:Api::Type::Enum
name: servingState
deprecation_message: "Not supported by Cloud Run fully managed"
Expand Down
24 changes: 24 additions & 0 deletions mmv1/products/cloudrun/terraform.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,30 @@ overrides: !ruby/object:Overrides::ResourceOverrides
cloud_run_service_name: "cloudrun-srv"
test_env_vars:
project: :PROJECT_NAME
- !ruby/object:Provider::Terraform::Examples
name: "cloud_run_service_secret_environment_variables"
min_version: beta
primary_resource_id: "default"
primary_resource_name: "fmt.Sprintf(\"tf-test-cloudrun-srv%s\", context[\"random_suffix\"])"
vars:
cloud_run_service_name: "cloudrun-srv"
secret_id: "secret"
test_env_vars:
project: :PROJECT_NAME
ignore_read_extra:
- "autogenerate_revision_name"
- !ruby/object:Provider::Terraform::Examples
name: "cloud_run_service_secret_volumes"
min_version: beta
primary_resource_id: "default"
primary_resource_name: "fmt.Sprintf(\"tf-test-cloudrun-srv%s\", context[\"random_suffix\"])"
vars:
cloud_run_service_name: "cloudrun-srv"
secret_id: "secret"
test_env_vars:
project: :PROJECT_NAME
ignore_read_extra:
- "autogenerate_revision_name"
virtual_fields:
- !ruby/object:Api::Type::Boolean
name: 'autogenerate_revision_name'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
data "google_project" "project" {
provider = google-beta
}

resource "google_project_service" "secret-manager" {
provider = google-beta

service = "secretmanager.googleapis.com"
}

resource "google_secret_manager_secret" "secret" {
provider = google-beta

secret_id = "<%= ctx[:vars]['secret_id'] %>"
replication {
automatic = true
}

depends_on = [google_project_service.secret-manager]
}

resource "google_secret_manager_secret_version" "secret-version-data" {
provider = google-beta

secret = google_secret_manager_secret.secret.name
secret_data = "secret-data"
}

resource "google_secret_manager_secret_iam_member" "secret-access" {
provider = google-beta

secret_id = google_secret_manager_secret.secret.id
role = "roles/secretmanager.secretAccessor"
member = "serviceAccount:${data.google_project.project.number}-compute@developer.gserviceaccount.com"
depends_on = [google_secret_manager_secret.secret]
}

resource "google_cloud_run_service" "<%= ctx[:primary_resource_id] %>" {
provider = google-beta

name = "<%= ctx[:vars]['cloud_run_service_name'] %>"
location = "us-central1"

template {
spec {
containers {
image = "gcr.io/cloudrun/hello"
env {
name = "SECRET_ENV_VAR"
value_from {
secret_key_ref {
name = google_secret_manager_secret.secret.secret_id
key = "1"
}
}
}
}
}
}

metadata {
annotations = {
generated-by = "magic-modules"
"run.googleapis.com/launch-stage" = "ALPHA"
}
}

traffic {
percent = 100
latest_revision = true
}
autogenerate_revision_name = true

lifecycle {
ignore_changes = [
metadata.0.annotations,
]
}

depends_on = [google_secret_manager_secret_version.secret-version-data]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
data "google_project" "project" {
provider = google-beta
}

resource "google_project_service" "secret-manager" {
provider = google-beta

service = "secretmanager.googleapis.com"
}

resource "google_secret_manager_secret" "secret" {
provider = google-beta

secret_id = "<%= ctx[:vars]['secret_id'] %>"
replication {
automatic = true
}

depends_on = [google_project_service.secret-manager]
}

resource "google_secret_manager_secret_version" "secret-version-data" {
provider = google-beta

secret = google_secret_manager_secret.secret.name
secret_data = "secret-data"
}

resource "google_secret_manager_secret_iam_member" "secret-access" {
provider = google-beta

secret_id = google_secret_manager_secret.secret.id
role = "roles/secretmanager.secretAccessor"
member = "serviceAccount:${data.google_project.project.number}-compute@developer.gserviceaccount.com"
depends_on = [google_secret_manager_secret.secret]
}

resource "google_cloud_run_service" "<%= ctx[:primary_resource_id] %>" {
provider = google-beta

name = "<%= ctx[:vars]['cloud_run_service_name'] %>"
location = "us-central1"

template {
spec {
containers {
image = "gcr.io/cloudrun/hello"
volume_mounts {
name = "a-volume"
mount_path = "/secrets"
}
}
volumes {
name = "a-volume"
secret {
secret_name = google_secret_manager_secret.secret.secret_id
items {
key = "1"
path = "my-secret"
}
}
}
}
}

metadata {
annotations = {
generated-by = "magic-modules"
"run.googleapis.com/launch-stage" = "ALPHA"
}
}

traffic {
percent = 100
latest_revision = true
}
autogenerate_revision_name = true

lifecycle {
ignore_changes = [
metadata.0.annotations,
]
}

depends_on = [google_secret_manager_secret_version.secret-version-data]
}
Loading

0 comments on commit 2170b50

Please sign in to comment.