diff --git a/.gitignore b/.gitignore index 299bea20c..12e8457c4 100644 --- a/.gitignore +++ b/.gitignore @@ -57,6 +57,8 @@ override.tf.json **/.kitchen **/.kitchen.local.yml **/Gemfile.lock +# Plan files +**/tmp_plan test/fixtures/shared/terraform.tfvars diff --git a/.kitchen.yml b/.kitchen.yml index fa2814907..ba924e449 100644 --- a/.kitchen.yml +++ b/.kitchen.yml @@ -113,3 +113,13 @@ suites: backend: local controls: - gcloud-projects + - name: app-infra + driver: + root_module_directory: test/fixtures/app-infra/ + verifier: + color: false + systems: + - name: app-infra + backend: gcp + controls: + - gcp-app-infra diff --git a/5-app-infra/README.md b/5-app-infra/README.md new file mode 100644 index 000000000..a7ae5d4c3 --- /dev/null +++ b/5-app-infra/README.md @@ -0,0 +1,72 @@ +# 5-app-infra + +The purpose of this step is to deploy a simple [Compute Engine](https://cloud.google.com/compute/) instance in one of the business unit projects using the infra pipeline setup in 4-projects. +The infra pipeline is created in step 4-projects within the shared env and has a [Cloudbuild](https://cloud.google.com/build/docs) pipeline configured to manage infrastructure within projects. To enable deployment via this pipeline, the projects deployed should [enable](https://github.com/terraform-google-modules/terraform-example-foundation/blob/master/4-projects/business_unit_1/development/example_base_shared_vpc_project.tf#L31-L32) `enable_cloudbuild_deploy` flag and provide the Cloud Build service account value via`cloudbuild_sa`. + +This enables the Cloud Build service account to impersonate the project service account and use it to deploy infrastructure. The roles required for project SA can also be [managed](https://github.com/terraform-google-modules/terraform-example-foundation/blob/master/4-projects/business_unit_1/development/example_base_shared_vpc_project.tf#L30) via `sa_roles`. (Note: This requires per project SA impersonation, if you would like to have a single SA managing an environment and all associated projects, that is also possible by [granting](https://github.com/terraform-google-modules/terraform-example-foundation/blob/master/4-projects/modules/single_project/main.tf#L62-L68) `roles/iam.serviceAccountTokenCreator` to an SA with the right roles in `4-projects/env`. + +There is also a [Source Repository](https://cloud.google.com/source-repositories) configured with build triggers similar to [foundation pipeline](https://github.com/terraform-google-modules/terraform-example-foundation#0-bootstrap) setup in `0-bootstrap`. +This Compute Engine instance will be created using the base network created during step 3-networks to access private services. + +## Prerequisites + +1. 0-bootstrap executed successfully. +1. 1-org executed successfully. +1. 2-environments executed successfully. +1. 3-networks executed successfully. +1. 4-projects executed successfully. + +## Usage + +### Setup to run via Cloud Build + +1. Clone repo `gcloud source repos clone bu1-example-app --project=prj-bu1-c-infra-pipeline-`. (this is from the terraform output from the previous section, run `terraform output cloudbuild_project_id` in the `4-projects/business_unit_1/shared` folder) +1. Navigate into the repo `cd bu1-example-app`. +1. Change freshly cloned repo and change to non master branch `git checkout -b plan`. +1. Copy contents of foundation to new repo `cp -RT ../terraform-example-foundation/5-app-infra/ .` (modify accordingly based on your current directory). +1. Copy cloud build configuration files for terraform `cp ../terraform-example-foundation/build/cloudbuild-tf-* . ` (modify accordingly based on your current directory). +1. Copy terraform wrapper script `cp ../terraform-example-foundation/build/tf-wrapper.sh . ` to the root of your new repository (modify accordingly based on your current directory). +1. Ensure wrapper script can be executed `chmod 755 ./tf-wrapper.sh`. +1. Rename `common.auto.example.tfvars` to `common.auto.tfvars` and update the file with values from your environment. +1. Rename `bu1-development.auto.example.tfvars` to `bu1-development.auto.tfvars` and update the file with values from your environment. +1. Rename `bu1-non-production.auto.example.tfvars` to `bu1-non-production.auto.tfvars` and update the file with values from your environment. +1. Rename `bu1-production.auto.example.tfvars` to `bu1-production.auto.tfvars` and update the file with values from your environment. +1. Commit changes with `git add .` and `git commit -m 'Your message'`. +1. Push your plan branch to trigger a plan for all environments `git push --set-upstream origin plan` (the branch `plan` is not a special one. Any branch which name is different from `development`, `non-production` or `production` will trigger a terraform plan). + 1. Review the plan output in your cloud build project https://console.cloud.google.com/cloud-build/builds?project=YOUR_CLOUD_BUILD_PROJECT_ID +1. Merge changes to development with `git checkout -b development` and `git push origin development`. + 1. Review the apply output in your cloud build project https://console.cloud.google.com/cloud-build/builds?project=YOUR_CLOUD_BUILD_PROJECT_ID +1. Merge changes to non-production with `git checkout -b non-production` and `git push origin non-production`. + 1. Review the apply output in your cloud build project https://console.cloud.google.com/cloud-build/builds?project=YOUR_CLOUD_BUILD_PROJECT_ID +1. Merge changes to production branch with `git checkout -b production` and `git push origin production`. + 1. Review the apply output in your cloud build project https://console.cloud.google.com/cloud-build/builds?project=YOUR_CLOUD_BUILD_PROJECT_ID + +### Run terraform locally + +1. Change into 5-app-infra folder. +1. Run `cp ../build/tf-wrapper.sh .` +1. Run `chmod 755 ./tf-wrapper.sh`. +1. Rename `common.auto.example.tfvars` to `common.auto.tfvars` and update the file with values from your environment and bootstrap. +1. Update backend.tf with your bucket from infra pipeline example. You can run +```for i in `find -name 'backend.tf'`; do sed -i 's/UPDATE_ME//' $i; done```. + +We will now deploy each of our environments(development/production/non-production) using this script. +When using Cloud Build or Jenkins as your CI/CD tool each environment corresponds to a branch is the repository for 5-app-infra step and only the corresponding environment is applied. + +To use the `validate` option of the `tf-wrapper.sh` script, the latest version of `terraform-validator` must be [installed](https://github.com/forseti-security/policy-library/blob/master/docs/user_guide.md#how-to-use-terraform-validator) in your system and in you `PATH`. + +1. Run `./tf-wrapper.sh init production`. +1. Run `./tf-wrapper.sh plan production` and review output. +1. Run `./tf-wrapper.sh validate production $(pwd)/../policy-library ` and check for violations. +1. Run `./tf-wrapper.sh apply production`. +1. Run `./tf-wrapper.sh init non-production`. +1. Run `./tf-wrapper.sh plan non-production` and review output. +1. Run `./tf-wrapper.sh plan non-production` and review output. +1. Run `./tf-wrapper.sh validate non-production $(pwd)/../policy-library ` and check for violations. +1. Run `./tf-wrapper.sh apply non-production`. +1. Run `./tf-wrapper.sh init development`. +1. Run `./tf-wrapper.sh plan development` and review output. +1. Run `./tf-wrapper.sh validate development $(pwd)/../policy-library ` and check for violations. +1. Run `./tf-wrapper.sh apply development`. + +If you received any errors or made any changes to the Terraform config or `terraform.tfvars` you must re-run `./tf-wrapper.sh plan ` before run `./tf-wrapper.sh apply `. diff --git a/5-app-infra/bu1-development.auto.example.tfvars b/5-app-infra/bu1-development.auto.example.tfvars new file mode 100644 index 000000000..a38bb029a --- /dev/null +++ b/5-app-infra/bu1-development.auto.example.tfvars @@ -0,0 +1,17 @@ +/** + * Copyright 2021 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. + */ + +project_service_account = "project-service-account@prj-bu1-d-sample-base-.iam.gserviceaccount.com" diff --git a/5-app-infra/bu1-non-production.auto.example.tfvars b/5-app-infra/bu1-non-production.auto.example.tfvars new file mode 100644 index 000000000..e1b0c4de4 --- /dev/null +++ b/5-app-infra/bu1-non-production.auto.example.tfvars @@ -0,0 +1,17 @@ +/** + * Copyright 2021 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. + */ + +project_service_account = "project-service-account@prj-bu1-n-sample-base-.iam.gserviceaccount.com" diff --git a/5-app-infra/bu1-production.auto.example.tfvars b/5-app-infra/bu1-production.auto.example.tfvars new file mode 100644 index 000000000..c72c951fb --- /dev/null +++ b/5-app-infra/bu1-production.auto.example.tfvars @@ -0,0 +1,17 @@ +/** + * Copyright 2021 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. + */ + +project_service_account = "project-service-account@prj-bu1-p-sample-base-.iam.gserviceaccount.com" diff --git a/5-app-infra/business_unit_1/development/README.md b/5-app-infra/business_unit_1/development/README.md new file mode 100644 index 000000000..11ca510f3 --- /dev/null +++ b/5-app-infra/business_unit_1/development/README.md @@ -0,0 +1,24 @@ + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| folder\_prefix | Name prefix to use for folders created. | `string` | `"fldr"` | no | +| instance\_region | The region where compute instance will be created. A subnetwork must exists in the instance region. | `string` | n/a | yes | +| org\_id | The organization id for the associated services | `string` | n/a | yes | +| parent\_folder | Optional - if using a folder for testing. | `string` | `""` | no | +| project\_service\_account | Service account email of the account created on step 4-project for the project where the GCE will be created | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| available\_zones | List of available zones in region | +| instances\_details | List of details for compute instances | +| instances\_names | List of names for compute instances | +| instances\_self\_links | List of self-links for compute instances | +| instances\_zones | List of zone for compute instances | +| project\_id | Project where compute instance was created | +| region | Region where compute instance was created | + + diff --git a/5-app-infra/business_unit_1/development/backend.tf b/5-app-infra/business_unit_1/development/backend.tf new file mode 100644 index 000000000..e5c336cc7 --- /dev/null +++ b/5-app-infra/business_unit_1/development/backend.tf @@ -0,0 +1,22 @@ +/** + * Copyright 2021 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. + */ + +terraform { + backend "gcs" { + bucket = "UPDATE_ME" + prefix = "terraform/app-infra/business_unit_1/development" + } +} diff --git a/5-app-infra/business_unit_1/development/bu1-development.auto.tfvars b/5-app-infra/business_unit_1/development/bu1-development.auto.tfvars new file mode 120000 index 000000000..69c1030b8 --- /dev/null +++ b/5-app-infra/business_unit_1/development/bu1-development.auto.tfvars @@ -0,0 +1 @@ +../../bu1-development.auto.tfvars \ No newline at end of file diff --git a/5-app-infra/business_unit_1/development/common.auto.tfvars b/5-app-infra/business_unit_1/development/common.auto.tfvars new file mode 120000 index 000000000..39aaa4621 --- /dev/null +++ b/5-app-infra/business_unit_1/development/common.auto.tfvars @@ -0,0 +1 @@ +../../common.auto.tfvars \ No newline at end of file diff --git a/5-app-infra/business_unit_1/development/main.tf b/5-app-infra/business_unit_1/development/main.tf new file mode 100644 index 000000000..689c2e1eb --- /dev/null +++ b/5-app-infra/business_unit_1/development/main.tf @@ -0,0 +1,33 @@ +/** + * Copyright 2021 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. + */ + + + +data "google_active_folder" "env" { + display_name = "${var.folder_prefix}-development" + parent = var.parent_folder != "" ? "folders/${var.parent_folder}" : "organizations/${var.org_id}" +} + +module "base_shared_gce_instance" { + source = "../../modules/env_base" + environment = "development" + vpc_type = "base" + num_instances = 1 + folder_id = data.google_active_folder.env.name + business_code = "bu1" + project_suffix = "sample-base" + region = var.instance_region +} diff --git a/5-app-infra/business_unit_1/development/outputs.tf b/5-app-infra/business_unit_1/development/outputs.tf new file mode 100644 index 000000000..5fa9ffbe6 --- /dev/null +++ b/5-app-infra/business_unit_1/development/outputs.tf @@ -0,0 +1,50 @@ +/** + * Copyright 2021 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 "instances_self_links" { + description = "List of self-links for compute instances" + value = module.base_shared_gce_instance.instances_self_links +} + +output "instances_names" { + description = "List of names for compute instances" + value = [for u in module.base_shared_gce_instance.instances_details : u.name] +} + +output "instances_zones" { + description = "List of zone for compute instances" + value = [for u in module.base_shared_gce_instance.instances_details : u.zone] +} + +output "instances_details" { + description = "List of details for compute instances" + value = module.base_shared_gce_instance.instances_details +} + +output "available_zones" { + description = "List of available zones in region" + value = module.base_shared_gce_instance.available_zones +} + +output "project_id" { + description = "Project where compute instance was created" + value = module.base_shared_gce_instance.project_id +} + +output "region" { + description = "Region where compute instance was created" + value = module.base_shared_gce_instance.region +} diff --git a/5-app-infra/business_unit_1/development/providers.tf b/5-app-infra/business_unit_1/development/providers.tf new file mode 100644 index 000000000..e5420f442 --- /dev/null +++ b/5-app-infra/business_unit_1/development/providers.tf @@ -0,0 +1,30 @@ +/** + * Copyright 2021 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 { + tf_sa = var.project_service_account +} + +/****************************************** + Provider credential configuration + *****************************************/ +provider "google" { + impersonate_service_account = local.tf_sa +} + +provider "google-beta" { + impersonate_service_account = local.tf_sa +} diff --git a/5-app-infra/business_unit_1/development/variables.tf b/5-app-infra/business_unit_1/development/variables.tf new file mode 100644 index 000000000..cb50a9e34 --- /dev/null +++ b/5-app-infra/business_unit_1/development/variables.tf @@ -0,0 +1,42 @@ +/** + * Copyright 2021 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 "project_service_account" { + description = "Service account email of the account created on step 4-project for the project where the GCE will be created" + type = string +} + +variable "org_id" { + description = "The organization id for the associated services" + type = string +} + +variable "instance_region" { + description = "The region where compute instance will be created. A subnetwork must exists in the instance region." + type = string +} + +variable "folder_prefix" { + description = "Name prefix to use for folders created." + type = string + default = "fldr" +} + +variable "parent_folder" { + description = "Optional - if using a folder for testing." + type = string + default = "" +} diff --git a/5-app-infra/business_unit_1/non-production/README.md b/5-app-infra/business_unit_1/non-production/README.md new file mode 100644 index 000000000..11ca510f3 --- /dev/null +++ b/5-app-infra/business_unit_1/non-production/README.md @@ -0,0 +1,24 @@ + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| folder\_prefix | Name prefix to use for folders created. | `string` | `"fldr"` | no | +| instance\_region | The region where compute instance will be created. A subnetwork must exists in the instance region. | `string` | n/a | yes | +| org\_id | The organization id for the associated services | `string` | n/a | yes | +| parent\_folder | Optional - if using a folder for testing. | `string` | `""` | no | +| project\_service\_account | Service account email of the account created on step 4-project for the project where the GCE will be created | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| available\_zones | List of available zones in region | +| instances\_details | List of details for compute instances | +| instances\_names | List of names for compute instances | +| instances\_self\_links | List of self-links for compute instances | +| instances\_zones | List of zone for compute instances | +| project\_id | Project where compute instance was created | +| region | Region where compute instance was created | + + diff --git a/5-app-infra/business_unit_1/non-production/backend.tf b/5-app-infra/business_unit_1/non-production/backend.tf new file mode 100644 index 000000000..74ed21718 --- /dev/null +++ b/5-app-infra/business_unit_1/non-production/backend.tf @@ -0,0 +1,22 @@ +/** + * Copyright 2021 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. + */ + +terraform { + backend "gcs" { + bucket = "UPDATE_ME" + prefix = "terraform/app-infra/business_unit_1/non-production" + } +} diff --git a/5-app-infra/business_unit_1/non-production/bu1-non-production.auto.tfvars b/5-app-infra/business_unit_1/non-production/bu1-non-production.auto.tfvars new file mode 120000 index 000000000..f98c6be57 --- /dev/null +++ b/5-app-infra/business_unit_1/non-production/bu1-non-production.auto.tfvars @@ -0,0 +1 @@ +../../bu1-non-production.auto.tfvars \ No newline at end of file diff --git a/5-app-infra/business_unit_1/non-production/common.auto.tfvars b/5-app-infra/business_unit_1/non-production/common.auto.tfvars new file mode 120000 index 000000000..39aaa4621 --- /dev/null +++ b/5-app-infra/business_unit_1/non-production/common.auto.tfvars @@ -0,0 +1 @@ +../../common.auto.tfvars \ No newline at end of file diff --git a/5-app-infra/business_unit_1/non-production/main.tf b/5-app-infra/business_unit_1/non-production/main.tf new file mode 100644 index 000000000..9b53c4fe7 --- /dev/null +++ b/5-app-infra/business_unit_1/non-production/main.tf @@ -0,0 +1,33 @@ +/** + * Copyright 2021 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. + */ + + + +data "google_active_folder" "env" { + display_name = "${var.folder_prefix}-non-production" + parent = var.parent_folder != "" ? "folders/${var.parent_folder}" : "organizations/${var.org_id}" +} + +module "base_shared_gce_instance" { + source = "../../modules/env_base" + environment = "non-production" + vpc_type = "base" + num_instances = 1 + folder_id = data.google_active_folder.env.name + business_code = "bu1" + project_suffix = "sample-base" + region = var.instance_region +} diff --git a/5-app-infra/business_unit_1/non-production/outputs.tf b/5-app-infra/business_unit_1/non-production/outputs.tf new file mode 100644 index 000000000..5fa9ffbe6 --- /dev/null +++ b/5-app-infra/business_unit_1/non-production/outputs.tf @@ -0,0 +1,50 @@ +/** + * Copyright 2021 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 "instances_self_links" { + description = "List of self-links for compute instances" + value = module.base_shared_gce_instance.instances_self_links +} + +output "instances_names" { + description = "List of names for compute instances" + value = [for u in module.base_shared_gce_instance.instances_details : u.name] +} + +output "instances_zones" { + description = "List of zone for compute instances" + value = [for u in module.base_shared_gce_instance.instances_details : u.zone] +} + +output "instances_details" { + description = "List of details for compute instances" + value = module.base_shared_gce_instance.instances_details +} + +output "available_zones" { + description = "List of available zones in region" + value = module.base_shared_gce_instance.available_zones +} + +output "project_id" { + description = "Project where compute instance was created" + value = module.base_shared_gce_instance.project_id +} + +output "region" { + description = "Region where compute instance was created" + value = module.base_shared_gce_instance.region +} diff --git a/5-app-infra/business_unit_1/non-production/providers.tf b/5-app-infra/business_unit_1/non-production/providers.tf new file mode 100644 index 000000000..e5420f442 --- /dev/null +++ b/5-app-infra/business_unit_1/non-production/providers.tf @@ -0,0 +1,30 @@ +/** + * Copyright 2021 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 { + tf_sa = var.project_service_account +} + +/****************************************** + Provider credential configuration + *****************************************/ +provider "google" { + impersonate_service_account = local.tf_sa +} + +provider "google-beta" { + impersonate_service_account = local.tf_sa +} diff --git a/5-app-infra/business_unit_1/non-production/variables.tf b/5-app-infra/business_unit_1/non-production/variables.tf new file mode 100644 index 000000000..cb50a9e34 --- /dev/null +++ b/5-app-infra/business_unit_1/non-production/variables.tf @@ -0,0 +1,42 @@ +/** + * Copyright 2021 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 "project_service_account" { + description = "Service account email of the account created on step 4-project for the project where the GCE will be created" + type = string +} + +variable "org_id" { + description = "The organization id for the associated services" + type = string +} + +variable "instance_region" { + description = "The region where compute instance will be created. A subnetwork must exists in the instance region." + type = string +} + +variable "folder_prefix" { + description = "Name prefix to use for folders created." + type = string + default = "fldr" +} + +variable "parent_folder" { + description = "Optional - if using a folder for testing." + type = string + default = "" +} diff --git a/5-app-infra/business_unit_1/production/README.md b/5-app-infra/business_unit_1/production/README.md new file mode 100644 index 000000000..11ca510f3 --- /dev/null +++ b/5-app-infra/business_unit_1/production/README.md @@ -0,0 +1,24 @@ + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| folder\_prefix | Name prefix to use for folders created. | `string` | `"fldr"` | no | +| instance\_region | The region where compute instance will be created. A subnetwork must exists in the instance region. | `string` | n/a | yes | +| org\_id | The organization id for the associated services | `string` | n/a | yes | +| parent\_folder | Optional - if using a folder for testing. | `string` | `""` | no | +| project\_service\_account | Service account email of the account created on step 4-project for the project where the GCE will be created | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| available\_zones | List of available zones in region | +| instances\_details | List of details for compute instances | +| instances\_names | List of names for compute instances | +| instances\_self\_links | List of self-links for compute instances | +| instances\_zones | List of zone for compute instances | +| project\_id | Project where compute instance was created | +| region | Region where compute instance was created | + + diff --git a/5-app-infra/business_unit_1/production/backend.tf b/5-app-infra/business_unit_1/production/backend.tf new file mode 100644 index 000000000..c95c43777 --- /dev/null +++ b/5-app-infra/business_unit_1/production/backend.tf @@ -0,0 +1,22 @@ +/** + * Copyright 2021 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. + */ + +terraform { + backend "gcs" { + bucket = "UPDATE_ME" + prefix = "terraform/app-infra/business_unit_1/production" + } +} diff --git a/5-app-infra/business_unit_1/production/bu1-production.auto.tfvars b/5-app-infra/business_unit_1/production/bu1-production.auto.tfvars new file mode 120000 index 000000000..5d3678edd --- /dev/null +++ b/5-app-infra/business_unit_1/production/bu1-production.auto.tfvars @@ -0,0 +1 @@ +../../bu1-production.auto.tfvars \ No newline at end of file diff --git a/5-app-infra/business_unit_1/production/common.auto.tfvars b/5-app-infra/business_unit_1/production/common.auto.tfvars new file mode 120000 index 000000000..39aaa4621 --- /dev/null +++ b/5-app-infra/business_unit_1/production/common.auto.tfvars @@ -0,0 +1 @@ +../../common.auto.tfvars \ No newline at end of file diff --git a/5-app-infra/business_unit_1/production/main.tf b/5-app-infra/business_unit_1/production/main.tf new file mode 100644 index 000000000..24c64757a --- /dev/null +++ b/5-app-infra/business_unit_1/production/main.tf @@ -0,0 +1,33 @@ +/** + * Copyright 2021 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. + */ + + + +data "google_active_folder" "env" { + display_name = "${var.folder_prefix}-production" + parent = var.parent_folder != "" ? "folders/${var.parent_folder}" : "organizations/${var.org_id}" +} + +module "base_shared_gce_instance" { + source = "../../modules/env_base" + environment = "production" + vpc_type = "base" + num_instances = 1 + folder_id = data.google_active_folder.env.name + business_code = "bu1" + project_suffix = "sample-base" + region = var.instance_region +} diff --git a/5-app-infra/business_unit_1/production/outputs.tf b/5-app-infra/business_unit_1/production/outputs.tf new file mode 100644 index 000000000..5fa9ffbe6 --- /dev/null +++ b/5-app-infra/business_unit_1/production/outputs.tf @@ -0,0 +1,50 @@ +/** + * Copyright 2021 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 "instances_self_links" { + description = "List of self-links for compute instances" + value = module.base_shared_gce_instance.instances_self_links +} + +output "instances_names" { + description = "List of names for compute instances" + value = [for u in module.base_shared_gce_instance.instances_details : u.name] +} + +output "instances_zones" { + description = "List of zone for compute instances" + value = [for u in module.base_shared_gce_instance.instances_details : u.zone] +} + +output "instances_details" { + description = "List of details for compute instances" + value = module.base_shared_gce_instance.instances_details +} + +output "available_zones" { + description = "List of available zones in region" + value = module.base_shared_gce_instance.available_zones +} + +output "project_id" { + description = "Project where compute instance was created" + value = module.base_shared_gce_instance.project_id +} + +output "region" { + description = "Region where compute instance was created" + value = module.base_shared_gce_instance.region +} diff --git a/5-app-infra/business_unit_1/production/providers.tf b/5-app-infra/business_unit_1/production/providers.tf new file mode 100644 index 000000000..e5420f442 --- /dev/null +++ b/5-app-infra/business_unit_1/production/providers.tf @@ -0,0 +1,30 @@ +/** + * Copyright 2021 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 { + tf_sa = var.project_service_account +} + +/****************************************** + Provider credential configuration + *****************************************/ +provider "google" { + impersonate_service_account = local.tf_sa +} + +provider "google-beta" { + impersonate_service_account = local.tf_sa +} diff --git a/5-app-infra/business_unit_1/production/variables.tf b/5-app-infra/business_unit_1/production/variables.tf new file mode 100644 index 000000000..8e0a4d1b2 --- /dev/null +++ b/5-app-infra/business_unit_1/production/variables.tf @@ -0,0 +1,42 @@ +/** + * Copyright 2021 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 "project_service_account" { + description = "Service account email of the account created on step 4-project for the project where the GCE will be created" + type = string +} + +variable "org_id" { + description = "The organization id for the associated services" + type = string +} + +variable "folder_prefix" { + description = "Name prefix to use for folders created." + type = string + default = "fldr" +} + +variable "instance_region" { + description = "The region where compute instance will be created. A subnetwork must exists in the instance region." + type = string +} + +variable "parent_folder" { + description = "Optional - if using a folder for testing." + type = string + default = "" +} diff --git a/5-app-infra/common.auto.example.tfvars b/5-app-infra/common.auto.example.tfvars new file mode 100644 index 000000000..2bb1352e7 --- /dev/null +++ b/5-app-infra/common.auto.example.tfvars @@ -0,0 +1,22 @@ +/** + * Copyright 2021 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. + */ + +org_id = "000000000000" + +instance_region = "us-east1" // should be one of the regions used to create network on step 3-networks + +//Optional - for development. Will place all resources under a specific folder instead of org root +//parent_folder = "01234567890" diff --git a/5-app-infra/modules/env_base/README.md b/5-app-infra/modules/env_base/README.md new file mode 100644 index 000000000..6671f4d46 --- /dev/null +++ b/5-app-infra/modules/env_base/README.md @@ -0,0 +1,26 @@ + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| business\_code | The code that describes which business unit owns the project | `string` | `"abcd"` | no | +| environment | The environment the single project belongs to | `string` | n/a | yes | +| folder\_id | The folder id where project will be created | `string` | n/a | yes | +| hostname | Hostname of instances | `string` | `"example-app"` | no | +| num\_instances | Number of instances to create | `number` | n/a | yes | +| project\_suffix | The name of the GCP project. Max 16 characters with 3 character business unit code. | `string` | n/a | yes | +| region | The GCP region to create and test resources in | `string` | `"us-central1"` | no | +| service\_account | Service account to attach to the instance. See https://www.terraform.io/docs/providers/google/r/compute_instance_template.html#service_account. |
object({
email = string,
scopes = set(string)
})
| `null` | no | +| vpc\_type | The type of VPC to attach the project to. Possible options are base or restricted. | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| available\_zones | List of available zones in region | +| instances\_details | List of details for compute instances | +| instances\_self\_links | List of self-links for compute instances | +| project\_id | Project where compute instance was created | +| region | Region where compute instance was created | + + diff --git a/5-app-infra/modules/env_base/data.tf b/5-app-infra/modules/env_base/data.tf new file mode 100644 index 000000000..12106910e --- /dev/null +++ b/5-app-infra/modules/env_base/data.tf @@ -0,0 +1,42 @@ +/** + * Copyright 2021 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. + */ + +data "google_projects" "network_projects" { + filter = "parent.id:${split("/", var.folder_id)[1]} labels.application_name=${var.vpc_type}-shared-vpc-host labels.environment=${var.environment} lifecycleState=ACTIVE" +} + +data "google_project" "network_project" { + project_id = data.google_projects.network_projects.projects[0].project_id +} + +data "google_projects" "environment_projects" { + filter = "parent.id:${split("/", var.folder_id)[1]} name:*${var.project_suffix}* labels.application_name=${var.business_code}-sample-application labels.environment=${var.environment} lifecycleState=ACTIVE" +} + +data "google_project" "env_project" { + project_id = data.google_projects.environment_projects.projects[0].project_id +} + +data "google_compute_network" "shared_vpc" { + name = "vpc-${local.environment_code}-shared-${var.vpc_type}" + project = data.google_project.network_project.project_id +} + +data "google_compute_subnetwork" "subnetwork" { + name = "sb-${local.environment_code}-shared-${var.vpc_type}-${var.region}" + region = var.region + project = data.google_project.network_project.project_id +} diff --git a/5-app-infra/modules/env_base/main.tf b/5-app-infra/modules/env_base/main.tf new file mode 100644 index 000000000..76f72d5b7 --- /dev/null +++ b/5-app-infra/modules/env_base/main.tf @@ -0,0 +1,47 @@ +/** + * Copyright 2021 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 { + environment_code = element(split("", var.environment), 0) +} + +resource "google_service_account" "compute_engine_service_account" { + project = data.google_project.env_project.project_id + account_id = "sa-example-app" + display_name = "Example app service Account" +} + +module "instance_template" { + source = "terraform-google-modules/vm/google//modules/instance_template" + version = "6.2.0" + region = var.region + project_id = data.google_project.env_project.project_id + subnetwork = data.google_compute_subnetwork.subnetwork.self_link + service_account = { + email = google_service_account.compute_engine_service_account.email + scopes = ["compute-rw"] + } +} + +module "compute_instance" { + source = "terraform-google-modules/vm/google//modules/compute_instance" + version = "6.2.0" + region = var.region + subnetwork = data.google_compute_subnetwork.subnetwork.self_link + num_instances = var.num_instances + hostname = var.hostname + instance_template = module.instance_template.self_link +} diff --git a/5-app-infra/modules/env_base/outputs.tf b/5-app-infra/modules/env_base/outputs.tf new file mode 100644 index 000000000..983f1329f --- /dev/null +++ b/5-app-infra/modules/env_base/outputs.tf @@ -0,0 +1,40 @@ +/** + * Copyright 2021 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 "instances_self_links" { + description = "List of self-links for compute instances" + value = module.compute_instance.instances_self_links +} + +output "instances_details" { + description = "List of details for compute instances" + value = module.compute_instance.instances_details +} + +output "available_zones" { + description = "List of available zones in region" + value = module.compute_instance.available_zones +} + +output "project_id" { + description = "Project where compute instance was created" + value = data.google_project.env_project.project_id +} + +output "region" { + description = "Region where compute instance was created" + value = var.region +} diff --git a/5-app-infra/modules/env_base/variables.tf b/5-app-infra/modules/env_base/variables.tf new file mode 100644 index 000000000..ce90c7175 --- /dev/null +++ b/5-app-infra/modules/env_base/variables.tf @@ -0,0 +1,66 @@ +/** + * Copyright 2021 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 "environment" { + description = "The environment the single project belongs to" + type = string +} + +variable "vpc_type" { + description = "The type of VPC to attach the project to. Possible options are base or restricted." + type = string +} + +variable "region" { + description = "The GCP region to create and test resources in" + type = string + default = "us-central1" +} + +variable "num_instances" { + description = "Number of instances to create" + type = number +} + +variable "hostname" { + description = "Hostname of instances" + default = "example-app" +} + +variable "service_account" { + default = null + type = object({ + email = string, + scopes = set(string) + }) + description = "Service account to attach to the instance. See https://www.terraform.io/docs/providers/google/r/compute_instance_template.html#service_account." +} + +variable "folder_id" { + description = "The folder id where project will be created" + type = string +} + +variable "business_code" { + description = "The code that describes which business unit owns the project" + type = string + default = "abcd" +} + +variable "project_suffix" { + description = "The name of the GCP project. Max 16 characters with 3 character business unit code." + type = string +} diff --git a/5-app-infra/modules/env_base/versions.tf b/5-app-infra/modules/env_base/versions.tf new file mode 100644 index 000000000..8a0efdc15 --- /dev/null +++ b/5-app-infra/modules/env_base/versions.tf @@ -0,0 +1,38 @@ +/** + * Copyright 2021 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. + */ + +terraform { + required_version = ">= 0.13" + required_providers { + google = { + source = "hashicorp/google" + version = ">= 3.61" + } + google-beta = { + source = "hashicorp/google-beta" + version = ">= 3.61" + } + null = { + source = "hashicorp/null" + version = "~> 2.1" + } + + random = { + source = "hashicorp/random" + version = "~> 2.3" + } + } +} diff --git a/build/int.cloudbuild.yaml b/build/int.cloudbuild.yaml index 64cde1a8c..7905a87c9 100644 --- a/build/int.cloudbuild.yaml +++ b/build/int.cloudbuild.yaml @@ -78,6 +78,18 @@ steps: - id: verify-projects name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' args: ['/bin/bash', '-c', 'source /usr/local/bin/task_helper_functions.sh && kitchen_do verify projects-default'] +- id: create-app-infra + name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' + args: ['/bin/bash', '-c', 'source /usr/local/bin/task_helper_functions.sh && kitchen_do create app-infra-default'] +- id: converge-app-infra + name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' + args: ['/bin/bash', '-c', 'source /usr/local/bin/task_helper_functions.sh && source ./test/export_sc.sh && kitchen_do converge app-infra-default'] +- id: verify-app-infra + name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' + args: ['/bin/bash', '-c', 'source /usr/local/bin/task_helper_functions.sh && kitchen_do verify app-infra-default'] +- id: destroy-app-infra + name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' + args: ['/bin/bash', '-c', 'source /usr/local/bin/task_helper_functions.sh && source ./test/export_sc.sh && kitchen_do destroy app-infra-default'] - id: destroy-projects name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' args: ['/bin/bash', '-c', 'source /usr/local/bin/task_helper_functions.sh && source ./test/export_sc.sh && export TF_VAR_policy_id=$(gcloud access-context-manager policies list --organization="${TF_VAR_org_id:?}" --format="value(name)") && kitchen_do destroy projects-default'] diff --git a/test/fixtures/app-infra/main.tf b/test/fixtures/app-infra/main.tf new file mode 100644 index 000000000..cf49e47fe --- /dev/null +++ b/test/fixtures/app-infra/main.tf @@ -0,0 +1,42 @@ +/** + * Copyright 2021 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. + */ + +module "app_infra_bu1_development" { + source = "../../../5-app-infra/business_unit_1/development" + parent_folder = var.parent_folder + org_id = var.org_id + project_service_account = var.terraform_service_account + folder_prefix = var.folder_prefix + instance_region = "us-west1" +} + +module "app_infra_bu1_nonproduction" { + source = "../../../5-app-infra/business_unit_1/non-production" + parent_folder = var.parent_folder + org_id = var.org_id + project_service_account = var.terraform_service_account + folder_prefix = var.folder_prefix + instance_region = "us-west1" +} + +module "app_infra_bu1_production" { + source = "../../../5-app-infra/business_unit_1/production" + parent_folder = var.parent_folder + org_id = var.org_id + project_service_account = var.terraform_service_account + folder_prefix = var.folder_prefix + instance_region = "us-west1" +} diff --git a/test/fixtures/app-infra/outputs.tf b/test/fixtures/app-infra/outputs.tf new file mode 100644 index 000000000..ccc244caf --- /dev/null +++ b/test/fixtures/app-infra/outputs.tf @@ -0,0 +1,120 @@ +/** + * Copyright 2021 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 "dev_bu1_instances_self_links" { + description = "List of self-links for compute instances" + value = module.app_infra_bu1_development.instances_self_links +} + +output "dev_bu1_instances_details" { + description = "List of details for compute instances" + value = module.app_infra_bu1_development.instances_details +} + +output "dev_bu1_instances_names" { + description = "List of names for compute instances" + value = module.app_infra_bu1_development.instances_names +} + +output "dev_bu1_instances_zones" { + description = "List of zones for compute instances" + value = module.app_infra_bu1_development.instances_zones +} + +output "dev_bu1_available_zones" { + description = "List of available zones in region" + value = module.app_infra_bu1_development.available_zones +} + +output "dev_bu1_project_id" { + description = "Project where compute instance was created" + value = module.app_infra_bu1_development.project_id +} + +output "dev_bu1_region" { + description = "Region where compute instance was created" + value = module.app_infra_bu1_development.region +} + +output "nonprod_bu1_instances_self_links" { + description = "List of self-links for compute instances" + value = module.app_infra_bu1_nonproduction.instances_self_links +} + +output "nonprod_bu1_instances_details" { + description = "List of details for compute instances" + value = module.app_infra_bu1_nonproduction.instances_details +} + +output "nonprod_bu1_instances_names" { + description = "List of names for compute instances" + value = module.app_infra_bu1_nonproduction.instances_names +} + +output "nonprod_bu1_instances_zones" { + description = "List of zones for compute instances" + value = module.app_infra_bu1_nonproduction.instances_zones +} + +output "nonprod_bu1_available_zones" { + description = "List of available zones in region" + value = module.app_infra_bu1_nonproduction.available_zones +} + +output "nonprod_bu1_project_id" { + description = "Project where compute instance was created" + value = module.app_infra_bu1_nonproduction.project_id +} + +output "nonprod_bu1_region" { + description = "Region where compute instance was created" + value = module.app_infra_bu1_nonproduction.region +} + +output "prod_bu1_instances_self_links" { + description = "List of self-links for compute instances" + value = module.app_infra_bu1_production.instances_self_links +} + +output "prod_bu1_instances_details" { + description = "List of details for compute instances" + value = module.app_infra_bu1_production.instances_details +} + +output "prod_bu1_instances_names" { + description = "List of names for compute instances" + value = module.app_infra_bu1_production.instances_names +} + +output "prod_bu1_instances_zones" { + description = "List of zones for compute instances" + value = module.app_infra_bu1_production.instances_zones +} + +output "prod_bu1_available_zones" { + description = "List of available zones in region" + value = module.app_infra_bu1_production.available_zones +} + +output "prod_bu1_project_id" { + description = "Project where compute instance was created" + value = module.app_infra_bu1_production.project_id +} + +output "prod_bu1_region" { + description = "Region where compute instance was created" + value = module.app_infra_bu1_production.region +} diff --git a/test/fixtures/app-infra/variables.tf b/test/fixtures/app-infra/variables.tf new file mode 100644 index 000000000..dd2808d0c --- /dev/null +++ b/test/fixtures/app-infra/variables.tf @@ -0,0 +1,36 @@ +/** + * Copyright 2021 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 "terraform_service_account" { + description = "The SA that will be used for creating projects." +} + +variable "folder_prefix" { + description = "Name prefix to use for folders created." + type = string + default = "fldr" +} + +variable "parent_folder" { + description = "Optional - if using a folder for testing." + type = string + default = "" +} + +variable "org_id" { + description = "The organization id for the associated services" + type = string +} diff --git a/test/integration/app-infra/controls/gcp_projects.rb b/test/integration/app-infra/controls/gcp_projects.rb new file mode 100644 index 000000000..3169a09ee --- /dev/null +++ b/test/integration/app-infra/controls/gcp_projects.rb @@ -0,0 +1,55 @@ +# Copyright 2021 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 +# +# https://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. + +dev_bu1_project_id = attribute('dev_bu1_project_id') +dev_bu1_instances_zones = attribute('dev_bu1_instances_zones') +dev_bu1_instances_names = attribute('dev_bu1_instances_names') + +nonprod_bu1_project_id = attribute('nonprod_bu1_project_id') +nonprod_bu1_instances_zones = attribute('nonprod_bu1_instances_zones') +nonprod_bu1_instances_names = attribute('nonprod_bu1_instances_names') + +prod_bu1_project_id = attribute('prod_bu1_project_id') +prod_bu1_instances_names = attribute('prod_bu1_instances_names') +prod_bu1_instances_zones = attribute('prod_bu1_instances_zones') +index = 0 + +control 'gcp-app-infra' do + title 'gcp step 5-app-infra tests' + dev_bu1_instances_names.each do |dev_bu1_instance_name| + describe google_compute_instance(project: dev_bu1_project_id, zone: dev_bu1_instances_zones[index], name: dev_bu1_instance_name) do + it { should exist } + its('machine_type') { should match 'n1-standard-1' } + end + index += 1 + end + + index = 0 + nonprod_bu1_instances_names.each do |nonprod_bu1_instance_name| + describe google_compute_instance(project: nonprod_bu1_project_id, zone: nonprod_bu1_instances_zones[index], name: nonprod_bu1_instance_name) do + it { should exist } + its('machine_type') { should match 'n1-standard-1' } + end + index += 1 + end + + index = 0 + prod_bu1_instances_names.each do |prod_bu1_instance_name| + describe google_compute_instance(project: prod_bu1_project_id, zone: prod_bu1_instances_zones[index], name: prod_bu1_instance_name) do + it { should exist } + its('machine_type') { should match 'n1-standard-1' } + end + index += 1 + end +end diff --git a/test/integration/app-infra/inspec.yml b/test/integration/app-infra/inspec.yml new file mode 100644 index 000000000..90abd3b2d --- /dev/null +++ b/test/integration/app-infra/inspec.yml @@ -0,0 +1,32 @@ +depends: + - name: inspec-gcp + git: https://github.com/inspec/inspec-gcp.git + tag: v1.7.0 +attributes: + - name: dev_bu1_project_id + required: true + type: string + - name: dev_bu1_instances_names + required: true + type: array + - name: dev_bu1_instances_zones + required: true + type: array + - name: nonprod_bu1_project_id + required: true + type: string + - name: nonprod_bu1_instances_names + required: true + type: array + - name: nonprod_bu1_instances_zones + required: true + type: array + - name: prod_bu1_project_id + required: true + type: string + - name: prod_bu1_instances_names + required: true + type: array + - name: prod_bu1_instances_zones + required: true + type: array