diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml index 33693873..21c0746a 100644 --- a/.github/workflows/linting.yml +++ b/.github/workflows/linting.yml @@ -37,7 +37,7 @@ jobs: - name: Set up Terraform uses: hashicorp/setup-terraform@v1 with: - terraform_version: 1.3 + terraform_version: 1.3.2 - name: Install dependencies run: | diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 9dc0121a..2a903525 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -48,10 +48,18 @@ jobs: with: python-version: ${{ env.PYTHON_VERSION }} + - name: Set up Terraform + uses: hashicorp/setup-terraform@v2 + with: + terraform_version: ${{ env.TF_VERSION }} + terraform_wrapper: false + + # avoid conflicts with user-installed providers on local machines - name: Pin provider versions run: | - sed -i 's/>=\(.*# tftest\)/=\1/g' default-versions.tf - find -name versions.tf -exec cp default-versions.tf {} \; + for f in $(find . -name versions.tf); do + sed -i 's/>=\(.*# tftest\)/=\1/g' $f; + done - name: Run tests on documentation examples id: pytest @@ -76,15 +84,17 @@ jobs: python-version: ${{ env.PYTHON_VERSION }} - name: Set up Terraform - uses: hashicorp/setup-terraform@v1 + uses: hashicorp/setup-terraform@v2 with: terraform_version: ${{ env.TF_VERSION }} terraform_wrapper: false + # avoid conflicts with user-installed providers on local machines - name: Pin provider versions run: | - sed -i 's/>=\(.*# tftest\)/=\1/g' default-versions.tf - find -name versions.tf -exec cp default-versions.tf {} \; + for f in $(find . -name versions.tf); do + sed -i 's/>=\(.*# tftest\)/=\1/g' $f; + done - name: Run tests environments id: pytest @@ -109,15 +119,17 @@ jobs: python-version: ${{ env.PYTHON_VERSION }} - name: Set up Terraform - uses: hashicorp/setup-terraform@v1 + uses: hashicorp/setup-terraform@v2 with: terraform_version: ${{ env.TF_VERSION }} terraform_wrapper: false + # avoid conflicts with user-installed providers on local machines - name: Pin provider versions run: | - sed -i 's/>=\(.*# tftest\)/=\1/g' default-versions.tf - find -name versions.tf -exec cp default-versions.tf {} \; + for f in $(find . -name versions.tf); do + sed -i 's/>=\(.*# tftest\)/=\1/g' $f; + done - name: Run tests modules id: pytest @@ -142,15 +154,17 @@ jobs: python-version: ${{ env.PYTHON_VERSION }} - name: Set up Terraform - uses: hashicorp/setup-terraform@v1 + uses: hashicorp/setup-terraform@v2 with: terraform_version: ${{ env.TF_VERSION }} terraform_wrapper: false + # avoid conflicts with user-installed providers on local machines - name: Pin provider versions run: | - sed -i 's/>=\(.*# tftest\)/=\1/g' default-versions.tf - find -name versions.tf -exec cp default-versions.tf {} \; + for f in $(find . -name versions.tf); do + sed -i 's/>=\(.*# tftest\)/=\1/g' $f; + done - name: Run tests on FAST stages id: pytest diff --git a/CHANGELOG.md b/CHANGELOG.md index 6de61242..1013e67b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ All notable changes to this project will be documented in this file. ### BLUEPRINTS +- [[#818](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/818)] Example wordpress ([skalolazka](https://github.com/skalolazka)) - [[#861](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/861)] Leverage new shared VPC project config defaults across the repo ([juliocc](https://github.com/juliocc)) - [[#854](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/854)] Added an example of a Nginx reverse proxy cluster using RMIGs ([rosmo](https://github.com/rosmo)) - [[#850](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/850)] Made sample alert creation optional ([maunope](https://github.com/maunope)) @@ -21,10 +22,12 @@ All notable changes to this project will be documented in this file. ### DOCUMENTATION +- [[#863](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/863)] Fabric vs CFT doc ([ludoo](https://github.com/ludoo)) - [[#806](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/806)] Companion Guide ([ajlopezn](https://github.com/ajlopezn)) ### FAST +- [[#865](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/865)] Enable FAST 00-cicd provider test ([ludoo](https://github.com/ludoo)) - [[#861](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/861)] Leverage new shared VPC project config defaults across the repo ([juliocc](https://github.com/juliocc)) - [[#858](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/858)] Default gcp-support to gcp-devops ([juliocc](https://github.com/juliocc)) - [[#842](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/842)] Comment redundant role in bootstrap stage, align IAM.md files, improve IAM tool ([ludoo](https://github.com/ludoo)) @@ -35,6 +38,7 @@ All notable changes to this project will be documented in this file. ### MODULES +- [[#860](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/860)] **incompatible change:** Refactor compute-vm for Terraform 1.3 ([ludoo](https://github.com/ludoo)) - [[#861](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/861)] Leverage new shared VPC project config defaults across the repo ([juliocc](https://github.com/juliocc)) - [[#859](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/859)] Make project shared VPC fields optional ([juliocc](https://github.com/juliocc)) - [[#853](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/853)] Fixes NVA issue when health checks are not enabled ([sruffilli](https://github.com/sruffilli)) @@ -54,6 +58,8 @@ All notable changes to this project will be documented in this file. ### TOOLS +- [[#865](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/865)] Enable FAST 00-cicd provider test ([ludoo](https://github.com/ludoo)) +- [[#864](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/864)] **incompatible change:** Bump terraform required version ([ludoo](https://github.com/ludoo)) - [[#842](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/842)] Comment redundant role in bootstrap stage, align IAM.md files, improve IAM tool ([ludoo](https://github.com/ludoo)) - [[#811](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/811)] Fix changelog generator ([ludoo](https://github.com/ludoo)) - [[#810](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/810)] Fully recursive e2e test runner for examples ([juliocc](https://github.com/juliocc)) diff --git a/FABRIC-AND-CFT.md b/FABRIC-AND-CFT.md new file mode 100644 index 00000000..1b8de626 --- /dev/null +++ b/FABRIC-AND-CFT.md @@ -0,0 +1,170 @@ +# Cloud Foundation Fabric and Cloud Foundation Toolkit + +This page highlights the main differences (both technical and philosophical) between Cloud Foundation Fabric and Cloud Foundation Toolkit for end users, to guide them in their decision making process for identifying the best suite of modules for their use cases. + +## Cloud Foundation Fabric (a.k.a Fabric, this repo) + +Fabric is a collection of Terraform modules and end to end examples meant to be cloned as a single unit and used as is for fast prototyping or decomposed and modified for usage in organizations. + +## Cloud Foundation Toolkit (a.k.a CFT) + +CFT is a collection of Terraform modules and examples with opinionated GCP best practices implemented as individual modules for gradual adoption and off the shelf usage in organizations. + +## Third-party reviews + +* [Google Cloud Landing Zone Comparison](https://www.meshcloud.io/2022/09/09/gcp-landing-zone-comparison/) by Meshcloud. + +## Key Differences + +
+ | +Fabric + | +CFT + | +
Target User + | +Organizations interested in forking, maintaining and customizing Terraform modules. + | +Organizations interested in using opinionated, prebuilt Terraform modules. + | +
Configuration + | +Less opinionated allowing end users higher flexibility. + | +Opinionated by default, end users may need to fork if it does not meet their use case. + | +
Extensibility + | +Built with extensibility in mind catering to fork and use patterns. Modules are often lightweight and easy to adopt / tailor to specific use cases. + | +Not built with fork and use extensibility, caters to off the shelf consumption. + | +
Config customization + | +Prefer customization using variables via objects, tight variable space. + | +Prefer customization using variables via primitives. + | +
Examples + | +Thorough examples for individual modules, and end to end examples composing multiple modules covering a wide variety of use cases from foundations to solutions. + | +Examples for a module mostly focus on that individual module. \ + \ +Composition is often not shown in examples but in other modules built using smaller modules. + | +
Resources + | +Leaner modules wrapping resources. + | +Heavier root modules that often compose leaner sub modules wrapping resources. + | +
Resource grouping + | +Generally grouped by logical entities. + | +Generally grouped by products/product areas. + | +
Release Cadence + | +Modules versioned and released together. + | +Modules versioned and released individually. + | +
Individual module usage + | +Individual modules consumed directly using Git as a module source.
+ +For production usage, we encourage customers to “fork and own” their own repository. + |
+ Individual repositories consumed via the Terraform registry.
+ +For production/airgapped usage, customers may also mirror modules to a private registry. + |
+
Factories + | +Fabric implements several "factories" in modules, where users can drive or automate Terraform via YAML files (projects, subnetworks, firewalls, etc.). + | ++ | +
Organizational adoption + | +Mono repo cloned into an organizational VCS (or catalog) and separated into individual modules for internal consumption. + | +Individual repos forked (for air gap) or wrapping upstream sources to create individual modules for internal consumption. + | +
Distribution + | +Distributed via Git/GitHub. + | +Distributed via Git/GitHub and Terraform Registry. + | +
Testing + | +Every PR performs unit tests on modules, examples, and documentation snippets by evaluating a Terraform plan via Python tftest library. + | +Every PR performs full end-to-end deployment with integration tests using the blueprint test framework. + | +
](https://ssh.cloud.google.com/cloudshell/editor?cloudshell_git_repo=https%3A%2F%2Fgithub.com%2FGoogleCloudPlatform%2Fcloud-foundation-fabric&cloudshell_print=cloud-shell-readme.txt&cloudshell_working_dir=blueprints%2Fthird-party-solutions%2Fwordpress) + +Otherwise, in your console of choice: +``` {shell} +git clone https://github.com/GoogleCloudPlatform/cloud-foundation-fabric +``` + +Before you deploy the architecture, you will need at least the following information (for more precise configuration see the Variables section): + +* The project ID. +* A Google Cloud Registry path to a Wordpress container image. + +### Step 1: Add Wordpress image + +In order to deploy the Wordpress service to Cloud Run, you need to store the [Wordpress image](https://hub.docker.com/r/bitnami/wordpress/) in Google Cloud Registry (GCR). + +Make sure that the Google Container Registry API is enabled and run the following commands in your Cloud Shell environment with your `project_id` in place of the `MY_PROJECT` placeholder: + +``` {shell} +docker pull bitnami/wordpress:6.0.2 +docker tag bitnami/wordpress gcr.io/MY_PROJECT/wordpress +docker push gcr.io/MY_PROJECT/wordpress +``` + +**Note**: This example has been built for this particular Docker image. If you decide to use another one, this example might not work (or you can edit the variables in the Terraform files). + +### Step 2: Prepare the variables + +Once you have the required information, head back to your cloned repository. Make sure you’re in the directory of this tutorial (where this README is in). + +Configure the Terraform variables in your `terraform.tfvars` file. See [terraform.tfvars.sample](terraform.tfvars.sample) as starting point - just copy it to `terraform.tfvars` and edit the latter. See the variables documentation below. + +**Notes**: +1. If you will want to change your admin password later on, please note that it will only work in the admin interface of Wordpress, but not with redeploying with Terraform, since Wordpress writes that password into the database upon installation and ignores the environment variables (that you can change with Terraform) after that. +2. If you have the [domain restriction org. policy](https://cloud.google.com/resource-manager/docs/organization-policy/restricting-domains) on your organization, you have to edit the `cloud_run_invoker` variable and give it a value that will be accepted in accordance to your policy. + +### Step 3: Deploy resources + +Initialize your Terraform environment and deploy the resources: + +``` {shell} +terraform init +terraform apply +``` +The resource creation will take a few minutes. + +**Note**: you might get the following error (or a similar one): +``` {shell} +│ Error: resource is in failed state "Ready:False", message: Revision '...' is not ready and cannot serve traffic.│ +``` +You might try to reapply at this point, the Cloud Run service just needs several minutes. + +### Step 4: Use the created resources + +Upon completion, you will see the output with the values for the Cloud Run service and the user and password to access the `/admin` part of the website. You can also view it later with: +``` {shell} +terraform output +# or for the concrete variable: +terraform output cloud_run_service +``` +1. Open your browser at the URL that you get with that last command, and you will see your Wordpress installation. +2. Add "/admin" in the end of the URL and log in to the admin interface, using the outputs "wp_user" and "wp_password". + +## Cleaning up your environment + +The easiest way to remove all the deployed resources is to run the following command in Cloud Shell: + +``` {shell} +terraform destroy +``` + +The above command will delete the associated resources so there will be no billable charges made afterwards. + + +## Variables + +| name | description | type | required | default | +|---|---|:---:|:---:|:---:| +| [project_id](variables.tf#L72) | Project id, references existing project if `project_create` is null. |
string
| ✓ | |
+| [wordpress_image](variables.tf#L83) | Image to run with Cloud Run, starts with \"gcr.io\" | string
| ✓ | |
+| [cloud_run_invoker](variables.tf#L18) | IAM member authorized to access the end-point (for example, 'user:YOUR_IAM_USER' for only you or 'allUsers' for everyone) | string
| | "allUsers"
|
+| [cloudsql_password](variables.tf#L24) | CloudSQL password (will be randomly generated by default) | string
| | null
|
+| [create_connector](variables.tf#L30) | Should a VPC serverless connector be created or not | bool
| | true
|
+| [ip_ranges](variables.tf#L37) | CIDR blocks: VPC serverless connector, Private Service Access(PSA) for CloudSQL, CloudSQL VPC | object({…})
| | {…}
|
+| [prefix](variables.tf#L51) | Unique prefix used for resource names. Not used for project if 'project_create' is null. | string
| | ""
|
+| [principals](variables.tf#L57) | List of users to give rights to (CloudSQL admin, client and instanceUser, Logging admin, Service Account User and TokenCreator), eg 'user@domain.com'. | list(string)
| | []
|
+| [project_create](variables.tf#L63) | Provide values if project creation is needed, uses existing project if null. Parent is in 'folders/nnn' or 'organizations/nnn' format. | object({…})
| | null
|
+| [region](variables.tf#L77) | Region for the created resources | string
| | "europe-west4"
|
+| [wordpress_password](variables.tf#L94) | Password for the Wordpress user (will be randomly generated by default) | string
| | null
|
+| [wordpress_port](variables.tf#L88) | Port for the Wordpress image | number
| | 8080
|
+
+## Outputs
+
+| name | description | sensitive |
+|---|---|:---:|
+| [cloud_run_service](outputs.tf#L17) | CloudRun service URL | ✓ |
+| [cloudsql_password](outputs.tf#L23) | CloudSQL password | ✓ |
+| [wp_password](outputs.tf#L34) | Wordpress user password | ✓ |
+| [wp_user](outputs.tf#L29) | Wordpress username | |
+
+
diff --git a/blueprints/third-party-solutions/wordpress/cloudrun/cloudsql.tf b/blueprints/third-party-solutions/wordpress/cloudrun/cloudsql.tf
new file mode 100644
index 00000000..11e6e311
--- /dev/null
+++ b/blueprints/third-party-solutions/wordpress/cloudrun/cloudsql.tf
@@ -0,0 +1,70 @@
+/**
+ * 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.
+ */
+
+
+resource "random_password" "cloudsql_password" {
+ length = 8
+}
+
+# create a VPC for CloudSQL
+module "vpc" {
+ source = "../../../../modules/net-vpc"
+ project_id = module.project.project_id
+ name = "${local.prefix}sql-vpc"
+ subnets = [
+ {
+ ip_cidr_range = var.ip_ranges.sql_vpc
+ name = "subnet"
+ region = var.region
+ secondary_ip_range = {}
+ }
+ ]
+
+ # Private Service Access
+ psa_config = {
+ ranges = {
+ cloud-sql = var.ip_ranges.psa
+ }
+ routes = null
+ }
+}
+
+
+# create a VPC connector for the ClouSQL VPC
+resource "google_vpc_access_connector" "connector" {
+ count = var.create_connector ? 1 : 0
+ project = module.project.project_id
+ name = "${local.prefix}wp-connector"
+ region = var.region
+ ip_cidr_range = var.ip_ranges.connector
+ network = module.vpc.self_link
+}
+
+
+# Set up CloudSQL
+module "cloudsql" {
+ source = "../../../../modules/cloudsql-instance"
+ project_id = module.project.project_id
+ network = module.vpc.self_link
+ name = "${local.prefix}mysql"
+ region = var.region
+ database_version = local.cloudsql_conf.database_version
+ tier = local.cloudsql_conf.tier
+ databases = [local.cloudsql_conf.db]
+ users = {
+ "${local.cloudsql_conf.user}" = "${local.cloudsql_conf.pass}"
+ }
+}
\ No newline at end of file
diff --git a/blueprints/third-party-solutions/wordpress/cloudrun/images/architecture.png b/blueprints/third-party-solutions/wordpress/cloudrun/images/architecture.png
new file mode 100644
index 00000000..ad914ecc
Binary files /dev/null and b/blueprints/third-party-solutions/wordpress/cloudrun/images/architecture.png differ
diff --git a/blueprints/third-party-solutions/wordpress/cloudrun/images/button.png b/blueprints/third-party-solutions/wordpress/cloudrun/images/button.png
new file mode 100644
index 00000000..21a3f3de
Binary files /dev/null and b/blueprints/third-party-solutions/wordpress/cloudrun/images/button.png differ
diff --git a/blueprints/third-party-solutions/wordpress/cloudrun/main.tf b/blueprints/third-party-solutions/wordpress/cloudrun/main.tf
new file mode 100644
index 00000000..3264619c
--- /dev/null
+++ b/blueprints/third-party-solutions/wordpress/cloudrun/main.tf
@@ -0,0 +1,121 @@
+/**
+ * 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.
+ */
+
+
+locals {
+ all_principals_iam = [for k in var.principals : "user:${k}"]
+ cloudsql_conf = {
+ database_version = "MYSQL_8_0"
+ tier = "db-g1-small"
+ db = "wp-mysql"
+ user = "admin"
+ pass = var.cloudsql_password == null ? random_password.cloudsql_password.result : var.cloudsql_password
+ }
+ iam = {
+ # CloudSQL
+ "roles/cloudsql.admin" = local.all_principals_iam
+ "roles/cloudsql.client" = local.all_principals_iam
+ "roles/cloudsql.instanceUser" = local.all_principals_iam
+ # common roles
+ "roles/logging.admin" = local.all_principals_iam
+ "roles/iam.serviceAccountUser" = local.all_principals_iam
+ "roles/iam.serviceAccountTokenCreator" = local.all_principals_iam
+ }
+ connector = var.connector == null ? google_vpc_access_connector.connector.0.self_link : var.connector
+ prefix = var.prefix == null ? "" : "${var.prefix}-"
+ wp_user = "user"
+ wp_pass = var.wordpress_password == null ? random_password.wp_password.result : var.wordpress_password
+}
+
+
+# either create a project or set up the given one
+module "project" {
+ source = "../../../../modules/project"
+ name = var.project_id
+ parent = try(var.project_create.parent, null)
+ billing_account = try(var.project_create.billing_account_id, null)
+ project_create = var.project_create != null
+ prefix = var.project_create == null ? null : var.prefix
+ iam = var.project_create != null ? local.iam : {}
+ iam_additive = var.project_create == null ? local.iam : {}
+ services = [
+ "run.googleapis.com",
+ "logging.googleapis.com",
+ "monitoring.googleapis.com",
+ "sqladmin.googleapis.com",
+ "sql-component.googleapis.com",
+ "vpcaccess.googleapis.com",
+ "servicenetworking.googleapis.com"
+ ]
+}
+
+
+resource "random_password" "wp_password" {
+ length = 8
+}
+
+
+# create the Cloud Run service
+module "cloud_run" {
+ source = "../../../../modules/cloud-run"
+ project_id = module.project.project_id
+ name = "${local.prefix}cr-wordpress"
+ region = var.region
+
+ containers = [{
+ image = var.wordpress_image
+ ports = [{
+ name = "http1"
+ protocol = null
+ container_port = var.wordpress_port
+ }]
+ options = {
+ command = null
+ args = null
+ env_from = null
+ # set up the database connection
+ env = {
+ "APACHE_HTTP_PORT_NUMBER" : var.wordpress_port
+ "WORDPRESS_DATABASE_HOST" : module.cloudsql.ip
+ "WORDPRESS_DATABASE_NAME" : local.cloudsql_conf.db
+ "WORDPRESS_DATABASE_USER" : local.cloudsql_conf.user
+ "WORDPRESS_DATABASE_PASSWORD" : local.cloudsql_conf.pass
+ "WORDPRESS_USERNAME" : local.wp_user
+ "WORDPRESS_PASSWORD" : local.wp_pass
+ }
+ }
+ resources = null
+ volume_mounts = null
+ }]
+
+ iam = {
+ "roles/run.invoker" : [var.cloud_run_invoker]
+ }
+
+ revision_annotations = {
+ autoscaling = {
+ min_scale = 1
+ max_scale = 2
+ }
+ # connect to CloudSQL
+ cloudsql_instances = [module.cloudsql.connection_name]
+ vpcaccess_connector = null
+ # allow all traffic
+ vpcaccess_egress = "all-traffic"
+ vpcaccess_connector = local.connector
+ }
+ ingress_settings = "all"
+}
\ No newline at end of file
diff --git a/blueprints/third-party-solutions/wordpress/cloudrun/outputs.tf b/blueprints/third-party-solutions/wordpress/cloudrun/outputs.tf
new file mode 100644
index 00000000..3bd300c9
--- /dev/null
+++ b/blueprints/third-party-solutions/wordpress/cloudrun/outputs.tf
@@ -0,0 +1,38 @@
+/**
+ * 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.
+ */
+
+output "cloud_run_service" {
+ description = "CloudRun service URL"
+ value = module.cloud_run.service.status[0].url
+ sensitive = true
+}
+
+output "cloudsql_password" {
+ description = "CloudSQL password"
+ value = local.cloudsql_conf.pass
+ sensitive = true
+}
+
+output "wp_user" {
+ description = "Wordpress username"
+ value = local.wp_user
+}
+
+output "wp_password" {
+ description = "Wordpress user password"
+ value = local.wp_pass
+ sensitive = true
+}
diff --git a/blueprints/third-party-solutions/wordpress/cloudrun/terraform.tfvars.sample b/blueprints/third-party-solutions/wordpress/cloudrun/terraform.tfvars.sample
new file mode 100644
index 00000000..5c71954c
--- /dev/null
+++ b/blueprints/third-party-solutions/wordpress/cloudrun/terraform.tfvars.sample
@@ -0,0 +1,3 @@
+prefix = "wp"
+project_id = "my-wordpress-project"
+wordpress_image = "gcr.io/my-wordpress-project/wordpress"
diff --git a/blueprints/third-party-solutions/wordpress/cloudrun/variables.tf b/blueprints/third-party-solutions/wordpress/cloudrun/variables.tf
new file mode 100644
index 00000000..eaa2543b
--- /dev/null
+++ b/blueprints/third-party-solutions/wordpress/cloudrun/variables.tf
@@ -0,0 +1,104 @@
+/**
+ * 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.
+ */
+
+# Documentation: https://cloud.google.com/run/docs/securing/managing-access#making_a_service_public
+variable "cloud_run_invoker" {
+ type = string
+ description = "IAM member authorized to access the end-point (for example, 'user:YOUR_IAM_USER' for only you or 'allUsers' for everyone)"
+ default = "allUsers"
+}
+
+variable "cloudsql_password" {
+ type = string
+ description = "CloudSQL password (will be randomly generated by default)"
+ default = null
+}
+
+variable "connector" {
+ type = string
+ description = "Existing VPC serverless connector to use if not creating a new one"
+ default = null
+}
+
+variable "create_connector" {
+ type = bool
+ description = "Should a VPC serverless connector be created or not"
+ default = true
+}
+
+# PSA: documentation: https://cloud.google.com/vpc/docs/configure-private-services-access#allocating-range
+variable "ip_ranges" {
+ description = "CIDR blocks: VPC serverless connector, Private Service Access(PSA) for CloudSQL, CloudSQL VPC"
+ type = object({
+ connector = string
+ psa = string
+ sql_vpc = string
+ })
+ default = {
+ connector = "10.8.0.0/28"
+ psa = "10.60.0.0/24"
+ sql_vpc = "10.0.0.0/20"
+ }
+}
+
+variable "prefix" {
+ description = "Unique prefix used for resource names. Not used for project if 'project_create' is null."
+ type = string
+ default = ""
+}
+
+variable "principals" {
+ description = "List of users to give rights to (CloudSQL admin, client and instanceUser, Logging admin, Service Account User and TokenCreator), eg 'user@domain.com'."
+ type = list(string)
+ default = []
+}
+
+variable "project_create" {
+ description = "Provide values if project creation is needed, uses existing project if null. Parent is in 'folders/nnn' or 'organizations/nnn' format."
+ type = object({
+ billing_account_id = string
+ parent = string
+ })
+ default = null
+}
+
+variable "project_id" {
+ description = "Project id, references existing project if `project_create` is null."
+ type = string
+}
+
+variable "region" {
+ type = string
+ description = "Region for the created resources"
+ default = "europe-west4"
+}
+
+variable "wordpress_image" {
+ type = string
+ description = "Image to run with Cloud Run, starts with \"gcr.io\""
+}
+
+variable "wordpress_port" {
+ type = number
+ description = "Port for the Wordpress image"
+ default = 8080
+}
+
+variable "wordpress_password" {
+ type = string
+ description = "Password for the Wordpress user (will be randomly generated by default)"
+ default = null
+}
\ No newline at end of file
diff --git a/default-versions.tf b/default-versions.tf
index 8abac788..adb52a93 100644
--- a/default-versions.tf
+++ b/default-versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/fast/stages/00-cicd/versions.tf b/fast/stages/00-cicd/versions.tf
index 3a6a1ed8..e51caaa1 100644
--- a/fast/stages/00-cicd/versions.tf
+++ b/fast/stages/00-cicd/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
@@ -33,5 +33,3 @@ terraform {
version = ">= 3.16.1"
}
}
-
-
diff --git a/fast/stages/02-networking-nva/README.md b/fast/stages/02-networking-nva/README.md
index 91071b2c..84c236cf 100644
--- a/fast/stages/02-networking-nva/README.md
+++ b/fast/stages/02-networking-nva/README.md
@@ -352,7 +352,7 @@ DNS configurations are centralised in the `dns-*.tf` files. Spokes delegate DNS
| [landing.tf](./landing.tf) | Landing VPC and related resources. | net-cloudnat
· net-vpc
· net-vpc-firewall
· project
| |
| [main.tf](./main.tf) | Networking folder and hierarchical policy. | folder
| |
| [monitoring.tf](./monitoring.tf) | Network monitoring dashboards. | | google_monitoring_dashboard
|
-| [nva.tf](./nva.tf) | None | compute-mig
· compute-vm
· net-ilb
| |
+| [nva.tf](./nva.tf) | None | compute-mig
· compute-vm
· simple-nva
| |
| [outputs.tf](./outputs.tf) | Module outputs. | | google_storage_bucket_object
· local_file
|
| [spoke-dev.tf](./spoke-dev.tf) | Dev spoke VPC and related resources. | net-vpc
· net-vpc-firewall
· net-vpc-peering
· project
| google_project_iam_binding
|
| [spoke-prod.tf](./spoke-prod.tf) | Production spoke VPC and related resources. | net-vpc
· net-vpc-firewall
· net-vpc-peering
· project
| google_project_iam_binding
|
diff --git a/fast/stages/02-networking-nva/nva.tf b/fast/stages/02-networking-nva/nva.tf
index b7dd6988..4e70d02f 100644
--- a/fast/stages/02-networking-nva/nva.tf
+++ b/fast/stages/02-networking-nva/nva.tf
@@ -15,181 +15,97 @@
*/
locals {
- _subnets = var.data_dir == null ? tomap({}) : {
- for f in fileset("${var.data_dir}/subnets", "**/*.yaml") :
- trimsuffix(basename(f), ".yaml") => yamldecode(file("${var.data_dir}/subnets/${f}"))
- }
- subnets = merge(
- { for k, v in local._subnets : "${k}-cidr" => v.ip_cidr_range },
- { for k, v in local._subnets : "${k}-gw" => cidrhost(v.ip_cidr_range, 1) }
- )
-}
-
-# europe-west1
-
-module "nva-template-ew1" {
- source = "../../../modules/compute-vm"
- project_id = module.landing-project.project_id
- name = "nva-template"
- zone = "europe-west1-b"
- tags = ["nva"]
- can_ip_forward = true
- network_interfaces = [
+ # routing_config should be aligned to the NVA network interfaces - i.e.
+ # local.routing_config[0] sets up the first interface, and so on.
+ routing_config = [
{
- network = module.landing-untrusted-vpc.self_link
- subnetwork = module.landing-untrusted-vpc.subnet_self_links["europe-west1/landing-untrusted-default-ew1"]
+ name = "untrusted"
+ routes = [
+ var.custom_adv.gcp_landing_untrusted_ew1,
+ var.custom_adv.gcp_landing_untrusted_ew4,
+ ]
},
{
- network = module.landing-trusted-vpc.self_link
- subnetwork = module.landing-trusted-vpc.subnet_self_links["europe-west1/landing-trusted-default-ew1"]
- }
+ name = "trusted"
+ routes = [
+ var.custom_adv.gcp_dev_ew1,
+ var.custom_adv.gcp_dev_ew4,
+ var.custom_adv.gcp_landing_trusted_ew1,
+ var.custom_adv.gcp_landing_trusted_ew4,
+ var.custom_adv.gcp_prod_ew1,
+ var.custom_adv.gcp_prod_ew4,
+ ]
+ },
]
- boot_disk = {
- image = "projects/debian-cloud/global/images/family/debian-10"
+ nva_locality = {
+ europe-west1-b = { region = "europe-west1", trigram = "ew1", zone = "b" },
+ europe-west1-c = { region = "europe-west1", trigram = "ew1", zone = "c" },
+ europe-west4-b = { region = "europe-west4", trigram = "ew4", zone = "b" },
+ europe-west4-c = { region = "europe-west4", trigram = "ew4", zone = "c" },
}
+
+}
+
+# NVA config
+module "nva-cloud-config" {
+ source = "../../../modules/cloud-config-container/simple-nva"
+ enable_health_checks = true
+ network_interfaces = local.routing_config
+}
+
+module "nva-template" {
+ for_each = local.nva_locality
+ source = "../../../modules/compute-vm"
+ project_id = module.landing-project.project_id
+ name = "nva-template-${each.value.trigram}-${each.value.zone}"
+ zone = "${each.value.region}-${each.value.zone}"
+ instance_type = "e2-standard-2"
+ tags = ["nva"]
create_template = true
- instance_type = "f1-micro"
- options = {
- spot = true
- termination_action = "STOP"
- }
- metadata = {
- startup-script = templatefile(
- "${path.module}/data/nva-startup-script.tftpl",
- {
- dev-default-ew1-cidr = local.subnets.dev-default-ew1-cidr
- dev-default-ew4-cidr = local.subnets.dev-default-ew4-cidr
- gateway-trusted = local.subnets.landing-trusted-default-ew1-gw
- gateway-untrusted = local.subnets.landing-untrusted-default-ew1-gw
- landing-trusted-other-region = local.subnets.landing-trusted-default-ew4-cidr
- landing-untrusted-other-region = local.subnets.landing-untrusted-default-ew4-cidr
- onprem-main-cidr = var.onprem_cidr.main
- prod-default-ew1-cidr = local.subnets.prod-default-ew1-cidr
- prod-default-ew4-cidr = local.subnets.prod-default-ew4-cidr
- }
- )
- }
-}
-
-module "nva-mig-ew1" {
- source = "../../../modules/compute-mig"
- project_id = module.landing-project.project_id
- regional = true
- location = "europe-west1"
- name = "nva-ew1"
- target_size = 2
- auto_healing_policies = {
- health_check = module.nva-mig-ew1.health_check.self_link
- initial_delay_sec = 30
- }
- health_check_config = {
- type = "tcp"
- check = { port = 22 }
- config = {}
- logging = true
- }
- default_version = {
- instance_template = module.nva-template-ew1.template.self_link
- name = "default"
- }
-}
-
-module "ilb-nva-untrusted-ew1" {
- source = "../../../modules/net-ilb"
- project_id = module.landing-project.project_id
- region = "europe-west1"
- name = "ilb-nva-untrusted-ew1"
- service_label = var.prefix
- global_access = true
- network = module.landing-untrusted-vpc.self_link
- subnetwork = module.landing-untrusted-vpc.subnet_self_links["europe-west1/landing-untrusted-default-ew1"]
- backends = [{
- failover = false
- group = module.nva-mig-ew1.group_manager.instance_group
- balancing_mode = "CONNECTION"
- }]
- health_check_config = {
- type = "tcp", check = { port = 22 }, config = {}, logging = false
- }
-}
-
-module "ilb-nva-trusted-ew1" {
- source = "../../../modules/net-ilb"
- project_id = module.landing-project.project_id
- region = "europe-west1"
- name = "ilb-nva-trusted-ew1"
- service_label = var.prefix
- global_access = true
- network = module.landing-trusted-vpc.self_link
- subnetwork = module.landing-trusted-vpc.subnet_self_links["europe-west1/landing-trusted-default-ew1"]
- backends = [{
- failover = false
- group = module.nva-mig-ew1.group_manager.instance_group
- balancing_mode = "CONNECTION"
- }]
- health_check_config = {
- type = "tcp", check = { port = 22 }, config = {}, logging = false
- }
-}
-
-# europe-west4
-
-module "nva-template-ew4" {
- source = "../../../modules/compute-vm"
- project_id = module.landing-project.project_id
- name = "nva-template"
- zone = "europe-west4-a"
- tags = ["nva"]
- can_ip_forward = true
+ can_ip_forward = true
network_interfaces = [
{
network = module.landing-untrusted-vpc.self_link
- subnetwork = module.landing-untrusted-vpc.subnet_self_links["europe-west4/landing-untrusted-default-ew4"]
+ subnetwork = module.landing-untrusted-vpc.subnet_self_links["${each.value.region}/landing-untrusted-default-${each.value.trigram}"]
nat = false
addresses = null
},
{
network = module.landing-trusted-vpc.self_link
- subnetwork = module.landing-trusted-vpc.subnet_self_links["europe-west4/landing-trusted-default-ew4"]
+ subnetwork = module.landing-trusted-vpc.subnet_self_links["${each.value.region}/landing-trusted-default-${each.value.trigram}"]
nat = false
addresses = null
}
]
boot_disk = {
- image = "projects/debian-cloud/global/images/family/debian-10"
- type = "pd-balanced"
+ image = "projects/cos-cloud/global/images/family/cos-stable"
size = 10
+ type = "pd-balanced"
+ }
+ options = {
+ allow_stopping_for_update = true
+ deletion_protection = false
+ spot = true
+ termination_action = "STOP"
}
- create_template = true
metadata = {
- startup-script = templatefile(
- "${path.module}/data/nva-startup-script.tftpl",
- {
- dev-default-ew1-cidr = local.subnets.dev-default-ew1-cidr
- dev-default-ew4-cidr = local.subnets.dev-default-ew4-cidr
- gateway-trusted = local.subnets.landing-trusted-default-ew4-gw
- gateway-untrusted = local.subnets.landing-untrusted-default-ew4-gw
- landing-trusted-other-region = local.subnets.landing-trusted-default-ew1-cidr
- landing-untrusted-other-region = local.subnets.landing-untrusted-default-ew1-cidr
- onprem-main-cidr = var.onprem_cidr.main
- prod-default-ew1-cidr = local.subnets.prod-default-ew1-cidr
- prod-default-ew4-cidr = local.subnets.prod-default-ew4-cidr
- }
- )
+ user-data = module.nva-cloud-config.cloud_config
}
}
-module "nva-mig-ew4" {
+module "nva-mig" {
+ for_each = local.nva_locality
source = "../../../modules/compute-mig"
project_id = module.landing-project.project_id
regional = true
- location = "europe-west4"
- name = "nva-ew4"
- target_size = 2
- auto_healing_policies = {
- health_check = module.nva-mig-ew4.health_check.self_link
- initial_delay_sec = 30
- }
+ location = each.value.region
+ name = "nva-cos-${each.value.trigram}-${each.value.zone}"
+ target_size = 1
+ # FIXME: cycle
+ # auto_healing_policies = {
+ # health_check = module.nva-mig[each.key].health_check.self_link
+ # initial_delay_sec = 30
+ # }
health_check_config = {
type = "tcp"
check = { port = 22 }
@@ -197,45 +113,51 @@ module "nva-mig-ew4" {
logging = true
}
default_version = {
- instance_template = module.nva-template-ew4.template.self_link
+ instance_template = module.nva-template[each.key].template.self_link
name = "default"
}
}
-module "ilb-nva-untrusted-ew4" {
+module "ilb-nva-untrusted" {
+ for_each = { for l in local.nva_locality : l.region => l.trigram... }
source = "../../../modules/net-ilb"
project_id = module.landing-project.project_id
- region = "europe-west4"
- name = "ilb-nva-untrusted-ew4"
+ region = each.key
+ name = "nva-untrusted-${each.value.0}"
service_label = var.prefix
global_access = true
network = module.landing-untrusted-vpc.self_link
- subnetwork = module.landing-untrusted-vpc.subnet_self_links["europe-west4/landing-untrusted-default-ew4"]
- backends = [{
- failover = false
- group = module.nva-mig-ew4.group_manager.instance_group
- balancing_mode = "CONNECTION"
- }]
+ subnetwork = module.landing-untrusted-vpc.subnet_self_links["${each.key}/landing-untrusted-default-${each.value.0}"]
+ backends = [for key, _ in local.nva_locality :
+ {
+ failover = false
+ group = module.nva-mig[key].group_manager.instance_group
+ balancing_mode = "CONNECTION"
+ } if local.nva_locality[key].region == each.key]
health_check_config = {
type = "tcp", check = { port = 22 }, config = {}, logging = false
}
}
-module "ilb-nva-trusted-ew4" {
+
+module "ilb-nva-trusted" {
+ for_each = { for l in local.nva_locality : l.region => l.trigram... }
source = "../../../modules/net-ilb"
project_id = module.landing-project.project_id
- region = "europe-west4"
- name = "ilb-nva-trusted-ew4"
+ region = each.key
+ name = "nva-trusted-${each.value.0}"
service_label = var.prefix
global_access = true
network = module.landing-trusted-vpc.self_link
- subnetwork = module.landing-trusted-vpc.subnet_self_links["europe-west4/landing-trusted-default-ew4"]
- backends = [{
- failover = false
- group = module.nva-mig-ew4.group_manager.instance_group
- balancing_mode = "CONNECTION"
- }]
+ subnetwork = module.landing-trusted-vpc.subnet_self_links["${each.key}/landing-trusted-default-${each.value.0}"]
+ backends = [for key, _ in local.nva_locality :
+ {
+ failover = false
+ group = module.nva-mig[key].group_manager.instance_group
+ balancing_mode = "CONNECTION"
+ } if local.nva_locality[key].region == each.key]
health_check_config = {
type = "tcp", check = { port = 22 }, config = {}, logging = false
}
}
+
diff --git a/fast/stages/02-networking-nva/spoke-dev.tf b/fast/stages/02-networking-nva/spoke-dev.tf
index ba11cd8e..3499206f 100644
--- a/fast/stages/02-networking-nva/spoke-dev.tf
+++ b/fast/stages/02-networking-nva/spoke-dev.tf
@@ -72,28 +72,28 @@ module "dev-spoke-vpc" {
priority = 1000
tags = ["ew1"]
next_hop_type = "ilb"
- next_hop = module.ilb-nva-trusted-ew1.forwarding_rule_address
+ next_hop = module.ilb-nva-trusted["europe-west1"].forwarding_rule_address
}
nva-ew4-to-ew4 = {
dest_range = "0.0.0.0/0"
priority = 1000
tags = ["ew4"]
next_hop_type = "ilb"
- next_hop = module.ilb-nva-trusted-ew4.forwarding_rule_address
+ next_hop = module.ilb-nva-trusted["europe-west4"].forwarding_rule_address
}
nva-ew1-to-ew4 = {
dest_range = "0.0.0.0/0"
priority = 1001
tags = ["ew1"]
next_hop_type = "ilb"
- next_hop = module.ilb-nva-trusted-ew4.forwarding_rule_address
+ next_hop = module.ilb-nva-trusted["europe-west4"].forwarding_rule_address
}
nva-ew4-to-ew1 = {
dest_range = "0.0.0.0/0"
priority = 1001
tags = ["ew4"]
next_hop_type = "ilb"
- next_hop = module.ilb-nva-trusted-ew1.forwarding_rule_address
+ next_hop = module.ilb-nva-trusted["europe-west1"].forwarding_rule_address
}
}
}
diff --git a/fast/stages/02-networking-nva/spoke-prod.tf b/fast/stages/02-networking-nva/spoke-prod.tf
index 7150195e..6a0c26c8 100644
--- a/fast/stages/02-networking-nva/spoke-prod.tf
+++ b/fast/stages/02-networking-nva/spoke-prod.tf
@@ -72,28 +72,28 @@ module "prod-spoke-vpc" {
priority = 1000
tags = ["ew1"]
next_hop_type = "ilb"
- next_hop = module.ilb-nva-trusted-ew1.forwarding_rule_address
+ next_hop = module.ilb-nva-trusted["europe-west1"].forwarding_rule_address
}
nva-ew4-to-ew4 = {
dest_range = "0.0.0.0/0"
priority = 1000
tags = ["ew4"]
next_hop_type = "ilb"
- next_hop = module.ilb-nva-trusted-ew4.forwarding_rule_address
+ next_hop = module.ilb-nva-trusted["europe-west4"].forwarding_rule_address
}
nva-ew1-to-ew4 = {
dest_range = "0.0.0.0/0"
priority = 1001
tags = ["ew1"]
next_hop_type = "ilb"
- next_hop = module.ilb-nva-trusted-ew4.forwarding_rule_address
+ next_hop = module.ilb-nva-trusted["europe-west4"].forwarding_rule_address
}
nva-ew4-to-ew1 = {
dest_range = "0.0.0.0/0"
priority = 1001
tags = ["ew4"]
next_hop_type = "ilb"
- next_hop = module.ilb-nva-trusted-ew1.forwarding_rule_address
+ next_hop = module.ilb-nva-trusted["europe-west1"].forwarding_rule_address
}
}
}
diff --git a/modules/__experimental/net-neg/versions.tf b/modules/__experimental/net-neg/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/__experimental/net-neg/versions.tf
+++ b/modules/__experimental/net-neg/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/api-gateway/versions.tf b/modules/api-gateway/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/api-gateway/versions.tf
+++ b/modules/api-gateway/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/apigee-organization/versions.tf b/modules/apigee-organization/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/apigee-organization/versions.tf
+++ b/modules/apigee-organization/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/apigee-x-instance/versions.tf b/modules/apigee-x-instance/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/apigee-x-instance/versions.tf
+++ b/modules/apigee-x-instance/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/artifact-registry/versions.tf b/modules/artifact-registry/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/artifact-registry/versions.tf
+++ b/modules/artifact-registry/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/bigquery-dataset/versions.tf b/modules/bigquery-dataset/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/bigquery-dataset/versions.tf
+++ b/modules/bigquery-dataset/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/bigtable-instance/versions.tf b/modules/bigtable-instance/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/bigtable-instance/versions.tf
+++ b/modules/bigtable-instance/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/billing-budget/versions.tf b/modules/billing-budget/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/billing-budget/versions.tf
+++ b/modules/billing-budget/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/binauthz/versions.tf b/modules/binauthz/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/binauthz/versions.tf
+++ b/modules/binauthz/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/cloud-config-container/coredns/versions.tf b/modules/cloud-config-container/coredns/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/cloud-config-container/coredns/versions.tf
+++ b/modules/cloud-config-container/coredns/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/cloud-config-container/cos-generic-metadata/versions.tf b/modules/cloud-config-container/cos-generic-metadata/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/cloud-config-container/cos-generic-metadata/versions.tf
+++ b/modules/cloud-config-container/cos-generic-metadata/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/cloud-config-container/envoy-traffic-director/versions.tf b/modules/cloud-config-container/envoy-traffic-director/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/cloud-config-container/envoy-traffic-director/versions.tf
+++ b/modules/cloud-config-container/envoy-traffic-director/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/cloud-config-container/mysql/versions.tf b/modules/cloud-config-container/mysql/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/cloud-config-container/mysql/versions.tf
+++ b/modules/cloud-config-container/mysql/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/cloud-config-container/nginx-tls/versions.tf b/modules/cloud-config-container/nginx-tls/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/cloud-config-container/nginx-tls/versions.tf
+++ b/modules/cloud-config-container/nginx-tls/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/cloud-config-container/nginx/versions.tf b/modules/cloud-config-container/nginx/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/cloud-config-container/nginx/versions.tf
+++ b/modules/cloud-config-container/nginx/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/cloud-config-container/onprem/versions.tf b/modules/cloud-config-container/onprem/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/cloud-config-container/onprem/versions.tf
+++ b/modules/cloud-config-container/onprem/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/cloud-config-container/simple-nva/README.md b/modules/cloud-config-container/simple-nva/README.md
index 7fbb109d..5014e9a3 100644
--- a/modules/cloud-config-container/simple-nva/README.md
+++ b/modules/cloud-config-container/simple-nva/README.md
@@ -1,4 +1,4 @@
-# Google Cloud DNS Module
+# Google Simple NVA Module
This module allows for the creation of a NVA (Network Virtual Appliance) to be used for experiments and as a stub for future appliances deployment.
diff --git a/modules/cloud-config-container/simple-nva/files/ipprefix_by_netmask.sh b/modules/cloud-config-container/simple-nva/files/ipprefix_by_netmask.sh
index 405c1649..a1c69822 100644
--- a/modules/cloud-config-container/simple-nva/files/ipprefix_by_netmask.sh
+++ b/modules/cloud-config-container/simple-nva/files/ipprefix_by_netmask.sh
@@ -15,7 +15,7 @@
# limitations under the License.
# https://stackoverflow.com/questions/50413579/bash-convert-netmask-in-cidr-notation
-c=0 x=0$(printf '%o' $${1//./ })
+c=0 x=0$(printf '%o' ${1//./ })
while [ $x -gt 0 ]; do
let c+=$((x % 2)) 'x>>=1'
done
diff --git a/modules/cloud-config-container/simple-nva/versions.tf b/modules/cloud-config-container/simple-nva/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/cloud-config-container/simple-nva/versions.tf
+++ b/modules/cloud-config-container/simple-nva/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/cloud-config-container/squid/versions.tf b/modules/cloud-config-container/squid/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/cloud-config-container/squid/versions.tf
+++ b/modules/cloud-config-container/squid/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/cloud-function/versions.tf b/modules/cloud-function/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/cloud-function/versions.tf
+++ b/modules/cloud-function/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/cloud-identity-group/versions.tf b/modules/cloud-identity-group/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/cloud-identity-group/versions.tf
+++ b/modules/cloud-identity-group/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/cloud-run/versions.tf b/modules/cloud-run/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/cloud-run/versions.tf
+++ b/modules/cloud-run/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/cloudsql-instance/versions.tf b/modules/cloudsql-instance/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/cloudsql-instance/versions.tf
+++ b/modules/cloudsql-instance/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/compute-mig/versions.tf b/modules/compute-mig/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/compute-mig/versions.tf
+++ b/modules/compute-mig/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/compute-vm/versions.tf b/modules/compute-vm/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/compute-vm/versions.tf
+++ b/modules/compute-vm/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/container-registry/versions.tf b/modules/container-registry/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/container-registry/versions.tf
+++ b/modules/container-registry/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/data-catalog-policy-tag/versions.tf b/modules/data-catalog-policy-tag/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/data-catalog-policy-tag/versions.tf
+++ b/modules/data-catalog-policy-tag/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/datafusion/versions.tf b/modules/datafusion/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/datafusion/versions.tf
+++ b/modules/datafusion/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/dns/versions.tf b/modules/dns/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/dns/versions.tf
+++ b/modules/dns/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/endpoints/versions.tf b/modules/endpoints/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/endpoints/versions.tf
+++ b/modules/endpoints/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/folder/versions.tf b/modules/folder/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/folder/versions.tf
+++ b/modules/folder/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/gcs/versions.tf b/modules/gcs/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/gcs/versions.tf
+++ b/modules/gcs/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/gke-cluster/versions.tf b/modules/gke-cluster/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/gke-cluster/versions.tf
+++ b/modules/gke-cluster/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/gke-hub/versions.tf b/modules/gke-hub/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/gke-hub/versions.tf
+++ b/modules/gke-hub/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/gke-nodepool/versions.tf b/modules/gke-nodepool/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/gke-nodepool/versions.tf
+++ b/modules/gke-nodepool/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/iam-service-account/versions.tf b/modules/iam-service-account/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/iam-service-account/versions.tf
+++ b/modules/iam-service-account/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/kms/versions.tf b/modules/kms/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/kms/versions.tf
+++ b/modules/kms/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/logging-bucket/versions.tf b/modules/logging-bucket/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/logging-bucket/versions.tf
+++ b/modules/logging-bucket/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/net-address/versions.tf b/modules/net-address/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/net-address/versions.tf
+++ b/modules/net-address/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/net-cloudnat/versions.tf b/modules/net-cloudnat/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/net-cloudnat/versions.tf
+++ b/modules/net-cloudnat/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/net-glb/versions.tf b/modules/net-glb/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/net-glb/versions.tf
+++ b/modules/net-glb/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/net-ilb-l7/versions.tf b/modules/net-ilb-l7/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/net-ilb-l7/versions.tf
+++ b/modules/net-ilb-l7/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/net-ilb/versions.tf b/modules/net-ilb/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/net-ilb/versions.tf
+++ b/modules/net-ilb/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/net-interconnect-attachment-direct/versions.tf b/modules/net-interconnect-attachment-direct/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/net-interconnect-attachment-direct/versions.tf
+++ b/modules/net-interconnect-attachment-direct/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/net-vpc-firewall/versions.tf b/modules/net-vpc-firewall/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/net-vpc-firewall/versions.tf
+++ b/modules/net-vpc-firewall/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/net-vpc-peering/versions.tf b/modules/net-vpc-peering/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/net-vpc-peering/versions.tf
+++ b/modules/net-vpc-peering/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/net-vpc/versions.tf b/modules/net-vpc/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/net-vpc/versions.tf
+++ b/modules/net-vpc/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/net-vpn-dynamic/versions.tf b/modules/net-vpn-dynamic/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/net-vpn-dynamic/versions.tf
+++ b/modules/net-vpn-dynamic/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/net-vpn-ha/versions.tf b/modules/net-vpn-ha/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/net-vpn-ha/versions.tf
+++ b/modules/net-vpn-ha/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/net-vpn-static/versions.tf b/modules/net-vpn-static/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/net-vpn-static/versions.tf
+++ b/modules/net-vpn-static/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/organization-policy/versions.tf b/modules/organization-policy/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/organization-policy/versions.tf
+++ b/modules/organization-policy/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/organization/versions.tf b/modules/organization/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/organization/versions.tf
+++ b/modules/organization/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/project/versions.tf b/modules/project/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/project/versions.tf
+++ b/modules/project/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/projects-data-source/versions.tf b/modules/projects-data-source/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/projects-data-source/versions.tf
+++ b/modules/projects-data-source/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/pubsub/versions.tf b/modules/pubsub/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/pubsub/versions.tf
+++ b/modules/pubsub/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/secret-manager/versions.tf b/modules/secret-manager/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/secret-manager/versions.tf
+++ b/modules/secret-manager/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/service-directory/versions.tf b/modules/service-directory/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/service-directory/versions.tf
+++ b/modules/service-directory/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/source-repository/versions.tf b/modules/source-repository/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/source-repository/versions.tf
+++ b/modules/source-repository/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/vpc-sc/versions.tf b/modules/vpc-sc/versions.tf
index 8abac788..adb52a93 100644
--- a/modules/vpc-sc/versions.tf
+++ b/modules/vpc-sc/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.3.0"
+ required_version = ">= 1.3.2"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/tests/conftest.py b/tests/conftest.py
index 48498db5..a5ded070 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -145,3 +145,8 @@ def apply_runner():
return apply, output
return run_apply
+
+
+@pytest.fixture
+def basedir():
+ return BASEDIR
diff --git a/tests/fast/stages/s00_cicd/__init__.py b/tests/fast/stages/s00_cicd/__init__.py
new file mode 100644
index 00000000..6d6d1266
--- /dev/null
+++ b/tests/fast/stages/s00_cicd/__init__.py
@@ -0,0 +1,13 @@
+# 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.
diff --git a/tests/fast/stages/s00_cicd/test_providers.py b/tests/fast/stages/s00_cicd/test_providers.py
new file mode 100644
index 00000000..e45c869e
--- /dev/null
+++ b/tests/fast/stages/s00_cicd/test_providers.py
@@ -0,0 +1,34 @@
+# 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 os
+'''
+github = {
+ source = "integrations/github"
+ version = "~> 4.0"
+}
+gitlab = {
+ source = "gitlabhq/gitlab"
+ version = ">= 3.16.1"
+}
+'''
+
+
+def test_providers(basedir):
+ "Test providers file."
+ p = os.path.join(basedir, 'fast/stages/00-cicd/versions.tf')
+ with open(p) as f:
+ data = f.read()
+ assert 'integrations/github' in data
+ assert 'gitlabhq/gitlab' in data