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:
Ludovico Magnocavallo
2023-04-01 14:06:29 +02:00
committed by GitHub
parent c5db50d1d7
commit 92b71a5098
16 changed files with 830 additions and 464 deletions

View File

@@ -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"]
}

View File

@@ -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"]
}

View File

@@ -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&#40;object&#40;&#123;&#10; image &#61; string&#10; options &#61; object&#40;&#123;&#10; command &#61; list&#40;string&#41;&#10; args &#61; list&#40;string&#41;&#10; env &#61; map&#40;string&#41;&#10; env_from &#61; map&#40;object&#40;&#123;&#10; key &#61; string&#10; name &#61; string&#10; &#125;&#41;&#41;&#10; &#125;&#41;&#10; resources &#61; object&#40;&#123;&#10; limits &#61; object&#40;&#123;&#10; cpu &#61; string&#10; memory &#61; string&#10; &#125;&#41;&#10; requests &#61; object&#40;&#123;&#10; cpu &#61; string&#10; memory &#61; string&#10; &#125;&#41;&#10; &#125;&#41;&#10; ports &#61; list&#40;object&#40;&#123;&#10; name &#61; string&#10; protocol &#61; string&#10; container_port &#61; string&#10; &#125;&#41;&#41;&#10; volume_mounts &#61; map&#40;string&#41;&#10;&#125;&#41;&#41;">list&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</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&#40;object&#40;&#123;&#10; service_name &#61; string&#10; method_name &#61; string&#10;&#125;&#41;&#41;">list&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>null</code> |
| [iam](variables.tf#L59) | IAM bindings for Cloud Run service in {ROLE => [MEMBERS]} format. | <code>map&#40;list&#40;string&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [ingress_settings](variables.tf#L65) | Ingress settings. | <code>string</code> | | <code>null</code> |
| [labels](variables.tf#L71) | Resource labels. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</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&#40;string&#41;</code> | | <code>null</code> |
| [region](variables.tf#L103) | Region used for all resources. | <code>string</code> | | <code>&#34;europe-west1&#34;</code> |
| [revision_annotations](variables.tf#L109) | Configure revision template annotations. | <code title="object&#40;&#123;&#10; autoscaling &#61; object&#40;&#123;&#10; max_scale &#61; number&#10; min_scale &#61; number&#10; &#125;&#41;&#10; cloudsql_instances &#61; list&#40;string&#41;&#10; vpcaccess_connector &#61; string&#10; vpcaccess_egress &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</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&#40;number&#41;</code> | | <code>null</code> |
| [volumes](variables.tf#L147) | Volumes. | <code title="list&#40;object&#40;&#123;&#10; name &#61; string&#10; secret_name &#61; string&#10; items &#61; list&#40;object&#40;&#123;&#10; key &#61; string&#10; path &#61; string&#10; &#125;&#41;&#41;&#10;&#125;&#41;&#41;">list&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</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&#40;&#123;&#10; ip_cidr_range &#61; string&#10; name &#61; string&#10; vpc_self_link &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</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&#40;object&#40;&#123;&#10; image &#61; string&#10; args &#61; optional&#40;list&#40;string&#41;&#41;&#10; command &#61; optional&#40;list&#40;string&#41;&#41;&#10; env &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; env_from_key &#61; optional&#40;map&#40;object&#40;&#123;&#10; key &#61; string&#10; name &#61; string&#10; &#125;&#41;&#41;, &#123;&#125;&#41;&#10; liveness_probe &#61; optional&#40;object&#40;&#123;&#10; action &#61; object&#40;&#123;&#10; grcp &#61; optional&#40;object&#40;&#123;&#10; port &#61; optional&#40;number&#41;&#10; service &#61; optional&#40;string&#41;&#10; &#125;&#41;&#41;&#10; http_get &#61; optional&#40;object&#40;&#123;&#10; http_headers &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; path &#61; optional&#40;string&#41;&#10; &#125;&#41;&#41;&#10; &#125;&#41;&#10; failure_threshold &#61; optional&#40;number&#41;&#10; initial_delay_seconds &#61; optional&#40;number&#41;&#10; period_seconds &#61; optional&#40;number&#41;&#10; timeout_seconds &#61; optional&#40;number&#41;&#10; &#125;&#41;&#41;&#10; ports &#61; optional&#40;map&#40;object&#40;&#123;&#10; container_port &#61; optional&#40;number&#41;&#10; name &#61; optional&#40;string&#41;&#10; protocol &#61; optional&#40;string&#41;&#10; &#125;&#41;&#41;, &#123;&#125;&#41;&#10; resources &#61; optional&#40;object&#40;&#123;&#10; limits &#61; optional&#40;object&#40;&#123;&#10; cpu &#61; string&#10; memory &#61; string&#10; &#125;&#41;&#41;&#10; requests &#61; optional&#40;object&#40;&#123;&#10; cpu &#61; string&#10; memory &#61; string&#10; &#125;&#41;&#41;&#10; &#125;&#41;&#41;&#10; startup_probe &#61; optional&#40;object&#40;&#123;&#10; action &#61; object&#40;&#123;&#10; grcp &#61; optional&#40;object&#40;&#123;&#10; port &#61; optional&#40;number&#41;&#10; service &#61; optional&#40;string&#41;&#10; &#125;&#41;&#41;&#10; http_get &#61; optional&#40;object&#40;&#123;&#10; http_headers &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; path &#61; optional&#40;string&#41;&#10; &#125;&#41;&#41;&#10; tcp_socket &#61; optional&#40;object&#40;&#123;&#10; port &#61; optional&#40;number&#41;&#10; &#125;&#41;&#41;&#10; &#125;&#41;&#10; failure_threshold &#61; optional&#40;number&#41;&#10; initial_delay_seconds &#61; optional&#40;number&#41;&#10; period_seconds &#61; optional&#40;number&#41;&#10; timeout_seconds &#61; optional&#40;number&#41;&#10; &#125;&#41;&#41;&#10; volume_mounts &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [eventarc_triggers](variables.tf#L91) | Event arc triggers for different sources. | <code title="object&#40;&#123;&#10; audit_log &#61; optional&#40;map&#40;object&#40;&#123;&#10; method &#61; string&#10; service &#61; string&#10; &#125;&#41;&#41;, &#123;&#125;&#41;&#10; pubsub &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [iam](variables.tf#L103) | IAM bindings for Cloud Run service in {ROLE => [MEMBERS]} format. | <code>map&#40;list&#40;string&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [ingress_settings](variables.tf#L109) | Ingress settings. | <code>string</code> | | <code>null</code> |
| [labels](variables.tf#L115) | Resource labels. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</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>&#34;europe-west1&#34;</code> |
| [revision_annotations](variables.tf#L147) | Configure revision template annotations. | <code title="object&#40;&#123;&#10; autoscaling &#61; optional&#40;object&#40;&#123;&#10; max_scale &#61; number&#10; min_scale &#61; number&#10; &#125;&#41;&#41;&#10; cloudsql_instances &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; vpcaccess_connector &#61; optional&#40;string&#41;&#10; vpcaccess_egress &#61; optional&#40;string&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</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&#40;object&#40;&#123;&#10; percent &#61; number&#10; latest &#61; optional&#40;bool&#41;&#10; tag &#61; optional&#40;string&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [volumes](variables.tf#L197) | Named volumes in containers in name => attributes format. | <code title="map&#40;object&#40;&#123;&#10; secret_name &#61; string&#10; default_mode &#61; optional&#40;string&#41;&#10; items &#61; optional&#40;map&#40;object&#40;&#123;&#10; path &#61; string&#10; mode &#61; optional&#40;string&#41;&#10; &#125;&#41;&#41;&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</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&#40;&#123;&#10; ip_cidr_range &#61; string&#10; vpc_self_link &#61; string&#10; machine_type &#61; optional&#40;string&#41;&#10; name &#61; optional&#40;string&#41;&#10; instances &#61; optional&#40;object&#40;&#123;&#10; max &#61; optional&#40;number&#41;&#10; min &#61; optional&#40;number&#41;&#10; &#125;&#41;, &#123;&#125;&#41;&#10; throughput &#61; optional&#40;object&#40;&#123;&#10; max &#61; optional&#40;number&#41;&#10; min &#61; optional&#40;number&#41;&#10; &#125;&#41;, &#123;&#125;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> |
## Outputs

View File

@@ -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 {

View File

@@ -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
}

View 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

View 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

View 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

View 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: {}

View 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

View File

@@ -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

View 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

View 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

View File

@@ -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

View File

@@ -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
}

View File

@@ -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)