├── test ├── setup │ ├── .gitignore │ ├── outputs.tf │ ├── variables.tf │ ├── versions.tf │ ├── iam.tf │ └── main.tf └── integration │ ├── discover_test.go │ ├── common │ └── common.go │ ├── sap_hana_simple │ └── sap_hana_simple_test.go │ ├── sap_hana_ha_simple │ └── sap_hana_ha_simple_test.go │ ├── sap_hana_scaleout_simple │ └── sap_hana_scaleout_simple_test.go │ └── go.mod ├── .github ├── renovate.json ├── release-please.yml ├── trusted-contribution.yml └── workflows │ ├── stale.yml │ └── lint.yaml ├── CODEOWNERS ├── modules ├── s4 │ ├── networks.tf │ ├── ansible_runner_permissions.tf │ ├── configuration_optional_buckets.tf │ ├── apis.tf │ ├── project.tf │ ├── README.md │ ├── ascs.tf │ ├── app.tf │ └── ansible.tf ├── s4_ha │ ├── networks.tf │ ├── ansible_runner_permissions.tf │ ├── configuration_optional_buckets.tf │ ├── apis.tf │ ├── project.tf │ └── README.md ├── sap_nw │ ├── outputs.tf │ ├── versions.tf │ ├── variables.tf │ ├── README.md │ └── main.tf ├── sap_ase │ ├── outputs.tf │ ├── versions.tf │ ├── README.md │ ├── variables.tf │ └── main.tf ├── sap_db2 │ ├── outputs.tf │ ├── versions.tf │ ├── utility │ │ └── README.md │ ├── README.md │ └── variables.tf ├── sap_nw_ha │ ├── versions.tf │ ├── outputs.tf │ └── README.md ├── sap_hana_scaleout │ ├── versions.tf │ └── outputs.tf ├── sap_hana │ ├── versions.tf │ └── outputs.tf └── sap_hana_ha │ ├── versions.tf │ └── outputs.tf ├── examples ├── sap_nw_simple │ ├── variables.tf │ ├── outputs.tf │ ├── README.md │ └── main.tf ├── sap_s4_simple │ ├── variables.tf │ ├── README.md │ └── main.tf ├── sap_hana_ha_simple │ ├── variables.tf │ ├── README.md │ ├── main.tf │ └── outputs.tf ├── sap_hana_simple │ ├── variables.tf │ ├── outputs.tf │ ├── README.md │ └── main.tf ├── sap_nw_ha_simple │ ├── variables.tf │ ├── outputs.tf │ ├── README.md │ └── main.tf ├── sap_s4_ha_simple │ ├── variables.tf │ ├── README.md │ └── main.tf └── sap_hana_scaleout_simple │ ├── variables.tf │ ├── README.md │ ├── main.tf │ └── outputs.tf ├── .gitignore ├── metadata.yaml ├── README.md ├── Makefile └── CHANGELOG.md /test/setup/.gitignore: -------------------------------------------------------------------------------- 1 | terraform.tfvars 2 | source.sh 3 | -------------------------------------------------------------------------------- /.github/renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": ["github>GoogleCloudPlatform/cloud-foundation-toolkit//infra/terraform/test-org/github/resources/renovate"] 4 | } 5 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | # NOTE: This file is automatically generated from values at: 2 | # https://github.com/GoogleCloudPlatform/cloud-foundation-toolkit/blob/main/infra/terraform/test-org/org/locals.tf 3 | 4 | * @terraform-google-modules/cft-admins @dfellmeth-google @megelatim @sjswerdlow 5 | 6 | # NOTE: GitHub CODEOWNERS locations: 7 | # https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners#codeowners-and-branch-protection 8 | 9 | CODEOWNERS @terraform-google-modules/cft-admins 10 | .github/CODEOWNERS @terraform-google-modules/cft-admins 11 | docs/CODEOWNERS @terraform-google-modules/cft-admins 12 | 13 | -------------------------------------------------------------------------------- /.github/release-please.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2022 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | releaseType: terraform-module 16 | handleGHRelease: true 17 | -------------------------------------------------------------------------------- /modules/s4/networks.tf: -------------------------------------------------------------------------------- 1 | # Copyright 2024 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | data "google_compute_network" "sap-vpc" { 16 | name = var.vpc_name 17 | project = var.network_project == "" ? var.gcp_project_id : var.network_project 18 | } 19 | -------------------------------------------------------------------------------- /modules/s4_ha/networks.tf: -------------------------------------------------------------------------------- 1 | # Copyright 2024 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | data "google_compute_network" "sap-vpc" { 16 | name = var.vpc_name 17 | project = var.network_project == "" ? var.gcp_project_id : var.network_project 18 | } 19 | -------------------------------------------------------------------------------- /examples/sap_nw_simple/variables.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | variable "project_id" { 18 | type = string 19 | description = "Project id where the instances will be created." 20 | } 21 | -------------------------------------------------------------------------------- /examples/sap_s4_simple/variables.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | variable "project_id" { 18 | type = string 19 | description = "Project id where the instances will be created" 20 | } 21 | -------------------------------------------------------------------------------- /examples/sap_hana_ha_simple/variables.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | variable "project_id" { 18 | type = string 19 | description = "Project id where the instances will be created." 20 | } 21 | -------------------------------------------------------------------------------- /examples/sap_hana_simple/variables.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | variable "project_id" { 18 | type = string 19 | description = "Project id where the instances will be created." 20 | } 21 | -------------------------------------------------------------------------------- /examples/sap_nw_ha_simple/variables.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | variable "project_id" { 18 | type = string 19 | description = "Project id where the instances will be created." 20 | } 21 | -------------------------------------------------------------------------------- /examples/sap_s4_ha_simple/variables.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | variable "project_id" { 18 | type = string 19 | description = "Project id where the instances will be created" 20 | } 21 | -------------------------------------------------------------------------------- /examples/sap_hana_scaleout_simple/variables.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | variable "project_id" { 18 | type = string 19 | description = "Project id where the instances will be created." 20 | } 21 | -------------------------------------------------------------------------------- /examples/sap_nw_simple/outputs.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | output "sap_nw_primary_self_link" { 17 | description = "SAP NW self-link for the instance created" 18 | value = module.sap_nw.sap_nw_self_link 19 | } 20 | -------------------------------------------------------------------------------- /modules/sap_nw/outputs.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | output "sap_nw_self_link" { 17 | description = "SAP NW self-link for instance created" 18 | value = google_compute_instance.sap_nw_instance.self_link 19 | } 20 | -------------------------------------------------------------------------------- /modules/sap_ase/outputs.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | output "sap_ase_instance_self_link" { 18 | description = "SAP ASE self-link for instance created" 19 | value = google_compute_instance.sap_ase_instance.self_link 20 | } 21 | -------------------------------------------------------------------------------- /modules/sap_db2/outputs.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | output "sap_db2_instance_self_link" { 18 | description = "DB2 self-link for instance created" 19 | value = google_compute_instance.sap_db2_instance.self_link 20 | } 21 | -------------------------------------------------------------------------------- /examples/sap_s4_simple/README.md: -------------------------------------------------------------------------------- 1 | # SAP S4 HANA example 2 | 3 | This example illustrates how to use the latest release of the terraform module for SAP on Google Cloud for provisioning SAP S4 HANA 4 | 5 | 6 | ## Inputs 7 | 8 | | Name | Description | Type | Default | Required | 9 | |------|-------------|------|---------|:--------:| 10 | | project\_id | Project id where the instances will be created | `string` | n/a | yes | 11 | 12 | ## Outputs 13 | 14 | No outputs. 15 | 16 | 17 | 18 | To provision this example, run the following from within this directory: 19 | - `terraform init` to get the plugins 20 | - `terraform plan` to see the infrastructure plan 21 | - `terraform apply` to apply the infrastructure build 22 | - `terraform destroy` to destroy the built infrastructure 23 | -------------------------------------------------------------------------------- /test/setup/outputs.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | output "project_id" { 18 | value = module.project.project_id 19 | } 20 | 21 | output "sa_key" { 22 | value = google_service_account_key.int_test.private_key 23 | sensitive = true 24 | } 25 | -------------------------------------------------------------------------------- /modules/sap_nw/versions.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | terraform { 17 | required_version = ">=0.12.6" 18 | required_providers { 19 | google = { 20 | source = "hashicorp/google" 21 | version = ">= 4.0.0, < 6" 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /modules/sap_nw_ha/versions.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | terraform { 17 | required_version = ">=0.12.6" 18 | required_providers { 19 | google = { 20 | source = "hashicorp/google" 21 | version = ">= 4.0.0, < 6" 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /examples/sap_s4_ha_simple/README.md: -------------------------------------------------------------------------------- 1 | # SAP S4 HANA HA example 2 | 3 | This example illustrates how to use the latest release of the terraform module for SAP on Google Cloud for provisioning SAP S4 HANA HA 4 | 5 | 6 | ## Inputs 7 | 8 | | Name | Description | Type | Default | Required | 9 | |------|-------------|------|---------|:--------:| 10 | | project\_id | Project id where the instances will be created | `string` | n/a | yes | 11 | 12 | ## Outputs 13 | 14 | No outputs. 15 | 16 | 17 | 18 | To provision this example, run the following from within this directory: 19 | - `terraform init` to get the plugins 20 | - `terraform plan` to see the infrastructure plan 21 | - `terraform apply` to apply the infrastructure build 22 | - `terraform destroy` to destroy the built infrastructure 23 | -------------------------------------------------------------------------------- /modules/sap_ase/versions.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | terraform { 18 | required_version = ">=0.12.6" # Uses "for_each" 19 | required_providers { 20 | google = { 21 | source = "hashicorp/google" 22 | version = ">= 4.0.0, < 6" 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /modules/sap_db2/versions.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | terraform { 18 | required_version = ">=0.12.6" # Uses "for_each" 19 | required_providers { 20 | google = { 21 | source = "hashicorp/google" 22 | version = ">= 4.0.0, < 6" 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX leaves these everywhere on SMB shares 2 | ._* 3 | 4 | # OSX trash 5 | .DS_Store 6 | 7 | # Python 8 | *.pyc 9 | 10 | # Emacs save files 11 | *~ 12 | \#*\# 13 | .\#* 14 | 15 | # Vim-related files 16 | [._]*.s[a-w][a-z] 17 | [._]s[a-w][a-z] 18 | *.un~ 19 | Session.vim 20 | .netrwhist 21 | 22 | ### https://raw.github.com/github/gitignore/90f149de451a5433aebd94d02d11b0e28843a1af/Terraform.gitignore 23 | 24 | # Local .terraform directories 25 | **/.terraform/* 26 | **/.terraform.* 27 | 28 | # .tfstate files 29 | *.tfstate 30 | *.tfstate.* 31 | 32 | # Crash log files 33 | crash.log 34 | 35 | # Kitchen files 36 | **/inspec.lock 37 | **/.kitchen 38 | **/kitchen.local.yml 39 | **/Gemfile.lock 40 | 41 | # Ignore any .tfvars files that are generated automatically for each Terraform run. Most 42 | # .tfvars files are managed as part of configuration and so should be included in 43 | # version control. 44 | **/*.tfvars 45 | 46 | credentials.json 47 | -------------------------------------------------------------------------------- /modules/sap_hana_scaleout/versions.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | terraform { 17 | required_version = ">=0.12.6" 18 | required_providers { 19 | google = { 20 | source = "hashicorp/google" 21 | version = ">= 4.0.0, < 6" 22 | } 23 | assert = { 24 | source = "bwoznicki/assert" 25 | version = "0.0.1" 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /test/setup/variables.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | variable "org_id" { 17 | description = "The numeric organization id" 18 | } 19 | 20 | variable "folder_id" { 21 | description = "The folder to deploy in" 22 | } 23 | 24 | variable "billing_account" { 25 | description = "The billing account id associated with the project, e.g. XXXXXX-YYYYYY-ZZZZZZ" 26 | } 27 | -------------------------------------------------------------------------------- /test/setup/versions.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | terraform { 18 | required_version = ">= 0.13" 19 | required_providers { 20 | google = { 21 | source = "hashicorp/google" 22 | version = ">= 3.25.0" 23 | } 24 | google-beta = { 25 | source = "hashicorp/google-beta" 26 | version = ">= 3.25.0" 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /examples/sap_nw_simple/README.md: -------------------------------------------------------------------------------- 1 | # SAP Netweaver example 2 | 3 | This example illustrates how to use the latest release of the terraform module for SAP on Google Cloud for provisioning SAP NW 4 | 5 | 6 | ## Inputs 7 | 8 | | Name | Description | Type | Default | Required | 9 | |------|-------------|------|---------|:--------:| 10 | | project\_id | Project id where the instances will be created. | `string` | n/a | yes | 11 | 12 | ## Outputs 13 | 14 | | Name | Description | 15 | |------|-------------| 16 | | sap\_nw\_primary\_self\_link | SAP NW self-link for the instance created | 17 | 18 | 19 | 20 | To provision this example, run the following from within this directory: 21 | - `terraform init` to get the plugins 22 | - `terraform plan` to see the infrastructure plan 23 | - `terraform apply` to apply the infrastructure build 24 | - `terraform destroy` to destroy the built infrastructure 25 | -------------------------------------------------------------------------------- /modules/s4/ansible_runner_permissions.tf: -------------------------------------------------------------------------------- 1 | # Copyright 2023 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # This will give the ansible runner service account required gcs permissions 16 | resource "google_storage_bucket_iam_member" "ansible_sa_test_role_1" { 17 | bucket = split("/", var.package_location)[2] 18 | role = "roles/storage.admin" 19 | member = "serviceAccount:${data.google_service_account.service_account_ansible.email}" 20 | } 21 | -------------------------------------------------------------------------------- /modules/s4_ha/ansible_runner_permissions.tf: -------------------------------------------------------------------------------- 1 | # Copyright 2023 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # This will give the ansible runner service account required gcs permissions 16 | resource "google_storage_bucket_iam_member" "ansible_sa_test_role_1" { 17 | bucket = split("/", var.package_location)[2] 18 | role = "roles/storage.admin" 19 | member = "serviceAccount:${data.google_service_account.service_account_ansible.email}" 20 | } 21 | -------------------------------------------------------------------------------- /examples/sap_nw_ha_simple/outputs.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | output "sap_nw_scs_primary_self_link" { 17 | description = "SAP NW SCS self-link for the instance created" 18 | value = module.sap_nw_ha.scs_instance 19 | } 20 | 21 | output "sap_nw_ers_worker_self_links" { 22 | description = "SAP NW ERS self-links for the instance created" 23 | value = module.sap_nw_ha.ers_instance 24 | } 25 | -------------------------------------------------------------------------------- /.github/trusted-contribution.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2025 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # NOTE: This file is automatically generated from: 16 | # https://github.com/GoogleCloudPlatform/cloud-foundation-toolkit/blob/main/infra/terraform/test-org/github 17 | 18 | annotations: 19 | - type: comment 20 | text: "/gcbrun" 21 | trustedContributors: 22 | - release-please[bot] 23 | - renovate[bot] 24 | - renovate-bot 25 | - forking-renovate[bot] 26 | - dependabot[bot] 27 | -------------------------------------------------------------------------------- /examples/sap_s4_simple/main.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | module "sap_s4" { 18 | source = "terraform-google-modules/sap/google//modules/s4" 19 | version = "~> 1.0" 20 | 21 | deployment_name = "my_s4" 22 | gcp_project_id = var.project_id 23 | filestore_location = "us-east1-b" 24 | region_name = "us-east1" 25 | media_bucket_name = "private-bucket" 26 | zone1_name = "us-east1-b" 27 | } 28 | -------------------------------------------------------------------------------- /examples/sap_hana_simple/outputs.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | output "sap_hana_primary_self_link" { 17 | description = "SAP HANA self-link for the primary instance created" 18 | value = module.sap_hana.sap_hana_primary_self_link 19 | } 20 | 21 | output "sap_hana_worker_self_links" { 22 | description = "SAP HANA self-links for the secondary instances created" 23 | value = module.sap_hana.sap_hana_worker_self_links 24 | } 25 | -------------------------------------------------------------------------------- /modules/sap_hana/versions.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | terraform { 17 | required_version = ">=0.12.6" 18 | required_providers { 19 | google = { 20 | source = "hashicorp/google" 21 | version = ">= 4.0.0, < 6" 22 | } 23 | assert = { 24 | source = "bwoznicki/assert" 25 | version = "0.0.1" 26 | } 27 | validation = { 28 | source = "tlkamp/validation" 29 | version = "1.1.3" 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /modules/sap_hana_ha/versions.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | terraform { 17 | required_version = ">=0.12.6" 18 | required_providers { 19 | google = { 20 | source = "hashicorp/google" 21 | version = ">= 4.0.0, < 6" 22 | } 23 | assert = { 24 | source = "bwoznicki/assert" 25 | version = "0.0.1" 26 | } 27 | validation = { 28 | source = "tlkamp/validation" 29 | version = "1.1.3" 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /examples/sap_hana_simple/README.md: -------------------------------------------------------------------------------- 1 | # SAP HANA example 2 | 3 | This example illustrates how to use the latest release of the terraform module for SAP on Google Cloud for provisioning SAP HANA 4 | 5 | 6 | ## Inputs 7 | 8 | | Name | Description | Type | Default | Required | 9 | |------|-------------|------|---------|:--------:| 10 | | project\_id | Project id where the instances will be created. | `string` | n/a | yes | 11 | 12 | ## Outputs 13 | 14 | | Name | Description | 15 | |------|-------------| 16 | | sap\_hana\_primary\_self\_link | SAP HANA self-link for the primary instance created | 17 | | sap\_hana\_worker\_self\_links | SAP HANA self-links for the secondary instances created | 18 | 19 | 20 | 21 | To provision this example, run the following from within this directory: 22 | - `terraform init` to get the plugins 23 | - `terraform plan` to see the infrastructure plan 24 | - `terraform apply` to apply the infrastructure build 25 | - `terraform destroy` to destroy the built infrastructure 26 | -------------------------------------------------------------------------------- /modules/sap_hana/outputs.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | output "sap_hana_primary_self_link" { 17 | description = "SAP HANA self-link for the primary instance created" 18 | value = google_compute_instance.sap_hana_primary_instance.self_link 19 | } 20 | 21 | output "sap_hana_worker_self_links" { 22 | description = "SAP HANA self-links for the secondary instances created" 23 | value = google_compute_instance.sap_hana_worker_instances[*].self_link 24 | } 25 | -------------------------------------------------------------------------------- /examples/sap_nw_simple/main.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | module "sap_nw" { 18 | source = "terraform-google-modules/sap/google//modules/sap_nw" 19 | version = "~> 1.0" 20 | 21 | project_id = var.project_id 22 | machine_type = "n1-standard-16" 23 | subnetwork = "default" 24 | linux_image = "rhel-8-4-sap-ha" 25 | linux_image_project = "rhel-sap-cloud" 26 | instance_name = "nwvm" 27 | zone = "us-east1-b" 28 | } 29 | -------------------------------------------------------------------------------- /examples/sap_nw_ha_simple/README.md: -------------------------------------------------------------------------------- 1 | # SAP NW HA example 2 | 3 | This example illustrates how to use the latest release of the terraform module for SAP on Google Cloud for provisioning SAP NetWeaver High-availability. 4 | 5 | 6 | ## Inputs 7 | 8 | | Name | Description | Type | Default | Required | 9 | |------|-------------|------|---------|:--------:| 10 | | project\_id | Project id where the instances will be created. | `string` | n/a | yes | 11 | 12 | ## Outputs 13 | 14 | | Name | Description | 15 | |------|-------------| 16 | | sap\_nw\_ers\_worker\_self\_links | SAP NW ERS self-links for the instance created | 17 | | sap\_nw\_scs\_primary\_self\_link | SAP NW SCS self-link for the instance created | 18 | 19 | 20 | 21 | To provision this example, run the following from within this directory: 22 | - `terraform init` to get the plugins 23 | - `terraform plan` to see the infrastructure plan 24 | - `terraform apply` to apply the infrastructure build 25 | - `terraform destroy` to destroy the built infrastructure 26 | -------------------------------------------------------------------------------- /examples/sap_s4_ha_simple/main.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | module "sap_s4_ha" { 18 | source = "terraform-google-modules/sap/google//modules/s4_ha" 19 | version = "~> 1.0" 20 | 21 | deployment_name = "my_s4_ha" 22 | gcp_project_id = var.project_id 23 | filestore_location = "us-east1-b" 24 | region_name = "us-east1" 25 | media_bucket_name = "private-bucket" 26 | zone1_name = "us-east1-b" 27 | zone2_name = "us-east1-c" 28 | } 29 | 30 | -------------------------------------------------------------------------------- /examples/sap_hana_simple/main.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | module "sap_hana" { 18 | source = "terraform-google-modules/sap/google//modules/sap_hana" 19 | version = "~> 1.0" 20 | 21 | project_id = var.project_id 22 | machine_type = "n1-standard-16" 23 | subnetwork = "default" 24 | linux_image = "rhel-8-4-sap-ha" 25 | linux_image_project = "rhel-sap-cloud" 26 | instance_name = "hana-instance" 27 | zone = "us-east1-b" 28 | sap_hana_sid = "XYZ" 29 | } 30 | -------------------------------------------------------------------------------- /modules/s4/configuration_optional_buckets.tf: -------------------------------------------------------------------------------- 1 | # Copyright 2024 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | resource "google_storage_bucket" "configuration" { 16 | count = var.configuration_bucket_name == "" ? 1 : 0 17 | force_destroy = true 18 | location = "US" 19 | name = "${var.gcp_project_id}-${var.deployment_name}-configuration" 20 | project = data.google_project.sap-project.project_id 21 | storage_class = "MULTI_REGIONAL" 22 | uniform_bucket_level_access = true 23 | } 24 | -------------------------------------------------------------------------------- /modules/s4_ha/configuration_optional_buckets.tf: -------------------------------------------------------------------------------- 1 | # Copyright 2024 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | resource "google_storage_bucket" "configuration" { 16 | count = var.configuration_bucket_name == "" ? 1 : 0 17 | force_destroy = true 18 | location = "US" 19 | name = "${var.gcp_project_id}-${var.deployment_name}-configuration" 20 | project = data.google_project.sap-project.project_id 21 | storage_class = "MULTI_REGIONAL" 22 | uniform_bucket_level_access = true 23 | } 24 | -------------------------------------------------------------------------------- /test/integration/discover_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package test 16 | 17 | import ( 18 | // should be imported to enable testing for GO modules 19 | "testing" 20 | 21 | // should be imported to use terraform helpers in blueprints test framework 22 | "github.com/GoogleCloudPlatform/cloud-foundation-toolkit/infra/blueprint-test/pkg/tft" 23 | ) 24 | 25 | // entry function for the test; can be named as Test* 26 | func TestAll(t *testing.T) { 27 | // the helper to autodiscover and test blueprint examples 28 | tft.AutoDiscoverAndTest(t) 29 | } 30 | -------------------------------------------------------------------------------- /modules/sap_db2/utility/README.md: -------------------------------------------------------------------------------- 1 | # GCP Virtual IP extension 2 | 3 | Please refer to 4 | https://cloud.google.com/solutions/sap/docs/sap-ibm-db2-ha-deployment-guide for 5 | the primary documentation. 6 | 7 | Two versions of the helper script for managing a virtual IP in the context of 8 | IBM Tivoli System Automation for Multi-Platforms: 9 | * gcp_floating_ip.sh - legacy script that provides basic route or alias IP 10 | based floating IP support in conjunction with HADR configurations with Db2 on 11 | Linux in a standard VPC. 12 | * gcp_floating_ip_svpc.sh - updated version of legacy script that provides 13 | route or alias IP based floating IP support in conjunction with HADR 14 | configurations with Db2 on Linux in a Shared VPC configuration on Google 15 | Cloud. 16 | 17 | For Db2 version 11.5.8 or later, customers should instead use IBM's provided 18 | integrated Pacemaker solution for Db2. 19 | 20 | ## Changelog 21 | 22 | 10MAY2024: Relocate legacy files. Add version of helper script that also 23 | supports a Shared VPC configuration 24 | 25OCT2019: Add additional logging options with inclusion and checking if eth0 25 | alias assignment already exists to avoid RTNETLINK File exists warning. 26 | -------------------------------------------------------------------------------- /examples/sap_hana_scaleout_simple/README.md: -------------------------------------------------------------------------------- 1 | # SAP HANA Scaleout example 2 | 3 | This example illustrates how to use the latest release of the terraform module for SAP on Google Cloud 4 | for provisioning SAP HANA with scaleout 5 | 6 | 7 | ## Inputs 8 | 9 | | Name | Description | Type | Default | Required | 10 | |------|-------------|------|---------|:--------:| 11 | | project\_id | Project id where the instances will be created. | `string` | n/a | yes | 12 | 13 | ## Outputs 14 | 15 | | Name | Description | 16 | |------|-------------| 17 | | hana\_scaleout\_standby\_self\_links | List of self-links for the hana scaleout standby workers created | 18 | | hana\_scaleout\_worker\_self\_links | List of self-links for the hana scaleout workers created | 19 | | sap\_hana\_primary\_self\_link | Self-link for the primary SAP HANA Scalout instance created. | 20 | 21 | 22 | 23 | To provision this example, run the following from within this directory: 24 | - `terraform init` to get the plugins 25 | - `terraform plan` to see the infrastructure plan 26 | - `terraform apply` to apply the infrastructure build 27 | - `terraform destroy` to destroy the built infrastructure 28 | -------------------------------------------------------------------------------- /examples/sap_hana_scaleout_simple/main.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | module "hana_scaleout" { 18 | source = "terraform-google-modules/sap/google//modules/sap_hana_scaleout" 19 | version = "~> 1.0" 20 | 21 | project_id = var.project_id 22 | zone = "us-east1-b" 23 | machine_type = "n1-standard-16" 24 | subnetwork = "default" 25 | linux_image = "rhel-8-4-sap-ha" 26 | linux_image_project = "rhel-sap-cloud" 27 | instance_name = "hana-instance-scaleout" 28 | sap_hana_sid = "ABC" 29 | sap_hana_shared_nfs = "10.128.0.100:/shared" 30 | sap_hana_backup_nfs = "10.128.0.101:/backup" 31 | } 32 | -------------------------------------------------------------------------------- /examples/sap_hana_ha_simple/README.md: -------------------------------------------------------------------------------- 1 | # SAP HANA HA example 2 | 3 | This example illustrates how to use the latest release of the terraform module for SAP on Google Cloud 4 | for provisioning SAP HANA with HA 5 | 6 | 7 | ## Inputs 8 | 9 | | Name | Description | Type | Default | Required | 10 | |------|-------------|------|---------|:--------:| 11 | | project\_id | Project id where the instances will be created. | `string` | n/a | yes | 12 | 13 | ## Outputs 14 | 15 | | Name | Description | 16 | |------|-------------| 17 | | sap\_hana\_ha\_firewall\_link | Link to the optional fire wall | 18 | | sap\_hana\_ha\_loadbalander\_link | Link to the optional load balancer | 19 | | sap\_hana\_ha\_primary\_instance\_self\_link | Self-link for the primary SAP HANA HA instance created. | 20 | | sap\_hana\_ha\_secondary\_instance\_self\_link | Self-link for the secondary SAP HANA HA instance created. | 21 | 22 | 23 | 24 | To provision this example, run the following from within this directory: 25 | - `terraform init` to get the plugins 26 | - `terraform plan` to see the infrastructure plan 27 | - `terraform apply` to apply the infrastructure build 28 | - `terraform destroy` to destroy the built infrastructure 29 | -------------------------------------------------------------------------------- /examples/sap_hana_ha_simple/main.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | module "sap_hana_ha" { 18 | source = "terraform-google-modules/sap/google//modules/sap_hana_ha" 19 | version = "~> 1.0" 20 | 21 | project_id = var.project_id 22 | machine_type = "n1-standard-16" 23 | network = "default" 24 | subnetwork = "default" 25 | linux_image = "rhel-8-4-sap-ha" 26 | linux_image_project = "rhel-sap-cloud" 27 | primary_instance_name = "hana-ha-primary" 28 | primary_zone = "us-east1-b" 29 | secondary_instance_name = "hana-ha-secondary" 30 | secondary_zone = "us-east1-c" 31 | } 32 | -------------------------------------------------------------------------------- /examples/sap_hana_scaleout_simple/outputs.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | output "sap_hana_primary_self_link" { 17 | description = "Self-link for the primary SAP HANA Scalout instance created." 18 | value = module.hana_scaleout.sap_hana_primary_self_link 19 | } 20 | 21 | output "hana_scaleout_worker_self_links" { 22 | description = "List of self-links for the hana scaleout workers created" 23 | value = module.hana_scaleout.hana_scaleout_worker_self_links 24 | } 25 | 26 | output "hana_scaleout_standby_self_links" { 27 | description = "List of self-links for the hana scaleout standby workers created" 28 | value = module.hana_scaleout.hana_scaleout_standby_self_links 29 | } 30 | -------------------------------------------------------------------------------- /test/setup/iam.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | locals { 18 | int_required_roles = [ 19 | "roles/owner" 20 | ] 21 | } 22 | 23 | resource "google_service_account" "int_test" { 24 | project = module.project.project_id 25 | account_id = "ci-account" 26 | display_name = "ci-account" 27 | } 28 | 29 | resource "google_project_iam_member" "int_test" { 30 | count = length(local.int_required_roles) 31 | 32 | project = module.project.project_id 33 | role = local.int_required_roles[count.index] 34 | member = "serviceAccount:${google_service_account.int_test.email}" 35 | } 36 | 37 | resource "google_service_account_key" "int_test" { 38 | service_account_id = google_service_account.int_test.id 39 | } 40 | -------------------------------------------------------------------------------- /modules/sap_hana_scaleout/outputs.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | output "sap_hana_primary_self_link" { 17 | description = "Self-link for the primary SAP HANA Scalout instance created." 18 | value = google_compute_instance.sap_hana_scaleout_primary_instance.self_link 19 | } 20 | output "hana_scaleout_worker_self_links" { 21 | description = "List of self-links for the hana scaleout workers created" 22 | value = google_compute_instance.sap_hana_scaleout_worker_instances[*].self_link 23 | } 24 | output "hana_scaleout_standby_self_links" { 25 | description = "List of self-links for the hana scaleout standbys created" 26 | value = google_compute_instance.sap_hana_scaleout_standby_instances[*].self_link 27 | } 28 | -------------------------------------------------------------------------------- /examples/sap_hana_ha_simple/outputs.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | output "sap_hana_ha_primary_instance_self_link" { 17 | description = "Self-link for the primary SAP HANA HA instance created." 18 | value = module.sap_hana_ha.sap_hana_ha_primary_instance_self_link 19 | } 20 | output "sap_hana_ha_secondary_instance_self_link" { 21 | description = "Self-link for the secondary SAP HANA HA instance created." 22 | value = module.sap_hana_ha.sap_hana_ha_secondary_instance_self_link 23 | } 24 | output "sap_hana_ha_loadbalander_link" { 25 | description = "Link to the optional load balancer" 26 | value = module.sap_hana_ha.sap_hana_ha_loadbalander_link 27 | } 28 | output "sap_hana_ha_firewall_link" { 29 | description = "Link to the optional fire wall" 30 | value = module.sap_hana_ha.sap_hana_ha_firewall_link 31 | } 32 | -------------------------------------------------------------------------------- /test/integration/common/common.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package common 16 | 17 | import "strings" 18 | 19 | func GetInstanceNameAndZone(insSelfLink string) (string, string) { 20 | instanceMd := insSelfLink[strings.LastIndex(insSelfLink, "zones/")+6:] 21 | instanceMdList := strings.Split(instanceMd, "/") 22 | 23 | return instanceMdList[0], instanceMdList[2] 24 | } 25 | 26 | func GetInstanceMachineType(machineTypeLink string) string { 27 | machineType := machineTypeLink[strings.LastIndex(machineTypeLink, "/")+1:] 28 | return machineType 29 | } 30 | 31 | func GetInstanceNetworkName(networkLink string) string { 32 | networkName := networkLink[strings.LastIndex(networkLink, "/")+1:] 33 | return networkName 34 | } 35 | 36 | func GetInstanceSubnetNameAndRegion(subnetLink string) (string, string) { 37 | subnetMd := subnetLink[strings.LastIndex(subnetLink, "regions/")+8:] 38 | subnetMdList := strings.Split(subnetMd, "/") 39 | 40 | return subnetMdList[0], subnetMdList[2] 41 | } 42 | -------------------------------------------------------------------------------- /test/setup/main.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | module "project" { 18 | source = "terraform-google-modules/project-factory/google" 19 | version = "~> 18.0" 20 | 21 | name = "ci-sap" 22 | random_project_id = "true" 23 | org_id = var.org_id 24 | folder_id = var.folder_id 25 | billing_account = var.billing_account 26 | 27 | activate_apis = [ 28 | "cloudresourcemanager.googleapis.com", 29 | "storage-api.googleapis.com", 30 | "serviceusage.googleapis.com", 31 | "compute.googleapis.com", 32 | ] 33 | } 34 | 35 | module "vpc" { 36 | source = "terraform-google-modules/network/google" 37 | version = "~> 10.0" 38 | 39 | project_id = module.project.project_id 40 | network_name = "default" 41 | delete_default_internet_gateway_routes = true 42 | 43 | subnets = [ 44 | { 45 | subnet_name = "default" 46 | subnet_ip = "10.128.0.0/20" 47 | subnet_region = "us-east1" 48 | }, 49 | ] 50 | } 51 | -------------------------------------------------------------------------------- /metadata.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2022 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | apiVersion: blueprints.cloud.google.com/v1alpha1 16 | kind: BlueprintMetadata 17 | metadata: 18 | name: terraform-google-sap 19 | annotations: 20 | config.kubernetes.io/local-config: "true" 21 | spec: 22 | title: terraform-google-sap 23 | source: 24 | repo: https://github.com/terraform-google-modules/terraform-google-sap.git 25 | sourceType: git 26 | subBlueprints: 27 | - name: sap_hana 28 | location: modules/sap_hana 29 | - name: sap_hana_ha 30 | location: modules/sap_hana_ha 31 | - name: sap_hana_scaleout 32 | location: modules/sap_hana_scaleout 33 | examples: 34 | - name: sap_hana_ha_simple 35 | location: examples/sap_hana_ha_simple 36 | - name: sap_hana_scaleout_simple 37 | location: examples/sap_hana_scaleout_simple 38 | - name: sap_hana_simple 39 | location: examples/sap_hana_simple 40 | roles: 41 | - level: Project 42 | roles: 43 | - roles/owner 44 | services: 45 | - cloudresourcemanager.googleapis.com 46 | - storage-api.googleapis.com 47 | - serviceusage.googleapis.com 48 | - compute.googleapis.com 49 | -------------------------------------------------------------------------------- /.github/workflows/stale.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2022-2025 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # NOTE: This file is automatically generated from: 16 | # https://github.com/GoogleCloudPlatform/cloud-foundation-toolkit/blob/main/infra/terraform/test-org/github 17 | 18 | name: "Close stale issues" 19 | on: 20 | schedule: 21 | - cron: "0 23 * * *" 22 | 23 | permissions: 24 | contents: read 25 | issues: write 26 | pull-requests: write 27 | actions: write 28 | 29 | jobs: 30 | stale: 31 | if: github.repository_owner == 'GoogleCloudPlatform' || github.repository_owner == 'terraform-google-modules' 32 | runs-on: ubuntu-latest 33 | steps: 34 | - uses: actions/stale@v10 35 | with: 36 | repo-token: ${{ secrets.GITHUB_TOKEN }} 37 | stale-issue-message: 'This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 7 days' 38 | stale-pr-message: 'This PR is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 7 days' 39 | exempt-issue-labels: 'triaged' 40 | exempt-pr-labels: 'dependencies,autorelease: pending' 41 | operations-per-run: 100 42 | -------------------------------------------------------------------------------- /examples/sap_nw_ha_simple/main.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | module "sap_nw_ha" { 18 | source = "terraform-google-modules/sap/google//modules/sap_nw_ha" 19 | version = "~> 1.0" 20 | 21 | project_id = var.project_id 22 | machine_type = "n1-standard-16" 23 | network = "default" 24 | subnetwork = "default" 25 | linux_image = "rhel-8-4-sap-ha" 26 | linux_image_project = "rhel-sap-cloud" 27 | sap_primary_instance = "hana-instance" 28 | sap_secondary_instance = "hana-instance" 29 | sap_primary_zone = "us-east1-b" 30 | sap_secondary_zone = "us-east1-c" 31 | sap_sid = "XYZ" 32 | nfs_path = "${google_filestore_instance.example.networks[0].ip_addresses[0]}:/${google_filestore_instance.example.file_shares[0].name}" 33 | } 34 | 35 | resource "google_filestore_instance" "example" { 36 | name = "example-instance" 37 | location = "us-central1-b" 38 | tier = "BASIC_HDD" 39 | 40 | file_shares { 41 | capacity_gb = 1024 42 | name = "share1" 43 | } 44 | 45 | networks { 46 | network = "default" 47 | modes = ["MODE_IPV4"] 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /modules/sap_nw_ha/outputs.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | output "scs_instance" { 17 | description = "SCS instance" 18 | value = google_compute_instance.scs_instance.self_link 19 | } 20 | output "ers_instance" { 21 | description = "ERS instance" 22 | value = google_compute_instance.ers_instance.self_link 23 | } 24 | output "nw_vips" { 25 | description = "NW virtual IPs" 26 | value = google_compute_address.nw_vips[*].self_link 27 | } 28 | output "nw_instance_groups" { 29 | description = "NW Instance Groups" 30 | value = google_compute_instance_group.nw_instance_groups[*].self_link 31 | } 32 | output "nw_hc" { 33 | description = "Health Checks" 34 | value = google_compute_health_check.nw_hc[*].self_link 35 | } 36 | output "nw_hc_firewall" { 37 | description = "Firewall rule for the Health Checks" 38 | value = google_compute_firewall.nw_hc_firewall_rule[*].self_link 39 | } 40 | output "nw_regional_backend_services" { 41 | description = "Backend Services" 42 | value = google_compute_region_backend_service.nw_regional_backend_services[*].self_link 43 | } 44 | output "nw_forwarding_rules" { 45 | description = "Forwarding rules" 46 | value = google_compute_forwarding_rule.nw_forwarding_rules[*].self_link 47 | } 48 | -------------------------------------------------------------------------------- /modules/sap_hana_ha/outputs.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | output "sap_hana_ha_primary_instance_self_link" { 17 | description = "Self-link for the primary SAP HANA HA instance created." 18 | value = google_compute_instance.sap_hana_ha_primary_instance.self_link 19 | } 20 | output "sap_hana_ha_primary_worker_self_links" { 21 | description = "Self-link for the worker nodes in the primary SAP HANA HA instance." 22 | value = google_compute_instance.sap_hana_ha_primary_workers[*].self_link 23 | } 24 | output "sap_hana_ha_secondary_instance_self_link" { 25 | description = "Self-link for the secondary SAP HANA HA instance created." 26 | value = google_compute_instance.sap_hana_ha_secondary_instance.self_link 27 | } 28 | output "sap_hana_ha_secondary_worker_self_links" { 29 | description = "Self-link for the worker nodes in the secondary SAP HANA HA instance." 30 | value = google_compute_instance.sap_hana_ha_secondary_workers[*].self_link 31 | } 32 | output "sap_hana_ha_loadbalander_link" { 33 | description = "Link to the optional load balancer" 34 | value = google_compute_region_backend_service.sap_hana_ha_loadbalancer[*].self_link 35 | } 36 | output "sap_hana_ha_firewall_link" { 37 | description = "Link to the optional fire wall" 38 | value = google_compute_firewall.sap_hana_ha_vpc_firewall[*].self_link 39 | } 40 | -------------------------------------------------------------------------------- /test/integration/sap_hana_simple/sap_hana_simple_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package sap_hana_simple 16 | 17 | import ( 18 | "fmt" 19 | "testing" 20 | 21 | "github.com/GoogleCloudPlatform/cloud-foundation-toolkit/infra/blueprint-test/pkg/gcloud" 22 | "github.com/GoogleCloudPlatform/cloud-foundation-toolkit/infra/blueprint-test/pkg/tft" 23 | "github.com/stretchr/testify/assert" 24 | "github.com/terraform-google-modules/terraform-google-sap/test/integration/common" 25 | ) 26 | 27 | func TestSapHanaSimpleModule(t *testing.T) { 28 | sapHana := tft.NewTFBlueprintTest(t) 29 | 30 | sapHana.DefineVerify(func(assert *assert.Assertions) { 31 | sapHana.DefaultVerify(assert) 32 | 33 | instanceSelfLinks := make(map[string]string) 34 | instanceSelfLinks["primary"] = sapHana.GetStringOutput("sap_hana_primary_self_link") 35 | 36 | // assert instance configurations 37 | for insType, insSelfLink := range instanceSelfLinks { 38 | zone, name := common.GetInstanceNameAndZone(insSelfLink) 39 | op := gcloud.Runf(t, "compute instances describe %s --zone %s --project %s", name, zone, sapHana.GetTFSetupStringOutput("project_id")) 40 | assert.Equal("n1-standard-16", common.GetInstanceMachineType(op.Get("machineType").String()), fmt.Sprintf("%s machine type set as n1-highmem-32", insType)) 41 | insNetworkInterface := op.Get("networkInterfaces").Array()[0] 42 | assert.Equal("default", common.GetInstanceNetworkName(insNetworkInterface.Get("network").String()), fmt.Sprintf("%s instance connected to default network", insType)) 43 | subnetRegion, subnetName := common.GetInstanceSubnetNameAndRegion(insNetworkInterface.Get("subnetwork").String()) 44 | assert.Equal("default | us-east1", subnetName+" | "+subnetRegion, fmt.Sprintf("%s instance connected to default subnet in the us-east1 region", insType)) 45 | } 46 | }) 47 | 48 | sapHana.Test() 49 | } 50 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # terraform-google-sap 2 | 3 | This module is a collection of multiple opinionated submodules to deploy SAP Products. 4 | Below is the list of available submodules: 5 | 6 | - [SAP HANA](./modules/sap_hana/README.md) 7 | - [SAP HANA HA](./modules/sap_hana_ha/README.md) 8 | - [SAP HANA Scaleout](./modules/sap_hana_scaleout/README.md) 9 | - [SAP NW](./modules/sap_nw/README.md) 10 | - [SAP NW HA](./modules/sap_nw_ha/README.md) 11 | - [SAP S4](./modules/s4/README.md) 12 | - [SAP S4 HA](./modules/s4_ha/README.md) 13 | 14 | ## Usage 15 | 16 | Each submodules have their own usage documented in the [modules](./modules) folder. 17 | For example, see the [SAP HANA Usage Section](./modules/sap_hana/README.md#Usage). 18 | 19 | Functional examples are included in the 20 | [examples](./examples/) directory. 21 | 22 | [^]: (autogen_docs_start) 23 | 24 | [^]: (autogen_docs_end) 25 | 26 | ## Requirements 27 | 28 | These sections describe requirements for using this module. 29 | 30 | ### Software 31 | 32 | The following dependencies must be available: 33 | 34 | - [Terraform][terraform] v0.12.6 35 | - [Terraform Provider for GCP][terraform-provider-gcp] plugin v4.0.0 36 | 37 | ### Service Account 38 | 39 | A service account with the following roles must be used to provision 40 | the resources of each submodule: 41 | 42 | - Compute Admin: `roles/compute.admin` 43 | 44 | Please refer to the documentation of specific submodules located in the [modules](./modules/) folder for additional requirements for the service account. 45 | 46 | The [Project Factory module][project-factory-module] and the 47 | [IAM module][iam-module] may be used in combination to provision a 48 | service account with the necessary roles applied. 49 | 50 | ### APIs 51 | 52 | A project with the following APIs enabled must be used to host the 53 | resources of this module: 54 | 55 | - Compute Engine API: `compute.googleapis.com` 56 | 57 | The [Project Factory module][project-factory-module] can be used to 58 | provision a project with the necessary APIs enabled. 59 | 60 | ## Contributing 61 | 62 | We are not accepting contributions at this time. 63 | 64 | 65 | [iam-module]: https://registry.terraform.io/modules/terraform-google-modules/iam/google 66 | [project-factory-module]: https://registry.terraform.io/modules/terraform-google-modules/project-factory/google 67 | [terraform-provider-gcp]: https://www.terraform.io/docs/providers/google/index.html 68 | [terraform]: https://www.terraform.io/downloads.html 69 | -------------------------------------------------------------------------------- /modules/s4/apis.tf: -------------------------------------------------------------------------------- 1 | # Copyright 2024 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | resource "google_project_service" "service_cloudresourcemanager_googleapis_com" { 16 | disable_on_destroy = false 17 | project = data.google_project.sap-project.project_id 18 | service = "cloudresourcemanager.googleapis.com" 19 | } 20 | 21 | resource "google_project_service" "service_compute_googleapis_com" { 22 | disable_on_destroy = false 23 | project = data.google_project.sap-project.project_id 24 | service = "compute.googleapis.com" 25 | } 26 | 27 | resource "google_project_service" "service_dns_googleapis_com" { 28 | disable_on_destroy = false 29 | project = data.google_project.sap-project.project_id 30 | service = "dns.googleapis.com" 31 | } 32 | 33 | resource "google_project_service" "service_file_googleapis_com" { 34 | disable_on_destroy = false 35 | project = data.google_project.sap-project.project_id 36 | service = "file.googleapis.com" 37 | } 38 | 39 | resource "google_project_service" "service_iam_googleapis_com" { 40 | disable_on_destroy = false 41 | project = data.google_project.sap-project.project_id 42 | service = "iam.googleapis.com" 43 | } 44 | 45 | resource "google_project_service" "service_iamcredentials_googleapis_com" { 46 | disable_on_destroy = false 47 | project = data.google_project.sap-project.project_id 48 | service = "iamcredentials.googleapis.com" 49 | } 50 | 51 | resource "google_project_service" "service_secretmanager_googleapis_com" { 52 | disable_on_destroy = false 53 | project = data.google_project.sap-project.project_id 54 | service = "secretmanager.googleapis.com" 55 | } 56 | 57 | resource "google_project_service" "service_serviceusage_googleapis_com" { 58 | disable_on_destroy = false 59 | project = data.google_project.sap-project.project_id 60 | service = "serviceusage.googleapis.com" 61 | } 62 | -------------------------------------------------------------------------------- /modules/s4_ha/apis.tf: -------------------------------------------------------------------------------- 1 | # Copyright 2024 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | resource "google_project_service" "service_cloudresourcemanager_googleapis_com" { 16 | disable_on_destroy = false 17 | project = data.google_project.sap-project.project_id 18 | service = "cloudresourcemanager.googleapis.com" 19 | } 20 | 21 | resource "google_project_service" "service_compute_googleapis_com" { 22 | disable_on_destroy = false 23 | project = data.google_project.sap-project.project_id 24 | service = "compute.googleapis.com" 25 | } 26 | 27 | resource "google_project_service" "service_dns_googleapis_com" { 28 | disable_on_destroy = false 29 | project = data.google_project.sap-project.project_id 30 | service = "dns.googleapis.com" 31 | } 32 | 33 | resource "google_project_service" "service_file_googleapis_com" { 34 | disable_on_destroy = false 35 | project = data.google_project.sap-project.project_id 36 | service = "file.googleapis.com" 37 | } 38 | 39 | resource "google_project_service" "service_iam_googleapis_com" { 40 | disable_on_destroy = false 41 | project = data.google_project.sap-project.project_id 42 | service = "iam.googleapis.com" 43 | } 44 | 45 | resource "google_project_service" "service_iamcredentials_googleapis_com" { 46 | disable_on_destroy = false 47 | project = data.google_project.sap-project.project_id 48 | service = "iamcredentials.googleapis.com" 49 | } 50 | 51 | resource "google_project_service" "service_secretmanager_googleapis_com" { 52 | disable_on_destroy = false 53 | project = data.google_project.sap-project.project_id 54 | service = "secretmanager.googleapis.com" 55 | } 56 | 57 | resource "google_project_service" "service_serviceusage_googleapis_com" { 58 | disable_on_destroy = false 59 | project = data.google_project.sap-project.project_id 60 | service = "serviceusage.googleapis.com" 61 | } 62 | -------------------------------------------------------------------------------- /test/integration/sap_hana_ha_simple/sap_hana_ha_simple_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package sap_hana_ha_simple 16 | 17 | import ( 18 | "fmt" 19 | "testing" 20 | 21 | "github.com/GoogleCloudPlatform/cloud-foundation-toolkit/infra/blueprint-test/pkg/gcloud" 22 | "github.com/GoogleCloudPlatform/cloud-foundation-toolkit/infra/blueprint-test/pkg/tft" 23 | "github.com/stretchr/testify/assert" 24 | "github.com/terraform-google-modules/terraform-google-sap/test/integration/common" 25 | ) 26 | 27 | func TestSapHanaHaSimpleModule(t *testing.T) { 28 | sapHanaHa := tft.NewTFBlueprintTest(t) 29 | 30 | sapHanaHa.DefineVerify(func(assert *assert.Assertions) { 31 | sapHanaHa.DefaultVerify(assert) 32 | 33 | instanceSelfLinks := make(map[string]string) 34 | instanceSelfLinks["primary"] = sapHanaHa.GetStringOutput("sap_hana_ha_primary_instance_self_link") 35 | instanceSelfLinks["secondary"] = sapHanaHa.GetStringOutput("sap_hana_ha_secondary_instance_self_link") 36 | 37 | // assert instance configurations 38 | for insType, insSelfLink := range instanceSelfLinks { 39 | zone, name := common.GetInstanceNameAndZone(insSelfLink) 40 | op := gcloud.Runf(t, "compute instances describe %s --zone %s --project %s", name, zone, sapHanaHa.GetTFSetupStringOutput("project_id")) 41 | assert.Equal("n1-standard-16", common.GetInstanceMachineType(op.Get("machineType").String()), fmt.Sprintf("%s machine type set as n1-highmem-32", insType)) 42 | insNetworkInterface := op.Get("networkInterfaces").Array()[0] 43 | assert.Equal("default", common.GetInstanceNetworkName(insNetworkInterface.Get("network").String()), fmt.Sprintf("%s instance connected to default network", insType)) 44 | subnetRegion, subnetName := common.GetInstanceSubnetNameAndRegion(insNetworkInterface.Get("subnetwork").String()) 45 | assert.Equal("default | us-east1", subnetName+" | "+subnetRegion, fmt.Sprintf("%s instance connected to default subnet in the us-east1 region", insType)) 46 | } 47 | }) 48 | 49 | sapHanaHa.Test() 50 | } 51 | -------------------------------------------------------------------------------- /.github/workflows/lint.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2025 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # NOTE: This file is automatically generated from values at: 16 | # https://github.com/GoogleCloudPlatform/cloud-foundation-toolkit/blob/main/infra/terraform/test-org/org/locals.tf 17 | 18 | name: 'lint' 19 | 20 | on: 21 | workflow_dispatch: 22 | pull_request: 23 | types: [opened, edited, reopened, synchronize] 24 | branches: [main] 25 | 26 | permissions: 27 | contents: read 28 | 29 | concurrency: 30 | group: '${{ github.workflow }}-${{ github.head_ref || github.ref }}' 31 | cancel-in-progress: true 32 | 33 | jobs: 34 | lint: 35 | name: 'lint' 36 | runs-on: 'ubuntu-latest' 37 | steps: 38 | - uses: 'actions/checkout@v6' 39 | - id: variables 40 | run: | 41 | MAKEFILE=$(find . -name Makefile -print -quit) 42 | if [ -z "$MAKEFILE" ]; then 43 | echo dev-tools=gcr.io/cloud-foundation-cicd/cft/developer-tools:1 >> "$GITHUB_OUTPUT" 44 | else 45 | VERSION=$(grep "DOCKER_TAG_VERSION_DEVELOPER_TOOLS := " $MAKEFILE | cut -d\ -f3) 46 | IMAGE=$(grep "DOCKER_IMAGE_DEVELOPER_TOOLS := " $MAKEFILE | cut -d\ -f3) 47 | REGISTRY=$(grep "REGISTRY_URL := " $MAKEFILE | cut -d\ -f3) 48 | echo dev-tools=${REGISTRY}/${IMAGE}:${VERSION} >> "$GITHUB_OUTPUT" 49 | fi 50 | - run: docker run --rm -v ${{ github.workspace }}:/workspace ${{ steps.variables.outputs.dev-tools }} module-swapper 51 | - run: docker run --rm -v ${{ github.workspace }}:/workspace ${{ steps.variables.outputs.dev-tools }} /usr/local/bin/test_lint.sh 52 | commitlint: 53 | runs-on: ubuntu-latest 54 | steps: 55 | - uses: actions/checkout@v6 56 | with: 57 | fetch-depth: 0 58 | - name: Setup node 59 | uses: actions/setup-node@v6 60 | with: 61 | node-version: lts/* 62 | - name: Install commitlint 63 | run: | 64 | npm install -D @commitlint/cli@20.2.0 @commitlint/config-conventional@20.2.0 65 | echo "module.exports = { extends: ['@commitlint/config-conventional'], rules: {'subject-case': [0], 'header-max-length': [0]} };" > commitlint.config.js 66 | npx commitlint --version 67 | - name: Validate PR commits with commitlint 68 | if: github.event_name == 'pull_request' 69 | env: 70 | TITLE: ${{ github.event.pull_request.title }} 71 | run: 'echo "$TITLE" | npx commitlint --verbose' 72 | -------------------------------------------------------------------------------- /test/integration/sap_hana_scaleout_simple/sap_hana_scaleout_simple_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package sap_hana_scaleout 16 | 17 | import ( 18 | "fmt" 19 | "strings" 20 | "testing" 21 | 22 | "github.com/GoogleCloudPlatform/cloud-foundation-toolkit/infra/blueprint-test/pkg/gcloud" 23 | "github.com/GoogleCloudPlatform/cloud-foundation-toolkit/infra/blueprint-test/pkg/tft" 24 | "github.com/gruntwork-io/terratest/modules/terraform" 25 | "github.com/stretchr/testify/assert" 26 | "github.com/terraform-google-modules/terraform-google-sap/test/integration/common" 27 | ) 28 | 29 | func TestSapHanaScaleoutModule(t *testing.T) { 30 | sapHanaSc := tft.NewTFBlueprintTest(t) 31 | 32 | sapHanaSc.DefineVerify(func(assert *assert.Assertions) { 33 | sapHanaSc.DefaultVerify(assert) 34 | 35 | instanceSelfLinks := make(map[string]string) 36 | instanceSelfLinks["primary"] = sapHanaSc.GetStringOutput("sap_hana_primary_self_link") 37 | workers := terraform.OutputList(t, sapHanaSc.GetTFOptions(), "hana_scaleout_worker_self_links") 38 | for i, workerLink := range workers { 39 | instanceSelfLinks[fmt.Sprintf("worker-%d", i)] = workerLink 40 | } 41 | 42 | standyListRaw := sapHanaSc.GetStringOutput("hana_scaleout_standby_self_links") 43 | standbys := strings.Split(strings.Trim(standyListRaw, "[]"), ",") 44 | for i, standbyLink := range standbys { 45 | instanceSelfLinks[fmt.Sprintf("standby-%d", i)] = standbyLink 46 | } 47 | 48 | // assert instance configurations 49 | for insType, insSelfLink := range instanceSelfLinks { 50 | zone, name := common.GetInstanceNameAndZone(insSelfLink) 51 | op := gcloud.Runf(t, "compute instances describe %s --zone %s --project %s", name, zone, sapHanaSc.GetTFSetupStringOutput("project_id")) 52 | assert.Equal("n1-standard-16", common.GetInstanceMachineType(op.Get("machineType").String()), fmt.Sprintf("%s machine type set as n1-highmem-32", insType)) 53 | insNetworkInterface := op.Get("networkInterfaces").Array()[0] 54 | assert.Equal("default", common.GetInstanceNetworkName(insNetworkInterface.Get("network").String()), fmt.Sprintf("%s instance connected to default network", insType)) 55 | subnetRegion, subnetName := common.GetInstanceSubnetNameAndRegion(insNetworkInterface.Get("subnetwork").String()) 56 | assert.Equal("default | us-east1", subnetName+" | "+subnetRegion, fmt.Sprintf("%s instance connected to default subnet in the us-east1 region", insType)) 57 | } 58 | }) 59 | 60 | sapHanaSc.Test() 61 | } 62 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Please note that this file was generated from [terraform-google-module-template](https://github.com/terraform-google-modules/terraform-google-module-template). 16 | # Please make sure to contribute relevant changes upstream! 17 | 18 | # Make will use bash instead of sh 19 | SHELL := /usr/bin/env bash 20 | 21 | DOCKER_TAG_VERSION_DEVELOPER_TOOLS := 1.22 22 | DOCKER_IMAGE_DEVELOPER_TOOLS := cft/developer-tools 23 | REGISTRY_URL := gcr.io/cloud-foundation-cicd 24 | 25 | # Enter docker container for local development 26 | .PHONY: docker_run 27 | docker_run: 28 | docker run --rm -it \ 29 | -e SERVICE_ACCOUNT_JSON \ 30 | -v "$(CURDIR)":/workspace \ 31 | $(REGISTRY_URL)/${DOCKER_IMAGE_DEVELOPER_TOOLS}:${DOCKER_TAG_VERSION_DEVELOPER_TOOLS} \ 32 | /bin/bash 33 | 34 | # Execute prepare tests within the docker container 35 | .PHONY: docker_test_prepare 36 | docker_test_prepare: 37 | docker run --rm -it \ 38 | -e SERVICE_ACCOUNT_JSON \ 39 | -e TF_VAR_org_id \ 40 | -e TF_VAR_folder_id \ 41 | -e TF_VAR_billing_account \ 42 | -v "$(CURDIR)":/workspace \ 43 | $(REGISTRY_URL)/${DOCKER_IMAGE_DEVELOPER_TOOLS}:${DOCKER_TAG_VERSION_DEVELOPER_TOOLS} \ 44 | /usr/local/bin/execute_with_credentials.sh prepare_environment 45 | 46 | # Clean up test environment within the docker container 47 | .PHONY: docker_test_cleanup 48 | docker_test_cleanup: 49 | docker run --rm -it \ 50 | -e SERVICE_ACCOUNT_JSON \ 51 | -e TF_VAR_org_id \ 52 | -e TF_VAR_folder_id \ 53 | -e TF_VAR_billing_account \ 54 | -v "$(CURDIR)":/workspace \ 55 | $(REGISTRY_URL)/${DOCKER_IMAGE_DEVELOPER_TOOLS}:${DOCKER_TAG_VERSION_DEVELOPER_TOOLS} \ 56 | /usr/local/bin/execute_with_credentials.sh cleanup_environment 57 | 58 | # Execute integration tests within the docker container 59 | .PHONY: docker_test_integration 60 | docker_test_integration: 61 | docker run --rm -it \ 62 | -e SERVICE_ACCOUNT_JSON \ 63 | -v "$(CURDIR)":/workspace \ 64 | $(REGISTRY_URL)/${DOCKER_IMAGE_DEVELOPER_TOOLS}:${DOCKER_TAG_VERSION_DEVELOPER_TOOLS} \ 65 | /usr/local/bin/test_integration.sh 66 | 67 | # Execute lint tests within the docker container 68 | .PHONY: docker_test_lint 69 | docker_test_lint: 70 | docker run --rm -it \ 71 | -v "$(CURDIR)":/workspace \ 72 | $(REGISTRY_URL)/${DOCKER_IMAGE_DEVELOPER_TOOLS}:${DOCKER_TAG_VERSION_DEVELOPER_TOOLS} \ 73 | /usr/local/bin/test_lint.sh 74 | 75 | # Generate documentation 76 | .PHONY: docker_generate_docs 77 | docker_generate_docs: 78 | docker run --rm -it \ 79 | -v "$(CURDIR)":/workspace \ 80 | $(REGISTRY_URL)/${DOCKER_IMAGE_DEVELOPER_TOOLS}:${DOCKER_TAG_VERSION_DEVELOPER_TOOLS} \ 81 | /bin/bash -c 'source /usr/local/bin/task_helper_functions.sh && generate_docs' 82 | 83 | # Alias for backwards compatibility 84 | .PHONY: generate_docs 85 | generate_docs: docker_generate_docs 86 | -------------------------------------------------------------------------------- /test/integration/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/terraform-google-modules/terraform-google-sap/test/integration 2 | 3 | go 1.22.7 4 | 5 | toolchain go1.22.9 6 | 7 | require ( 8 | github.com/GoogleCloudPlatform/cloud-foundation-toolkit/infra/blueprint-test v0.16.3 9 | github.com/gruntwork-io/terratest v0.47.2 10 | github.com/stretchr/testify v1.9.0 11 | ) 12 | 13 | require ( 14 | cloud.google.com/go v0.110.7 // indirect 15 | cloud.google.com/go/compute v1.23.0 // indirect 16 | cloud.google.com/go/compute/metadata v0.2.3 // indirect 17 | cloud.google.com/go/iam v1.1.2 // indirect 18 | cloud.google.com/go/storage v1.33.0 // indirect 19 | github.com/agext/levenshtein v1.2.3 // indirect 20 | github.com/alexflint/go-filemutex v1.3.0 // indirect 21 | github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect 22 | github.com/aws/aws-sdk-go v1.45.5 // indirect 23 | github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect 24 | github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect 25 | github.com/go-errors/errors v1.5.0 // indirect 26 | github.com/go-openapi/jsonpointer v0.20.0 // indirect 27 | github.com/go-openapi/jsonreference v0.20.2 // indirect 28 | github.com/go-openapi/swag v0.22.4 // indirect 29 | github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect 30 | github.com/golang/protobuf v1.5.3 // indirect 31 | github.com/google/gnostic-models v0.6.8 // indirect 32 | github.com/google/go-cmp v0.6.0 // indirect 33 | github.com/google/s2a-go v0.1.7 // indirect 34 | github.com/google/uuid v1.6.0 // indirect 35 | github.com/googleapis/enterprise-certificate-proxy v0.2.5 // indirect 36 | github.com/googleapis/gax-go/v2 v2.12.0 // indirect 37 | github.com/hashicorp/errwrap v1.1.0 // indirect 38 | github.com/hashicorp/go-cleanhttp v0.5.2 // indirect 39 | github.com/hashicorp/go-getter v1.7.6 // indirect 40 | github.com/hashicorp/go-multierror v1.1.1 // indirect 41 | github.com/hashicorp/go-safetemp v1.0.0 // indirect 42 | github.com/hashicorp/go-version v1.7.0 // indirect 43 | github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f // indirect 44 | github.com/hashicorp/hcl/v2 v2.20.1 // indirect 45 | github.com/hashicorp/terraform-config-inspect v0.0.0-20240801114854-6714b46f5fe4 // indirect 46 | github.com/hashicorp/terraform-json v0.23.0 // indirect 47 | github.com/jinzhu/copier v0.4.0 // indirect 48 | github.com/jmespath/go-jmespath v0.4.0 // indirect 49 | github.com/josharian/intern v1.0.0 // indirect 50 | github.com/klauspost/compress v1.16.7 // indirect 51 | github.com/mailru/easyjson v0.7.7 // indirect 52 | github.com/mattn/go-zglob v0.0.4 // indirect 53 | github.com/mitchellh/go-homedir v1.1.0 // indirect 54 | github.com/mitchellh/go-testing-interface v1.14.2-0.20210821155943-2d9075ca8770 // indirect 55 | github.com/mitchellh/go-wordwrap v1.0.1 // indirect 56 | github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect 57 | github.com/tidwall/gjson v1.18.0 // indirect 58 | github.com/tidwall/match v1.1.1 // indirect 59 | github.com/tidwall/pretty v1.2.1 // indirect 60 | github.com/tidwall/sjson v1.2.5 // indirect 61 | github.com/tmccombs/hcl2json v0.6.0 // indirect 62 | github.com/ulikunitz/xz v0.5.11 // indirect 63 | github.com/zclconf/go-cty v1.15.0 // indirect 64 | go.opencensus.io v0.24.0 // indirect 65 | golang.org/x/crypto v0.31.0 // indirect 66 | golang.org/x/mod v0.21.0 // indirect 67 | golang.org/x/net v0.25.0 // indirect 68 | golang.org/x/oauth2 v0.12.0 // indirect 69 | golang.org/x/sync v0.10.0 // indirect 70 | golang.org/x/sys v0.28.0 // indirect 71 | golang.org/x/text v0.21.0 // indirect 72 | golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect 73 | golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect 74 | google.golang.org/api v0.138.0 // indirect 75 | google.golang.org/appengine v1.6.8 // indirect 76 | google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d // indirect 77 | google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d // indirect 78 | google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect 79 | google.golang.org/grpc v1.58.3 // indirect 80 | google.golang.org/protobuf v1.33.0 // indirect 81 | gopkg.in/yaml.v3 v3.0.1 // indirect 82 | k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect 83 | sigs.k8s.io/kustomize/kyaml v0.18.1 // indirect 84 | sigs.k8s.io/yaml v1.4.0 // indirect 85 | ) 86 | -------------------------------------------------------------------------------- /modules/s4/project.tf: -------------------------------------------------------------------------------- 1 | # Copyright 2024 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | data "google_dns_managed_zone" "sap_zone" { 16 | count = var.deployment_has_dns ? 1 : 0 17 | name = var.existing_dns_zone_name == "" ? resource.google_dns_managed_zone.sap_zone[0].name : var.existing_dns_zone_name 18 | project = data.google_project.sap-project.project_id 19 | } 20 | 21 | data "google_project" "sap-project" { 22 | project_id = var.gcp_project_id 23 | } 24 | 25 | locals { 26 | cpu_platform_map = { 27 | m1-megamem-96 = "Intel Skylake" 28 | n1-highmem-16 = "Intel Broadwell" 29 | n1-highmem-32 = "Intel Broadwell" 30 | n1-highmem-64 = "Intel Broadwell" 31 | n1-highmem-8 = "Intel Broadwell" 32 | n1-highmem-96 = "Intel Skylake" 33 | n1-megamem-96 = "Intel Skylake" 34 | n1-standard-16 = "Intel Broadwell" 35 | n1-standard-32 = "Intel Broadwell" 36 | n1-standard-64 = "Intel Broadwell" 37 | n1-standard-8 = "Intel Broadwell" 38 | n1-standard-96 = "Intel Skylake" 39 | } 40 | } 41 | 42 | locals { 43 | fstore_url1 = var.fstore_mount_point == "" ? "${google_filestore_instance.sap_fstore_1[0].networks[0].ip_addresses[0]}:/${google_filestore_instance.sap_fstore_1[0].file_shares[0].name}" : var.fstore_mount_point 44 | } 45 | 46 | provider "google" { 47 | project = "!!! Terraform resource is using default project name !!!" 48 | region = "!!! Terraform resource is using default region !!!" 49 | } 50 | 51 | resource "google_compute_firewall" "intra_vm_communication" { 52 | allow { 53 | protocol = "tcp" 54 | } 55 | allow { 56 | protocol = "icmp" 57 | } 58 | allow { 59 | protocol = "udp" 60 | } 61 | count = var.create_comms_firewall ? 1 : 0 62 | description = "Enables intra VM communications" 63 | name = "${var.deployment_name}-communication-firewall" 64 | network = data.google_compute_network.sap-vpc.self_link 65 | project = data.google_compute_network.sap-vpc.project 66 | source_tags = ["${var.deployment_name}-s4-comms"] 67 | target_tags = ["${var.deployment_name}-s4-comms"] 68 | } 69 | 70 | resource "google_dns_managed_zone" "sap_zone" { 71 | count = (var.deployment_has_dns && var.existing_dns_zone_name == "") ? 1 : 0 72 | depends_on = [google_project_service.service_dns_googleapis_com] 73 | description = "${var.deployment_name} SAP DNS zone" 74 | dns_name = "${var.deployment_name}.${var.dns_zone_name_suffix}" 75 | force_destroy = true 76 | name = var.deployment_name 77 | private_visibility_config { 78 | networks { 79 | network_url = data.google_compute_network.sap-vpc.self_link 80 | } 81 | } 82 | project = data.google_project.sap-project.project_id 83 | visibility = "private" 84 | } 85 | 86 | resource "google_dns_record_set" "sap_fstore_1" { 87 | count = ((var.fstore_mount_point == "") && var.deployment_has_dns) ? 1 : 0 88 | managed_zone = data.google_dns_managed_zone.sap_zone[0].name 89 | name = "fstore-${var.deployment_name}-1.${data.google_dns_managed_zone.sap_zone[0].dns_name}" 90 | project = data.google_project.sap-project.project_id 91 | rrdatas = [ 92 | google_filestore_instance.sap_fstore_1[count.index].networks[0].ip_addresses[0] 93 | ] 94 | ttl = 60 95 | type = "A" 96 | } 97 | 98 | resource "google_filestore_instance" "sap_fstore_1" { 99 | count = var.fstore_mount_point == "" ? 1 : 0 100 | depends_on = [google_project_service.service_file_googleapis_com] 101 | file_shares { 102 | capacity_gb = var.filestore_gb 103 | name = "default" 104 | } 105 | location = var.filestore_location == "" ? var.region_name : var.filestore_location 106 | name = "fstore-${var.deployment_name}-1" 107 | networks { 108 | modes = ["MODE_IPV4"] 109 | network = data.google_compute_network.sap-vpc.id 110 | } 111 | project = data.google_compute_network.sap-vpc.project 112 | tier = var.filestore_tier 113 | timeouts { 114 | create = "30m" 115 | delete = "30m" 116 | update = "30m" 117 | } 118 | } 119 | 120 | terraform { 121 | required_providers { 122 | google = { 123 | source = "hashicorp/google" 124 | version = ">= 4.0.0, < 6" 125 | } 126 | } 127 | required_version = ">=0.12.6" 128 | } 129 | -------------------------------------------------------------------------------- /modules/s4_ha/project.tf: -------------------------------------------------------------------------------- 1 | # Copyright 2024 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | data "google_dns_managed_zone" "sap_zone" { 16 | count = var.deployment_has_dns ? 1 : 0 17 | name = var.existing_dns_zone_name == "" ? resource.google_dns_managed_zone.sap_zone[0].name : var.existing_dns_zone_name 18 | project = data.google_project.sap-project.project_id 19 | } 20 | 21 | data "google_project" "sap-project" { 22 | project_id = var.gcp_project_id 23 | } 24 | 25 | locals { 26 | cpu_platform_map = { 27 | m1-megamem-96 = "Intel Skylake" 28 | n1-highmem-16 = "Intel Broadwell" 29 | n1-highmem-32 = "Intel Broadwell" 30 | n1-highmem-64 = "Intel Broadwell" 31 | n1-highmem-8 = "Intel Broadwell" 32 | n1-highmem-96 = "Intel Skylake" 33 | n1-megamem-96 = "Intel Skylake" 34 | n1-standard-16 = "Intel Broadwell" 35 | n1-standard-32 = "Intel Broadwell" 36 | n1-standard-64 = "Intel Broadwell" 37 | n1-standard-8 = "Intel Broadwell" 38 | n1-standard-96 = "Intel Skylake" 39 | } 40 | } 41 | 42 | locals { 43 | fstore_url1 = var.fstore_mount_point == "" ? "${google_filestore_instance.sap_fstore_1[0].networks[0].ip_addresses[0]}:/${google_filestore_instance.sap_fstore_1[0].file_shares[0].name}" : var.fstore_mount_point 44 | } 45 | 46 | provider "google" { 47 | project = "!!! Terraform resource is using default project name !!!" 48 | region = "!!! Terraform resource is using default region !!!" 49 | } 50 | 51 | resource "google_compute_firewall" "intra_vm_communication" { 52 | allow { 53 | protocol = "tcp" 54 | } 55 | allow { 56 | protocol = "icmp" 57 | } 58 | allow { 59 | protocol = "udp" 60 | } 61 | count = var.create_comms_firewall ? 1 : 0 62 | description = "Enables intra VM communications" 63 | name = "${var.deployment_name}-communication-firewall" 64 | network = data.google_compute_network.sap-vpc.self_link 65 | project = data.google_compute_network.sap-vpc.project 66 | source_tags = ["${var.deployment_name}-s4-comms"] 67 | target_tags = ["${var.deployment_name}-s4-comms"] 68 | } 69 | 70 | resource "google_dns_managed_zone" "sap_zone" { 71 | count = (var.deployment_has_dns && var.existing_dns_zone_name == "") ? 1 : 0 72 | depends_on = [google_project_service.service_dns_googleapis_com] 73 | description = "${var.deployment_name} SAP DNS zone" 74 | dns_name = "${var.deployment_name}.${var.dns_zone_name_suffix}" 75 | force_destroy = true 76 | name = var.deployment_name 77 | private_visibility_config { 78 | networks { 79 | network_url = data.google_compute_network.sap-vpc.self_link 80 | } 81 | } 82 | project = data.google_project.sap-project.project_id 83 | visibility = "private" 84 | } 85 | 86 | resource "google_dns_record_set" "sap_fstore_1" { 87 | count = ((var.fstore_mount_point == "") && var.deployment_has_dns) ? 1 : 0 88 | managed_zone = data.google_dns_managed_zone.sap_zone[0].name 89 | name = "fstore-${var.deployment_name}-1.${data.google_dns_managed_zone.sap_zone[0].dns_name}" 90 | project = data.google_project.sap-project.project_id 91 | rrdatas = [ 92 | google_filestore_instance.sap_fstore_1[count.index].networks[0].ip_addresses[0] 93 | ] 94 | ttl = 60 95 | type = "A" 96 | } 97 | 98 | resource "google_filestore_instance" "sap_fstore_1" { 99 | count = var.fstore_mount_point == "" ? 1 : 0 100 | depends_on = [google_project_service.service_file_googleapis_com] 101 | file_shares { 102 | capacity_gb = var.filestore_gb 103 | name = "default" 104 | } 105 | location = var.filestore_location == "" ? var.region_name : var.filestore_location 106 | name = "fstore-${var.deployment_name}-1" 107 | networks { 108 | modes = ["MODE_IPV4"] 109 | network = data.google_compute_network.sap-vpc.id 110 | } 111 | project = data.google_compute_network.sap-vpc.project 112 | tier = var.filestore_tier 113 | timeouts { 114 | create = "30m" 115 | delete = "30m" 116 | update = "30m" 117 | } 118 | } 119 | 120 | terraform { 121 | required_providers { 122 | google = { 123 | source = "hashicorp/google" 124 | version = ">= 4.0.0, < 6" 125 | } 126 | } 127 | required_version = ">=0.12.6" 128 | } 129 | -------------------------------------------------------------------------------- /modules/sap_ase/README.md: -------------------------------------------------------------------------------- 1 | TODO 2 | 3 | ## Inputs 4 | 5 | | Name | Description | Type | Default | Required | 6 | |------|-------------|------|---------|:--------:| 7 | | ase\_backup\_size | OPTIONAL - Size in GB of the /sybasebackup volume. If set to 0, no disk will be created. | `number` | `0` | no | 8 | | ase\_diag\_size | Size in GB of /sybase/[DBSID]/sapdiag - Which holds the diagnostic tablespace for SAPTOOLS. | `number` | `8` | no | 9 | | ase\_log\_size | Size in GB of /sybase/[DBSID]/logdir - Which holds the database transaction logs. | `number` | `8` | no | 10 | | ase\_log\_ssd | SSD toggle for the log drive. If set to true, the log disk will be SSD. | `bool` | `true` | no | 11 | | ase\_sap\_data\_size | Size in GB of /sybase/[DBSID]/sapdata - Which holds the database data files. | `number` | `30` | no | 12 | | ase\_sap\_data\_ssd | SSD toggle for the data drive. If set to true, the data disk will be SSD. | `bool` | `true` | no | 13 | | ase\_sap\_temp\_size | Size in GB of /sybase/[DBSID]/saptmp - Which holds the database temporary table space. | `number` | `8` | no | 14 | | ase\_sid | The database instance/SID name. | `string` | n/a | yes | 15 | | ase\_sid\_size | Size in GB of /sybase/[DBSID] - the root directory of the database instance. | `number` | `8` | no | 16 | | can\_ip\_forward | Whether sending and receiving of packets with non-matching source or destination IPs is allowed. | `bool` | `true` | no | 17 | | custom\_metadata | Optional - default is empty. Custom metadata to be added to the VM. | `map(string)` | `{}` | no | 18 | | instance\_name | Hostname of the GCE instance. | `string` | n/a | yes | 19 | | linux\_image | Linux image name to use. | `string` | n/a | yes | 20 | | linux\_image\_project | The project which the Linux image belongs to. | `string` | n/a | yes | 21 | | machine\_type | Machine type for the instances. | `string` | n/a | yes | 22 | | network\_tags | OPTIONAL - Network tags can be associated to your instance on deployment. This can be used for firewalling or routing purposes. | `list(string)` | `[]` | no | 23 | | post\_deployment\_script | OPTIONAL - gs:// or https:// location of a script to execute on the created VM's post deployment. | `string` | `""` | no | 24 | | primary\_startup\_url | Startup script to be executed when the VM boots, should not be overridden. | `string` | `"curl -s https://storage.googleapis.com/cloudsapdeploy/terraform/latest/terraform/sap_ase/startup.sh | bash -x -s https://storage.googleapis.com/cloudsapdeploy/terraform/latest/terraform"` | no | 25 | | project\_id | Project id where the instances will be created. | `string` | n/a | yes | 26 | | public\_ip | OPTIONAL - Defines whether a public IP address should be added to your VM. By default this is set to Yes. Note that if you set this to No without appropriate network nat and tags in place, there will be no route to the internet and thus the installation will fail. | `bool` | `true` | no | 27 | | reservation\_name | Use a reservation specified by RESERVATION\_NAME.
By default ANY\_RESERVATION is used when this variable is empty.
In order for a reservation to be used it must be created with the
"Select specific reservation" selected (specificReservationRequired set to true)
Be sure to create your reservation with the correct Min CPU Platform for the
following instance types:
n1-highmem-32 : Intel Broadwell
n1-highmem-64 : Intel Broadwell
n1-highmem-96 : Intel Skylake
n1-megamem-96 : Intel Skylake
m1-megamem-96 : Intel Skylake
All other instance types can have automatic Min CPU Platform" | `string` | `""` | no | 28 | | sap\_deployment\_debug | OPTIONAL - If this value is set to true, the deployment will generates verbose deployment logs. Only turn this setting on if a Google support engineer asks you to enable debugging. | `bool` | `false` | no | 29 | | sap\_mnt\_size | OPTIONAL - Only required if you plan on deploying SAP NetWeaver on the same VM as the ase database instance. If set to 0, no disk will be created. | `number` | `0` | no | 30 | | service\_account | OPTIONAL - Ability to define a custom service account instead of using the default project service account. | `string` | `""` | no | 31 | | subnetwork | The sub network to deploy the instance in. | `string` | n/a | yes | 32 | | swap\_size | OPTIONAL - Only required if you plan on deploying SAP NetWeaver on the same VM as the ase database instance. If set to 0, no disk will be created. | `number` | `0` | no | 33 | | usr\_sap\_size | OPTIONAL - Only required if you plan on deploying SAP NetWeaver on the same VM as the ase database instance. If set to 0, no disk will be created. | `number` | `0` | no | 34 | | zone | Zone where the instances will be created. | `string` | n/a | yes | 35 | 36 | ## Outputs 37 | 38 | | Name | Description | 39 | |------|-------------| 40 | | sap\_ase\_instance\_self\_link | SAP ASE self-link for instance created | 41 | 42 | 43 | -------------------------------------------------------------------------------- /modules/sap_db2/README.md: -------------------------------------------------------------------------------- 1 | 2 | ## Inputs 3 | 4 | | Name | Description | Type | Default | Required | 5 | |------|-------------|------|---------|:--------:| 6 | | can\_ip\_forward | Whether sending and receiving of packets with non-matching source or destination IPs is allowed. | `bool` | `true` | no | 7 | | custom\_metadata | Optional - default is empty. Custom metadata to be added to the VM. | `map(string)` | `{}` | no | 8 | | db2\_backup\_size | OPTIONAL - Size in GB of the /db2backup - If set to 0, no disk will be created. | `number` | `0` | no | 9 | | db2\_dump\_size | Size in GB of /db2/[DBSID]/db2dump - this directory holds dump files from DB2 which may be useful for diagnosing problems. | `number` | `8` | no | 10 | | db2\_home\_size | Size in GB of /db2/db2[DBSID] - the home directory of the database instance. | `number` | `8` | no | 11 | | db2\_log\_size | Size in GB of /db2/[DBSID]/logdir - Which holds the database transaction logs. | `number` | `8` | no | 12 | | db2\_log\_ssd | SSD toggle for the log drive. If set to true, the log disk will be SSD. | `bool` | `true` | no | 13 | | db2\_sap\_data\_size | Size in GB of /db2/[DBSID]/sapdata - Which holds the database data files. | `number` | `30` | no | 14 | | db2\_sap\_data\_ssd | SSD toggle for the data drive. If set to true, the data disk will be SSD. | `bool` | `true` | no | 15 | | db2\_sap\_temp\_size | Size in GB of /db2/[DBSID]/saptmp - Which holds the database temporary table space. | `number` | `8` | no | 16 | | db2\_sid | The database instance/SID name. | `string` | n/a | yes | 17 | | db2\_sid\_size | Size in GB of /db2/[DBSID] - the root directory of the database instance. | `number` | `8` | no | 18 | | instance\_name | Hostname of the GCE instance. | `string` | n/a | yes | 19 | | linux\_image | Linux image name to use. | `string` | n/a | yes | 20 | | linux\_image\_project | The project which the Linux image belongs to. | `string` | n/a | yes | 21 | | machine\_type | Machine type for the instances. | `string` | n/a | yes | 22 | | network\_tags | OPTIONAL - Network tags can be associated to your instance on deployment. This can be used for firewalling or routing purposes. | `list(string)` | `[]` | no | 23 | | post\_deployment\_script | OPTIONAL - gs:// or https:// location of a script to execute on the created VM's post deployment. | `string` | `""` | no | 24 | | primary\_startup\_url | Startup script to be executed when the VM boots, should not be overridden. | `string` | `"curl -s https://storage.googleapis.com/cloudsapdeploy/terraform/latest/terraform/sap_db2/startup.sh | bash -x -s https://storage.googleapis.com/cloudsapdeploy/terraform/latest/terraform"` | no | 25 | | project\_id | Project id where the instances will be created. | `string` | n/a | yes | 26 | | public\_ip | OPTIONAL - Defines whether a public IP address should be added to your VM. By default this is set to Yes. Note that if you set this to No without appropriate network nat and tags in place, there will be no route to the internet and thus the installation will fail. | `bool` | `true` | no | 27 | | reservation\_name | Use a reservation specified by RESERVATION\_NAME.
By default ANY\_RESERVATION is used when this variable is empty.
In order for a reservation to be used it must be created with the
"Select specific reservation" selected (specificReservationRequired set to true)
Be sure to create your reservation with the correct Min CPU Platform for the
following instance types:
n1-highmem-32 : Intel Broadwell
n1-highmem-64 : Intel Broadwell
n1-highmem-96 : Intel Skylake
n1-megamem-96 : Intel Skylake
m1-megamem-96 : Intel Skylake
All other instance types can have automatic Min CPU Platform" | `string` | `""` | no | 28 | | sap\_deployment\_debug | OPTIONAL - If this value is set to true, the deployment will generates verbose deployment logs. Only turn this setting on if a Google support engineer asks you to enable debugging. | `bool` | `false` | no | 29 | | sap\_mnt\_size | OPTIONAL - Only required if you plan on deploying SAP NetWeaver on the same VM as the db2 database instance. If set to 0, no disk will be created. | `number` | `0` | no | 30 | | service\_account | OPTIONAL - Ability to define a custom service account instead of using the default project service account. | `string` | `""` | no | 31 | | subnetwork | The sub network to deploy the instance in. | `string` | n/a | yes | 32 | | swap\_size | OPTIONAL - Only required if you plan on deploying SAP NetWeaver on the same VM as the db2 database instance. If set to 0, no disk will be created. | `number` | `0` | no | 33 | | usr\_sap\_size | OPTIONAL - Only required if you plan on deploying SAP NetWeaver on the same VM as the db2 database instance. If set to 0, no disk will be created. | `number` | `0` | no | 34 | | zone | Zone where the instances will be created. | `string` | n/a | yes | 35 | 36 | ## Outputs 37 | 38 | | Name | Description | 39 | |------|-------------| 40 | | sap\_db2\_instance\_self\_link | DB2 self-link for instance created | 41 | 42 | 43 | -------------------------------------------------------------------------------- /modules/sap_nw/variables.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | variable "project_id" { 17 | type = string 18 | description = "Project id where the instances will be created." 19 | } 20 | 21 | variable "zone" { 22 | type = string 23 | description = "Zone where the instances will be created." 24 | } 25 | 26 | variable "machine_type" { 27 | type = string 28 | description = "Machine type for the instances." 29 | } 30 | 31 | variable "subnetwork" { 32 | type = string 33 | description = "The sub network to deploy the instance in." 34 | } 35 | 36 | variable "linux_image" { 37 | type = string 38 | description = "Linux image name to use." 39 | } 40 | 41 | variable "linux_image_project" { 42 | type = string 43 | description = "The project which the Linux image belongs to." 44 | } 45 | 46 | variable "instance_name" { 47 | type = string 48 | description = "Hostname of the GCE instance." 49 | validation { 50 | condition = can(regex("^[a-z0-9\\-]+$", var.instance_name)) 51 | error_message = "The instance_name must consist of lowercase letters (a-z), numbers, and hyphens." 52 | } 53 | } 54 | 55 | variable "usr_sap_size" { 56 | type = number 57 | description = "Size of /usr/sap in GB" 58 | default = 8 59 | validation { 60 | condition = var.usr_sap_size >= 8 61 | error_message = "Size of /usr/sap must be larger than 8 GB." 62 | } 63 | } 64 | 65 | variable "sap_mnt_size" { 66 | type = number 67 | description = "Size of /sapmnt in GB" 68 | default = 8 69 | validation { 70 | condition = var.sap_mnt_size >= 8 71 | error_message = "Size of /sapmnt must be larger than 8 GB." 72 | } 73 | } 74 | 75 | variable "swap_size" { 76 | type = number 77 | description = "Size in GB of swap volume" 78 | default = 8 79 | validation { 80 | condition = var.swap_size >= 8 81 | error_message = "Size of swap must be larger than 8 GB." 82 | } 83 | } 84 | 85 | variable "network_tags" { 86 | type = list(string) 87 | description = "OPTIONAL - Network tags can be associated to your instance on deployment. This can be used for firewalling or routing purposes." 88 | default = [] 89 | } 90 | 91 | variable "public_ip" { 92 | type = bool 93 | description = "OPTIONAL - Defines whether a public IP address should be added to your VM. By default this is set to Yes. Note that if you set this to No without appropriate network nat and tags in place, there will be no route to the internet and thus the installation will fail." 94 | default = true 95 | } 96 | 97 | variable "service_account" { 98 | type = string 99 | description = "OPTIONAL - Ability to define a custom service account instead of using the default project service account." 100 | default = "" 101 | } 102 | 103 | variable "sap_deployment_debug" { 104 | type = bool 105 | description = "OPTIONAL - If this value is set to true, the deployment will generates verbose deployment logs. Only turn this setting on if a Google support engineer asks you to enable debugging." 106 | default = false 107 | } 108 | 109 | variable "reservation_name" { 110 | type = string 111 | description = <<-EOT 112 | Use a reservation specified by RESERVATION_NAME. 113 | By default ANY_RESERVATION is used when this variable is empty. 114 | In order for a reservation to be used it must be created with the 115 | "Select specific reservation" selected (specificReservationRequired set to true) 116 | Be sure to create your reservation with the correct Min CPU Platform for the 117 | following instance types: 118 | n1-highmem-32 : Intel Broadwell 119 | n1-highmem-64 : Intel Broadwell 120 | n1-highmem-96 : Intel Skylake 121 | n1-megamem-96 : Intel Skylake 122 | m1-megamem-96 : Intel Skylake 123 | All other instance types can have automatic Min CPU Platform" 124 | EOT 125 | default = "" 126 | } 127 | 128 | variable "post_deployment_script" { 129 | type = string 130 | description = "OPTIONAL - gs:// or https:// location of a script to execute on the created VM's post deployment." 131 | default = "" 132 | } 133 | 134 | # 135 | # DO NOT MODIFY unless you know what you are doing 136 | # 137 | variable "primary_startup_url" { 138 | type = string 139 | description = "Startup script to be executed when the VM boots, should not be overridden." 140 | default = "curl -s https://storage.googleapis.com/cloudsapdeploy/terraform/latest/terraform/sap_nw/nw_startup.sh | bash -s https://storage.googleapis.com/cloudsapdeploy/terraform/latest/terraform" 141 | } 142 | 143 | variable "can_ip_forward" { 144 | type = bool 145 | description = "Whether sending and receiving of packets with non-matching source or destination IPs is allowed." 146 | default = true 147 | } 148 | 149 | variable "custom_metadata" { 150 | type = map(string) 151 | description = "Optional - default is empty. Custom metadata to be added to the VM." 152 | default = {} 153 | } 154 | -------------------------------------------------------------------------------- /modules/sap_nw/README.md: -------------------------------------------------------------------------------- 1 | # Terraform for SAP NW for Google Cloud 2 | This template follows the documented steps https://cloud.google.com/solutions/sap/docs/netweaver-deployment-guide-linux and deploys GCP and Pacemaker resources up to the installation of SAP's central services. 3 | 4 | ## Set up Terraform 5 | 6 | Install Terraform on the machine you would like to use to deploy from by following https://learn.hashicorp.com/tutorials/terraform/install-cli?in=terraform/gcp-get-started#install-terraform 7 | 8 | ## How to deploy 9 | 10 | 1. Download .tf file into an empty directory 11 | `curl https://storage.googleapis.com/cloudsapdeploy/terraform/latest/terraform/sap_nw/terraform/sap_nw.tf -o sap_nw.tf` 12 | 13 | 2. Fill in mandatory variables and if the desired optional variable in the .tf file. 14 | 15 | 3. Deploy 16 | 1. Run `terraform init` (only needed once) 17 | 2. Run `terraform plan` to see what is going to be deployed. Verify if names, zones, sizes, etc. are as desired. 18 | 3. Run `terrafom apply` to deploy the resources 19 | 4. Run `terrafom destroy` to remove the resources 20 | 21 | 4. Continue installation of SAP software and setup of remaining cluster resources as per documentation at https://cloud.google.com/solutions/sap/docs/netweaver-deployment-guide-linux 22 | 23 | ## Additional information 24 | 25 | For additional information see https://www.terraform.io/docs/index.html and https://cloud.google.com/docs/terraform 26 | 27 | 28 | ## Inputs 29 | 30 | | Name | Description | Type | Default | Required | 31 | |------|-------------|------|---------|:--------:| 32 | | can\_ip\_forward | Whether sending and receiving of packets with non-matching source or destination IPs is allowed. | `bool` | `true` | no | 33 | | custom\_metadata | Optional - default is empty. Custom metadata to be added to the VM. | `map(string)` | `{}` | no | 34 | | instance\_name | Hostname of the GCE instance. | `string` | n/a | yes | 35 | | linux\_image | Linux image name to use. | `string` | n/a | yes | 36 | | linux\_image\_project | The project which the Linux image belongs to. | `string` | n/a | yes | 37 | | machine\_type | Machine type for the instances. | `string` | n/a | yes | 38 | | network\_tags | OPTIONAL - Network tags can be associated to your instance on deployment. This can be used for firewalling or routing purposes. | `list(string)` | `[]` | no | 39 | | post\_deployment\_script | OPTIONAL - gs:// or https:// location of a script to execute on the created VM's post deployment. | `string` | `""` | no | 40 | | primary\_startup\_url | Startup script to be executed when the VM boots, should not be overridden. | `string` | `"curl -s https://storage.googleapis.com/cloudsapdeploy/terraform/latest/terraform/sap_nw/nw_startup.sh | bash -s https://storage.googleapis.com/cloudsapdeploy/terraform/latest/terraform"` | no | 41 | | project\_id | Project id where the instances will be created. | `string` | n/a | yes | 42 | | public\_ip | OPTIONAL - Defines whether a public IP address should be added to your VM. By default this is set to Yes. Note that if you set this to No without appropriate network nat and tags in place, there will be no route to the internet and thus the installation will fail. | `bool` | `true` | no | 43 | | reservation\_name | Use a reservation specified by RESERVATION\_NAME.
By default ANY\_RESERVATION is used when this variable is empty.
In order for a reservation to be used it must be created with the
"Select specific reservation" selected (specificReservationRequired set to true)
Be sure to create your reservation with the correct Min CPU Platform for the
following instance types:
n1-highmem-32 : Intel Broadwell
n1-highmem-64 : Intel Broadwell
n1-highmem-96 : Intel Skylake
n1-megamem-96 : Intel Skylake
m1-megamem-96 : Intel Skylake
All other instance types can have automatic Min CPU Platform" | `string` | `""` | no | 44 | | sap\_deployment\_debug | OPTIONAL - If this value is set to true, the deployment will generates verbose deployment logs. Only turn this setting on if a Google support engineer asks you to enable debugging. | `bool` | `false` | no | 45 | | sap\_mnt\_size | Size of /sapmnt in GB | `number` | `8` | no | 46 | | service\_account | OPTIONAL - Ability to define a custom service account instead of using the default project service account. | `string` | `""` | no | 47 | | subnetwork | The sub network to deploy the instance in. | `string` | n/a | yes | 48 | | swap\_size | Size in GB of swap volume | `number` | `8` | no | 49 | | usr\_sap\_size | Size of /usr/sap in GB | `number` | `8` | no | 50 | | zone | Zone where the instances will be created. | `string` | n/a | yes | 51 | 52 | ## Outputs 53 | 54 | | Name | Description | 55 | |------|-------------| 56 | | sap\_nw\_self\_link | SAP NW self-link for instance created | 57 | 58 | 59 | 60 | ## Requirements 61 | 62 | These sections describe requirements for using this module. 63 | 64 | ### Software 65 | 66 | The following dependencies must be available: 67 | 68 | - [Terraform][terraform] v0.13 69 | - [Terraform Provider for GCP][terraform-provider-gcp] plugin v4.0 70 | 71 | ## Contributing 72 | 73 | Refer to the [contribution guidelines](./CONTRIBUTING.md) for 74 | information on contributing to this module. 75 | 76 | [iam-module]: https://registry.terraform.io/modules/terraform-google-modules/iam/google 77 | [project-factory-module]: https://registry.terraform.io/modules/terraform-google-modules/project-factory/google 78 | [terraform-provider-gcp]: https://www.terraform.io/docs/providers/google/index.html 79 | [terraform]: https://www.terraform.io/downloads.html 80 | 81 | ## Security Disclosures 82 | 83 | Please see our [security disclosure process](./SECURITY.md). 84 | -------------------------------------------------------------------------------- /modules/sap_nw/main.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | # 17 | # Terraform SAP NW for Google Cloud 18 | # 19 | # Version: DATETIME_OF_BUILD 20 | # 21 | 22 | ################################################################################ 23 | # Local variables 24 | ################################################################################ 25 | locals { 26 | zone_split = split("-", var.zone) 27 | region = "${local.zone_split[0]}-${local.zone_split[1]}" 28 | subnetwork_split = split("/", var.subnetwork) 29 | subnetwork_uri = length(local.subnetwork_split) > 1 ? ( 30 | "projects/${local.subnetwork_split[0]}/regions/${local.region}/subnetworks/${local.subnetwork_split[1]}") : ( 31 | "projects/${var.project_id}/regions/${local.region}/subnetworks/${var.subnetwork}") 32 | 33 | 34 | cpu_map = { 35 | "n1-highmem-96" : "Intel Skylake", 36 | "n1-megamem-96" : "Intel Skylake", 37 | } 38 | primary_startup_url = var.sap_deployment_debug ? replace(var.primary_startup_url, "bash -s", "bash -x -s") : var.primary_startup_url 39 | 40 | only_hyperdisks_supported = length(regexall("c4-", var.machine_type)) > 0 41 | } 42 | 43 | ################################################################################ 44 | # disks 45 | ################################################################################ 46 | resource "google_compute_disk" "sap_nw_boot_disk" { 47 | name = "${var.instance_name}-boot" 48 | type = local.only_hyperdisks_supported ? "hyperdisk-balanced" : "pd-balanced" 49 | zone = var.zone 50 | size = 30 # GB 51 | project = var.project_id 52 | image = "${var.linux_image_project}/${var.linux_image}" 53 | 54 | lifecycle { 55 | # Ignores newer versions of the OS image. Removing this lifecycle 56 | # and re-applying will cause the current disk to be deleted. 57 | # All existing data will be lost. 58 | ignore_changes = [image] 59 | } 60 | } 61 | 62 | resource "google_compute_disk" "sap_nw_usrsap_disk" { 63 | count = var.usr_sap_size > 0 ? 1 : 0 64 | name = "${var.instance_name}-usrsap" 65 | type = local.only_hyperdisks_supported ? "hyperdisk-balanced" : "pd-balanced" 66 | zone = var.zone 67 | size = var.usr_sap_size 68 | project = var.project_id 69 | } 70 | 71 | resource "google_compute_disk" "sap_nw_swap_disk" { 72 | count = var.swap_size > 0 ? 1 : 0 73 | name = "${var.instance_name}-swap" 74 | type = local.only_hyperdisks_supported ? "hyperdisk-balanced" : "pd-balanced" 75 | zone = var.zone 76 | size = var.swap_size 77 | project = var.project_id 78 | } 79 | 80 | resource "google_compute_disk" "sap_nw_sapmnt_disk" { 81 | count = var.sap_mnt_size > 0 ? 1 : 0 82 | name = "${var.instance_name}-sapmnt" 83 | type = local.only_hyperdisks_supported ? "hyperdisk-balanced" : "pd-balanced" 84 | size = var.sap_mnt_size 85 | zone = var.zone 86 | project = var.project_id 87 | } 88 | 89 | ################################################################################ 90 | # VIPs 91 | ################################################################################ 92 | resource "google_compute_address" "sap_nw_vm_ip" { 93 | name = var.instance_name 94 | subnetwork = local.subnetwork_uri 95 | address_type = "INTERNAL" 96 | region = local.region 97 | project = var.project_id 98 | } 99 | ################################################################################ 100 | # instances 101 | ################################################################################ 102 | resource "google_compute_instance" "sap_nw_instance" { 103 | name = var.instance_name 104 | machine_type = var.machine_type 105 | zone = var.zone 106 | project = var.project_id 107 | min_cpu_platform = lookup(local.cpu_map, var.machine_type, "Automatic") 108 | 109 | boot_disk { 110 | auto_delete = true 111 | device_name = "boot" 112 | source = google_compute_disk.sap_nw_boot_disk.self_link 113 | } 114 | 115 | dynamic "attached_disk" { 116 | for_each = var.usr_sap_size > 0 ? [1] : [] 117 | content { 118 | device_name = google_compute_disk.sap_nw_usrsap_disk[0].name 119 | source = google_compute_disk.sap_nw_usrsap_disk[0].self_link 120 | } 121 | } 122 | 123 | dynamic "attached_disk" { 124 | for_each = var.sap_mnt_size > 0 ? [1] : [] 125 | content { 126 | device_name = google_compute_disk.sap_nw_sapmnt_disk[0].name 127 | source = google_compute_disk.sap_nw_sapmnt_disk[0].self_link 128 | } 129 | } 130 | 131 | dynamic "attached_disk" { 132 | for_each = var.swap_size > 0 ? [1] : [] 133 | content { 134 | device_name = google_compute_disk.sap_nw_swap_disk[0].name 135 | source = google_compute_disk.sap_nw_swap_disk[0].self_link 136 | } 137 | } 138 | 139 | can_ip_forward = var.can_ip_forward 140 | 141 | network_interface { 142 | subnetwork = local.subnetwork_uri 143 | network_ip = google_compute_address.sap_nw_vm_ip.address 144 | 145 | # we only include access_config if public_ip is true, an empty access_config 146 | # will create an ephemeral public ip 147 | dynamic "access_config" { 148 | for_each = var.public_ip ? [1] : [] 149 | content { 150 | } 151 | } 152 | } 153 | 154 | tags = var.network_tags 155 | 156 | service_account { 157 | # An empty string service account will default to the projects default compute engine service account 158 | email = var.service_account 159 | scopes = [ 160 | "https://www.googleapis.com/auth/cloud-platform" 161 | ] 162 | } 163 | 164 | dynamic "reservation_affinity" { 165 | for_each = length(var.reservation_name) > 1 ? [1] : [] 166 | content { 167 | type = "SPECIFIC_RESERVATION" 168 | specific_reservation { 169 | key = "compute.googleapis.com/reservation-name" 170 | values = [var.reservation_name] 171 | } 172 | } 173 | } 174 | 175 | metadata = merge(var.custom_metadata, { 176 | startup-script = local.primary_startup_url 177 | post_deployment_script = var.post_deployment_script 178 | sap_deployment_debug = var.sap_deployment_debug 179 | template-type = "TERRAFORM" 180 | }) 181 | 182 | lifecycle { 183 | # Ignore changes in the instance metadata, since it is modified by the SAP startup script. 184 | ignore_changes = [metadata] 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /modules/s4/README.md: -------------------------------------------------------------------------------- 1 | # Terraform for SAP S/4HANA for Google Cloud 2 | 3 | This template implements the GCP S4 reference architecture 4 | https://cloud.google.com/solutions/sap/docs/architectures/sap-s4hana-on-gcp. 5 | 6 | ## Usage 7 | 8 | Basic usage of this module is as follows: 9 | 10 | ```hcl 11 | module "sap_s4" { 12 | source = "terraform-google-modules/sap/google//modules/s4" 13 | version = "~> 2.0" 14 | 15 | gcp_project_id = "PROJECT_ID" # example: my-project-x 16 | deployment_name = "DEPLOYMENT_NAME" # example: my-deployment 17 | media_bucket_name = "GCS_BUCKET" # example: my-bucket 18 | filestore_location = "ZONE/REGION" # example: us-east1 19 | region_name = "REGION" # example: us-east1 20 | zone1_name = "ZONE" # example: us-east1-b 21 | } 22 | ``` 23 | 24 | Functional example is included in the 25 | [examples](../../examples/sap_hana_simple) directory. 26 | 27 | 28 | ## Inputs 29 | 30 | | Name | Description | Type | Default | Required | 31 | |------|-------------|------|---------|:--------:| 32 | | allow\_stopping\_for\_update | allow\_stopping\_for\_update | `bool` | `true` | no | 33 | | ansible\_sa\_email | ansible\_sa\_email | `string` | `""` | no | 34 | | app\_disk\_export\_interfaces\_size | app\_disk\_export\_interfaces\_size | `number` | `128` | no | 35 | | app\_disk\_type | app\_disk\_type | `string` | `"pd-balanced"` | no | 36 | | app\_disk\_usr\_sap\_size | app\_disk\_usr\_sap\_size | `number` | `128` | no | 37 | | app\_machine\_type | app\_machine\_type | `string` | `"n1-highem-32"` | no | 38 | | app\_sa\_email | app\_sa\_email | `string` | `""` | no | 39 | | app\_sid | app\_sid | `string` | `"ED1"` | no | 40 | | app\_vm\_names | app\_vm\_names | `list(any)` | `[]` | no | 41 | | app\_vms\_multiplier | Multiplies app VMs. E.g. if there is 2 VMs then with value 3 each VM will be multiplied by 3 (so there will be 6 total VMs) | `number` | `1` | no | 42 | | application\_secret\_name | application\_secret\_name | `string` | `"default"` | no | 43 | | ascs\_disk\_type | ascs\_disk\_type | `string` | `"pd-balanced"` | no | 44 | | ascs\_disk\_usr\_sap\_size | ascs\_disk\_usr\_sap\_size | `number` | `128` | no | 45 | | ascs\_machine\_type | ascs\_machine\_type | `string` | `"n1-standard-8"` | no | 46 | | ascs\_sa\_email | ascs\_sa\_email | `string` | `""` | no | 47 | | ascs\_vm\_names | ascs\_vm\_names | `list(any)` | `[]` | no | 48 | | configuration\_bucket\_name | configuration\_bucket\_name | `string` | `""` | no | 49 | | create\_comms\_firewall | create\_comms\_firewall | `bool` | `true` | no | 50 | | custom\_app\_metadata | Optional - default is empty. Custom metadata to be added to the app VMs. | `map(string)` | `{}` | no | 51 | | custom\_ascs\_metadata | Optional - default is empty. Custom metadata to be added to the ASCS VMs. | `map(string)` | `{}` | no | 52 | | custom\_db\_metadata | Optional - default is empty. Custom metadata to be added to the DB VMs. | `map(string)` | `{}` | no | 53 | | custom\_tags | custom\_tags | `list(any)` | `[]` | no | 54 | | data\_stripe\_size | data\_stripe\_size | `string` | `"256k"` | no | 55 | | db\_data\_disk\_type | db\_data\_disk\_type | `string` | `"pd-balanced"` | no | 56 | | db\_disk\_backup\_size | db\_disk\_backup\_size | `number` | `128` | no | 57 | | db\_disk\_hana\_data\_size | db\_disk\_hana\_data\_size | `number` | `249` | no | 58 | | db\_disk\_hana\_log\_size | db\_disk\_hana\_log\_size | `number` | `104` | no | 59 | | db\_disk\_hana\_shared\_size | db\_disk\_hana\_shared\_size | `number` | `208` | no | 60 | | db\_disk\_type | Disk type for the non log/data disks. | `string` | `"pd-balanced"` | no | 61 | | db\_disk\_usr\_sap\_size | db\_disk\_usr\_sap\_size | `number` | `32` | no | 62 | | db\_log\_disk\_type | db\_log\_disk\_type | `string` | `"pd-balanced"` | no | 63 | | db\_machine\_type | db\_machine\_type | `string` | `"n1-highmem-32"` | no | 64 | | db\_sa\_email | db\_sa\_email | `string` | `""` | no | 65 | | db\_sid | db\_sid | `string` | `"HD1"` | no | 66 | | db\_vm\_names | db\_vm\_names | `list(any)` | `[]` | no | 67 | | deployment\_has\_dns | Set to false to deploy without a DNS zone | `bool` | `true` | no | 68 | | deployment\_name | deployment\_name | `string` | n/a | yes | 69 | | disk\_size\_map | disk\_size\_map | `map(number)` | `{}` | no | 70 | | dns\_zone\_name\_suffix | dns\_zone\_name\_suffix | `string` | `"gcp.sapcloud.goog."` | no | 71 | | existing\_dns\_zone\_name | existing\_dns\_zone\_name | `string` | `""` | no | 72 | | filestore\_gb | filestore\_gb | `number` | `1024` | no | 73 | | filestore\_location | filestore\_location | `string` | n/a | yes | 74 | | filestore\_tier | filestore\_tier | `string` | `"ENTERPRISE"` | no | 75 | | fstore\_mount\_point | Optional - default is empty. NFS mount point of the nfs to use. If none is provided one will be created. | `string` | `""` | no | 76 | | gcp\_project\_id | gcp\_project\_id | `string` | n/a | yes | 77 | | hana\_secret\_name | hana\_secret\_name | `string` | `"default"` | no | 78 | | is\_test | is\_test | `string` | `"false"` | no | 79 | | log\_stripe\_size | log\_stripe\_size | `string` | `"64k"` | no | 80 | | media\_bucket\_name | media\_bucket\_name | `string` | n/a | yes | 81 | | network\_project | network\_project | `string` | `""` | no | 82 | | number\_data\_disks | Optional - default is 1. Number of disks to use for data volume striping (if larger than 1). | `number` | `1` | no | 83 | | number\_log\_disks | Optional - default is 1. Number of disks to use for log volume striping (if larger than 1). | `number` | `1` | no | 84 | | package\_location | package\_location | `string` | `"gs://cloudsapdeploy/deployments/latest"` | no | 85 | | primary\_startup\_url | primary\_startup\_url | `string` | `"gs://cloudsapdeploy/deployments/latest/startup/ansible_runner_startup.sh"` | no | 86 | | public\_ansible\_runner\_ip | public\_ansible\_runner\_ip | `bool` | `true` | no | 87 | | public\_ip | public\_ip | `bool` | `false` | no | 88 | | region\_name | region\_name | `string` | n/a | yes | 89 | | sap\_boot\_disk\_image | sap\_boot\_disk\_image | `string` | `"projects/rhel-sap-cloud/global/images/rhel-8-4-sap-v20220719"` | no | 90 | | sap\_boot\_disk\_image\_app | sap\_boot\_disk\_image\_app | `string` | `""` | no | 91 | | sap\_boot\_disk\_image\_ascs | sap\_boot\_disk\_image\_ascs | `string` | `""` | no | 92 | | sap\_boot\_disk\_image\_db | sap\_boot\_disk\_image\_db | `string` | `""` | no | 93 | | sap\_instance\_id\_app | sap\_instance\_id\_app | `string` | `"10"` | no | 94 | | sap\_instance\_id\_ascs | sap\_instance\_id\_ascs | `string` | `"11"` | no | 95 | | sap\_instance\_id\_db | sap\_instance\_id\_db | `string` | `"00"` | no | 96 | | sap\_version | sap\_version | `string` | `"2021"` | no | 97 | | subnet\_name | subnet\_name | `string` | `"default"` | no | 98 | | virtualize\_disks | virtualize\_disks | `bool` | `true` | no | 99 | | vm\_prefix | vm\_prefix | `string` | `"sap"` | no | 100 | | vpc\_name | vpc\_name | `string` | `"default"` | no | 101 | | zone1\_name | zone1\_name | `string` | n/a | yes | 102 | 103 | ## Outputs 104 | 105 | No outputs. 106 | 107 | 108 | 109 | ## Requirements 110 | 111 | These sections describe requirements for using this module. 112 | 113 | ### Software 114 | 115 | The following dependencies must be available: 116 | 117 | - [Terraform][terraform] v0.13 118 | - [Terraform Provider for GCP][terraform-provider-gcp] plugin v4.0 119 | 120 | ## Contributing 121 | 122 | Refer to the [contribution guidelines](./CONTRIBUTING.md) for 123 | information on contributing to this module. 124 | 125 | [iam-module]: https://registry.terraform.io/modules/terraform-google-modules/iam/google 126 | [project-factory-module]: https://registry.terraform.io/modules/terraform-google-modules/project-factory/google 127 | [terraform-provider-gcp]: https://www.terraform.io/docs/providers/google/index.html 128 | [terraform]: https://www.terraform.io/downloads.html 129 | 130 | ## Security Disclosures 131 | 132 | Please see our [security disclosure process](./SECURITY.md). 133 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on 6 | [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 7 | and this project adheres to 8 | [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 9 | 10 | ## [2.0.0](https://github.com/terraform-google-modules/terraform-google-sap/compare/v1.1.2...v2.0.0) (2024-11-21) 11 | 12 | 13 | ### Features 14 | 15 | * Latest sot ([#147](https://github.com/terraform-google-modules/terraform-google-sap/issues/147)) ([c90e2e2](https://github.com/terraform-google-modules/terraform-google-sap/commit/c90e2e2413e49156a9c32968f4672c385da112b4)) 16 | * Latest SOT sync of NW, HANA, and S4 templates. ([#140](https://github.com/terraform-google-modules/terraform-google-sap/issues/140)) ([d103087](https://github.com/terraform-google-modules/terraform-google-sap/commit/d103087e138e4d213ebedc9f16042ca028826d01)) 17 | 18 | 19 | ### Bug Fixes 20 | 21 | * **deps:** Update Terraform validation to v1.1.1 ([#143](https://github.com/terraform-google-modules/terraform-google-sap/issues/143)) ([ab274a2](https://github.com/terraform-google-modules/terraform-google-sap/commit/ab274a294136f7e6c29e4ceda5d00ccb86ae95e1)) 22 | * **deps:** Update Terraform validation to v1.1.1 ([#149](https://github.com/terraform-google-modules/terraform-google-sap/issues/149)) ([febc30d](https://github.com/terraform-google-modules/terraform-google-sap/commit/febc30daafeaabbd1a2fa790c30ad61d8136d1c0)) 23 | 24 | ## [1.1.2](https://github.com/terraform-google-modules/terraform-google-sap/compare/v1.1.1...v1.1.2) (2024-04-11) 25 | 26 | 27 | ### Bug Fixes 28 | 29 | * updates for tflint ([#124](https://github.com/terraform-google-modules/terraform-google-sap/issues/124)) ([97adeec](https://github.com/terraform-google-modules/terraform-google-sap/commit/97adeec924b4e3b54b2da1c0d74673dda93fe04a)) 30 | * upgraded versions.tf to include minor bumps from tpg v5 ([#112](https://github.com/terraform-google-modules/terraform-google-sap/issues/112)) ([2aaabe1](https://github.com/terraform-google-modules/terraform-google-sap/commit/2aaabe1f99c43d1e47fd4bae72a22d7add9c103c)) 31 | 32 | ## [1.1.1](https://github.com/terraform-google-modules/terraform-google-sap/compare/v1.1.0...v1.1.1) (2022-12-29) 33 | 34 | 35 | ### Bug Fixes 36 | 37 | * fixes lint issues and generated metadata ([#74](https://github.com/terraform-google-modules/terraform-google-sap/issues/74)) ([6df49df](https://github.com/terraform-google-modules/terraform-google-sap/commit/6df49df92fac96b22d224a1fdced29a2b9272345)) 38 | 39 | ## [1.1.0](https://github.com/terraform-google-modules/terraform-google-sap/compare/v1.0.0...v1.1.0) (2022-12-02) 40 | 41 | 42 | ### Features 43 | 44 | * makes the sap_hana_scaleout example consistent with the other examples ([#70](https://github.com/terraform-google-modules/terraform-google-sap/issues/70)) ([69dea7b](https://github.com/terraform-google-modules/terraform-google-sap/commit/69dea7b523501885e4b547ddd749a6a8d2c806a1)) 45 | 46 | ## [1.0.0](https://github.com/terraform-google-modules/terraform-google-sap/compare/v0.5.0...v1.0.0) (2022-11-18) 47 | 48 | 49 | ### ⚠ BREAKING CHANGES 50 | 51 | * adds sap hana modules and examples (#62) 52 | 53 | ### Features 54 | 55 | * adds sap hana modules and examples ([#62](https://github.com/terraform-google-modules/terraform-google-sap/issues/62)) ([b379c7b](https://github.com/terraform-google-modules/terraform-google-sap/commit/b379c7bd3a244af52539972af2813aefc41338e6)) 56 | * changes prepare the repository for the new templates. ([#56](https://github.com/terraform-google-modules/terraform-google-sap/issues/56)) ([9d95c22](https://github.com/terraform-google-modules/terraform-google-sap/commit/9d95c227f61c7f7a0cb6143385c417092bb86cc5)) 57 | * updates top level readme for v1.0 ([#65](https://github.com/terraform-google-modules/terraform-google-sap/issues/65)) ([223ce64](https://github.com/terraform-google-modules/terraform-google-sap/commit/223ce64d66a5d8e4ed3fa61285f81d71156ff15b)) 58 | 59 | ## [0.5.0](https://www.github.com/terraform-google-modules/terraform-google-sap/compare/v0.4.0...v0.5.0) (2021-06-18) 60 | 61 | 62 | ### ⚠ BREAKING CHANGES 63 | 64 | * add Terraform 0.13 constraint and module attribution (#36) 65 | 66 | ### Features 67 | 68 | * add Terraform 0.13 constraint and module attribution ([#36](https://www.github.com/terraform-google-modules/terraform-google-sap/issues/36)) ([f97fce9](https://www.github.com/terraform-google-modules/terraform-google-sap/commit/f97fce90bb4a4ad608d0a648142f62cbe5eefdb3)) 69 | 70 | 71 | ### Bug Fixes 72 | 73 | * Add support for Terraform 0.13 + deployment validation check for NW ([#34](https://www.github.com/terraform-google-modules/terraform-google-sap/issues/34)) ([969ff19](https://www.github.com/terraform-google-modules/terraform-google-sap/commit/969ff1942b7b01e0964598de104d55e1f9206084)) 74 | 75 | 76 | ### Miscellaneous Chores 77 | 78 | * release 0.5.0 ([f6a6fc9](https://www.github.com/terraform-google-modules/terraform-google-sap/commit/f6a6fc9d45a7493377badc0df8ac0461655c605f)) 79 | 80 | ## [0.4.0](https://www.github.com/terraform-google-modules/terraform-google-sap/compare/v0.3.0...v0.4.0) (2020-07-27) 81 | 82 | 83 | ### Features 84 | 85 | * Adding the option public_ip that will allow to disable the external IP ([#16](https://www.github.com/terraform-google-modules/terraform-google-sap/issues/16)) ([52ef304](https://www.github.com/terraform-google-modules/terraform-google-sap/commit/52ef304cb583f64fedf13749ecd37467af4ac01d)) 86 | * Adding the option to create instance with a static private IP ([#25](https://www.github.com/terraform-google-modules/terraform-google-sap/issues/25)) ([d8a5752](https://www.github.com/terraform-google-modules/terraform-google-sap/commit/d8a57529bab3caa004cb2017c34e077f56b0d344)) 87 | 88 | 89 | ### Bug Fixes 90 | 91 | * Repair wrong disk sizes for HANA VMs issue [#18](https://www.github.com/terraform-google-modules/terraform-google-sap/issues/18) ([#23](https://www.github.com/terraform-google-modules/terraform-google-sap/issues/23)) ([9bb69ed](https://www.github.com/terraform-google-modules/terraform-google-sap/commit/9bb69ed3abaafbc069eb18ad0382d9975e499a21)) 92 | 93 | ## [0.3.0](https://www.github.com/terraform-google-modules/terraform-google-sap/compare/v0.2.0...v0.3.0) (2020-05-04) 94 | 95 | 96 | ### Features 97 | 98 | * add CMEK support in persistent disks attached to the instances ([#12](https://www.github.com/terraform-google-modules/terraform-google-sap/issues/12)) ([90d2cc6](https://www.github.com/terraform-google-modules/terraform-google-sap/commit/90d2cc644d43c876ddc8a07e3826c6edf7cc816b)) 99 | 100 | 101 | ### Bug Fixes 102 | 103 | * Avoid instance metadata conflicts after instance setup ([#11](https://www.github.com/terraform-google-modules/terraform-google-sap/issues/11)) ([a5592c2](https://www.github.com/terraform-google-modules/terraform-google-sap/commit/a5592c2f9d56181f3c60df1fd9d138440e7c542a)) 104 | 105 | ## [Unreleased] 106 | 107 | ### Added 108 | 109 | - Added support for [Customer Managed Encryption Keys](https://cloud.google.com/compute/docs/disks/customer-managed-encryption) in persistent disks attached to the instances. 110 | 111 | ### Changed 112 | 113 | - Updated for Terraform 0.12. [#11] 114 | - Updated tests and examples to Google provider 3.13. 115 | 116 | ### Fixed 117 | 118 | - Avoid metadata conflicts after SAP startup script completes. [#11] 119 | 120 | ## [0.2.0] - 2019-09-10 121 | 122 | ### Added 123 | 124 | - Submodule to deploy NetWeaver. [#2] 125 | 126 | ### Fixed 127 | 128 | - Required VM instance service account roles added to the submodule READMEs. [#4] 129 | 130 | ## [0.1.0] - 2019-07-04 131 | 132 | ### Added 133 | 134 | - Initial release 135 | 136 | [Unreleased]: https://github.com/terraform-google-modules/terraform-google-sap/compare/v0.2.0...HEAD 137 | [0.2.0]: https://github.com/terraform-google-modules/terraform-google-sap/compare/v0.1.0...v0.2.0 138 | [0.1.0]: https://github.com/terraform-google-modules/terraform-google-sap/releases/tag/v0.1.0 139 | [#2]: https://github.com/terraform-google-modules/terraform-google-sap/pull/2 140 | [#4]: https://github.com/terraform-google-modules/terraform-google-sap/issues/4 141 | [#11]: https://github.com/terraform-google-modules/terraform-google-sap/pull/11 142 | -------------------------------------------------------------------------------- /modules/s4/ascs.tf: -------------------------------------------------------------------------------- 1 | # Copyright 2024 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | data "google_compute_subnetwork" "sap-subnet-ascs-1" { 16 | name = var.subnet_name 17 | project = data.google_compute_network.sap-vpc.project 18 | region = var.region_name 19 | } 20 | 21 | data "google_service_account" "service_account_ascs" { 22 | account_id = var.ascs_sa_email == "" ? google_service_account.service_account_ascs[0].email : var.ascs_sa_email 23 | } 24 | 25 | resource "google_compute_address" "sapdascs11-1" { 26 | address_type = "INTERNAL" 27 | name = "${length(var.ascs_vm_names) > 0 ? var.ascs_vm_names[0] : "${var.vm_prefix}ascs11"}-internal" 28 | project = data.google_project.sap-project.project_id 29 | region = var.region_name 30 | subnetwork = data.google_compute_subnetwork.sap-subnet-ascs-1.self_link 31 | } 32 | 33 | resource "google_compute_disk" "sapdascs11" { 34 | image = var.sap_boot_disk_image_ascs == "" ? var.sap_boot_disk_image : var.sap_boot_disk_image_ascs 35 | lifecycle { 36 | ignore_changes = [snapshot, image] 37 | } 38 | name = length(var.ascs_vm_names) > 0 ? var.ascs_vm_names[0] : "${var.vm_prefix}ascs11" 39 | project = data.google_project.sap-project.project_id 40 | size = length(regexall("metal|c4-", var.ascs_machine_type)) > 0 ? 64 : 50 41 | timeouts { 42 | create = "1h" 43 | delete = "1h" 44 | update = "1h" 45 | } 46 | type = length(regexall("metal|c4-", var.ascs_machine_type)) > 0 ? "hyperdisk-balanced" : "pd-ssd" 47 | zone = var.zone1_name 48 | } 49 | 50 | resource "google_compute_disk" "sapdascs11_usr_sap" { 51 | lifecycle { 52 | ignore_changes = [snapshot] 53 | } 54 | name = "${length(var.ascs_vm_names) > 0 ? var.ascs_vm_names[0] : "${var.vm_prefix}ascs11"}-usr-sap" 55 | project = data.google_project.sap-project.project_id 56 | provisioned_iops = var.ascs_disk_type == "hyperdisk-extreme" ? max(10000, 2 * (lookup(var.disk_size_map, "ascs_disk_usr_sap_size", var.ascs_disk_usr_sap_size))) : null 57 | size = lookup(var.disk_size_map, "ascs_disk_usr_sap_size", var.ascs_disk_usr_sap_size) 58 | timeouts { 59 | create = "1h" 60 | delete = "1h" 61 | update = "1h" 62 | } 63 | type = var.ascs_disk_type 64 | zone = var.zone1_name 65 | } 66 | 67 | resource "google_compute_instance" "sapdascs11" { 68 | allow_stopping_for_update = var.allow_stopping_for_update 69 | attached_disk { 70 | device_name = google_compute_disk.sapdascs11_usr_sap.name 71 | source = google_compute_disk.sapdascs11_usr_sap.self_link 72 | } 73 | boot_disk { 74 | auto_delete = false 75 | device_name = "persistent-disk-0" 76 | source = google_compute_disk.sapdascs11.self_link 77 | } 78 | lifecycle { 79 | ignore_changes = [ 80 | min_cpu_platform, 81 | network_interface[0].alias_ip_range, 82 | metadata["ssh-keys"] 83 | ] 84 | } 85 | machine_type = var.ascs_machine_type 86 | metadata = merge(var.custom_ascs_metadata, { 87 | enable-oslogin = "FALSE" 88 | ssh-keys = "" 89 | }) 90 | min_cpu_platform = lookup(local.cpu_platform_map, var.ascs_machine_type, "Automatic") 91 | name = length(var.ascs_vm_names) > 0 ? var.ascs_vm_names[0] : "${var.vm_prefix}ascs11" 92 | network_interface { 93 | dynamic "access_config" { 94 | content { 95 | } 96 | for_each = var.public_ip ? [1] : [] 97 | } 98 | network = data.google_compute_network.sap-vpc.self_link 99 | network_ip = google_compute_address.sapdascs11-1.address 100 | subnetwork = data.google_compute_subnetwork.sap-subnet-ascs-1.self_link 101 | } 102 | project = data.google_project.sap-project.project_id 103 | scheduling { 104 | automatic_restart = true 105 | on_host_maintenance = length(regexall("metal", var.ascs_machine_type)) > 0 ? "TERMINATE" : "MIGRATE" 106 | preemptible = false 107 | } 108 | service_account { 109 | email = data.google_service_account.service_account_ascs.email 110 | scopes = ["https://www.googleapis.com/auth/cloud-platform"] 111 | } 112 | tags = compact(concat(["${var.deployment_name}-s4-comms"], var.custom_tags)) 113 | zone = var.zone1_name 114 | } 115 | 116 | resource "google_dns_record_set" "ascs_alidascs11" { 117 | count = var.deployment_has_dns ? 1 : 0 118 | managed_zone = data.google_dns_managed_zone.sap_zone[0].name 119 | name = "alidascs11.${data.google_dns_managed_zone.sap_zone[0].dns_name}" 120 | project = data.google_project.sap-project.project_id 121 | rrdatas = [google_dns_record_set.to_vm_sapdascs11[0].name] 122 | ttl = 300 123 | type = "CNAME" 124 | } 125 | 126 | resource "google_dns_record_set" "to_vm_sapdascs11" { 127 | count = var.deployment_has_dns ? 1 : 0 128 | managed_zone = data.google_dns_managed_zone.sap_zone[0].name 129 | name = "${length(var.ascs_vm_names) > 0 ? var.ascs_vm_names[0] : "${var.vm_prefix}ascs11"}.${data.google_dns_managed_zone.sap_zone[0].dns_name}" 130 | project = data.google_project.sap-project.project_id 131 | rrdatas = [google_compute_instance.sapdascs11.network_interface[0].network_ip] 132 | ttl = 300 133 | type = "A" 134 | } 135 | 136 | resource "google_project_iam_member" "ascs_sa_role_1" { 137 | count = var.ascs_sa_email == "" ? 1 : 0 138 | member = "serviceAccount:${data.google_service_account.service_account_ascs.email}" 139 | project = data.google_project.sap-project.project_id 140 | role = "roles/compute.instanceAdmin.v1" 141 | } 142 | 143 | resource "google_project_iam_member" "ascs_sa_role_2" { 144 | count = var.ascs_sa_email == "" ? 1 : 0 145 | member = "serviceAccount:${data.google_service_account.service_account_ascs.email}" 146 | project = data.google_project.sap-project.project_id 147 | role = "roles/storage.objectViewer" 148 | } 149 | 150 | resource "google_project_iam_member" "ascs_sa_role_3" { 151 | count = var.ascs_sa_email == "" ? 1 : 0 152 | member = "serviceAccount:${data.google_service_account.service_account_ascs.email}" 153 | project = data.google_project.sap-project.project_id 154 | role = "roles/monitoring.metricWriter" 155 | } 156 | 157 | resource "google_project_iam_member" "ascs_sa_role_4" { 158 | count = var.ascs_sa_email == "" ? 1 : 0 159 | member = "serviceAccount:${data.google_service_account.service_account_ascs.email}" 160 | project = data.google_project.sap-project.project_id 161 | role = "roles/logging.admin" 162 | } 163 | 164 | resource "google_project_iam_member" "ascs_sa_role_5" { 165 | count = var.ascs_sa_email == "" ? 1 : 0 166 | member = "serviceAccount:${data.google_service_account.service_account_ascs.email}" 167 | project = data.google_project.sap-project.project_id 168 | role = "roles/monitoring.admin" 169 | } 170 | 171 | resource "google_project_iam_member" "ascs_sa_role_6" { 172 | count = var.ascs_sa_email == "" ? 1 : 0 173 | member = "serviceAccount:${data.google_service_account.service_account_ascs.email}" 174 | project = data.google_project.sap-project.project_id 175 | role = "roles/compute.viewer" 176 | } 177 | 178 | resource "google_project_iam_member" "ascs_sa_role_7" { 179 | count = var.ascs_sa_email == "" ? 1 : 0 180 | member = "serviceAccount:${data.google_service_account.service_account_ascs.email}" 181 | project = data.google_project.sap-project.project_id 182 | role = "roles/workloadmanager.insightWriter" 183 | } 184 | 185 | resource "google_service_account" "service_account_ascs" { 186 | account_id = "${var.deployment_name}-ascs" 187 | count = var.ascs_sa_email == "" ? 1 : 0 188 | project = data.google_project.sap-project.project_id 189 | } 190 | -------------------------------------------------------------------------------- /modules/s4_ha/README.md: -------------------------------------------------------------------------------- 1 | # Terraform for SAP S/4HANA HA for Google Cloud 2 | 3 | This template implements the GCP S4 High Availability reference architecture 4 | https://cloud.google.com/solutions/sap/docs/architectures/sap-s4hana-on-gcp. 5 | 6 | ## Usage 7 | 8 | Basic usage of this module is as follows: 9 | 10 | ```hcl 11 | module "s4_ha" { 12 | source = "terraform-google-modules/sap/google//modules/s4_ha" 13 | version = "~> 2.0" 14 | 15 | gcp_project_id = "PROJECT_ID" # example: my-project-x 16 | deployment_name = "DEPLOYMENT_NAME" # example: my-deployment 17 | media_bucket_name = "GCS_BUCKET" # example: my-bucket 18 | filestore_location = "ZONE/REGION" # example: us-east1 19 | region_name = "REGION" # example: us-east1 20 | zone1_name = "ZONE" # example: us-east1-b 21 | zone2_name = "ZONE" # example: us-east1-c 22 | } 23 | ``` 24 | 25 | Functional example is included in the 26 | [examples](../../examples/sap_hana_simple) directory. 27 | 28 | 29 | ## Inputs 30 | 31 | | Name | Description | Type | Default | Required | 32 | |------|-------------|------|---------|:--------:| 33 | | allow\_stopping\_for\_update | allow\_stopping\_for\_update | `bool` | `true` | no | 34 | | ansible\_sa\_email | ansible\_sa\_email | `string` | `""` | no | 35 | | app\_disk\_export\_interfaces\_size | app\_disk\_export\_interfaces\_size | `number` | `128` | no | 36 | | app\_disk\_type | app\_disk\_type | `string` | `"pd-balanced"` | no | 37 | | app\_disk\_usr\_sap\_size | app\_disk\_usr\_sap\_size | `number` | `128` | no | 38 | | app\_machine\_type | app\_machine\_type | `string` | `"n1-highem-32"` | no | 39 | | app\_sa\_email | app\_sa\_email | `string` | `""` | no | 40 | | app\_sid | app\_sid | `string` | `"ED1"` | no | 41 | | app\_vm\_names | app\_vm\_names | `list(any)` | `[]` | no | 42 | | app\_vms\_multiplier | Multiplies app VMs. E.g. if there is 2 VMs then with value 3 each VM will be multiplied by 3 (so there will be 6 total VMs) | `string` | `1` | no | 43 | | application\_secret\_name | application\_secret\_name | `string` | `"default"` | no | 44 | | ascs\_disk\_type | ascs\_disk\_type | `string` | `"pd-balanced"` | no | 45 | | ascs\_disk\_usr\_sap\_size | ascs\_disk\_usr\_sap\_size | `number` | `128` | no | 46 | | ascs\_ilb\_healthcheck\_port | ascs\_ilb\_healthcheck\_port | `number` | `60001` | no | 47 | | ascs\_machine\_type | ascs\_machine\_type | `string` | `"n1-standard-8"` | no | 48 | | ascs\_sa\_email | ascs\_sa\_email | `string` | `""` | no | 49 | | ascs\_vm\_names | ascs\_vm\_names | `list(any)` | `[]` | no | 50 | | configuration\_bucket\_name | configuration\_bucket\_name | `string` | `""` | no | 51 | | create\_comms\_firewall | create\_comms\_firewall | `bool` | `true` | no | 52 | | custom\_app\_metadata | Optional - default is empty. Custom metadata to be added to the app VMs. | `map(string)` | `{}` | no | 53 | | custom\_ascs\_metadata | Optional - default is empty. Custom metadata to be added to the ASCS VMs. | `map(string)` | `{}` | no | 54 | | custom\_db\_metadata | Optional - default is empty. Custom metadata to be added to the DB VMs. | `map(string)` | `{}` | no | 55 | | custom\_tags | custom\_tags | `list(any)` | `[]` | no | 56 | | data\_stripe\_size | data\_stripe\_size | `string` | `"256k"` | no | 57 | | db\_data\_disk\_type | db\_data\_disk\_type | `string` | `"pd-balanced"` | no | 58 | | db\_disk\_backup\_size | db\_disk\_backup\_size | `number` | `128` | no | 59 | | db\_disk\_hana\_data\_size | db\_disk\_hana\_data\_size | `number` | `249` | no | 60 | | db\_disk\_hana\_log\_size | db\_disk\_hana\_log\_size | `number` | `104` | no | 61 | | db\_disk\_hana\_shared\_size | db\_disk\_hana\_shared\_size | `number` | `208` | no | 62 | | db\_disk\_type | Disk type for the non log/data disks. | `string` | `"pd-balanced"` | no | 63 | | db\_disk\_usr\_sap\_size | db\_disk\_usr\_sap\_size | `number` | `32` | no | 64 | | db\_ilb\_healthcheck\_port | db\_ilb\_healthcheck\_port | `number` | `60000` | no | 65 | | db\_log\_disk\_type | db\_log\_disk\_type | `string` | `"pd-balanced"` | no | 66 | | db\_machine\_type | db\_machine\_type | `string` | `"n1-highmem-32"` | no | 67 | | db\_sa\_email | db\_sa\_email | `string` | `""` | no | 68 | | db\_sid | db\_sid | `string` | `"HD1"` | no | 69 | | db\_vm\_names | db\_vm\_names | `list(any)` | `[]` | no | 70 | | deployment\_has\_dns | Set to false to deploy without a DNS zone | `bool` | `true` | no | 71 | | deployment\_name | deployment\_name | `string` | n/a | yes | 72 | | disk\_size\_map | disk\_size\_map | `map(number)` | `{}` | no | 73 | | dns\_zone\_name\_suffix | dns\_zone\_name\_suffix | `string` | `"gcp.sapcloud.goog."` | no | 74 | | ers\_ilb\_healthcheck\_port | ers\_ilb\_healthcheck\_port | `number` | `60002` | no | 75 | | existing\_dns\_zone\_name | existing\_dns\_zone\_name | `string` | `""` | no | 76 | | filestore\_gb | filestore\_gb | `number` | `1024` | no | 77 | | filestore\_location | filestore\_location | `string` | n/a | yes | 78 | | filestore\_tier | filestore\_tier | `string` | `"ENTERPRISE"` | no | 79 | | fstore\_mount\_point | Optional - default is empty. NFS mount point of the nfs to use. If none is provided one will be created. | `string` | `""` | no | 80 | | gcp\_project\_id | gcp\_project\_id | `string` | n/a | yes | 81 | | hana\_secret\_name | hana\_secret\_name | `string` | `"default"` | no | 82 | | is\_test | is\_test | `string` | `"false"` | no | 83 | | log\_stripe\_size | log\_stripe\_size | `string` | `"64k"` | no | 84 | | media\_bucket\_name | media\_bucket\_name | `string` | n/a | yes | 85 | | network\_project | network\_project | `string` | `""` | no | 86 | | number\_data\_disks | Optional - default is 1. Number of disks to use for data volume striping (if larger than 1). | `number` | `1` | no | 87 | | number\_log\_disks | Optional - default is 1. Number of disks to use for log volume striping (if larger than 1). | `number` | `1` | no | 88 | | package\_location | package\_location | `string` | `"gs://cloudsapdeploy/deployments/latest"` | no | 89 | | primary\_startup\_url | primary\_startup\_url | `string` | `"gs://cloudsapdeploy/deployments/latest/startup/ansible_runner_startup.sh"` | no | 90 | | public\_ansible\_runner\_ip | public\_ansible\_runner\_ip | `bool` | `true` | no | 91 | | public\_ip | public\_ip | `bool` | `false` | no | 92 | | region\_name | region\_name | `string` | n/a | yes | 93 | | sap\_boot\_disk\_image | sap\_boot\_disk\_image | `string` | `"projects/rhel-sap-cloud/global/images/rhel-8-4-sap-v20220719"` | no | 94 | | sap\_boot\_disk\_image\_app | sap\_boot\_disk\_image\_app | `string` | `""` | no | 95 | | sap\_boot\_disk\_image\_ascs | sap\_boot\_disk\_image\_ascs | `string` | `""` | no | 96 | | sap\_boot\_disk\_image\_db | sap\_boot\_disk\_image\_db | `string` | `""` | no | 97 | | sap\_instance\_id\_app | sap\_instance\_id\_app | `string` | `"10"` | no | 98 | | sap\_instance\_id\_ascs | sap\_instance\_id\_ascs | `string` | `"11"` | no | 99 | | sap\_instance\_id\_db | sap\_instance\_id\_db | `string` | `"00"` | no | 100 | | sap\_instance\_id\_ers | sap\_instance\_id\_ers | `string` | `"12"` | no | 101 | | sap\_version | sap\_version | `string` | `"2021"` | no | 102 | | subnet\_name | subnet\_name | `string` | `"default"` | no | 103 | | virtualize\_disks | virtualize\_disks | `bool` | `true` | no | 104 | | vm\_prefix | vm\_prefix | `string` | `"sapha"` | no | 105 | | vpc\_name | vpc\_name | `string` | `"default"` | no | 106 | | zone1\_name | zone1\_name | `string` | n/a | yes | 107 | | zone2\_name | zone2\_name | `string` | n/a | yes | 108 | 109 | ## Outputs 110 | 111 | No outputs. 112 | 113 | 114 | 115 | ## Requirements 116 | 117 | These sections describe requirements for using this module. 118 | 119 | ### Software 120 | 121 | The following dependencies must be available: 122 | 123 | - [Terraform][terraform] v0.13 124 | - [Terraform Provider for GCP][terraform-provider-gcp] plugin v4.0 125 | 126 | ## Contributing 127 | 128 | Refer to the [contribution guidelines](./CONTRIBUTING.md) for 129 | information on contributing to this module. 130 | 131 | [iam-module]: https://registry.terraform.io/modules/terraform-google-modules/iam/google 132 | [project-factory-module]: https://registry.terraform.io/modules/terraform-google-modules/project-factory/google 133 | [terraform-provider-gcp]: https://www.terraform.io/docs/providers/google/index.html 134 | [terraform]: https://www.terraform.io/downloads.html 135 | 136 | ## Security Disclosures 137 | 138 | Please see our [security disclosure process](./SECURITY.md). 139 | -------------------------------------------------------------------------------- /modules/sap_ase/variables.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | variable "project_id" { 18 | type = string 19 | description = "Project id where the instances will be created." 20 | } 21 | 22 | variable "zone" { 23 | type = string 24 | description = "Zone where the instances will be created." 25 | } 26 | 27 | variable "machine_type" { 28 | type = string 29 | description = "Machine type for the instances." 30 | } 31 | 32 | variable "subnetwork" { 33 | type = string 34 | description = "The sub network to deploy the instance in." 35 | } 36 | 37 | variable "linux_image" { 38 | type = string 39 | description = "Linux image name to use." 40 | } 41 | 42 | variable "linux_image_project" { 43 | type = string 44 | description = "The project which the Linux image belongs to." 45 | } 46 | 47 | variable "instance_name" { 48 | type = string 49 | description = "Hostname of the GCE instance." 50 | validation { 51 | condition = can(regex("^[a-z0-9\\-]+$", var.instance_name)) 52 | error_message = "The instance_name must consist of lowercase letters (a-z), numbers, and hyphens." 53 | } 54 | } 55 | 56 | variable "ase_sid" { 57 | type = string 58 | description = "The database instance/SID name." 59 | validation { 60 | condition = can(regex("[A-Za-z][A-Za-z0-9]{2}", var.ase_sid)) 61 | error_message = "The ase_sid must be 3 alphanumeric characters, and start with a letter." 62 | } 63 | } 64 | 65 | variable "ase_sid_size" { 66 | type = number 67 | description = "Size in GB of /sybase/[DBSID] - the root directory of the database instance." 68 | default = 8 69 | validation { 70 | condition = var.ase_sid_size >= 8 71 | error_message = "The ase_sid_size must be at least 8GB." 72 | } 73 | } 74 | 75 | variable "ase_diag_size" { 76 | type = number 77 | description = "Size in GB of /sybase/[DBSID]/sapdiag - Which holds the diagnostic tablespace for SAPTOOLS." 78 | default = 8 79 | validation { 80 | condition = var.ase_diag_size >= 8 81 | error_message = "The ase_diag_size must be at least 8GB." 82 | } 83 | } 84 | 85 | variable "ase_sap_temp_size" { 86 | type = number 87 | description = "Size in GB of /sybase/[DBSID]/saptmp - Which holds the database temporary table space." 88 | default = 8 89 | validation { 90 | condition = var.ase_sap_temp_size >= 8 91 | error_message = "The ase_sap_temp_size must be at least 8GB." 92 | } 93 | } 94 | 95 | variable "ase_sap_data_size" { 96 | type = number 97 | description = "Size in GB of /sybase/[DBSID]/sapdata - Which holds the database data files." 98 | default = 30 99 | validation { 100 | condition = var.ase_sap_data_size >= 30 101 | error_message = "The ase_sap_data_size must be at least 30GB." 102 | } 103 | } 104 | 105 | variable "ase_sap_data_ssd" { 106 | type = bool 107 | description = "SSD toggle for the data drive. If set to true, the data disk will be SSD." 108 | default = true 109 | } 110 | 111 | variable "ase_log_size" { 112 | type = number 113 | description = "Size in GB of /sybase/[DBSID]/logdir - Which holds the database transaction logs." 114 | default = 8 115 | validation { 116 | condition = var.ase_log_size >= 8 117 | error_message = "The ase_log_size must be at least 8GB." 118 | } 119 | } 120 | 121 | variable "ase_log_ssd" { 122 | type = bool 123 | description = "SSD toggle for the log drive. If set to true, the log disk will be SSD." 124 | default = true 125 | } 126 | 127 | variable "ase_backup_size" { 128 | type = number 129 | description = "OPTIONAL - Size in GB of the /sybasebackup volume. If set to 0, no disk will be created." 130 | default = 0 131 | validation { 132 | condition = var.ase_backup_size >= 0 133 | error_message = "The ase_backup_size must be positive or 0." 134 | } 135 | } 136 | 137 | variable "usr_sap_size" { 138 | type = number 139 | description = "OPTIONAL - Only required if you plan on deploying SAP NetWeaver on the same VM as the ase database instance. If set to 0, no disk will be created." 140 | default = 0 141 | validation { 142 | condition = var.usr_sap_size >= 0 143 | error_message = "The usr_sap_size must be positive or 0." 144 | } 145 | } 146 | 147 | variable "sap_mnt_size" { 148 | type = number 149 | description = "OPTIONAL - Only required if you plan on deploying SAP NetWeaver on the same VM as the ase database instance. If set to 0, no disk will be created." 150 | default = 0 151 | validation { 152 | condition = var.sap_mnt_size >= 0 153 | error_message = "The sap_mnt_size must be positive or 0." 154 | } 155 | } 156 | 157 | variable "swap_size" { 158 | type = number 159 | description = "OPTIONAL - Only required if you plan on deploying SAP NetWeaver on the same VM as the ase database instance. If set to 0, no disk will be created." 160 | default = 0 161 | validation { 162 | condition = var.swap_size >= 0 163 | error_message = "The swap_size must be positive or 0." 164 | } 165 | } 166 | 167 | variable "network_tags" { 168 | type = list(string) 169 | description = "OPTIONAL - Network tags can be associated to your instance on deployment. This can be used for firewalling or routing purposes." 170 | default = [] 171 | } 172 | 173 | variable "public_ip" { 174 | type = bool 175 | description = "OPTIONAL - Defines whether a public IP address should be added to your VM. By default this is set to Yes. Note that if you set this to No without appropriate network nat and tags in place, there will be no route to the internet and thus the installation will fail." 176 | default = true 177 | } 178 | 179 | variable "service_account" { 180 | type = string 181 | description = "OPTIONAL - Ability to define a custom service account instead of using the default project service account." 182 | default = "" 183 | } 184 | 185 | variable "sap_deployment_debug" { 186 | type = bool 187 | description = "OPTIONAL - If this value is set to true, the deployment will generates verbose deployment logs. Only turn this setting on if a Google support engineer asks you to enable debugging." 188 | default = false 189 | } 190 | 191 | variable "reservation_name" { 192 | type = string 193 | description = <<-EOT 194 | Use a reservation specified by RESERVATION_NAME. 195 | By default ANY_RESERVATION is used when this variable is empty. 196 | In order for a reservation to be used it must be created with the 197 | "Select specific reservation" selected (specificReservationRequired set to true) 198 | Be sure to create your reservation with the correct Min CPU Platform for the 199 | following instance types: 200 | n1-highmem-32 : Intel Broadwell 201 | n1-highmem-64 : Intel Broadwell 202 | n1-highmem-96 : Intel Skylake 203 | n1-megamem-96 : Intel Skylake 204 | m1-megamem-96 : Intel Skylake 205 | All other instance types can have automatic Min CPU Platform" 206 | EOT 207 | default = "" 208 | } 209 | 210 | variable "post_deployment_script" { 211 | type = string 212 | description = "OPTIONAL - gs:// or https:// location of a script to execute on the created VM's post deployment." 213 | default = "" 214 | } 215 | 216 | # 217 | # DO NOT MODIFY unless you know what you are doing 218 | # 219 | variable "primary_startup_url" { 220 | type = string 221 | description = "Startup script to be executed when the VM boots, should not be overridden." 222 | default = "curl -s https://storage.googleapis.com/cloudsapdeploy/terraform/latest/terraform/sap_ase/startup.sh | bash -x -s https://storage.googleapis.com/cloudsapdeploy/terraform/latest/terraform" 223 | } 224 | 225 | variable "can_ip_forward" { 226 | type = bool 227 | description = "Whether sending and receiving of packets with non-matching source or destination IPs is allowed." 228 | default = true 229 | } 230 | 231 | variable "custom_metadata" { 232 | type = map(string) 233 | description = "Optional - default is empty. Custom metadata to be added to the VM." 234 | default = {} 235 | } 236 | -------------------------------------------------------------------------------- /modules/s4/app.tf: -------------------------------------------------------------------------------- 1 | # Copyright 2024 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | data "google_compute_subnetwork" "sap-subnet-app-1" { 16 | name = var.subnet_name 17 | project = data.google_compute_network.sap-vpc.project 18 | region = var.region_name 19 | } 20 | 21 | data "google_service_account" "service_account_app" { 22 | account_id = var.app_sa_email == "" ? google_service_account.service_account_app[0].email : var.app_sa_email 23 | } 24 | 25 | resource "google_compute_address" "sapdapp11-1" { 26 | address_type = "INTERNAL" 27 | count = var.app_vms_multiplier 28 | name = "${length(var.app_vm_names) > (0 + (count.index * 2)) ? var.app_vm_names[0 + (count.index * 2)] : "${var.vm_prefix}app1${1 + (count.index * 2)}"}-internal" 29 | project = data.google_project.sap-project.project_id 30 | region = var.region_name 31 | subnetwork = data.google_compute_subnetwork.sap-subnet-app-1.self_link 32 | } 33 | 34 | resource "google_compute_disk" "sapdapp11" { 35 | count = var.app_vms_multiplier 36 | image = var.sap_boot_disk_image_app == "" ? var.sap_boot_disk_image : var.sap_boot_disk_image_app 37 | lifecycle { 38 | ignore_changes = [snapshot, image] 39 | } 40 | name = length(var.app_vm_names) > (0 + (count.index * 2)) ? var.app_vm_names[0 + (count.index * 2)] : "${var.vm_prefix}app1${1 + (count.index * 2)}" 41 | project = data.google_project.sap-project.project_id 42 | size = length(regexall("metal|c4-", var.app_machine_type)) > 0 ? 64 : 50 43 | timeouts { 44 | create = "1h" 45 | delete = "1h" 46 | update = "1h" 47 | } 48 | type = length(regexall("metal|c4-", var.app_machine_type)) > 0 ? "hyperdisk-balanced" : "pd-ssd" 49 | zone = var.zone1_name 50 | } 51 | 52 | resource "google_compute_disk" "sapdapp11_export_interfaces" { 53 | count = var.app_vms_multiplier 54 | lifecycle { 55 | ignore_changes = [snapshot] 56 | } 57 | name = "${length(var.app_vm_names) > (0 + (count.index * 2)) ? var.app_vm_names[0 + (count.index * 2)] : "${var.vm_prefix}app1${1 + (count.index * 2)}"}-export-interfaces" 58 | project = data.google_project.sap-project.project_id 59 | provisioned_iops = var.app_disk_type == "hyperdisk-extreme" ? max(10000, 2 * (lookup(var.disk_size_map, "app_disk_export_interfaces_size", var.app_disk_export_interfaces_size))) : null 60 | size = lookup(var.disk_size_map, "app_disk_export_interfaces_size", var.app_disk_export_interfaces_size) 61 | 62 | timeouts { 63 | create = "1h" 64 | delete = "1h" 65 | update = "1h" 66 | } 67 | type = var.app_disk_type 68 | zone = var.zone1_name 69 | } 70 | 71 | resource "google_compute_disk" "sapdapp11_usr_sap" { 72 | count = var.app_vms_multiplier 73 | lifecycle { 74 | ignore_changes = [snapshot] 75 | } 76 | name = "${length(var.app_vm_names) > (0 + (count.index * 2)) ? var.app_vm_names[0 + (count.index * 2)] : "${var.vm_prefix}app1${1 + (count.index * 2)}"}-usr-sap" 77 | project = data.google_project.sap-project.project_id 78 | provisioned_iops = var.app_disk_type == "hyperdisk-extreme" ? max(10000, 2 * (lookup(var.disk_size_map, "app_disk_usr_sap_size", var.app_disk_usr_sap_size))) : null 79 | size = lookup(var.disk_size_map, "app_disk_usr_sap_size", var.app_disk_usr_sap_size) 80 | timeouts { 81 | create = "1h" 82 | delete = "1h" 83 | update = "1h" 84 | } 85 | type = var.app_disk_type 86 | zone = var.zone1_name 87 | } 88 | 89 | resource "google_compute_instance" "sapdapp11" { 90 | allow_stopping_for_update = var.allow_stopping_for_update 91 | attached_disk { 92 | device_name = google_compute_disk.sapdapp11_usr_sap[count.index].name 93 | source = google_compute_disk.sapdapp11_usr_sap[count.index].self_link 94 | } 95 | attached_disk { 96 | device_name = google_compute_disk.sapdapp11_export_interfaces[count.index].name 97 | source = google_compute_disk.sapdapp11_export_interfaces[count.index].self_link 98 | } 99 | boot_disk { 100 | auto_delete = false 101 | device_name = "persistent-disk-0" 102 | source = google_compute_disk.sapdapp11[count.index].self_link 103 | } 104 | count = var.app_vms_multiplier 105 | lifecycle { 106 | ignore_changes = [ 107 | min_cpu_platform, 108 | network_interface[0].alias_ip_range, 109 | metadata["ssh-keys"] 110 | ] 111 | } 112 | machine_type = var.app_machine_type 113 | metadata = merge(var.custom_app_metadata, { 114 | enable-oslogin = "FALSE" 115 | ssh-keys = "" 116 | }) 117 | min_cpu_platform = lookup(local.cpu_platform_map, var.app_machine_type, "Automatic") 118 | name = length(var.app_vm_names) > (0 + (count.index * 2)) ? var.app_vm_names[0 + (count.index * 2)] : "${var.vm_prefix}app1${1 + (count.index * 2)}" 119 | network_interface { 120 | dynamic "access_config" { 121 | content { 122 | } 123 | for_each = var.public_ip ? [1] : [] 124 | } 125 | network = data.google_compute_network.sap-vpc.self_link 126 | network_ip = google_compute_address.sapdapp11-1[count.index].address 127 | subnetwork = data.google_compute_subnetwork.sap-subnet-app-1.self_link 128 | } 129 | project = data.google_project.sap-project.project_id 130 | scheduling { 131 | automatic_restart = true 132 | on_host_maintenance = length(regexall("metal", var.app_machine_type)) > 0 ? "TERMINATE" : "MIGRATE" 133 | preemptible = false 134 | } 135 | service_account { 136 | email = data.google_service_account.service_account_app.email 137 | scopes = ["https://www.googleapis.com/auth/cloud-platform"] 138 | } 139 | tags = compact(concat(["${var.deployment_name}-s4-comms"], var.custom_tags)) 140 | zone = var.zone1_name 141 | } 142 | 143 | resource "google_dns_record_set" "to_vm_sapdapp11" { 144 | count = var.deployment_has_dns ? var.app_vms_multiplier : 0 145 | managed_zone = data.google_dns_managed_zone.sap_zone[0].name 146 | name = "${length(var.app_vm_names) > (0 + (count.index * 2)) ? var.app_vm_names[0 + (count.index * 2)] : "${var.vm_prefix}app1${1 + (count.index * 2)}"}.${data.google_dns_managed_zone.sap_zone[0].dns_name}" 147 | project = data.google_project.sap-project.project_id 148 | rrdatas = [ 149 | google_compute_instance.sapdapp11[count.index].network_interface[0].network_ip 150 | ] 151 | ttl = 300 152 | type = "A" 153 | } 154 | 155 | resource "google_project_iam_member" "app_sa_role_1" { 156 | count = var.app_sa_email == "" ? 1 : 0 157 | member = "serviceAccount:${data.google_service_account.service_account_app.email}" 158 | project = data.google_project.sap-project.project_id 159 | role = "roles/storage.objectViewer" 160 | } 161 | 162 | resource "google_project_iam_member" "app_sa_role_2" { 163 | count = var.app_sa_email == "" ? 1 : 0 164 | member = "serviceAccount:${data.google_service_account.service_account_app.email}" 165 | project = data.google_project.sap-project.project_id 166 | role = "roles/monitoring.metricWriter" 167 | } 168 | 169 | resource "google_project_iam_member" "app_sa_role_3" { 170 | count = var.app_sa_email == "" ? 1 : 0 171 | member = "serviceAccount:${data.google_service_account.service_account_app.email}" 172 | project = data.google_project.sap-project.project_id 173 | role = "roles/logging.admin" 174 | } 175 | 176 | resource "google_project_iam_member" "app_sa_role_4" { 177 | count = var.app_sa_email == "" ? 1 : 0 178 | member = "serviceAccount:${data.google_service_account.service_account_app.email}" 179 | project = data.google_project.sap-project.project_id 180 | role = "roles/monitoring.admin" 181 | } 182 | 183 | resource "google_project_iam_member" "app_sa_role_5" { 184 | count = var.app_sa_email == "" ? 1 : 0 185 | member = "serviceAccount:${data.google_service_account.service_account_app.email}" 186 | project = data.google_project.sap-project.project_id 187 | role = "roles/compute.viewer" 188 | } 189 | 190 | resource "google_project_iam_member" "app_sa_role_6" { 191 | count = var.app_sa_email == "" ? 1 : 0 192 | member = "serviceAccount:${data.google_service_account.service_account_app.email}" 193 | project = data.google_project.sap-project.project_id 194 | role = "roles/workloadmanager.insightWriter" 195 | } 196 | 197 | resource "google_service_account" "service_account_app" { 198 | account_id = "${var.deployment_name}-app" 199 | count = var.app_sa_email == "" ? 1 : 0 200 | project = data.google_project.sap-project.project_id 201 | } 202 | -------------------------------------------------------------------------------- /modules/sap_nw_ha/README.md: -------------------------------------------------------------------------------- 1 | # Terraform for SAP NW HA for Google Cloud 2 | This template follows the documented steps https://cloud.google.com/solutions/sap/docs/netweaver-ha-config-sles and https://cloud.google.com/solutions/sap/docs/netweaver-ha-config-rhel and deploys GCP and Pacemaker resources up to the installation of SAP's central services. 3 | 4 | ## Set up Terraform 5 | 6 | Install Terraform on the machine you would like to use to deploy from by following https://learn.hashicorp.com/tutorials/terraform/install-cli?in=terraform/gcp-get-started#install-terraform 7 | 8 | ## How to deploy 9 | 10 | 1. Download .tf file into an empty directory 11 | `curl https://storage.googleapis.com/cloudsapdeploy/deploymentmanager/latest/dm-templates/sap_nw_ha/terraform/sap_nw_ha.tf -o sap_nw_ha.tf` 12 | 13 | 2. Fill in mandatory variables and if the desired optional variable in the .tf file. 14 | 15 | 3. Deploy 16 | 1. Run `terraform init` (only needed once) 17 | 2. Run `terraform plan` to see what is going to be deployed. Verify if names, zones, sizes, etc. are as desired. 18 | 3. Run `terrafom apply` to deploy the resources 19 | 4. Run `terrafom destroy` to remove the resources 20 | 21 | 4. Continue installation of SAP software and setup of remaining cluster resources as per documentation at https://cloud.google.com/solutions/sap/docs/netweaver-ha-config-sles or https://cloud.google.com/solutions/sap/docs/netweaver-ha-config-rhel 22 | 23 | ## Additional information 24 | 25 | For additional information see https://www.terraform.io/docs/index.html and https://cloud.google.com/docs/terraform 26 | 27 | 28 | ## Inputs 29 | 30 | | Name | Description | Type | Default | Required | 31 | |------|-------------|------|---------|:--------:| 32 | | can\_ip\_forward | Whether sending and receiving of packets with non-matching source or destination IPs is allowed. | `bool` | `true` | no | 33 | | custom\_primary\_metadata | Optional - default is empty. Custom metadata to be added to the primary VM. | `map(string)` | `{}` | no | 34 | | custom\_secondary\_metadata | Optional - default is empty. Custom metadata to be added to the secondary VM. | `map(string)` | `{}` | no | 35 | | ers\_backend\_svc\_name | Name of ERS backend service | `string` | `""` | no | 36 | | ers\_forw\_rule\_name | Name of ERS forwarding rule | `string` | `""` | no | 37 | | ers\_hc\_name | Name of ERS health check | `string` | `""` | no | 38 | | ers\_hc\_port | Port of ERS health check | `string` | `""` | no | 39 | | ers\_inst\_group\_name | Name of ERS instance group | `string` | `""` | no | 40 | | ers\_vip\_address | Address of ERS virtual IP | `string` | `""` | no | 41 | | ers\_vip\_name | Name of ERS virtual IP | `string` | `""` | no | 42 | | hc\_firewall\_rule\_name | Name of firewall rule for the health check | `string` | `""` | no | 43 | | hc\_network\_tag | Network tag for the health check firewall rule | `list(string)` | `[]` | no | 44 | | linux\_image | Linux image name | `string` | n/a | yes | 45 | | linux\_image\_project | Linux image project | `string` | n/a | yes | 46 | | machine\_type | Machine type for the instances | `string` | n/a | yes | 47 | | network | Network for the instances | `string` | n/a | yes | 48 | | network\_tags | Network tags to apply to the instances | `list(string)` | `[]` | no | 49 | | nfs\_path | NFS path for shared file system, e.g. 10.163.58.114:/ssd | `string` | n/a | yes | 50 | | pacemaker\_cluster\_name | Name of Pacemaker cluster. | `string` | `""` | no | 51 | | post\_deployment\_script | Specifies the location of a script to run after the deployment is complete.
The script should be hosted on a web server or in a GCS bucket. The URL should
begin with http:// https:// or gs://. Note that this script will be executed
on all VM's that the template creates. If you only want to run it on the master
instance you will need to add a check at the top of your script. | `string` | `""` | no | 52 | | primary\_reservation\_name | Use a reservation specified by RESERVATION\_NAME.
By default ANY\_RESERVATION is used when this variable is empty.
In order for a reservation to be used it must be created with the
"Select specific reservation" selected (specificReservationRequired set to true)
Be sure to create your reservation with the correct Min CPU Platform for the
following instance types:
n1-highmem-32 : Intel Broadwell
n1-highmem-64 : Intel Broadwell
n1-highmem-96 : Intel Skylake
n1-megamem-96 : Intel Skylake
m1-megamem-96 : "Intel Skylake"
All other instance types can have automatic Min CPU Platform" | `string` | `""` | no | 53 | | primary\_startup\_url | DO NOT USE | `string` | `"curl -s https://storage.googleapis.com/cloudsapdeploy/terraform/latest/terraform/sap_nw_ha/nw_ha_startup_scs.sh | bash -s https://storage.googleapis.com/cloudsapdeploy/terraform/latest/terraform"` | no | 54 | | project\_id | Project id where the instances will be created | `string` | n/a | yes | 55 | | public\_ip | Create an ephemeral public ip for the instances | `bool` | `false` | no | 56 | | sap\_deployment\_debug | Debug log level for deployment | `bool` | `false` | no | 57 | | sap\_ers\_instance\_number | ERS instance number | `string` | `"10"` | no | 58 | | sap\_nw\_abap | Is this a Netweaver ABAP installation. Set 'false' for NW Java. Dual stack is not supported by this script. | `bool` | `true` | no | 59 | | sap\_primary\_instance | Name of first instance (initial SCS location) | `string` | n/a | yes | 60 | | sap\_primary\_zone | Zone where the first instance will be created | `string` | n/a | yes | 61 | | sap\_scs\_instance\_number | SCS instance number | `string` | `"00"` | no | 62 | | sap\_secondary\_instance | Name of second instance (initial ERS location) | `string` | n/a | yes | 63 | | sap\_secondary\_zone | Zone where the second instance will be created | `string` | n/a | yes | 64 | | sap\_sid | SAP System ID | `string` | n/a | yes | 65 | | scs\_backend\_svc\_name | Name of SCS backend service | `string` | `""` | no | 66 | | scs\_forw\_rule\_name | Name of SCS forwarding rule | `string` | `""` | no | 67 | | scs\_hc\_name | Name of SCS health check | `string` | `""` | no | 68 | | scs\_hc\_port | Port of SCS health check | `string` | `""` | no | 69 | | scs\_inst\_group\_name | Name of SCS instance group | `string` | `""` | no | 70 | | scs\_vip\_address | Address of SCS virtual IP | `string` | `""` | no | 71 | | scs\_vip\_name | Name of SCS virtual IP | `string` | `""` | no | 72 | | secondary\_reservation\_name | Use a reservation specified by RESERVATION\_NAME.
By default ANY\_RESERVATION is used when this variable is empty.
In order for a reservation to be used it must be created with the
"Select specific reservation" selected (specificReservationRequired set to true)
Be sure to create your reservation with the correct Min CPU Platform for the
following instance types:
n1-highmem-32 : Intel Broadwell
n1-highmem-64 : Intel Broadwell
n1-highmem-96 : Intel Skylake
n1-megamem-96 : Intel Skylake
m1-megamem-96 : "Intel Skylake"
All other instance types can have automatic Min CPU Platform" | `string` | `""` | no | 73 | | secondary\_startup\_url | DO NOT USE | `string` | `"curl -s https://storage.googleapis.com/cloudsapdeploy/terraform/latest/terraform/sap_nw_ha/nw_ha_startup_ers.sh | bash -s https://storage.googleapis.com/cloudsapdeploy/terraform/latest/terraform"` | no | 74 | | service\_account | Service account that will be used as the service account on the created instance.
Leave this blank to use the project default service account | `string` | `""` | no | 75 | | subnetwork | Subnetwork for the instances | `string` | n/a | yes | 76 | | swap\_size | Size in GB of swap volume | `number` | `8` | no | 77 | | usr\_sap\_size | Size of /usr/sap in GB | `number` | `8` | no | 78 | 79 | ## Outputs 80 | 81 | | Name | Description | 82 | |------|-------------| 83 | | ers\_instance | ERS instance | 84 | | nw\_forwarding\_rules | Forwarding rules | 85 | | nw\_hc | Health Checks | 86 | | nw\_hc\_firewall | Firewall rule for the Health Checks | 87 | | nw\_instance\_groups | NW Instance Groups | 88 | | nw\_regional\_backend\_services | Backend Services | 89 | | nw\_vips | NW virtual IPs | 90 | | scs\_instance | SCS instance | 91 | 92 | 93 | 94 | ## Requirements 95 | 96 | These sections describe requirements for using this module. 97 | 98 | ### Software 99 | 100 | The following dependencies must be available: 101 | 102 | - [Terraform][terraform] v0.13 103 | - [Terraform Provider for GCP][terraform-provider-gcp] plugin v4.0 104 | 105 | ## Contributing 106 | 107 | Refer to the [contribution guidelines](./CONTRIBUTING.md) for 108 | information on contributing to this module. 109 | 110 | [iam-module]: https://registry.terraform.io/modules/terraform-google-modules/iam/google 111 | [project-factory-module]: https://registry.terraform.io/modules/terraform-google-modules/project-factory/google 112 | [terraform-provider-gcp]: https://www.terraform.io/docs/providers/google/index.html 113 | [terraform]: https://www.terraform.io/downloads.html 114 | 115 | ## Security Disclosures 116 | 117 | Please see our [security disclosure process](./SECURITY.md). 118 | -------------------------------------------------------------------------------- /modules/sap_db2/variables.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | variable "project_id" { 18 | type = string 19 | description = "Project id where the instances will be created." 20 | } 21 | 22 | variable "zone" { 23 | type = string 24 | description = "Zone where the instances will be created." 25 | } 26 | 27 | variable "machine_type" { 28 | type = string 29 | description = "Machine type for the instances." 30 | } 31 | 32 | variable "subnetwork" { 33 | type = string 34 | description = "The sub network to deploy the instance in." 35 | } 36 | 37 | variable "linux_image" { 38 | type = string 39 | description = "Linux image name to use." 40 | } 41 | 42 | variable "linux_image_project" { 43 | type = string 44 | description = "The project which the Linux image belongs to." 45 | } 46 | 47 | variable "instance_name" { 48 | type = string 49 | description = "Hostname of the GCE instance." 50 | validation { 51 | condition = can(regex("^[a-z0-9\\-]+$", var.instance_name)) 52 | error_message = "The instance_name must consist of lowercase letters (a-z), numbers, and hyphens." 53 | } 54 | } 55 | 56 | variable "db2_sid" { 57 | type = string 58 | description = "The database instance/SID name." 59 | validation { 60 | condition = can(regex("[A-Za-z][A-Za-z0-9]{2}", var.db2_sid)) 61 | error_message = "The db2_sid must be 3 alphanumeric characters, and start with a letter." 62 | } 63 | } 64 | 65 | variable "db2_sid_size" { 66 | type = number 67 | description = "Size in GB of /db2/[DBSID] - the root directory of the database instance." 68 | default = 8 69 | validation { 70 | condition = var.db2_sid_size >= 8 71 | error_message = "The db2_sid_size must be at least 8GB." 72 | } 73 | } 74 | 75 | variable "db2_sap_temp_size" { 76 | type = number 77 | description = "Size in GB of /db2/[DBSID]/saptmp - Which holds the database temporary table space." 78 | default = 8 79 | validation { 80 | condition = var.db2_sap_temp_size >= 8 81 | error_message = "The db2_sap_temp_size must be at least 8GB." 82 | } 83 | } 84 | 85 | variable "db2_sap_data_size" { 86 | type = number 87 | description = "Size in GB of /db2/[DBSID]/sapdata - Which holds the database data files." 88 | default = 30 89 | validation { 90 | condition = var.db2_sap_data_size >= 30 91 | error_message = "The db2_sap_data_size must be at least 30GB." 92 | } 93 | } 94 | 95 | variable "db2_sap_data_ssd" { 96 | type = bool 97 | description = "SSD toggle for the data drive. If set to true, the data disk will be SSD." 98 | default = true 99 | } 100 | 101 | variable "db2_log_size" { 102 | type = number 103 | 104 | description = "Size in GB of /db2/[DBSID]/logdir - Which holds the database transaction logs." 105 | default = 8 106 | validation { 107 | condition = var.db2_log_size >= 8 108 | error_message = "The db2_log_size must be at least 8GB." 109 | } 110 | } 111 | 112 | variable "db2_log_ssd" { 113 | type = bool 114 | description = "SSD toggle for the log drive. If set to true, the log disk will be SSD." 115 | default = true 116 | } 117 | 118 | variable "db2_dump_size" { 119 | type = number 120 | description = "Size in GB of /db2/[DBSID]/db2dump - this directory holds dump files from DB2 which may be useful for diagnosing problems." 121 | default = 8 122 | validation { 123 | condition = var.db2_dump_size >= 8 124 | error_message = "The db2_dump_size must be at least 8GB." 125 | } 126 | } 127 | 128 | variable "db2_home_size" { 129 | type = number 130 | description = "Size in GB of /db2/db2[DBSID] - the home directory of the database instance." 131 | default = 8 132 | validation { 133 | condition = var.db2_home_size >= 8 134 | error_message = "The db2_home_size must be at least 8GB." 135 | } 136 | } 137 | 138 | variable "db2_backup_size" { 139 | type = number 140 | description = "OPTIONAL - Size in GB of the /db2backup - If set to 0, no disk will be created." 141 | default = 0 142 | validation { 143 | condition = var.db2_backup_size >= 0 144 | error_message = "The db2_backup_size must be positive or 0." 145 | } 146 | } 147 | 148 | variable "usr_sap_size" { 149 | type = number 150 | description = "OPTIONAL - Only required if you plan on deploying SAP NetWeaver on the same VM as the db2 database instance. If set to 0, no disk will be created." 151 | default = 0 152 | validation { 153 | condition = var.usr_sap_size >= 0 154 | error_message = "The usr_sap_size must be positive or 0." 155 | } 156 | } 157 | 158 | variable "sap_mnt_size" { 159 | type = number 160 | description = "OPTIONAL - Only required if you plan on deploying SAP NetWeaver on the same VM as the db2 database instance. If set to 0, no disk will be created." 161 | default = 0 162 | validation { 163 | condition = var.sap_mnt_size >= 0 164 | error_message = "The sap_mnt_size must be positive or 0." 165 | } 166 | } 167 | 168 | variable "swap_size" { 169 | type = number 170 | description = "OPTIONAL - Only required if you plan on deploying SAP NetWeaver on the same VM as the db2 database instance. If set to 0, no disk will be created." 171 | default = 0 172 | validation { 173 | condition = var.swap_size >= 0 174 | error_message = "The swap_size must be positive or 0." 175 | } 176 | } 177 | variable "network_tags" { 178 | type = list(string) 179 | description = "OPTIONAL - Network tags can be associated to your instance on deployment. This can be used for firewalling or routing purposes." 180 | default = [] 181 | } 182 | 183 | variable "public_ip" { 184 | type = bool 185 | description = "OPTIONAL - Defines whether a public IP address should be added to your VM. By default this is set to Yes. Note that if you set this to No without appropriate network nat and tags in place, there will be no route to the internet and thus the installation will fail." 186 | default = true 187 | } 188 | 189 | variable "service_account" { 190 | type = string 191 | description = "OPTIONAL - Ability to define a custom service account instead of using the default project service account." 192 | default = "" 193 | } 194 | 195 | variable "sap_deployment_debug" { 196 | type = bool 197 | description = "OPTIONAL - If this value is set to true, the deployment will generates verbose deployment logs. Only turn this setting on if a Google support engineer asks you to enable debugging." 198 | default = false 199 | } 200 | 201 | variable "reservation_name" { 202 | type = string 203 | description = <<-EOT 204 | Use a reservation specified by RESERVATION_NAME. 205 | By default ANY_RESERVATION is used when this variable is empty. 206 | In order for a reservation to be used it must be created with the 207 | "Select specific reservation" selected (specificReservationRequired set to true) 208 | Be sure to create your reservation with the correct Min CPU Platform for the 209 | following instance types: 210 | n1-highmem-32 : Intel Broadwell 211 | n1-highmem-64 : Intel Broadwell 212 | n1-highmem-96 : Intel Skylake 213 | n1-megamem-96 : Intel Skylake 214 | m1-megamem-96 : Intel Skylake 215 | All other instance types can have automatic Min CPU Platform" 216 | EOT 217 | default = "" 218 | } 219 | 220 | variable "post_deployment_script" { 221 | type = string 222 | description = "OPTIONAL - gs:// or https:// location of a script to execute on the created VM's post deployment." 223 | default = "" 224 | } 225 | 226 | # 227 | # DO NOT MODIFY unless you know what you are doing 228 | # 229 | variable "primary_startup_url" { 230 | type = string 231 | description = "Startup script to be executed when the VM boots, should not be overridden." 232 | default = "curl -s https://storage.googleapis.com/cloudsapdeploy/terraform/latest/terraform/sap_db2/startup.sh | bash -x -s https://storage.googleapis.com/cloudsapdeploy/terraform/latest/terraform" 233 | } 234 | 235 | variable "can_ip_forward" { 236 | type = bool 237 | description = "Whether sending and receiving of packets with non-matching source or destination IPs is allowed." 238 | default = true 239 | } 240 | 241 | variable "custom_metadata" { 242 | type = map(string) 243 | description = "Optional - default is empty. Custom metadata to be added to the VM." 244 | default = {} 245 | } 246 | -------------------------------------------------------------------------------- /modules/sap_ase/main.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | # 17 | # Terraform SAP ASE for Google Cloud 18 | # 19 | # Version: DATETIME_OF_BUILD 20 | # 21 | 22 | ################################################################################ 23 | # Local variables 24 | ################################################################################ 25 | locals { 26 | zone_split = split("-", var.zone) 27 | region = "${local.zone_split[0]}-${local.zone_split[1]}" 28 | subnetwork_split = split("/", var.subnetwork) 29 | subnetwork_uri = length(local.subnetwork_split) > 1 ? ( 30 | "projects/${local.subnetwork_split[0]}/regions/${local.region}/subnetworks/${local.subnetwork_split[1]}") : ( 31 | "projects/${var.project_id}/regions/${local.region}/subnetworks/${var.subnetwork}") 32 | primary_startup_url = var.sap_deployment_debug ? replace(var.primary_startup_url, "bash -s", "bash -x -s") : var.primary_startup_url 33 | } 34 | 35 | ################################################################################ 36 | # disks 37 | ################################################################################ 38 | resource "google_compute_disk" "sap_ase_boot_disk" { 39 | name = "${var.instance_name}-boot" 40 | type = "pd-balanced" 41 | zone = var.zone 42 | size = 30 # GB 43 | project = var.project_id 44 | image = "${var.linux_image_project}/${var.linux_image}" 45 | } 46 | 47 | resource "google_compute_disk" "sap_ase_sid_disk" { 48 | name = "${var.instance_name}-asesid" 49 | type = "pd-balanced" 50 | zone = var.zone 51 | size = var.ase_sid_size 52 | project = var.project_id 53 | } 54 | 55 | resource "google_compute_disk" "sap_ase_sap_temp_disk" { 56 | name = "${var.instance_name}-asesaptemp" 57 | type = "pd-balanced" 58 | zone = var.zone 59 | size = var.ase_sap_temp_size 60 | project = var.project_id 61 | } 62 | 63 | resource "google_compute_disk" "sap_ase_log_disk" { 64 | name = "${var.instance_name}-aselog" 65 | type = var.ase_log_ssd ? "pd-ssd" : "pd-balanced" 66 | zone = var.zone 67 | size = var.ase_log_size 68 | project = var.project_id 69 | } 70 | 71 | resource "google_compute_disk" "sap_ase_sap_data_disk" { 72 | name = "${var.instance_name}-asesapdata" 73 | type = var.ase_sap_data_ssd ? "pd-ssd" : "pd-balanced" 74 | zone = var.zone 75 | size = var.ase_sap_data_size 76 | project = var.project_id 77 | } 78 | 79 | resource "google_compute_disk" "sap_ase_diag_disk" { 80 | name = "${var.instance_name}-asesapdiag" 81 | type = "pd-balanced" 82 | zone = var.zone 83 | size = var.ase_diag_size 84 | project = var.project_id 85 | } 86 | 87 | resource "google_compute_disk" "sap_ase_backup_disk" { 88 | count = var.ase_backup_size > 0 ? 1 : 0 89 | name = "${var.instance_name}-asebackup" 90 | type = "pd-balanced" 91 | zone = var.zone 92 | size = var.ase_backup_size 93 | project = var.project_id 94 | } 95 | 96 | # NW disks don't get 'ase' prepended. 97 | resource "google_compute_disk" "sap_ase_usr_sap_disk" { 98 | count = var.usr_sap_size > 0 ? 1 : 0 99 | name = "${var.instance_name}-usrsap" 100 | type = "pd-balanced" 101 | zone = var.zone 102 | size = var.usr_sap_size 103 | project = var.project_id 104 | } 105 | 106 | resource "google_compute_disk" "sap_ase_swap_disk" { 107 | count = var.swap_size > 0 ? 1 : 0 108 | name = "${var.instance_name}-swap" 109 | type = "pd-balanced" 110 | zone = var.zone 111 | size = var.swap_size 112 | project = var.project_id 113 | } 114 | 115 | resource "google_compute_disk" "sap_ase_sap_mnt_disk" { 116 | count = var.sap_mnt_size > 0 ? 1 : 0 117 | name = "${var.instance_name}-sapmnt" 118 | type = "pd-balanced" 119 | size = var.sap_mnt_size 120 | zone = var.zone 121 | project = var.project_id 122 | } 123 | ################################################################################ 124 | # VIPs 125 | ################################################################################ 126 | 127 | resource "google_compute_address" "sap_ase_vm_ip" { 128 | name = var.instance_name 129 | subnetwork = local.subnetwork_uri 130 | address_type = "INTERNAL" 131 | region = local.region 132 | project = var.project_id 133 | } 134 | ################################################################################ 135 | # instances 136 | ################################################################################ 137 | resource "google_compute_instance" "sap_ase_instance" { 138 | name = var.instance_name 139 | machine_type = var.machine_type 140 | zone = var.zone 141 | project = var.project_id 142 | min_cpu_platform = "Automatic" 143 | 144 | boot_disk { 145 | auto_delete = true 146 | device_name = "boot" 147 | source = google_compute_disk.sap_ase_boot_disk.self_link 148 | } 149 | 150 | attached_disk { 151 | device_name = google_compute_disk.sap_ase_sid_disk.name 152 | source = google_compute_disk.sap_ase_sid_disk.self_link 153 | } 154 | 155 | attached_disk { 156 | device_name = google_compute_disk.sap_ase_sap_temp_disk.name 157 | source = google_compute_disk.sap_ase_sap_temp_disk.self_link 158 | } 159 | 160 | attached_disk { 161 | device_name = google_compute_disk.sap_ase_log_disk.name 162 | source = google_compute_disk.sap_ase_log_disk.self_link 163 | } 164 | 165 | attached_disk { 166 | device_name = google_compute_disk.sap_ase_sap_data_disk.name 167 | source = google_compute_disk.sap_ase_sap_data_disk.self_link 168 | } 169 | 170 | attached_disk { 171 | device_name = google_compute_disk.sap_ase_diag_disk.name 172 | source = google_compute_disk.sap_ase_diag_disk.self_link 173 | } 174 | 175 | dynamic "attached_disk" { 176 | for_each = var.ase_backup_size > 0 ? [1] : [] 177 | content { 178 | device_name = google_compute_disk.sap_ase_backup_disk[0].name 179 | source = google_compute_disk.sap_ase_backup_disk[0].self_link 180 | } 181 | } 182 | 183 | dynamic "attached_disk" { 184 | for_each = var.usr_sap_size > 0 ? [1] : [] 185 | content { 186 | device_name = google_compute_disk.sap_ase_usr_sap_disk[0].name 187 | source = google_compute_disk.sap_ase_usr_sap_disk[0].self_link 188 | } 189 | } 190 | 191 | dynamic "attached_disk" { 192 | for_each = var.swap_size > 0 ? [1] : [] 193 | content { 194 | device_name = google_compute_disk.sap_ase_swap_disk[0].name 195 | source = google_compute_disk.sap_ase_swap_disk[0].self_link 196 | } 197 | } 198 | 199 | dynamic "attached_disk" { 200 | for_each = var.sap_mnt_size > 0 ? [1] : [] 201 | content { 202 | device_name = google_compute_disk.sap_ase_sap_mnt_disk[0].name 203 | source = google_compute_disk.sap_ase_sap_mnt_disk[0].self_link 204 | } 205 | } 206 | 207 | can_ip_forward = var.can_ip_forward 208 | 209 | network_interface { 210 | subnetwork = local.subnetwork_uri 211 | network_ip = google_compute_address.sap_ase_vm_ip.address 212 | 213 | # we only include access_config if public_ip is true, an empty access_config 214 | # will create an ephemeral public ip 215 | dynamic "access_config" { 216 | for_each = var.public_ip ? [1] : [] 217 | content { 218 | } 219 | } 220 | } 221 | 222 | tags = var.network_tags 223 | 224 | service_account { 225 | # An empty string service account will default to the projects default compute engine service account 226 | email = var.service_account 227 | scopes = [ 228 | "https://www.googleapis.com/auth/cloud-platform" 229 | ] 230 | } 231 | 232 | dynamic "reservation_affinity" { 233 | for_each = length(var.reservation_name) > 1 ? [1] : [] 234 | content { 235 | type = "SPECIFIC_RESERVATION" 236 | specific_reservation { 237 | key = "compute.googleapis.com/reservation-name" 238 | values = [var.reservation_name] 239 | } 240 | } 241 | } 242 | 243 | metadata = merge(var.custom_metadata, { 244 | startup-script = local.primary_startup_url 245 | post_deployment_script = var.post_deployment_script 246 | sap_deployment_debug = var.sap_deployment_debug 247 | sap_ase_sid = var.ase_sid 248 | template-type = "TERRAFORM" 249 | }) 250 | 251 | lifecycle { 252 | # Ignore changes in the instance metadata, since it is modified by the SAP startup script. 253 | ignore_changes = [metadata] 254 | } 255 | } 256 | -------------------------------------------------------------------------------- /modules/s4/ansible.tf: -------------------------------------------------------------------------------- 1 | # Copyright 2024 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | data "google_compute_subnetwork" "sap-subnet-ansible-1" { 16 | name = var.subnet_name 17 | project = data.google_compute_network.sap-vpc.project 18 | region = var.region_name 19 | } 20 | 21 | data "google_service_account" "service_account_ansible" { 22 | account_id = var.ansible_sa_email == "" ? google_service_account.service_account_ansible[0].email : var.ansible_sa_email 23 | } 24 | 25 | resource "google_compute_address" "sapdansible11-1" { 26 | address_type = "INTERNAL" 27 | name = "${var.deployment_name}-ansible-runner-internal" 28 | project = data.google_project.sap-project.project_id 29 | region = var.region_name 30 | subnetwork = data.google_compute_subnetwork.sap-subnet-ansible-1.self_link 31 | } 32 | 33 | resource "google_compute_disk" "sapdansible11" { 34 | image = "projects/rhel-cloud/global/images/rhel-9-v20230615" 35 | lifecycle { 36 | ignore_changes = [snapshot, image] 37 | } 38 | name = "${var.deployment_name}-ansible-runner" 39 | project = data.google_project.sap-project.project_id 40 | size = 50 41 | timeouts { 42 | create = "1h" 43 | delete = "1h" 44 | update = "1h" 45 | } 46 | type = "pd-ssd" 47 | zone = var.zone1_name 48 | } 49 | 50 | resource "google_compute_instance" "sapdansible11" { 51 | allow_stopping_for_update = var.allow_stopping_for_update 52 | boot_disk { 53 | auto_delete = false 54 | device_name = "persistent-disk-0" 55 | source = google_compute_disk.sapdansible11.self_link 56 | } 57 | depends_on = [ 58 | google_storage_bucket_object.ansible_inventory, 59 | google_compute_instance.sapdapp11, 60 | google_compute_instance.sapddb11, 61 | google_compute_instance.sapdascs11 62 | ] 63 | labels = { 64 | active_region = true 65 | component = "ansible" 66 | component_type = "generic" 67 | environment = var.deployment_name 68 | service_group = "ansible_runner" 69 | } 70 | lifecycle { 71 | ignore_changes = [ 72 | min_cpu_platform, 73 | network_interface[0].alias_ip_range, 74 | metadata["ssh-keys"] 75 | ] 76 | } 77 | machine_type = "n1-standard-16" 78 | metadata = { 79 | active_region = true 80 | ansible_sa_email = data.google_service_account.service_account_ansible.email 81 | app_sa_email = data.google_service_account.service_account_app.email 82 | ascs_sa_email = data.google_service_account.service_account_ascs.email 83 | configuration_bucket_name = data.google_storage_bucket.configuration.name 84 | db_sa_email = data.google_service_account.service_account_db.email 85 | dns_zone_name = var.deployment_has_dns ? data.google_dns_managed_zone.sap_zone[0].name : "" 86 | is_test = var.is_test 87 | media_bucket_name = var.media_bucket_name 88 | ssh-keys = "" 89 | startup-script = "gsutil cp ${var.primary_startup_url} ./local_startup.sh; bash local_startup.sh ${var.package_location} ${var.deployment_name}" 90 | template_name = "s4" 91 | } 92 | name = "${var.deployment_name}-ansible-runner" 93 | network_interface { 94 | dynamic "access_config" { 95 | content { 96 | } 97 | for_each = var.public_ansible_runner_ip ? [1] : [] 98 | } 99 | network = data.google_compute_network.sap-vpc.self_link 100 | network_ip = google_compute_address.sapdansible11-1.address 101 | subnetwork = data.google_compute_subnetwork.sap-subnet-ansible-1.self_link 102 | } 103 | project = data.google_project.sap-project.project_id 104 | scheduling { 105 | automatic_restart = true 106 | on_host_maintenance = "MIGRATE" 107 | preemptible = false 108 | } 109 | service_account { 110 | email = data.google_service_account.service_account_ansible.email 111 | scopes = ["https://www.googleapis.com/auth/cloud-platform"] 112 | } 113 | tags = compact(concat(["${var.deployment_name}-s4-comms"], var.custom_tags)) 114 | zone = var.zone1_name 115 | } 116 | 117 | resource "google_project_iam_member" "ansible_sa_role_1" { 118 | count = var.ansible_sa_email == "" ? 1 : 0 119 | member = "serviceAccount:${data.google_service_account.service_account_ansible.email}" 120 | project = data.google_project.sap-project.project_id 121 | role = "roles/compute.instanceAdmin.v1" 122 | } 123 | 124 | resource "google_project_iam_member" "ansible_sa_role_10" { 125 | count = var.ansible_sa_email == "" ? 1 : 0 126 | member = "serviceAccount:${data.google_service_account.service_account_ansible.email}" 127 | project = data.google_project.sap-project.project_id 128 | role = "roles/iam.roleViewer" 129 | } 130 | 131 | resource "google_project_iam_member" "ansible_sa_role_11" { 132 | count = var.ansible_sa_email == "" ? 1 : 0 133 | member = "serviceAccount:${data.google_service_account.service_account_ansible.email}" 134 | project = data.google_project.sap-project.project_id 135 | role = "roles/workloadmanager.insightWriter" 136 | } 137 | 138 | resource "google_project_iam_member" "ansible_sa_role_2" { 139 | count = var.ansible_sa_email == "" ? 1 : 0 140 | member = "serviceAccount:${data.google_service_account.service_account_ansible.email}" 141 | project = data.google_project.sap-project.project_id 142 | role = "roles/storage.objectViewer" 143 | } 144 | 145 | resource "google_project_iam_member" "ansible_sa_role_3" { 146 | count = var.ansible_sa_email == "" ? 1 : 0 147 | member = "serviceAccount:${data.google_service_account.service_account_ansible.email}" 148 | project = data.google_project.sap-project.project_id 149 | role = "roles/dns.admin" 150 | } 151 | 152 | resource "google_project_iam_member" "ansible_sa_role_4" { 153 | count = var.ansible_sa_email == "" ? 1 : 0 154 | member = "serviceAccount:${data.google_service_account.service_account_ansible.email}" 155 | project = data.google_project.sap-project.project_id 156 | role = "roles/logging.admin" 157 | } 158 | 159 | resource "google_project_iam_member" "ansible_sa_role_5" { 160 | count = var.ansible_sa_email == "" ? 1 : 0 161 | member = "serviceAccount:${data.google_service_account.service_account_ansible.email}" 162 | project = data.google_project.sap-project.project_id 163 | role = "roles/iam.serviceAccountUser" 164 | } 165 | 166 | resource "google_project_iam_member" "ansible_sa_role_6" { 167 | count = var.ansible_sa_email == "" ? 1 : 0 168 | member = "serviceAccount:${data.google_service_account.service_account_ansible.email}" 169 | project = data.google_project.sap-project.project_id 170 | role = "roles/secretmanager.viewer" 171 | } 172 | 173 | resource "google_project_iam_member" "ansible_sa_role_7" { 174 | count = var.ansible_sa_email == "" ? 1 : 0 175 | member = "serviceAccount:${data.google_service_account.service_account_ansible.email}" 176 | project = data.google_project.sap-project.project_id 177 | role = "roles/secretmanager.secretAccessor" 178 | } 179 | 180 | resource "google_project_iam_member" "ansible_sa_role_8" { 181 | count = var.ansible_sa_email == "" ? 1 : 0 182 | member = "serviceAccount:${data.google_service_account.service_account_ansible.email}" 183 | project = data.google_project.sap-project.project_id 184 | role = "roles/monitoring.admin" 185 | } 186 | 187 | resource "google_project_iam_member" "ansible_sa_role_9" { 188 | count = var.ansible_sa_email == "" ? 1 : 0 189 | member = "serviceAccount:${data.google_service_account.service_account_ansible.email}" 190 | project = data.google_project.sap-project.project_id 191 | role = "roles/compute.viewer" 192 | } 193 | 194 | resource "google_service_account" "service_account_ansible" { 195 | account_id = "${var.deployment_name}-ansible" 196 | count = var.ansible_sa_email == "" ? 1 : 0 197 | project = data.google_project.sap-project.project_id 198 | } 199 | 200 | resource "google_service_account_iam_member" "ansible_sa_user_of_app" { 201 | count = var.ansible_sa_email == "" ? 1 : 0 202 | member = "serviceAccount:${data.google_service_account.service_account_ansible.email}" 203 | role = "roles/iam.serviceAccountUser" 204 | service_account_id = data.google_service_account.service_account_app.name 205 | } 206 | 207 | resource "google_service_account_iam_member" "ansible_sa_user_of_ascs" { 208 | count = var.ansible_sa_email == "" ? 1 : 0 209 | member = "serviceAccount:${data.google_service_account.service_account_ansible.email}" 210 | role = "roles/iam.serviceAccountUser" 211 | service_account_id = data.google_service_account.service_account_ascs.name 212 | } 213 | 214 | resource "google_service_account_iam_member" "ansible_sa_user_of_db" { 215 | count = var.ansible_sa_email == "" ? 1 : 0 216 | member = "serviceAccount:${data.google_service_account.service_account_ansible.email}" 217 | role = "roles/iam.serviceAccountUser" 218 | service_account_id = data.google_service_account.service_account_db.name 219 | } 220 | --------------------------------------------------------------------------------