Refactor cloud run module to use optionals and support all features (#1293)
* refactor cloud run resource and variables * vpc connector variables and resource * refactor env variable, combine and fix env examples * fix volume example * fix traffic split example * fix eventarc/pubsub example * fix eventarc/audit log example * fix SA examples, fix examples formatting * refactor eventarc variable * tfdoc * add IAM to example * add examples for revision annotations and serverless connector * fix new examples * remove legacy module tests * blueprint tests * Add tests to cloud-run module --------- Co-authored-by: Julio Castillo <jccb@google.com>
This commit is contained in:
committed by
GitHub
parent
c5db50d1d7
commit
92b71a5098
@@ -18,11 +18,24 @@ locals {
|
||||
cloud_run_domain = "run.app."
|
||||
service_name_cr1 = "cart"
|
||||
service_name_cr2 = "checkout"
|
||||
tf_id = (var.tf_identity == null ? null :
|
||||
length(regexall("iam.gserviceaccount.com", var.tf_identity)) > 0 ?
|
||||
"serviceAccount:${var.tf_identity}" : "user:${var.tf_identity}")
|
||||
vpc_sc_create = (length(module.project_prj1) > 0 &&
|
||||
(var.access_policy != null || var.access_policy_create != null)) ? 1 : 0
|
||||
tf_id = (
|
||||
var.tf_identity == null
|
||||
? null
|
||||
: (
|
||||
length(regexall("iam.gserviceaccount.com", var.tf_identity)) > 0
|
||||
? "serviceAccount:${var.tf_identity}"
|
||||
: "user:${var.tf_identity}"
|
||||
)
|
||||
)
|
||||
vpc_sc_create = (
|
||||
(
|
||||
length(module.project_prj1) > 0
|
||||
&&
|
||||
(var.access_policy != null || var.access_policy_create != null)
|
||||
)
|
||||
? 1
|
||||
: 0
|
||||
)
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
@@ -109,13 +122,11 @@ module "cloud_run_hello" {
|
||||
project_id = module.project_main.project_id
|
||||
name = "hello"
|
||||
region = var.region
|
||||
containers = [{
|
||||
image = var.image
|
||||
options = null
|
||||
ports = null
|
||||
resources = null
|
||||
volume_mounts = null
|
||||
}]
|
||||
containers = {
|
||||
default = {
|
||||
image = var.image
|
||||
}
|
||||
}
|
||||
iam = {
|
||||
"roles/run.invoker" = ["allUsers"]
|
||||
}
|
||||
@@ -129,13 +140,11 @@ module "cloud_run_cart" {
|
||||
project_id = module.project_svc1[0].project_id
|
||||
name = local.service_name_cr1 # "cart"
|
||||
region = var.region
|
||||
containers = [{
|
||||
image = var.image
|
||||
options = null
|
||||
ports = null
|
||||
resources = null
|
||||
volume_mounts = null
|
||||
}]
|
||||
containers = {
|
||||
default = {
|
||||
image = var.image
|
||||
}
|
||||
}
|
||||
iam = {
|
||||
"roles/run.invoker" = ["allUsers"]
|
||||
}
|
||||
@@ -149,13 +158,11 @@ module "cloud_run_checkout" {
|
||||
project_id = module.project_svc1[0].project_id
|
||||
name = local.service_name_cr2 # "checkout"
|
||||
region = var.region
|
||||
containers = [{
|
||||
image = var.image
|
||||
options = null
|
||||
ports = null
|
||||
resources = null
|
||||
volume_mounts = null
|
||||
}]
|
||||
containers = {
|
||||
default = {
|
||||
image = var.image
|
||||
}
|
||||
}
|
||||
iam = {
|
||||
"roles/run.invoker" = ["allUsers"]
|
||||
}
|
||||
|
||||
@@ -43,13 +43,11 @@ module "cloud_run" {
|
||||
project_id = module.project.project_id
|
||||
name = var.run_svc_name
|
||||
region = var.region
|
||||
containers = [{
|
||||
image = var.image
|
||||
options = null
|
||||
ports = null
|
||||
resources = null
|
||||
volume_mounts = null
|
||||
}]
|
||||
containers = {
|
||||
default = {
|
||||
image = var.image
|
||||
}
|
||||
}
|
||||
iam = {
|
||||
"roles/run.invoker" = ["allUsers"]
|
||||
}
|
||||
|
||||
@@ -1,95 +1,124 @@
|
||||
# Cloud Run Module
|
||||
|
||||
Cloud Run management, with support for IAM roles and optional Eventarc trigger creation.
|
||||
Cloud Run management, with support for IAM roles, revision annotations and optional Eventarc trigger creation.
|
||||
|
||||
## Examples
|
||||
|
||||
### Environment variables
|
||||
- [IAM and environment variables](#iam-and-environment-variables)
|
||||
- [Mounting secrets as volumes](#mounting-secrets-as-volumes)
|
||||
- [Revision annotations](#revision-annotations)
|
||||
- [VPC Access Connector creation](#vpc-access-connector-creation)
|
||||
- [Traffic split](#traffic-split)
|
||||
- [Eventarc triggers](#eventarc-triggers)
|
||||
- [Service account](#service-account)
|
||||
|
||||
This deploys a Cloud Run service and sets some environment variables.
|
||||
### IAM and environment variables
|
||||
|
||||
IAM bindings support the usual syntax. Container environment values can be declared as key-value strings or as references to Secret Manager secrets. Both can be combined as long as there's no duplication of keys:
|
||||
|
||||
```hcl
|
||||
module "cloud_run" {
|
||||
source = "./fabric/modules/cloud-run"
|
||||
project_id = "my-project"
|
||||
name = "hello"
|
||||
containers = [{
|
||||
image = "us-docker.pkg.dev/cloudrun/container/hello"
|
||||
options = {
|
||||
command = null
|
||||
args = null
|
||||
containers = {
|
||||
hello = {
|
||||
image = "us-docker.pkg.dev/cloudrun/container/hello"
|
||||
env = {
|
||||
"VAR1" : "VALUE1",
|
||||
"VAR2" : "VALUE2",
|
||||
VAR1 = "VALUE1"
|
||||
VAR2 = "VALUE2"
|
||||
}
|
||||
env_from = null
|
||||
}
|
||||
ports = null
|
||||
resources = null
|
||||
volume_mounts = null
|
||||
}]
|
||||
}
|
||||
# tftest modules=1 resources=1
|
||||
```
|
||||
|
||||
### Environment variables (value read from secret)
|
||||
|
||||
```hcl
|
||||
module "cloud_run" {
|
||||
source = "./fabric/modules/cloud-run"
|
||||
project_id = "my-project"
|
||||
name = "hello"
|
||||
containers = [{
|
||||
image = "us-docker.pkg.dev/cloudrun/container/hello"
|
||||
options = {
|
||||
command = null
|
||||
args = null
|
||||
env = null
|
||||
env_from = {
|
||||
"CREDENTIALS" : {
|
||||
SECRET1 = {
|
||||
name = "credentials"
|
||||
key = "1"
|
||||
}
|
||||
}
|
||||
}
|
||||
ports = null
|
||||
resources = null
|
||||
volume_mounts = null
|
||||
}]
|
||||
}
|
||||
iam = {
|
||||
"roles/run.invoker" = ["allUsers"]
|
||||
}
|
||||
}
|
||||
# tftest modules=1 resources=1
|
||||
# tftest modules=1 resources=2 inventory=simple.yaml
|
||||
```
|
||||
|
||||
### Secret mounted as volume
|
||||
### Mounting secrets as volumes
|
||||
|
||||
```hcl
|
||||
module "cloud_run" {
|
||||
source = "./fabric/modules/cloud-run"
|
||||
project_id = var.project_id
|
||||
name = "hello"
|
||||
region = var.region
|
||||
revision_name = "green"
|
||||
containers = [{
|
||||
image = "us-docker.pkg.dev/cloudrun/container/hello"
|
||||
options = null
|
||||
ports = null
|
||||
resources = null
|
||||
volume_mounts = {
|
||||
"credentials" : "/credentials"
|
||||
source = "./fabric/modules/cloud-run"
|
||||
project_id = var.project_id
|
||||
name = "hello"
|
||||
region = var.region
|
||||
containers = {
|
||||
hello = {
|
||||
image = "us-docker.pkg.dev/cloudrun/container/hello"
|
||||
volume_mounts = {
|
||||
"credentials" = "/credentials"
|
||||
}
|
||||
}
|
||||
}]
|
||||
volumes = [
|
||||
{
|
||||
}
|
||||
volumes = {
|
||||
credentials = {
|
||||
name = "credentials"
|
||||
secret_name = "credentials"
|
||||
items = [{
|
||||
key = "1"
|
||||
path = "v1.txt"
|
||||
}]
|
||||
items = {
|
||||
v1 = { path = "v1.txt" }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
# tftest modules=1 resources=1
|
||||
# tftest modules=1 resources=1 inventory=secrets.yaml
|
||||
```
|
||||
|
||||
### Revision annotations
|
||||
|
||||
Annotations can be specified via the `revision_annotations` variable:
|
||||
|
||||
```hcl
|
||||
module "cloud_run" {
|
||||
source = "./fabric/modules/cloud-run"
|
||||
project_id = var.project_id
|
||||
name = "hello"
|
||||
containers = {
|
||||
hello = {
|
||||
image = "us-docker.pkg.dev/cloudrun/container/hello"
|
||||
}
|
||||
}
|
||||
revision_annotations = {
|
||||
autoscaling = {
|
||||
max_scale = 10
|
||||
min_scale = 1
|
||||
}
|
||||
cloudsql_unstances = ["sql-0", "sql-1"]
|
||||
vpcaccess_connector = "foo"
|
||||
vpcaccess_egress = "all-traffic"
|
||||
}
|
||||
}
|
||||
# tftest modules=1 resources=1 inventory=revision-annotations.yaml
|
||||
```
|
||||
|
||||
### VPC Access Connector creation
|
||||
|
||||
If creation of a [VPC Access Connector](https://cloud.google.com/vpc/docs/serverless-vpc-access) is required, use the `vpc_connector_create` variable which also support optional attribtues for number of instances, machine type, and throughput (not shown here). The annotation to use the connector will be added automatically.
|
||||
|
||||
```hcl
|
||||
module "cloud_run" {
|
||||
source = "./fabric/modules/cloud-run"
|
||||
project_id = var.project_id
|
||||
name = "hello"
|
||||
containers = {
|
||||
hello = {
|
||||
image = "us-docker.pkg.dev/cloudrun/container/hello"
|
||||
}
|
||||
}
|
||||
vpc_connector_create = {
|
||||
ip_cidr_range = "10.10.10.0/24"
|
||||
vpc_self_link = "projects/example/host/global/networks/host"
|
||||
}
|
||||
}
|
||||
# tftest modules=1 resources=2 inventory=connector.yaml
|
||||
```
|
||||
|
||||
### Traffic split
|
||||
@@ -102,22 +131,22 @@ module "cloud_run" {
|
||||
project_id = "my-project"
|
||||
name = "hello"
|
||||
revision_name = "green"
|
||||
containers = [{
|
||||
image = "us-docker.pkg.dev/cloudrun/container/hello"
|
||||
options = null
|
||||
ports = null
|
||||
resources = null
|
||||
volume_mounts = null
|
||||
}]
|
||||
containers = {
|
||||
hello = {
|
||||
image = "us-docker.pkg.dev/cloudrun/container/hello"
|
||||
}
|
||||
}
|
||||
traffic = {
|
||||
"blue" = 25
|
||||
"green" = 75
|
||||
blue = { percent = 25 }
|
||||
green = { percent = 75 }
|
||||
}
|
||||
}
|
||||
# tftest modules=1 resources=1
|
||||
# tftest modules=1 resources=1 inventory=traffic.yaml
|
||||
```
|
||||
|
||||
### Eventarc trigger (Pub/Sub)
|
||||
### Eventarc triggers
|
||||
|
||||
#### PubSub
|
||||
|
||||
This deploys a Cloud Run service that will be triggered when messages are published to Pub/Sub topics.
|
||||
|
||||
@@ -126,22 +155,22 @@ module "cloud_run" {
|
||||
source = "./fabric/modules/cloud-run"
|
||||
project_id = "my-project"
|
||||
name = "hello"
|
||||
containers = [{
|
||||
image = "us-docker.pkg.dev/cloudrun/container/hello"
|
||||
options = null
|
||||
ports = null
|
||||
resources = null
|
||||
volume_mounts = null
|
||||
}]
|
||||
pubsub_triggers = [
|
||||
"topic1",
|
||||
"topic2"
|
||||
]
|
||||
containers = {
|
||||
hello = {
|
||||
image = "us-docker.pkg.dev/cloudrun/container/hello"
|
||||
}
|
||||
}
|
||||
eventarc_triggers = {
|
||||
pubsub = {
|
||||
topic-1 = "topic1"
|
||||
topic-2 = "topic2"
|
||||
}
|
||||
}
|
||||
}
|
||||
# tftest modules=1 resources=3
|
||||
# tftest modules=1 resources=3 inventory=eventarc.yaml
|
||||
```
|
||||
|
||||
### Eventarc trigger (Audit logs)
|
||||
#### Audit logs
|
||||
|
||||
This deploys a Cloud Run service that will be triggered when specific log events are written to Google Cloud audit logs.
|
||||
|
||||
@@ -150,24 +179,24 @@ module "cloud_run" {
|
||||
source = "./fabric/modules/cloud-run"
|
||||
project_id = "my-project"
|
||||
name = "hello"
|
||||
containers = [{
|
||||
image = "us-docker.pkg.dev/cloudrun/container/hello"
|
||||
options = null
|
||||
ports = null
|
||||
resources = null
|
||||
volume_mounts = null
|
||||
}]
|
||||
audit_log_triggers = [
|
||||
{
|
||||
service_name = "cloudresourcemanager.googleapis.com"
|
||||
method_name = "SetIamPolicy"
|
||||
containers = {
|
||||
hello = {
|
||||
image = "us-docker.pkg.dev/cloudrun/container/hello"
|
||||
}
|
||||
]
|
||||
}
|
||||
eventarc_triggers = {
|
||||
audit_log = {
|
||||
setiampolicy = {
|
||||
method = "SetIamPolicy"
|
||||
service = "cloudresourcemanager.googleapis.com"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
# tftest modules=1 resources=2
|
||||
# tftest modules=1 resources=2 inventory=audit-logs.yaml
|
||||
```
|
||||
|
||||
### Service account management
|
||||
### Service account
|
||||
|
||||
To use a custom service account managed by the module, set `service_account_create` to `true` and leave `service_account` set to `null` value (default).
|
||||
|
||||
@@ -176,16 +205,14 @@ module "cloud_run" {
|
||||
source = "./fabric/modules/cloud-run"
|
||||
project_id = "my-project"
|
||||
name = "hello"
|
||||
containers = [{
|
||||
image = "us-docker.pkg.dev/cloudrun/container/hello"
|
||||
options = null
|
||||
ports = null
|
||||
resources = null
|
||||
volume_mounts = null
|
||||
}]
|
||||
containers = {
|
||||
hello = {
|
||||
image = "us-docker.pkg.dev/cloudrun/container/hello"
|
||||
}
|
||||
}
|
||||
service_account_create = true
|
||||
}
|
||||
# tftest modules=1 resources=2
|
||||
# tftest modules=1 resources=2 inventory=service-account.yaml
|
||||
```
|
||||
|
||||
To use an externally managed service account, pass its email in `service_account` and leave `service_account_create` to `false` (the default).
|
||||
@@ -195,16 +222,14 @@ module "cloud_run" {
|
||||
source = "./fabric/modules/cloud-run"
|
||||
project_id = "my-project"
|
||||
name = "hello"
|
||||
containers = [{
|
||||
image = "us-docker.pkg.dev/cloudrun/container/hello"
|
||||
options = null
|
||||
ports = null
|
||||
resources = null
|
||||
volume_mounts = null
|
||||
}]
|
||||
containers = {
|
||||
hello = {
|
||||
image = "us-docker.pkg.dev/cloudrun/container/hello"
|
||||
}
|
||||
}
|
||||
service_account = "cloud-run@my-project.iam.gserviceaccount.com"
|
||||
}
|
||||
# tftest modules=1 resources=1
|
||||
# tftest modules=1 resources=1 inventory=service-account-external.yaml
|
||||
```
|
||||
<!-- BEGIN TFDOC -->
|
||||
|
||||
@@ -212,23 +237,24 @@ module "cloud_run" {
|
||||
|
||||
| name | description | type | required | default |
|
||||
|---|---|:---:|:---:|:---:|
|
||||
| [containers](variables.tf#L27) | Containers. | <code title="list(object({ image = string options = object({ command = list(string) args = list(string) env = map(string) env_from = map(object({ key = string name = string })) }) resources = object({ limits = object({ cpu = string memory = string }) requests = object({ cpu = string memory = string }) }) ports = list(object({ name = string protocol = string container_port = string })) volume_mounts = map(string) }))">list(object({…}))</code> | ✓ | |
|
||||
| [name](variables.tf#L77) | Name used for cloud run service. | <code>string</code> | ✓ | |
|
||||
| [project_id](variables.tf#L92) | Project id used for all resources. | <code>string</code> | ✓ | |
|
||||
| [audit_log_triggers](variables.tf#L18) | Event arc triggers (Audit log). | <code title="list(object({ service_name = string method_name = string }))">list(object({…}))</code> | | <code>null</code> |
|
||||
| [iam](variables.tf#L59) | IAM bindings for Cloud Run service in {ROLE => [MEMBERS]} format. | <code>map(list(string))</code> | | <code>{}</code> |
|
||||
| [ingress_settings](variables.tf#L65) | Ingress settings. | <code>string</code> | | <code>null</code> |
|
||||
| [labels](variables.tf#L71) | Resource labels. | <code>map(string)</code> | | <code>{}</code> |
|
||||
| [prefix](variables.tf#L82) | Optional prefix used for resource names. | <code>string</code> | | <code>null</code> |
|
||||
| [pubsub_triggers](variables.tf#L97) | Eventarc triggers (Pub/Sub). | <code>list(string)</code> | | <code>null</code> |
|
||||
| [region](variables.tf#L103) | Region used for all resources. | <code>string</code> | | <code>"europe-west1"</code> |
|
||||
| [revision_annotations](variables.tf#L109) | Configure revision template annotations. | <code title="object({ autoscaling = object({ max_scale = number min_scale = number }) cloudsql_instances = list(string) vpcaccess_connector = string vpcaccess_egress = string })">object({…})</code> | | <code>null</code> |
|
||||
| [revision_name](variables.tf#L123) | Revision name. | <code>string</code> | | <code>null</code> |
|
||||
| [service_account](variables.tf#L129) | Service account email. Unused if service account is auto-created. | <code>string</code> | | <code>null</code> |
|
||||
| [service_account_create](variables.tf#L135) | Auto-create service account. | <code>bool</code> | | <code>false</code> |
|
||||
| [traffic](variables.tf#L141) | Traffic. | <code>map(number)</code> | | <code>null</code> |
|
||||
| [volumes](variables.tf#L147) | Volumes. | <code title="list(object({ name = string secret_name = string items = list(object({ key = string path = string })) }))">list(object({…}))</code> | | <code>null</code> |
|
||||
| [vpc_connector_create](variables.tf#L160) | Populate this to create a VPC connector. You can then refer to it in the template annotations. | <code title="object({ ip_cidr_range = string name = string vpc_self_link = string })">object({…})</code> | | <code>null</code> |
|
||||
| [name](variables.tf#L121) | Name used for cloud run service. | <code>string</code> | ✓ | |
|
||||
| [project_id](variables.tf#L136) | Project id used for all resources. | <code>string</code> | ✓ | |
|
||||
| [container_concurrency](variables.tf#L18) | Maximum allowed in-flight (concurrent) requests per container of the revision. | <code>string</code> | | <code>null</code> |
|
||||
| [containers](variables.tf#L24) | Containers in arbitrary key => attributes format. | <code title="map(object({ image = string args = optional(list(string)) command = optional(list(string)) env = optional(map(string), {}) env_from_key = optional(map(object({ key = string name = string })), {}) liveness_probe = optional(object({ action = object({ grcp = optional(object({ port = optional(number) service = optional(string) })) http_get = optional(object({ http_headers = optional(map(string), {}) path = optional(string) })) }) failure_threshold = optional(number) initial_delay_seconds = optional(number) period_seconds = optional(number) timeout_seconds = optional(number) })) ports = optional(map(object({ container_port = optional(number) name = optional(string) protocol = optional(string) })), {}) resources = optional(object({ limits = optional(object({ cpu = string memory = string })) requests = optional(object({ cpu = string memory = string })) })) startup_probe = optional(object({ action = object({ grcp = optional(object({ port = optional(number) service = optional(string) })) http_get = optional(object({ http_headers = optional(map(string), {}) path = optional(string) })) tcp_socket = optional(object({ port = optional(number) })) }) failure_threshold = optional(number) initial_delay_seconds = optional(number) period_seconds = optional(number) timeout_seconds = optional(number) })) volume_mounts = optional(map(string), {}) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||
| [eventarc_triggers](variables.tf#L91) | Event arc triggers for different sources. | <code title="object({ audit_log = optional(map(object({ method = string service = string })), {}) pubsub = optional(map(string), {}) })">object({…})</code> | | <code>{}</code> |
|
||||
| [iam](variables.tf#L103) | IAM bindings for Cloud Run service in {ROLE => [MEMBERS]} format. | <code>map(list(string))</code> | | <code>{}</code> |
|
||||
| [ingress_settings](variables.tf#L109) | Ingress settings. | <code>string</code> | | <code>null</code> |
|
||||
| [labels](variables.tf#L115) | Resource labels. | <code>map(string)</code> | | <code>{}</code> |
|
||||
| [prefix](variables.tf#L126) | Optional prefix used for resource names. | <code>string</code> | | <code>null</code> |
|
||||
| [region](variables.tf#L141) | Region used for all resources. | <code>string</code> | | <code>"europe-west1"</code> |
|
||||
| [revision_annotations](variables.tf#L147) | Configure revision template annotations. | <code title="object({ autoscaling = optional(object({ max_scale = number min_scale = number })) cloudsql_instances = optional(list(string), []) vpcaccess_connector = optional(string) vpcaccess_egress = optional(string) })">object({…})</code> | | <code>{}</code> |
|
||||
| [revision_name](variables.tf#L162) | Revision name. | <code>string</code> | | <code>null</code> |
|
||||
| [service_account](variables.tf#L168) | Service account email. Unused if service account is auto-created. | <code>string</code> | | <code>null</code> |
|
||||
| [service_account_create](variables.tf#L174) | Auto-create service account. | <code>bool</code> | | <code>false</code> |
|
||||
| [timeout_seconds](variables.tf#L180) | Maximum duration the instance is allowed for responding to a request. | <code>number</code> | | <code>null</code> |
|
||||
| [traffic](variables.tf#L186) | Traffic steering configuration. If revision name is null the latest revision will be used. | <code title="map(object({ percent = number latest = optional(bool) tag = optional(string) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||
| [volumes](variables.tf#L197) | Named volumes in containers in name => attributes format. | <code title="map(object({ secret_name = string default_mode = optional(string) items = optional(map(object({ path = string mode = optional(string) }))) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||
| [vpc_connector_create](variables.tf#L211) | Populate this to create a VPC connector. You can then refer to it in the template annotations. | <code title="object({ ip_cidr_range = string vpc_self_link = string machine_type = optional(string) name = optional(string) instances = optional(object({ max = optional(number) min = optional(number) }), {}) throughput = optional(object({ max = optional(number) min = optional(number) }), {}) })">object({…})</code> | | <code>null</code> |
|
||||
|
||||
## Outputs
|
||||
|
||||
|
||||
@@ -21,10 +21,12 @@ locals {
|
||||
"run.googleapis.com/vpc-access-connector" = google_vpc_access_connector.connector.0.id
|
||||
}
|
||||
: (
|
||||
try(var.revision_annotations.vpcaccess_connector, null) == null
|
||||
var.revision_annotations.vpcaccess_connector == null
|
||||
? {}
|
||||
: {
|
||||
"run.googleapis.com/vpc-access-connector" = var.revision_annotations.vpcaccess_connector
|
||||
"run.googleapis.com/vpc-access-connector" = (
|
||||
var.revision_annotations.vpcaccess_connector
|
||||
)
|
||||
}
|
||||
)
|
||||
)
|
||||
@@ -35,20 +37,26 @@ locals {
|
||||
)
|
||||
prefix = var.prefix == null ? "" : "${var.prefix}-"
|
||||
revision_annotations = merge(
|
||||
try(var.revision_annotations.autoscaling.max_scale, null) == null ? {} : {
|
||||
"autoscaling.knative.dev/maxScale" = var.revision_annotations.autoscaling.max_scale
|
||||
try(var.revision_annotations.autoscaling, null) == null ? {} : {
|
||||
"autoscaling.knative.dev/maxScale" = (
|
||||
var.revision_annotations.autoscaling.max_scale
|
||||
)
|
||||
},
|
||||
try(var.revision_annotations.autoscaling.min_scale, null) == null ? {} : {
|
||||
"autoscaling.knative.dev/minScale" = var.revision_annotations.autoscaling.min_scale
|
||||
"autoscaling.knative.dev/minScale" = (
|
||||
var.revision_annotations.autoscaling.min_scale
|
||||
)
|
||||
},
|
||||
try(var.revision_annotations.cloudsql_instances, null) == null ? {} : {
|
||||
"run.googleapis.com/cloudsql-instances" = join(",", coalesce(
|
||||
var.revision_annotations.cloudsql_instances, []
|
||||
))
|
||||
length(var.revision_annotations.cloudsql_instances) == 0 ? {} : {
|
||||
"run.googleapis.com/cloudsql-instances" = (
|
||||
join(",", var.revision_annotations.cloudsql_instances)
|
||||
)
|
||||
},
|
||||
local._vpcaccess_annotation,
|
||||
try(var.revision_annotations.vpcaccess_egress, null) == null ? {} : {
|
||||
"run.googleapis.com/vpc-access-egress" = var.revision_annotations.vpcaccess_egress
|
||||
var.revision_annotations.vpcaccess_egress == null ? {} : {
|
||||
"run.googleapis.com/vpc-access-egress" = (
|
||||
var.revision_annotations.vpcaccess_egress
|
||||
)
|
||||
},
|
||||
)
|
||||
revision_name = (
|
||||
@@ -69,12 +77,21 @@ locals {
|
||||
}
|
||||
|
||||
resource "google_vpc_access_connector" "connector" {
|
||||
count = local.vpc_connector_create ? 1 : 0
|
||||
project = var.project_id
|
||||
name = var.vpc_connector_create.name
|
||||
region = var.region
|
||||
ip_cidr_range = var.vpc_connector_create.ip_cidr_range
|
||||
network = var.vpc_connector_create.vpc_self_link
|
||||
count = local.vpc_connector_create ? 1 : 0
|
||||
project = var.project_id
|
||||
name = (
|
||||
var.vpc_connector_create.name != null
|
||||
? var.vpc_connector_create.name
|
||||
: var.name
|
||||
)
|
||||
region = var.region
|
||||
ip_cidr_range = var.vpc_connector_create.ip_cidr_range
|
||||
network = var.vpc_connector_create.vpc_self_link
|
||||
machine_type = var.vpc_connector_create.machine_type
|
||||
max_instances = var.vpc_connector_create.instances.max
|
||||
max_throughput = var.vpc_connector_create.throughput.max
|
||||
min_instances = var.vpc_connector_create.instances.min
|
||||
min_throughput = var.vpc_connector_create.throughput.min
|
||||
}
|
||||
|
||||
resource "google_cloud_run_service" "service" {
|
||||
@@ -85,54 +102,75 @@ resource "google_cloud_run_service" "service" {
|
||||
|
||||
template {
|
||||
spec {
|
||||
container_concurrency = var.container_concurrency
|
||||
service_account_name = local.service_account_email
|
||||
timeout_seconds = var.timeout_seconds
|
||||
dynamic "containers" {
|
||||
for_each = var.containers == null ? {} : {
|
||||
for i, container in var.containers : i => container
|
||||
}
|
||||
for_each = var.containers
|
||||
content {
|
||||
image = containers.value.image
|
||||
command = try(containers.value.options.command, null)
|
||||
args = try(containers.value.options.args, null)
|
||||
args = containers.value.args
|
||||
command = containers.value.command
|
||||
dynamic "env" {
|
||||
for_each = (
|
||||
try(containers.value.options.env, null) == null
|
||||
? {}
|
||||
: containers.value.options.env
|
||||
)
|
||||
for_each = containers.value.env
|
||||
content {
|
||||
name = env.key
|
||||
value = env.value
|
||||
}
|
||||
}
|
||||
dynamic "env" {
|
||||
for_each = (
|
||||
try(containers.value.options.env_from, null) == null
|
||||
? {}
|
||||
: containers.value.options.env_from
|
||||
)
|
||||
for_each = containers.value.env_from_key
|
||||
content {
|
||||
name = env.key
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = env.value.name
|
||||
key = env.value.key
|
||||
name = env.value.name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
dynamic "liveness_probe" {
|
||||
for_each = containers.value.liveness_probe == null ? [] : [""]
|
||||
content {
|
||||
failure_threshold = containers.value.liveness_probe.failure_threshold
|
||||
initial_delay_seconds = containers.value.liveness_probe.initial_delay_seconds
|
||||
period_seconds = containers.value.liveness_probe.period_seconds
|
||||
timeout_seconds = containers.value.liveness_probe.timeout_seconds
|
||||
dynamic "grpc" {
|
||||
for_each = (
|
||||
containers.value.liveness_probe.action.grpc == null ? [] : [""]
|
||||
)
|
||||
content {
|
||||
port = containers.value.liveness_probe.action.grpc.port
|
||||
service = containers.value.liveness_probe.action.grpc.service
|
||||
}
|
||||
}
|
||||
dynamic "http_get" {
|
||||
for_each = (
|
||||
containers.value.liveness_probe.action.http_get == null ? [] : [""]
|
||||
)
|
||||
content {
|
||||
path = containers.value.liveness_probe.action.http_get.path
|
||||
dynamic "http_headers" {
|
||||
for_each = (
|
||||
containers.value.liveness_probe.action.http_get.http_headers
|
||||
)
|
||||
content {
|
||||
name = http_headers.key
|
||||
value = http_headers.value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
dynamic "ports" {
|
||||
for_each = (
|
||||
containers.value.ports == null
|
||||
? {}
|
||||
: {
|
||||
for port in containers.value.ports :
|
||||
"${port.name}-${port.container_port}" => port
|
||||
}
|
||||
)
|
||||
for_each = containers.value.ports
|
||||
content {
|
||||
container_port = ports.value.container_port
|
||||
name = ports.value.name
|
||||
protocol = ports.value.protocol
|
||||
container_port = ports.value.container_port
|
||||
}
|
||||
}
|
||||
dynamic "resources" {
|
||||
@@ -142,12 +180,51 @@ resource "google_cloud_run_service" "service" {
|
||||
requests = containers.value.resources.requests
|
||||
}
|
||||
}
|
||||
dynamic "startup_probe" {
|
||||
for_each = containers.value.startup_probe == null ? [] : [""]
|
||||
content {
|
||||
failure_threshold = containers.value.startup_probe.failure_threshold
|
||||
initial_delay_seconds = containers.value.startup_probe.initial_delay_seconds
|
||||
period_seconds = containers.value.startup_probe.period_seconds
|
||||
timeout_seconds = containers.value.startup_probe.timeout_seconds
|
||||
dynamic "grpc" {
|
||||
for_each = (
|
||||
containers.value.startup_probe.action.grpc == null ? [] : [""]
|
||||
)
|
||||
content {
|
||||
port = containers.value.startup_probe.action.grpc.port
|
||||
service = containers.value.startup_probe.action.grpc.service
|
||||
}
|
||||
}
|
||||
dynamic "http_get" {
|
||||
for_each = (
|
||||
containers.value.startup_probe.action.http_get == null ? [] : [""]
|
||||
)
|
||||
content {
|
||||
path = containers.value.startup_probe.action.http_get.path
|
||||
dynamic "http_headers" {
|
||||
for_each = (
|
||||
containers.value.startup_probe.action.http_get.http_headers
|
||||
)
|
||||
content {
|
||||
name = http_headers.key
|
||||
value = http_headers.value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
dynamic "tcp_socket" {
|
||||
for_each = (
|
||||
containers.value.startup_probe.action.tcp_socket == null ? [] : [""]
|
||||
)
|
||||
content {
|
||||
port = containers.value.startup_probe.action.tcp_socket.port
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
dynamic "volume_mounts" {
|
||||
for_each = (
|
||||
containers.value.volume_mounts == null
|
||||
? {}
|
||||
: containers.value.volume_mounts
|
||||
)
|
||||
for_each = containers.value.volume_mounts
|
||||
content {
|
||||
name = volume_mounts.key
|
||||
mount_path = volume_mounts.value
|
||||
@@ -155,20 +232,19 @@ resource "google_cloud_run_service" "service" {
|
||||
}
|
||||
}
|
||||
}
|
||||
service_account_name = local.service_account_email
|
||||
dynamic "volumes" {
|
||||
for_each = var.volumes == null ? [] : var.volumes
|
||||
for_each = var.volumes
|
||||
content {
|
||||
name = volumes.value.name
|
||||
name = volumes.key
|
||||
secret {
|
||||
secret_name = volumes.value.secret_name
|
||||
secret_name = volumes.value.secret_name
|
||||
default_mode = volumes.value.default_mode
|
||||
dynamic "items" {
|
||||
for_each = (
|
||||
volumes.value.items == null ? [] : volumes.value.items
|
||||
)
|
||||
for_each = volumes.value.items
|
||||
content {
|
||||
key = items.value.key
|
||||
key = items.key
|
||||
path = items.value.path
|
||||
mode = items.value.mode
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -186,10 +262,16 @@ resource "google_cloud_run_service" "service" {
|
||||
}
|
||||
|
||||
dynamic "traffic" {
|
||||
for_each = var.traffic == null ? {} : var.traffic
|
||||
for_each = var.traffic
|
||||
content {
|
||||
percent = traffic.value
|
||||
revision_name = "${var.name}-${traffic.key}"
|
||||
percent = traffic.value.percent
|
||||
latest_revision = traffic.value.latest == true
|
||||
revision_name = (
|
||||
traffic.value.latest == true
|
||||
? null
|
||||
: "${var.name}-${traffic.key}"
|
||||
)
|
||||
tag = traffic.value.tag
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,11 +299,8 @@ resource "google_service_account" "service_account" {
|
||||
}
|
||||
|
||||
resource "google_eventarc_trigger" "audit_log_triggers" {
|
||||
for_each = var.audit_log_triggers == null ? {} : {
|
||||
for trigger in var.audit_log_triggers :
|
||||
"${trigger.service_name}-${trigger.method_name}" => trigger
|
||||
}
|
||||
name = "${local.prefix}${each.key}-audit-log-trigger"
|
||||
for_each = var.eventarc_triggers.audit_log
|
||||
name = "${local.prefix}audit-log-${each.key}"
|
||||
location = google_cloud_run_service.service.location
|
||||
project = google_cloud_run_service.service.project
|
||||
matching_criteria {
|
||||
@@ -230,11 +309,11 @@ resource "google_eventarc_trigger" "audit_log_triggers" {
|
||||
}
|
||||
matching_criteria {
|
||||
attribute = "serviceName"
|
||||
value = each.value.service_name
|
||||
value = each.value.service
|
||||
}
|
||||
matching_criteria {
|
||||
attribute = "methodName"
|
||||
value = each.value.method_name
|
||||
value = each.value.method
|
||||
}
|
||||
destination {
|
||||
cloud_run_service {
|
||||
@@ -245,24 +324,17 @@ resource "google_eventarc_trigger" "audit_log_triggers" {
|
||||
}
|
||||
|
||||
resource "google_eventarc_trigger" "pubsub_triggers" {
|
||||
for_each = var.pubsub_triggers == null ? [] : toset(var.pubsub_triggers)
|
||||
name = (
|
||||
each.value == ""
|
||||
? "${local.prefix}default-pubsub-trigger"
|
||||
: "${local.prefix}${each.value}-pubsub-trigger"
|
||||
)
|
||||
for_each = var.eventarc_triggers.pubsub
|
||||
name = "${local.prefix}pubsub-${each.key}"
|
||||
location = google_cloud_run_service.service.location
|
||||
project = google_cloud_run_service.service.project
|
||||
matching_criteria {
|
||||
attribute = "type"
|
||||
value = "google.cloud.pubsub.topic.v1.messagePublished"
|
||||
}
|
||||
dynamic "transport" {
|
||||
for_each = each.value == null ? [] : [""]
|
||||
content {
|
||||
pubsub {
|
||||
topic = each.value
|
||||
}
|
||||
transport {
|
||||
pubsub {
|
||||
topic = each.value
|
||||
}
|
||||
}
|
||||
destination {
|
||||
|
||||
@@ -15,45 +15,89 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
variable "audit_log_triggers" {
|
||||
description = "Event arc triggers (Audit log)."
|
||||
type = list(object({
|
||||
service_name = string
|
||||
method_name = string
|
||||
}))
|
||||
default = null
|
||||
variable "container_concurrency" {
|
||||
description = "Maximum allowed in-flight (concurrent) requests per container of the revision."
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "containers" {
|
||||
description = "Containers."
|
||||
type = list(object({
|
||||
image = string
|
||||
options = object({
|
||||
command = list(string)
|
||||
args = list(string)
|
||||
env = map(string)
|
||||
env_from = map(object({
|
||||
key = string
|
||||
name = string
|
||||
}))
|
||||
})
|
||||
resources = object({
|
||||
limits = object({
|
||||
cpu = string
|
||||
memory = string
|
||||
description = "Containers in arbitrary key => attributes format."
|
||||
type = map(object({
|
||||
image = string
|
||||
args = optional(list(string))
|
||||
command = optional(list(string))
|
||||
env = optional(map(string), {})
|
||||
env_from_key = optional(map(object({
|
||||
key = string
|
||||
name = string
|
||||
})), {})
|
||||
liveness_probe = optional(object({
|
||||
action = object({
|
||||
grcp = optional(object({
|
||||
port = optional(number)
|
||||
service = optional(string)
|
||||
}))
|
||||
http_get = optional(object({
|
||||
http_headers = optional(map(string), {})
|
||||
path = optional(string)
|
||||
}))
|
||||
})
|
||||
requests = object({
|
||||
cpu = string
|
||||
memory = string
|
||||
})
|
||||
})
|
||||
ports = list(object({
|
||||
name = string
|
||||
protocol = string
|
||||
container_port = string
|
||||
failure_threshold = optional(number)
|
||||
initial_delay_seconds = optional(number)
|
||||
period_seconds = optional(number)
|
||||
timeout_seconds = optional(number)
|
||||
}))
|
||||
volume_mounts = map(string)
|
||||
ports = optional(map(object({
|
||||
container_port = optional(number)
|
||||
name = optional(string)
|
||||
protocol = optional(string)
|
||||
})), {})
|
||||
resources = optional(object({
|
||||
limits = optional(object({
|
||||
cpu = string
|
||||
memory = string
|
||||
}))
|
||||
requests = optional(object({
|
||||
cpu = string
|
||||
memory = string
|
||||
}))
|
||||
}))
|
||||
startup_probe = optional(object({
|
||||
action = object({
|
||||
grcp = optional(object({
|
||||
port = optional(number)
|
||||
service = optional(string)
|
||||
}))
|
||||
http_get = optional(object({
|
||||
http_headers = optional(map(string), {})
|
||||
path = optional(string)
|
||||
}))
|
||||
tcp_socket = optional(object({
|
||||
port = optional(number)
|
||||
}))
|
||||
})
|
||||
failure_threshold = optional(number)
|
||||
initial_delay_seconds = optional(number)
|
||||
period_seconds = optional(number)
|
||||
timeout_seconds = optional(number)
|
||||
}))
|
||||
volume_mounts = optional(map(string), {})
|
||||
}))
|
||||
default = {}
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "eventarc_triggers" {
|
||||
description = "Event arc triggers for different sources."
|
||||
type = object({
|
||||
audit_log = optional(map(object({
|
||||
method = string
|
||||
service = string
|
||||
})), {})
|
||||
pubsub = optional(map(string), {})
|
||||
})
|
||||
default = {}
|
||||
}
|
||||
|
||||
variable "iam" {
|
||||
@@ -94,12 +138,6 @@ variable "project_id" {
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "pubsub_triggers" {
|
||||
description = "Eventarc triggers (Pub/Sub)."
|
||||
type = list(string)
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "region" {
|
||||
description = "Region used for all resources."
|
||||
type = string
|
||||
@@ -109,15 +147,16 @@ variable "region" {
|
||||
variable "revision_annotations" {
|
||||
description = "Configure revision template annotations."
|
||||
type = object({
|
||||
autoscaling = object({
|
||||
autoscaling = optional(object({
|
||||
max_scale = number
|
||||
min_scale = number
|
||||
})
|
||||
cloudsql_instances = list(string)
|
||||
vpcaccess_connector = string
|
||||
vpcaccess_egress = string
|
||||
}))
|
||||
cloudsql_instances = optional(list(string), [])
|
||||
vpcaccess_connector = optional(string)
|
||||
vpcaccess_egress = optional(string)
|
||||
})
|
||||
default = null
|
||||
default = {}
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "revision_name" {
|
||||
@@ -138,31 +177,52 @@ variable "service_account_create" {
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "traffic" {
|
||||
description = "Traffic."
|
||||
type = map(number)
|
||||
variable "timeout_seconds" {
|
||||
description = "Maximum duration the instance is allowed for responding to a request."
|
||||
type = number
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "volumes" {
|
||||
description = "Volumes."
|
||||
type = list(object({
|
||||
name = string
|
||||
secret_name = string
|
||||
items = list(object({
|
||||
key = string
|
||||
path = string
|
||||
}))
|
||||
variable "traffic" {
|
||||
description = "Traffic steering configuration. If revision name is null the latest revision will be used."
|
||||
type = map(object({
|
||||
percent = number
|
||||
latest = optional(bool)
|
||||
tag = optional(string)
|
||||
}))
|
||||
default = null
|
||||
default = {}
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "volumes" {
|
||||
description = "Named volumes in containers in name => attributes format."
|
||||
type = map(object({
|
||||
secret_name = string
|
||||
default_mode = optional(string)
|
||||
items = optional(map(object({
|
||||
path = string
|
||||
mode = optional(string)
|
||||
})))
|
||||
}))
|
||||
default = {}
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "vpc_connector_create" {
|
||||
description = "Populate this to create a VPC connector. You can then refer to it in the template annotations."
|
||||
type = object({
|
||||
ip_cidr_range = string
|
||||
name = string
|
||||
vpc_self_link = string
|
||||
machine_type = optional(string)
|
||||
name = optional(string)
|
||||
instances = optional(object({
|
||||
max = optional(number)
|
||||
min = optional(number)
|
||||
}), {})
|
||||
throughput = optional(object({
|
||||
max = optional(number)
|
||||
min = optional(number)
|
||||
}), {})
|
||||
})
|
||||
default = null
|
||||
}
|
||||
|
||||
42
tests/modules/cloud_run/examples/audit-logs.yaml
Normal file
42
tests/modules/cloud_run/examples/audit-logs.yaml
Normal file
@@ -0,0 +1,42 @@
|
||||
# Copyright 2023 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.
|
||||
|
||||
values:
|
||||
module.cloud_run.google_cloud_run_service.service: {}
|
||||
module.cloud_run.google_eventarc_trigger.audit_log_triggers["setiampolicy"]:
|
||||
destination:
|
||||
- cloud_function: null
|
||||
cloud_run_service:
|
||||
- path: null
|
||||
region: europe-west1
|
||||
service: hello
|
||||
gke: []
|
||||
workflow: null
|
||||
location: europe-west1
|
||||
matching_criteria:
|
||||
- attribute: methodName
|
||||
operator: ''
|
||||
value: SetIamPolicy
|
||||
- attribute: serviceName
|
||||
operator: ''
|
||||
value: cloudresourcemanager.googleapis.com
|
||||
- attribute: type
|
||||
operator: ''
|
||||
value: google.cloud.audit.log.v1.written
|
||||
name: audit-log-setiampolicy
|
||||
project: my-project
|
||||
|
||||
counts:
|
||||
google_cloud_run_service: 1
|
||||
google_eventarc_trigger: 1
|
||||
48
tests/modules/cloud_run/examples/connector.yaml
Normal file
48
tests/modules/cloud_run/examples/connector.yaml
Normal file
@@ -0,0 +1,48 @@
|
||||
# Copyright 2023 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.
|
||||
|
||||
values:
|
||||
module.cloud_run.google_cloud_run_service.service:
|
||||
autogenerate_revision_name: false
|
||||
location: europe-west1
|
||||
name: hello
|
||||
project: project-id
|
||||
template:
|
||||
- metadata:
|
||||
- labels: null
|
||||
spec:
|
||||
- containers:
|
||||
- args: null
|
||||
command: null
|
||||
env: []
|
||||
env_from: []
|
||||
image: us-docker.pkg.dev/cloudrun/container/hello
|
||||
liveness_probe: []
|
||||
volume_mounts: []
|
||||
working_dir: null
|
||||
volumes: []
|
||||
module.cloud_run.google_vpc_access_connector.connector[0]:
|
||||
ip_cidr_range: 10.10.10.0/24
|
||||
machine_type: e2-micro
|
||||
max_throughput: 300
|
||||
min_throughput: 200
|
||||
name: hello
|
||||
network: projects/example/host/global/networks/host
|
||||
project: project-id
|
||||
region: europe-west1
|
||||
subnet: []
|
||||
|
||||
counts:
|
||||
google_cloud_run_service: 1
|
||||
google_vpc_access_connector: 1
|
||||
58
tests/modules/cloud_run/examples/eventarc.yaml
Normal file
58
tests/modules/cloud_run/examples/eventarc.yaml
Normal file
@@ -0,0 +1,58 @@
|
||||
# Copyright 2023 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.
|
||||
|
||||
values:
|
||||
module.cloud_run.google_cloud_run_service.service: {}
|
||||
module.cloud_run.google_eventarc_trigger.pubsub_triggers["topic-1"]:
|
||||
destination:
|
||||
- cloud_function: null
|
||||
cloud_run_service:
|
||||
- path: null
|
||||
region: europe-west1
|
||||
service: hello
|
||||
gke: []
|
||||
workflow: null
|
||||
location: europe-west1
|
||||
matching_criteria:
|
||||
- attribute: type
|
||||
operator: ''
|
||||
value: google.cloud.pubsub.topic.v1.messagePublished
|
||||
name: pubsub-topic-1
|
||||
project: my-project
|
||||
transport:
|
||||
- pubsub:
|
||||
- topic: topic1
|
||||
module.cloud_run.google_eventarc_trigger.pubsub_triggers["topic-2"]:
|
||||
destination:
|
||||
- cloud_function: null
|
||||
cloud_run_service:
|
||||
- path: null
|
||||
region: europe-west1
|
||||
service: hello
|
||||
gke: []
|
||||
workflow: null
|
||||
location: europe-west1
|
||||
matching_criteria:
|
||||
- attribute: type
|
||||
operator: ''
|
||||
value: google.cloud.pubsub.topic.v1.messagePublished
|
||||
name: pubsub-topic-2
|
||||
project: my-project
|
||||
transport:
|
||||
- pubsub:
|
||||
- topic: topic2
|
||||
|
||||
counts:
|
||||
google_cloud_run_service: 1
|
||||
google_eventarc_trigger: 2
|
||||
42
tests/modules/cloud_run/examples/revision-annotations.yaml
Normal file
42
tests/modules/cloud_run/examples/revision-annotations.yaml
Normal file
@@ -0,0 +1,42 @@
|
||||
# Copyright 2023 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.
|
||||
|
||||
values:
|
||||
module.cloud_run.google_cloud_run_service.service:
|
||||
template:
|
||||
- metadata:
|
||||
- annotations:
|
||||
autoscaling.knative.dev/maxScale: '10'
|
||||
autoscaling.knative.dev/minScale: '1'
|
||||
run.googleapis.com/vpc-access-connector: foo
|
||||
run.googleapis.com/vpc-access-egress: all-traffic
|
||||
labels: null
|
||||
spec:
|
||||
- containers:
|
||||
- args: null
|
||||
command: null
|
||||
env: []
|
||||
env_from: []
|
||||
image: us-docker.pkg.dev/cloudrun/container/hello
|
||||
liveness_probe: []
|
||||
volume_mounts: []
|
||||
working_dir: null
|
||||
volumes: []
|
||||
|
||||
counts:
|
||||
google_cloud_run_service: 1
|
||||
modules: 1
|
||||
resources: 1
|
||||
|
||||
outputs: {}
|
||||
43
tests/modules/cloud_run/examples/secrets.yaml
Normal file
43
tests/modules/cloud_run/examples/secrets.yaml
Normal file
@@ -0,0 +1,43 @@
|
||||
# Copyright 2023 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.
|
||||
|
||||
values:
|
||||
module.cloud_run.google_cloud_run_service.service:
|
||||
template:
|
||||
- metadata:
|
||||
- labels: null
|
||||
spec:
|
||||
- containers:
|
||||
- args: null
|
||||
command: null
|
||||
env: []
|
||||
env_from: []
|
||||
image: us-docker.pkg.dev/cloudrun/container/hello
|
||||
liveness_probe: []
|
||||
volume_mounts:
|
||||
- mount_path: /credentials
|
||||
name: credentials
|
||||
working_dir: null
|
||||
volumes:
|
||||
- name: credentials
|
||||
secret:
|
||||
- default_mode: null
|
||||
items:
|
||||
- key: v1
|
||||
mode: null
|
||||
path: v1.txt
|
||||
secret_name: credentials
|
||||
|
||||
counts:
|
||||
google_cloud_run_service: 1
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2022 Google LLC
|
||||
# Copyright 2023 Google LLC
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@@ -11,3 +11,24 @@
|
||||
# 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.
|
||||
|
||||
values:
|
||||
module.cloud_run.google_cloud_run_service.service:
|
||||
template:
|
||||
- metadata:
|
||||
- labels: null
|
||||
spec:
|
||||
- containers:
|
||||
- args: null
|
||||
command: null
|
||||
env: []
|
||||
env_from: []
|
||||
image: us-docker.pkg.dev/cloudrun/container/hello
|
||||
liveness_probe: []
|
||||
volume_mounts: []
|
||||
working_dir: null
|
||||
service_account_name: cloud-run@my-project.iam.gserviceaccount.com
|
||||
volumes: []
|
||||
|
||||
counts:
|
||||
google_cloud_run_service: 1
|
||||
43
tests/modules/cloud_run/examples/service-account.yaml
Normal file
43
tests/modules/cloud_run/examples/service-account.yaml
Normal file
@@ -0,0 +1,43 @@
|
||||
# Copyright 2023 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.
|
||||
|
||||
values:
|
||||
module.cloud_run.google_cloud_run_service.service:
|
||||
autogenerate_revision_name: false
|
||||
location: europe-west1
|
||||
metadata:
|
||||
- {}
|
||||
name: hello
|
||||
project: my-project
|
||||
template:
|
||||
- metadata:
|
||||
- labels: null
|
||||
spec:
|
||||
- containers:
|
||||
- args: null
|
||||
command: null
|
||||
env: []
|
||||
env_from: []
|
||||
image: us-docker.pkg.dev/cloudrun/container/hello
|
||||
liveness_probe: []
|
||||
volume_mounts: []
|
||||
working_dir: null
|
||||
volumes: []
|
||||
module.cloud_run.google_service_account.service_account[0]:
|
||||
account_id: tf-cr-hello
|
||||
project: my-project
|
||||
|
||||
counts:
|
||||
google_cloud_run_service: 1
|
||||
google_service_account: 1
|
||||
52
tests/modules/cloud_run/examples/simple.yaml
Normal file
52
tests/modules/cloud_run/examples/simple.yaml
Normal file
@@ -0,0 +1,52 @@
|
||||
# Copyright 2023 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.
|
||||
|
||||
values:
|
||||
module.cloud_run.google_cloud_run_service.service:
|
||||
autogenerate_revision_name: false
|
||||
location: europe-west1
|
||||
name: hello
|
||||
project: my-project
|
||||
template:
|
||||
- metadata:
|
||||
- labels: null
|
||||
spec:
|
||||
- containers:
|
||||
- args: null
|
||||
command: null
|
||||
env:
|
||||
- name: VAR1
|
||||
value: VALUE1
|
||||
value_from: []
|
||||
- name: VAR2
|
||||
value: VALUE2
|
||||
value_from: []
|
||||
env_from: []
|
||||
image: us-docker.pkg.dev/cloudrun/container/hello
|
||||
liveness_probe: []
|
||||
volume_mounts: []
|
||||
working_dir: null
|
||||
volumes: []
|
||||
module.cloud_run.google_cloud_run_service_iam_binding.binding["roles/run.invoker"]:
|
||||
condition: []
|
||||
location: europe-west1
|
||||
members:
|
||||
- allUsers
|
||||
project: my-project
|
||||
role: roles/run.invoker
|
||||
service: hello
|
||||
|
||||
counts:
|
||||
google_cloud_run_service: 1
|
||||
google_cloud_run_service_iam_binding: 1
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2022 Google LLC
|
||||
# Copyright 2023 Google LLC
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@@ -11,3 +11,18 @@
|
||||
# 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.
|
||||
|
||||
values:
|
||||
module.cloud_run.google_cloud_run_service.service:
|
||||
traffic:
|
||||
- latest_revision: false
|
||||
percent: 25
|
||||
revision_name: hello-blue
|
||||
tag: null
|
||||
- latest_revision: false
|
||||
percent: 75
|
||||
revision_name: hello-green
|
||||
tag: null
|
||||
|
||||
counts:
|
||||
google_cloud_run_service: 1
|
||||
@@ -1,54 +0,0 @@
|
||||
# Copyright 2022 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.
|
||||
|
||||
variable "revision_annotations" {
|
||||
description = "Configure revision template annotations."
|
||||
type = any
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "vpc_connector_create" {
|
||||
description = "Populate this to create a VPC connector. You can then refer to it in the template annotations."
|
||||
type = any
|
||||
default = null
|
||||
}
|
||||
|
||||
module "cloud_run" {
|
||||
source = "../../../../modules/cloud-run"
|
||||
project_id = "my-project"
|
||||
name = "hello"
|
||||
audit_log_triggers = [
|
||||
{
|
||||
"service_name" : "cloudresourcemanager.googleapis.com",
|
||||
"method_name" : "SetIamPolicy"
|
||||
}
|
||||
]
|
||||
containers = [{
|
||||
image = "us-docker.pkg.dev/cloudrun/container/hello"
|
||||
options = null
|
||||
ports = null
|
||||
resources = null
|
||||
volume_mounts = null
|
||||
}]
|
||||
iam = {
|
||||
"roles/run.invoker" = ["allUsers"]
|
||||
}
|
||||
pubsub_triggers = [
|
||||
"topic1",
|
||||
"topic2"
|
||||
]
|
||||
revision_name = "blue"
|
||||
revision_annotations = var.revision_annotations
|
||||
vpc_connector_create = var.vpc_connector_create
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
# Copyright 2022 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.
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def resources(plan_runner):
|
||||
_, resources = plan_runner()
|
||||
return resources
|
||||
|
||||
|
||||
def test_resource_count(resources):
|
||||
"Test number of resources created."
|
||||
assert len(resources) == 5
|
||||
|
||||
|
||||
def test_iam(resources):
|
||||
"Test IAM binding resources."
|
||||
bindings = [
|
||||
r['values']
|
||||
for r in resources
|
||||
if r['type'] == 'google_cloud_run_service_iam_binding'
|
||||
]
|
||||
assert len(bindings) == 1
|
||||
assert bindings[0]['role'] == 'roles/run.invoker'
|
||||
|
||||
|
||||
def test_audit_log_triggers(resources):
|
||||
"Test audit logs Eventarc trigger resources."
|
||||
audit_log_triggers = [
|
||||
r['values']
|
||||
for r in resources
|
||||
if r['type'] == 'google_eventarc_trigger' and
|
||||
r['name'] == 'audit_log_triggers'
|
||||
]
|
||||
assert len(audit_log_triggers) == 1
|
||||
|
||||
|
||||
def test_pubsub_triggers(resources):
|
||||
"Test Pub/Sub Eventarc trigger resources."
|
||||
pubsub_triggers = [
|
||||
r['values'] for r in resources if
|
||||
r['type'] == 'google_eventarc_trigger' and r['name'] == 'pubsub_triggers'
|
||||
]
|
||||
assert len(pubsub_triggers) == 2
|
||||
|
||||
|
||||
def test_revision_annotations(plan_runner):
|
||||
revision_annotations = '''{
|
||||
autoscaling = null
|
||||
cloudsql_instances = ["a", "b"]
|
||||
vpcaccess_connector = "foo"
|
||||
vpcaccess_egress = "all-traffic"
|
||||
}'''
|
||||
_, resources = plan_runner(revision_annotations=revision_annotations)
|
||||
r = [
|
||||
r['values'] for r in resources if r['type'] == 'google_cloud_run_service'
|
||||
][0]
|
||||
assert r['template'][0]['metadata'][0]['annotations'] == {
|
||||
'run.googleapis.com/cloudsql-instances': 'a,b',
|
||||
'run.googleapis.com/vpc-access-connector': 'foo',
|
||||
'run.googleapis.com/vpc-access-egress': 'all-traffic'
|
||||
}
|
||||
|
||||
|
||||
def test_revision_annotations_autoscaling(plan_runner):
|
||||
revision_annotations = '''{
|
||||
autoscaling = {max_scale = 5, min_scale = 1}
|
||||
cloudsql_instances = null
|
||||
vpcaccess_connector = null
|
||||
vpcaccess_egress = null
|
||||
}'''
|
||||
_, resources = plan_runner(revision_annotations=revision_annotations)
|
||||
r = [
|
||||
r['values'] for r in resources if r['type'] == 'google_cloud_run_service'
|
||||
][0]
|
||||
assert r['template'][0]['metadata'][0]['annotations'] == {
|
||||
'autoscaling.knative.dev/maxScale': '5',
|
||||
'autoscaling.knative.dev/minScale': '1'
|
||||
}
|
||||
|
||||
|
||||
def test_revision_annotations_none(resources):
|
||||
r = [
|
||||
r['values'] for r in resources if r['type'] == 'google_cloud_run_service'
|
||||
][0]
|
||||
assert r['template'][0]['metadata'][0].get('annotations') is None
|
||||
|
||||
|
||||
def test_vpc_connector_create(plan_runner):
|
||||
vpc_connector_create = '''{
|
||||
ip_cidr_range = "10.10.10.0/24", name = "foo", vpc_self_link = "foo-vpc"
|
||||
}'''
|
||||
_, resources = plan_runner(vpc_connector_create=vpc_connector_create)
|
||||
assert any(r['type'] == 'google_vpc_access_connector' for r in resources)
|
||||
Reference in New Issue
Block a user