├── .envrc ├── .gitignore ├── LICENSE ├── README.md ├── ci ├── assets │ └── template │ │ ├── control-plane-config.yml │ │ ├── director-config.yml │ │ └── srt-config.yml ├── configure └── pipeline.yml ├── modules ├── certs │ └── self_signed_certs.tf ├── control_plane │ ├── main.tf │ ├── outputs.tf │ └── variables.tf ├── infra │ ├── bosh.tf │ └── main.tf ├── isolation_segment │ ├── dns.tf │ ├── load_balancer.tf │ ├── outputs.tf │ ├── self_signed_certs.tf │ └── variables.tf ├── ops_manager │ ├── ops_manager.tf │ ├── outputs.tf │ └── variables.tf ├── pas │ ├── diegosshlb.tf │ ├── dns.tf │ ├── mysqllb.tf │ ├── outputs.tf │ ├── storage.tf │ ├── subnets.tf │ ├── tcplb.tf │ ├── variables.tf │ └── weblb.tf └── pks │ ├── firewall.tf │ ├── lb.tf │ ├── networking.tf │ ├── outputs.tf │ └── variables.tf ├── scripts ├── configure-director └── configure-product ├── terraforming-pas ├── main.tf ├── outputs.tf └── variables.tf └── terraforming-pks ├── main.tf ├── outputs.tf └── variables.tf /.envrc: -------------------------------------------------------------------------------- 1 | export PROJECT_DIR="${PWD}" 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.terraform 2 | *.tfstate.* 3 | *.tfstate 4 | .idea 5 | *.tfvars 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DEPRECATION 2 | 3 | This repo is going to be archived. 4 | The terraform templates that _should_ be used for deploying an Ops Manager, PAS and/or PKS, can be found at https://github.com/pivotal/paving 5 | No PRs or Issues will be responded to here. 6 | 7 | # Terraforming Azure 8 | 9 | ## How Does One Use This? 10 | 11 | Please note that the master branch is generally *unstable*. If you are looking for something "tested", please consume one of our [releases](https://github.com/pivotal-cf/terraforming-azure/releases). 12 | 13 | ## What Does This Do? 14 | 15 | Will go from zero to having a deployed ops-manager. You'll get networking, a storage account, and 16 | a booted ops-manager VM. 17 | 18 | ## Looking to setup a different IAAS 19 | 20 | We have other terraform templates to help you! 21 | 22 | - [aws](https://github.com/pivotal-cf/terraforming-aws) 23 | - [gcp](https://github.com/pivotal-cf/terraforming-gcp) 24 | 25 | ## Prerequisites 26 | 27 | - [terraform](https://learn.hashicorp.com/terraform/getting-started/install.html) 28 | - [azure cli](https://azure.microsoft.com/en-us/documentation/articles/xplat-cli-install/) 29 | 30 | ```bash 31 | brew update 32 | brew install terraform 33 | brew install az 34 | brew install jq 35 | ``` 36 | 37 | ## Creating A Service Principal 38 | 39 | You need a [service principal account](https://docs.microsoft.com/en-us/cli/azure/create-an-azure-service-principal-azure-cli?view=azure-cli-latest#create-a-service-principal) 40 | to deploy anything on top of Azure. 41 | 42 | 1. Login. 43 | ```bash 44 | $ az login 45 | $ az account show | jq -r '.id, .tenantId' 46 | the-subscription-id 47 | the-tenant-id 48 | ``` 49 | 50 | 1. Create the service principal where the name is a valid URI. 51 | ```bash 52 | $ az ad sp create-for-rbac --name http:// | jq -r '.appId, .password' 53 | the-app-id 54 | the-password 55 | ``` 56 | 57 | 1. Create a `terraform.tfvars` file the following: 58 | ```hcl 59 | subscription_id = "the-subscription-id" 60 | tenant_id = "the-tenant-id" 61 | client_id = "the-app-id" 62 | client_secret = "the-password" 63 | ``` 64 | 65 | ## Are you using Platform Automation? 66 | Be sure to skip the creation of the Ops Manager VM. Do not include the `ops_manager_image_uri` var as a [variable](/README.md#variables). If you create your Ops Manager using terraform, you will not be able to manage it with [Platform Automation](https://docs.pivotal.io/platform-automation). 67 | 68 | Deployment of the infrastructure is still required. 69 | 70 | ## Deploying Infrastructure 71 | 72 | *Note:* If you're using Platform Automation, be sure to skip this step as explained [here](/README.md#variables). If you create your Ops Manager here, you will not be able to manage it with [Platform Automation](https://docs.pivotal.io/platform-automation). 73 | 74 | Depending if you're deploying PAS or PKS you need to perform the following steps: 75 | 76 | 1. `cd` into the proper directory: 77 | - [terraforming-pas/](terraforming-pas/) 78 | 1. Create [`terraform.tfvars`](/README.md#var-file) file 79 | 1. Run terraform apply: 80 | ```bash 81 | terraform init 82 | terraform plan -out=plan 83 | terraform apply plan 84 | ``` 85 | 86 | 87 | ### Var File 88 | 89 | Copy the stub content below into a file called `terraform.tfvars` and put it in the root of this project. 90 | These vars will be used when you run `terraform apply`. 91 | You should fill in the stub values with the correct content. 92 | 93 | ```hcl 94 | subscription_id = "the-subscription-id" 95 | tenant_id = "the-tenant-id" 96 | client_id = "the-app-id" 97 | client_secret = "the-password" 98 | 99 | env_name = "banana" 100 | ops_manager_image_uri = "url-to-opsman-image" 101 | location = "West US" 102 | dns_suffix = "domain.com" 103 | 104 | # optional. if left blank, will default to the pattern `env_name.dns_suffix`. 105 | dns_subdomain = "" 106 | ``` 107 | 108 | ## Variables 109 | 110 | - env_name: **(required)** An arbitrary unique name for namespacing resources 111 | - subscription_id: **(required)** Azure account subscription id 112 | - tenant_id: **(required)** Azure account tenant id 113 | - client_id: **(required)** Azure automation account client id 114 | - client_secret: **(required)** Azure automation account client secret 115 | - ops_manager_image_uri: **(optional)** URL for an OpsMan image hosted on Azure (if not provided you get no Ops Manager) 116 | - location: **(required)** Azure location to stand up environment in 117 | - dns_suffix: **(required)** Domain to add environment subdomain to 118 | 119 | ### Optional 120 | 121 | When deploying the isolation segments tile you can optionally route traffic through 122 | a separate domain and load balancer by specifying: 123 | 124 | - isolation_segment: **(default false)** Creates a DNS record and load balancer for 125 | isolation segment network traffic when set to true. 126 | 127 | ## Running 128 | 129 | Note: please make sure you have created the `terraform.tfvars` file above as mentioned. 130 | 131 | ### Standing up environment 132 | 133 | ```bash 134 | terraform init 135 | terraform plan -out=plan 136 | terraform apply plan 137 | ``` 138 | 139 | ### Tearing down environment 140 | 141 | **Note:** This will only destroy resources deployed by Terraform. You will need to clean up anything deployed on top of that infrastructure yourself (e.g. by running `om delete-installation`) 142 | 143 | ```bash 144 | terraform destroy 145 | ``` 146 | -------------------------------------------------------------------------------- /ci/assets/template/control-plane-config.yml: -------------------------------------------------------------------------------- 1 | product-name: control-plane 2 | network-properties: 3 | network: 4 | name: {{.control_plane_subnet_name}} 5 | other_availability_zones: 6 | - name: 'zone-2' 7 | singleton_availability_zone: 8 | name: 'zone-1' 9 | product-properties: 10 | .properties.domain: 11 | value: {{.control_plane_domain}} 12 | .properties.control_plane_database: 13 | value: external 14 | .properties.control_plane_database.external.host: 15 | value: {{.control_plane_fqdn}} 16 | .properties.control_plane_database.external.port: 17 | value: '5432' 18 | .properties.control_plane_database.external.atc_db_name: 19 | value: atc 20 | .properties.control_plane_database.external.atc_db_username: 21 | value: {{.control_plane_db_username}} 22 | .properties.control_plane_database.external.atc_db_password: 23 | value: 24 | secret: {{.control_plane_db_password}} 25 | .properties.control_plane_database.external.credhub_db_name: 26 | value: credhub 27 | .properties.control_plane_database.external.credhub_db_username: 28 | value: {{.control_plane_db_username}} 29 | .properties.control_plane_database.external.credhub_db_password: 30 | value: 31 | secret: {{.control_plane_db_password}} 32 | .properties.control_plane_database.external.uaa_db_name: 33 | value: uaa 34 | .properties.control_plane_database.external.uaa_db_username: 35 | value: {{.control_plane_db_username}} 36 | .properties.control_plane_database.external.uaa_db_password: 37 | value: 38 | secret: {{.control_plane_db_password}} 39 | .properties.control_plane_database.external.ca_cert: 40 | value: {{toJson .db_ca_cert}} 41 | resource-config: 42 | web: 43 | instances: automatic 44 | elb_names: 45 | - {{.control_plane_lb_name}} 46 | internet_connected: true 47 | worker: 48 | internet_connected: true 49 | -------------------------------------------------------------------------------- /ci/assets/template/director-config.yml: -------------------------------------------------------------------------------- 1 | properties-configuration: 2 | director_configuration: 3 | ntp_servers_string: us.pool.ntp.org 4 | iaas_configuration: 5 | subscription_id: {{.subscription_id}} 6 | tenant_id: {{.tenant_id}} 7 | client_id: {{.client_id}} 8 | client_secret: {{.client_secret}} 9 | resource_group_name: {{.pcf_resource_group_name}} 10 | bosh_storage_account_name: {{.bosh_root_storage_account}} 11 | ssh_public_key: {{.ops_manager_ssh_public_key}} 12 | ssh_private_key: {{toJson .ops_manager_ssh_private_key}} 13 | {{if index . "terraforming_ca_cert"}} 14 | security_configuration: 15 | trusted_certificates: | 16 | {{indent 6 .terraforming_ca_cert}} 17 | {{end}} 18 | network-assignment: 19 | singleton_availability_zone: 20 | name: zone-1 21 | network: 22 | name: {{.infrastructure_subnet_name}} 23 | networks-configuration: 24 | icmp_checks_enabled: false 25 | networks: 26 | - name: {{.infrastructure_subnet_name}} 27 | subnets: 28 | - cidr: {{.infrastructure_subnet_cidr}} 29 | dns: 168.63.129.16 30 | gateway: {{.infrastructure_subnet_gateway}} 31 | iaas_identifier: {{.network_name}}/{{.infrastructure_subnet_name}} 32 | reserved_ip_ranges: {{cidrhost .infrastructure_subnet_cidr 0}}-{{cidrhost .infrastructure_subnet_cidr 5}} 33 | {{if index . "pas_subnet_cidr"}} 34 | - name: {{.pas_subnet_name}} 35 | subnets: 36 | - cidr: {{.pas_subnet_cidr}} 37 | dns: 168.63.129.16 38 | gateway: {{.pas_subnet_gateway}} 39 | iaas_identifier: {{.network_name}}/{{.pas_subnet_name}} 40 | reserved_ip_ranges: {{cidrhost .pas_subnet_cidr 0}}-{{cidrhost .pas_subnet_cidr 5}} 41 | {{end}} 42 | {{if index . "pks_subnet_cidr"}} 43 | - name: {{.pks_subnet_name}} 44 | subnets: 45 | - cidr: {{.pks_subnet_cidr}} 46 | dns: 168.63.129.16 47 | gateway: {{.pks_subnet_gateway}} 48 | iaas_identifier: {{.network_name}}/{{.pks_subnet_name}} 49 | reserved_ip_ranges: {{cidrhost .pks_subnet_cidr 0}}-{{cidrhost .pks_subnet_cidr 5}} 50 | {{end}} 51 | {{if index . "services_subnet_cidr"}} 52 | - name: {{.services_subnet_name}} 53 | subnets: 54 | - cidr: {{.services_subnet_cidr}} 55 | dns: 168.63.129.16 56 | gateway: {{.services_subnet_gateway}} 57 | iaas_identifier: {{.network_name}}/{{.services_subnet_name}} 58 | reserved_ip_ranges: {{cidrhost .services_subnet_cidr 0}}-{{cidrhost .services_subnet_cidr 5}} 59 | {{end}} 60 | {{if index . "control_plane_subnet_cidr"}} 61 | - name: {{.control_plane_subnet_name}} 62 | subnets: 63 | - cidr: {{.control_plane_subnet_cidr}} 64 | dns: 168.63.129.16 65 | gateway: {{.control_plane_subnet_gateway}} 66 | iaas_identifier: {{.network_name}}/{{.control_plane_subnet_name}} 67 | reserved_ip_ranges: {{cidrhost .control_plane_subnet_cidr 0}}-{{cidrhost .control_plane_subnet_cidr 5}} 68 | {{end}} 69 | resource-configuration: 70 | compilation: 71 | instance_type: 72 | id: automatic 73 | -------------------------------------------------------------------------------- /ci/assets/template/srt-config.yml: -------------------------------------------------------------------------------- 1 | product-name: cf 2 | network-properties: 3 | network: 4 | name: {{.pas_subnet_name}} 5 | service_network: 6 | name: {{.services_subnet_name}} 7 | other_availability_zones: 8 | - name: 'zone-2' 9 | singleton_availability_zone: 10 | name: 'zone-1' 11 | product-properties: 12 | .cloud_controller.apps_domain: 13 | value: {{.apps_domain}} 14 | .cloud_controller.system_domain: 15 | value: {{.sys_domain}} 16 | .properties.cf_networking_search_domains: 17 | value: apps.internal 18 | .ha_proxy.skip_cert_verify: 19 | value: true 20 | .mysql_monitor.recipient_email: 21 | value: cf-infra@pivotal.io 22 | .properties.credhub_key_encryption_passwords: 23 | value: 24 | - key: 25 | secret: 1a2b3c4d5e6f7g8h9i0j 26 | name: Key 27 | primary: true 28 | provider: internal 29 | .properties.haproxy_forward_tls: 30 | value: disable 31 | .properties.networking_poe_ssl_certs: 32 | value: 33 | - certificate: 34 | cert_pem: | 35 | {{indent 10 .ssl_cert}} 36 | private_key_pem: | 37 | {{indent 10 .ssl_private_key}} 38 | name: Certificate 39 | .properties.security_acknowledgement: 40 | value: X 41 | .properties.system_blobstore: 42 | value: external_azure 43 | .properties.system_blobstore.external_azure.access_key: 44 | value: 45 | secret: {{.cf_storage_account_access_key}} 46 | .properties.system_blobstore.external_azure.account_name: 47 | value: {{.cf_storage_account_name}} 48 | .properties.system_blobstore.external_azure.buildpacks_container: 49 | value: {{.cf_buildpacks_storage_container}} 50 | .properties.system_blobstore.external_azure.droplets_container: 51 | value: {{.cf_droplets_storage_container}} 52 | .properties.system_blobstore.external_azure.packages_container: 53 | value: {{.cf_packages_storage_container}} 54 | .properties.system_blobstore.external_azure.resources_container: 55 | value: {{.cf_resources_storage_container}} 56 | .router.frontend_idle_timeout: 57 | value: 180 58 | .properties.tcp_routing: 59 | value: enable 60 | .properties.tcp_routing.enable.reservable_ports: 61 | value: 1024-1123 62 | .uaa.service_provider_key_credentials: 63 | value: 64 | cert_pem: | 65 | {{indent 10 .ssl_cert}} 66 | private_key_pem: | 67 | {{indent 10 .ssl_private_key}} 68 | resource-config: 69 | compute: 70 | instances: 1 71 | control: 72 | elb_names: 73 | - {{.diego_ssh_lb_name}} 74 | router: 75 | elb_names: 76 | - {{.web_lb_name}} 77 | instances: 1 78 | tcp_router: 79 | elb_names: 80 | - {{.tcp_lb_name}} 81 | database: 82 | elb_names: 83 | - {{.mysql_lb_name}} 84 | -------------------------------------------------------------------------------- /ci/configure: -------------------------------------------------------------------------------- 1 | #!/bin/bash -eu 2 | 3 | main() { 4 | fly -t "ovoc" set-pipeline -p terraforming-azure \ 5 | -c "${PROJECT_DIR}/ci/pipeline.yml" 6 | } 7 | 8 | main "$@" 9 | -------------------------------------------------------------------------------- /ci/pipeline.yml: -------------------------------------------------------------------------------- 1 | resource_types: 2 | - name: terraform 3 | type: docker-image 4 | source: 5 | repository: ljfranklin/terraform-resource 6 | tag: beta-backend 7 | 8 | - name: pivnet 9 | type: docker-image 10 | source: 11 | repository: pivotalcf/pivnet-resource 12 | tag: latest-final 13 | 14 | shared: 15 | - params: &modify-terraforming-dns-params 16 | GCP_DNS_PROJECT_ID: ((cf_infra_gcp_project_id)) 17 | GCP_DNS_SERVICE_ACCOUNT_EMAIL: ((cf_infra_gcp_service_account_email)) 18 | GCP_DNS_SERVICE_ACCOUNT_KEY: ((cf_infra_gcp_service_account_key)) 19 | GCP_DNS_ZONE_NAME: infrastructure 20 | GCP_DNS_SUFFIX: azure.infrastructure.cf-app.com 21 | GCP_DNS_RECORD_TTL: 60 22 | 23 | - params: &om-creds 24 | OM_USERNAME: ((om.username)) 25 | OM_PASSWORD: ((om.password)) 26 | 27 | resources: 28 | - name: after-midnight 29 | type: time 30 | source: 31 | start: 12:00 AM -0700 32 | stop: 2:00 AM -0700 33 | 34 | - name: cf-infra-tracker 35 | type: tracker 36 | source: 37 | token: ((cf_infra_tracker_token)) 38 | project_id: ((cf_infrastructure_tracker_id)) 39 | tracker_url: https://www.pivotaltracker.com 40 | 41 | - name: terraforming 42 | type: git 43 | source: 44 | branch: master 45 | uri: git@github.com:pivotal-cf/terraforming-azure.git 46 | private_key: ((cf_infra_bot_github_user.private_key)) 47 | 48 | - name: terraforming-release 49 | type: github-release 50 | source: 51 | owner: pivotal-cf 52 | repository: terraforming-azure 53 | access_token: ((cf_infra_bot_user_github_access_token)) 54 | drafts: true 55 | 56 | - name: version 57 | type: semver 58 | source: 59 | initial_version: 0.16.0 60 | driver: s3 61 | bucket: terraforming 62 | key: terraforming-azure/version 63 | access_key_id: ((aws_access_key_id)) 64 | secret_access_key: ((aws_secret_access_key)) 65 | 66 | - name: env-state-azure 67 | type: terraform 68 | source: 69 | backend_type: gcs 70 | backend_config: 71 | bucket: infra-tf-states 72 | prefix: azure 73 | region: us-central1 74 | credentials: ((cf_infra_gcp_service_account_key)) 75 | vars: 76 | location: "East US" 77 | subscription_id: ((azure_subscription_id)) 78 | tenant_id: ((azure_tenant_id)) 79 | client_id: ((azure_client_id)) 80 | client_secret: ((azure_client_secret)) 81 | vm_admin_username: "admin-username" 82 | vm_admin_password: ((azure_vm_admin_password)) 83 | dns_suffix: azure.infrastructure.cf-app.com 84 | ssl_cert: ((terraforming-azure.certificate)) 85 | ssl_private_key: ((terraforming-azure.private_key)) 86 | 87 | - name: infrastructure-ci 88 | type: git 89 | source: 90 | branch: master 91 | uri: https://github.com/cloudfoundry/infrastructure-ci.git 92 | 93 | - name: pcf-releng-ci 94 | type: git 95 | source: 96 | uri: git@github.com:pivotal-cf/pcf-releng-ci.git 97 | private_key: ((cf_infra_bot_github_user.private_key)) 98 | ignore_paths: 99 | - pipelines 100 | - ci_screen 101 | 102 | - name: srt 103 | type: pivnet 104 | source: 105 | api_token: ((pivnet_token)) 106 | product_slug: elastic-runtime 107 | product_version: ^\d+\.\d+\.\d+ 108 | sort_by: semver 109 | 110 | - name: opsman-image 111 | type: pivnet 112 | source: 113 | product_slug: ops-manager 114 | api_token: ((pivnet_token)) 115 | product_version: ^\d+\.\d+\.\d+ 116 | sort_by: semver 117 | 118 | jobs: 119 | - name: deploy-pas 120 | serial: true 121 | public: false 122 | plan: 123 | - aggregate: 124 | - get: after-midnight 125 | trigger: true 126 | - get: terraforming 127 | trigger: true 128 | - get: ci 129 | resource: infrastructure-ci 130 | - get: pcf-releng-ci 131 | - get: srt 132 | trigger: true 133 | params: 134 | globs: 135 | - srt-*.pivotal 136 | - get: opsman-image 137 | trigger: true 138 | params: 139 | globs: 140 | - '*azure*.yml' 141 | - do: 142 | - task: opsman-url 143 | file: ci/scripts/terraforming/latest-opsman/task.yml 144 | params: 145 | IAAS: azure 146 | KEY: east_us 147 | - put: env-state-azure 148 | params: 149 | env_name: tf-ci 150 | terraform_source: terraforming/terraforming-pas 151 | var_files: [tfvars/terraform.yml] 152 | - task: add-dns 153 | file: ci/scripts/common/manage-gcp-dns/task-terraforming.yml 154 | params: 155 | <<: *modify-terraforming-dns-params 156 | ACTION: add 157 | input_mapping: 158 | env-state: env-state-azure 159 | - task: configure-director 160 | file: ci/scripts/terraforming/configure-director/task.yml 161 | params: 162 | <<: *om-creds 163 | TEMPLATE_PATH: director-config-template/ci/assets/template/director-config.yml 164 | CA_CERT: ((terraforming-ca.ca)) 165 | input_mapping: 166 | env-state: env-state-azure 167 | director-config-template: terraforming 168 | - task: download-stemcell 169 | file: pcf-releng-ci/tasks/configuration/download-pivnet-stemcell/task.yml 170 | input_mapping: 171 | ert-product: srt 172 | params: 173 | IAAS_TYPE: azure 174 | PIVNET_TOKEN: ((pivnet_token)) 175 | - task: upload-configure-stage-pas 176 | file: ci/scripts/terraforming/upload-configure-stage/task.yml 177 | params: 178 | <<: *om-creds 179 | PRODUCT_NAME: cf 180 | PRODUCT_CONFIG_TEMPLATE: ci/assets/template/srt-config.yml 181 | input_mapping: 182 | env-state: env-state-azure 183 | product: srt 184 | product-config-repo: terraforming 185 | - task: apply-changes 186 | file: ci/scripts/terraforming/apply-changes/task.yml 187 | params: 188 | <<: *om-creds 189 | input_mapping: 190 | env-state: env-state-azure 191 | ensure: 192 | do: 193 | - task: delete-installation 194 | file: pcf-releng-ci/tasks/environment/delete-installation/task.yml 195 | params: 196 | OPSMAN_USERNAME: ((om.username)) 197 | OPSMAN_PASSWORD: ((om.password)) 198 | OPSMAN_URL_SUFFIX: azure.infrastructure.cf-app.com 199 | input_mapping: 200 | environment: env-state-azure 201 | - aggregate: 202 | - task: remove-dns 203 | file: ci/scripts/common/manage-gcp-dns/task-terraforming.yml 204 | params: 205 | <<: *modify-terraforming-dns-params 206 | ACTION: remove 207 | CHECK_DNS: false 208 | input_mapping: 209 | env-state: env-state-azure 210 | - put: env-state-azure 211 | params: 212 | terraform_source: terraforming/terraforming-pas 213 | env_name_file: env-state-azure/name 214 | delete_on_failure: true 215 | action: destroy 216 | var_files: [tfvars/terraform.yml] 217 | get_params: 218 | action: destroy 219 | 220 | - name: publish 221 | serial: true 222 | plan: 223 | - aggregate: 224 | - get: terraforming 225 | passed: [deploy-pas] 226 | trigger: true 227 | - get: version 228 | params: 229 | bump: minor 230 | - get: ci 231 | resource: infrastructure-ci 232 | - task: release 233 | file: ci/scripts/terraforming/release/task.yml 234 | params: 235 | IAAS: azure 236 | - put: terraforming-release 237 | params: 238 | name: release/version 239 | tag: release/version 240 | commitish: release/commitish 241 | globs: 242 | - release/terraforming-azure-*.tar.gz 243 | - put: version 244 | params: 245 | file: version/version 246 | 247 | - name: deliver-stories 248 | plan: 249 | - get: terraforming 250 | trigger: true 251 | passed: 252 | - deploy-pas 253 | - put: cf-infra-tracker 254 | params: 255 | repos: 256 | - terraforming 257 | -------------------------------------------------------------------------------- /modules/certs/self_signed_certs.tf: -------------------------------------------------------------------------------- 1 | variable "env_name" { 2 | default = "" 3 | } 4 | 5 | variable "dns_suffix" { 6 | default = "" 7 | } 8 | 9 | variable "ssl_ca_cert" { 10 | default = "" 11 | } 12 | 13 | variable "ssl_ca_private_key" { 14 | default = "" 15 | } 16 | 17 | resource "tls_cert_request" "ssl_csr" { 18 | key_algorithm = "RSA" 19 | private_key_pem = "${tls_private_key.ssl_private_key.private_key_pem}" 20 | 21 | dns_names = [ 22 | "*.apps.${var.env_name}.${var.dns_suffix}", 23 | "*.sys.${var.env_name}.${var.dns_suffix}", 24 | ] 25 | 26 | count = "${length(var.ssl_ca_cert) > 0 ? 1 : 0}" 27 | 28 | subject { 29 | common_name = "${var.env_name}.${var.dns_suffix}" 30 | organization = "Pivotal" 31 | organizational_unit = "Cloudfoundry" 32 | country = "US" 33 | province = "CA" 34 | locality = "San Francisco" 35 | } 36 | } 37 | 38 | resource "tls_locally_signed_cert" "ssl_cert" { 39 | cert_request_pem = "${tls_cert_request.ssl_csr.cert_request_pem}" 40 | ca_key_algorithm = "RSA" 41 | ca_private_key_pem = "${var.ssl_ca_private_key}" 42 | ca_cert_pem = "${var.ssl_ca_cert}" 43 | 44 | count = "${length(var.ssl_ca_cert) > 0 ? 1 : 0}" 45 | 46 | validity_period_hours = 8760 # 1year 47 | 48 | allowed_uses = [ 49 | "key_encipherment", 50 | "digital_signature", 51 | "server_auth", 52 | ] 53 | } 54 | 55 | resource "tls_private_key" "ssl_private_key" { 56 | algorithm = "RSA" 57 | rsa_bits = "2048" 58 | 59 | count = "${length(var.ssl_ca_cert) > 0 ? 1 : 0}" 60 | } 61 | 62 | output "ssl_cert" { 63 | sensitive = true 64 | value = "${element(concat(tls_locally_signed_cert.ssl_cert.*.cert_pem, list("")), 0)}" 65 | } 66 | 67 | output "ssl_private_key" { 68 | sensitive = true 69 | value = "${element(concat(tls_private_key.ssl_private_key.*.private_key_pem, list("")), 0)}" 70 | } 71 | -------------------------------------------------------------------------------- /modules/control_plane/main.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | name_prefix = "${var.env_name}-plane" 3 | web_ports = [80, 443, 8443, 8844, 2222] 4 | } 5 | 6 | # DNS 7 | 8 | resource "azurerm_dns_a_record" "plane" { 9 | resource_group_name = "${var.resource_group_name}" 10 | name = "plane" 11 | zone_name = "${var.dns_zone_name}" 12 | ttl = "60" 13 | records = ["${azurerm_public_ip.plane.ip_address}"] 14 | } 15 | 16 | # Load Balancers 17 | 18 | resource "azurerm_public_ip" "plane" { 19 | resource_group_name = "${var.resource_group_name}" 20 | name = "${local.name_prefix}-ip" 21 | location = "${var.location}" 22 | allocation_method = "Static" 23 | sku = "Standard" 24 | } 25 | 26 | resource "azurerm_lb" "plane" { 27 | resource_group_name = "${var.resource_group_name}" 28 | name = "${var.env_name}-lb" 29 | location = "${var.location}" 30 | 31 | frontend_ip_configuration { 32 | name = "${local.name_prefix}-ip" 33 | public_ip_address_id = "${azurerm_public_ip.plane.id}" 34 | } 35 | } 36 | 37 | resource "azurerm_lb_backend_address_pool" "plane" { 38 | resource_group_name = "${var.resource_group_name}" 39 | name = "${local.name_prefix}-pool" 40 | loadbalancer_id = "${azurerm_lb.plane.id}" 41 | } 42 | 43 | resource "azurerm_lb_probe" "plane" { 44 | resource_group_name = "${var.resource_group_name}" 45 | count = "${length(local.web_ports)}" 46 | name = "${local.name_prefix}-${element(local.web_ports, count.index)}-probe" 47 | 48 | port = "${element(local.web_ports, count.index)}" 49 | protocol = "Tcp" 50 | 51 | loadbalancer_id = "${azurerm_lb.plane.id}" 52 | interval_in_seconds = 5 53 | number_of_probes = 2 54 | } 55 | 56 | resource "azurerm_lb_rule" "plane" { 57 | resource_group_name = "${var.resource_group_name}" 58 | count = "${length(local.web_ports)}" 59 | name = "${local.name_prefix}-${element(local.web_ports, count.index)}" 60 | 61 | protocol = "Tcp" 62 | loadbalancer_id = "${azurerm_lb.plane.id}" 63 | frontend_port = "${element(local.web_ports, count.index)}" 64 | backend_port = "${element(local.web_ports, count.index)}" 65 | backend_address_pool_id = "${azurerm_lb_backend_address_pool.plane.id}" 66 | frontend_ip_configuration_name = "${azurerm_public_ip.plane.name}" 67 | probe_id = "${element(azurerm_lb_probe.plane.*.id, count.index)}" 68 | } 69 | 70 | # Firewall 71 | 72 | resource "azurerm_network_security_group" "plane" { 73 | name = "${local.name_prefix}-security-group" 74 | location = "${var.location}" 75 | resource_group_name = "${var.resource_group_name}" 76 | } 77 | 78 | resource "azurerm_network_security_rule" "plane" { 79 | resource_group_name = "${var.resource_group_name}" 80 | network_security_group_name = "${azurerm_network_security_group.plane.name}" 81 | 82 | name = "${local.name_prefix}-security-group-rule" 83 | priority = 100 84 | direction = "Inbound" 85 | access = "Allow" 86 | protocol = "Tcp" 87 | source_port_range = "*" 88 | destination_port_ranges = "${local.web_ports}" 89 | source_address_prefix = "*" 90 | destination_address_prefix = "*" 91 | } 92 | 93 | # Network 94 | 95 | resource "azurerm_subnet" "plane" { 96 | name = "${local.name_prefix}-subnet" 97 | resource_group_name = "${var.resource_group_name}" 98 | virtual_network_name = "${var.network_name}" 99 | address_prefix = "${var.cidr}" 100 | } 101 | 102 | # Database 103 | 104 | resource "azurerm_postgresql_server" "plane" { 105 | name = "${local.name_prefix}-postgres" 106 | resource_group_name = "${var.resource_group_name}" 107 | location = "${var.location}" 108 | 109 | sku { 110 | name = "B_Gen5_2" 111 | capacity = 2 112 | tier = "Basic" 113 | family = "Gen5" 114 | } 115 | 116 | storage_profile { 117 | storage_mb = 10240 118 | backup_retention_days = 7 119 | geo_redundant_backup = "Disabled" 120 | } 121 | 122 | administrator_login = "${var.postgres_username}" 123 | administrator_login_password = "${random_string.postgres_password.result}" 124 | version = "9.6" 125 | ssl_enforcement = "Enabled" 126 | 127 | count = "${var.external_db ? 1 : 0}" 128 | } 129 | 130 | resource "azurerm_postgresql_firewall_rule" "plane" { 131 | name = "${local.name_prefix}-postgres-firewall" 132 | resource_group_name = "${var.resource_group_name}" 133 | server_name = "${element(azurerm_postgresql_server.plane.*.name, 0)}" 134 | 135 | # Note, these only refer to internal AZURE IPs and not external 136 | # access from anywhere. Please don't change them unless you know 137 | # what you are doing. See terraform docs for details 138 | 139 | start_ip_address = "0.0.0.0" 140 | end_ip_address = "0.0.0.0" 141 | count = "${var.external_db ? 1 : 0}" 142 | } 143 | 144 | resource "azurerm_postgresql_database" "atc" { 145 | resource_group_name = "${var.resource_group_name}" 146 | name = "atc" 147 | 148 | server_name = "${azurerm_postgresql_server.plane.name}" 149 | charset = "UTF8" 150 | collation = "English_United States.1252" 151 | 152 | count = "${var.external_db ? 1 : 0}" 153 | } 154 | 155 | resource "azurerm_postgresql_database" "credhub" { 156 | resource_group_name = "${var.resource_group_name}" 157 | name = "credhub" 158 | 159 | server_name = "${azurerm_postgresql_server.plane.name}" 160 | charset = "UTF8" 161 | collation = "English_United States.1252" 162 | 163 | depends_on = ["azurerm_postgresql_database.atc"] 164 | count = "${var.external_db ? 1 : 0}" 165 | } 166 | 167 | resource "azurerm_postgresql_database" "uaa" { 168 | resource_group_name = "${var.resource_group_name}" 169 | name = "uaa" 170 | 171 | server_name = "${azurerm_postgresql_server.plane.name}" 172 | charset = "UTF8" 173 | collation = "English_United States.1252" 174 | 175 | depends_on = ["azurerm_postgresql_database.credhub"] 176 | count = "${var.external_db ? 1 : 0}" 177 | } 178 | 179 | resource "random_string" "postgres_password" { 180 | length = 16 181 | special = false 182 | } 183 | -------------------------------------------------------------------------------- /modules/control_plane/outputs.tf: -------------------------------------------------------------------------------- 1 | output "cidr" { 2 | value = "${var.cidr}" 3 | } 4 | 5 | output "postgres_fqdn" { 6 | value = "${element(concat(azurerm_postgresql_server.plane.*.fqdn, list("")), 0)}" 7 | } 8 | 9 | output "postgres_password" { 10 | value = "${random_string.postgres_password.result}" 11 | } 12 | 13 | output "postgres_username" { 14 | value = "${var.postgres_username}@${element(concat(azurerm_postgresql_server.plane.*.name, list("")), 0)}" 15 | } 16 | 17 | output "plane_lb_name" { 18 | value = "${azurerm_lb.plane.name}" 19 | } 20 | 21 | output "dns_name" { 22 | value = "${azurerm_dns_a_record.plane.name}.${azurerm_dns_a_record.plane.zone_name}" 23 | } 24 | 25 | output "network_name" { 26 | value = "${azurerm_subnet.plane.name}" 27 | } 28 | 29 | output "subnet_gateway" { 30 | value = "${cidrhost(var.cidr, 1)}" 31 | } 32 | -------------------------------------------------------------------------------- /modules/control_plane/variables.tf: -------------------------------------------------------------------------------- 1 | variable "cidr" {} 2 | variable "dns_zone_name" {} 3 | variable "env_name" {} 4 | variable "external_db" {} 5 | variable "location" {} 6 | variable "resource_group_name" {} 7 | variable "network_name" {} 8 | variable "postgres_username" {} 9 | -------------------------------------------------------------------------------- /modules/infra/bosh.tf: -------------------------------------------------------------------------------- 1 | resource random_string "bosh_storage_account_name" { 2 | length = 20 3 | special = false 4 | upper = false 5 | } 6 | 7 | resource "azurerm_storage_account" "bosh_root_storage_account" { 8 | name = "${random_string.bosh_storage_account_name.result}" 9 | resource_group_name = "${azurerm_resource_group.pcf_resource_group.name}" 10 | location = "${var.location}" 11 | account_tier = "Standard" 12 | account_replication_type = "LRS" 13 | 14 | tags = { 15 | environment = "${var.env_name}" 16 | account_for = "bosh" 17 | } 18 | } 19 | 20 | resource "azurerm_storage_container" "bosh_storage_container" { 21 | name = "bosh" 22 | depends_on = ["azurerm_storage_account.bosh_root_storage_account"] 23 | resource_group_name = "${azurerm_resource_group.pcf_resource_group.name}" 24 | storage_account_name = "${azurerm_storage_account.bosh_root_storage_account.name}" 25 | container_access_type = "private" 26 | } 27 | 28 | resource "azurerm_storage_container" "stemcell_storage_container" { 29 | name = "stemcell" 30 | depends_on = ["azurerm_storage_account.bosh_root_storage_account"] 31 | resource_group_name = "${azurerm_resource_group.pcf_resource_group.name}" 32 | storage_account_name = "${azurerm_storage_account.bosh_root_storage_account.name}" 33 | container_access_type = "blob" 34 | } 35 | 36 | resource "azurerm_storage_table" "stemcells_storage_table" { 37 | name = "stemcells" 38 | resource_group_name = "${azurerm_resource_group.pcf_resource_group.name}" 39 | storage_account_name = "${azurerm_storage_account.bosh_root_storage_account.name}" 40 | } 41 | 42 | output "bosh_root_storage_account" { 43 | value = "${azurerm_storage_account.bosh_root_storage_account.name}" 44 | } 45 | -------------------------------------------------------------------------------- /modules/infra/main.tf: -------------------------------------------------------------------------------- 1 | variable "env_name" { 2 | default = "" 3 | } 4 | 5 | variable "location" { 6 | default = "" 7 | } 8 | 9 | variable "dns_subdomain" { 10 | default = "" 11 | } 12 | 13 | variable "dns_suffix" { 14 | default = "" 15 | } 16 | 17 | variable "pcf_virtual_network_address_space" { 18 | type = "list" 19 | default = [] 20 | } 21 | 22 | variable "pcf_infrastructure_subnet" { 23 | default = "" 24 | } 25 | 26 | resource "azurerm_resource_group" "pcf_resource_group" { 27 | name = "${var.env_name}" 28 | location = "${var.location}" 29 | } 30 | 31 | # ============== Security Groups =============== 32 | 33 | resource "azurerm_network_security_group" "ops_manager_security_group" { 34 | name = "${var.env_name}-ops-manager-security-group" 35 | location = "${var.location}" 36 | resource_group_name = "${azurerm_resource_group.pcf_resource_group.name}" 37 | 38 | security_rule { 39 | name = "ssh" 40 | priority = 200 41 | direction = "Inbound" 42 | access = "Allow" 43 | protocol = "Tcp" 44 | source_port_range = "*" 45 | destination_port_range = 22 46 | source_address_prefix = "Internet" 47 | destination_address_prefix = "*" 48 | } 49 | 50 | security_rule { 51 | name = "http" 52 | priority = 204 53 | direction = "Inbound" 54 | access = "Allow" 55 | protocol = "*" 56 | source_port_range = "*" 57 | destination_port_range = 80 58 | source_address_prefix = "Internet" 59 | destination_address_prefix = "*" 60 | } 61 | 62 | security_rule { 63 | name = "https" 64 | priority = 205 65 | direction = "Inbound" 66 | access = "Allow" 67 | protocol = "*" 68 | source_port_range = "*" 69 | destination_port_range = 443 70 | source_address_prefix = "Internet" 71 | destination_address_prefix = "*" 72 | } 73 | } 74 | 75 | resource "azurerm_network_security_group" "bosh_deployed_vms_security_group" { 76 | name = "${var.env_name}-bosh-deployed-vms-security-group" 77 | location = "${var.location}" 78 | resource_group_name = "${azurerm_resource_group.pcf_resource_group.name}" 79 | 80 | security_rule { 81 | name = "internal-anything" 82 | priority = 100 83 | direction = "Inbound" 84 | access = "Allow" 85 | protocol = "*" 86 | source_port_range = "*" 87 | destination_port_range = "*" 88 | source_address_prefix = "VirtualNetwork" 89 | destination_address_prefix = "*" 90 | } 91 | 92 | security_rule { 93 | name = "ssh" 94 | priority = 200 95 | direction = "Inbound" 96 | access = "Allow" 97 | protocol = "Tcp" 98 | source_port_range = "*" 99 | destination_port_range = 22 100 | source_address_prefix = "Internet" 101 | destination_address_prefix = "*" 102 | } 103 | 104 | security_rule { 105 | name = "bosh-agent" 106 | priority = 201 107 | direction = "Inbound" 108 | access = "Allow" 109 | protocol = "Tcp" 110 | source_port_range = "*" 111 | destination_port_range = 6868 112 | source_address_prefix = "Internet" 113 | destination_address_prefix = "*" 114 | } 115 | 116 | security_rule { 117 | name = "bosh-director" 118 | priority = 202 119 | direction = "Inbound" 120 | access = "Allow" 121 | protocol = "Tcp" 122 | source_port_range = "*" 123 | destination_port_range = 25555 124 | source_address_prefix = "Internet" 125 | destination_address_prefix = "*" 126 | } 127 | 128 | security_rule { 129 | name = "dns" 130 | priority = 203 131 | direction = "Inbound" 132 | access = "Allow" 133 | protocol = "*" 134 | source_port_range = "*" 135 | destination_port_range = 53 136 | source_address_prefix = "Internet" 137 | destination_address_prefix = "*" 138 | } 139 | 140 | security_rule { 141 | name = "http" 142 | priority = 204 143 | direction = "Inbound" 144 | access = "Allow" 145 | protocol = "*" 146 | source_port_range = "*" 147 | destination_port_range = 80 148 | source_address_prefix = "Internet" 149 | destination_address_prefix = "*" 150 | } 151 | 152 | security_rule { 153 | name = "https" 154 | priority = 205 155 | direction = "Inbound" 156 | access = "Allow" 157 | protocol = "*" 158 | source_port_range = "*" 159 | destination_port_range = 443 160 | source_address_prefix = "Internet" 161 | destination_address_prefix = "*" 162 | } 163 | 164 | security_rule { 165 | name = "loggregator" 166 | priority = 206 167 | direction = "Inbound" 168 | access = "Allow" 169 | protocol = "*" 170 | source_port_range = "*" 171 | destination_port_range = 4443 172 | source_address_prefix = "Internet" 173 | destination_address_prefix = "*" 174 | } 175 | 176 | security_rule { 177 | name = "diego-ssh" 178 | priority = 209 179 | direction = "Inbound" 180 | access = "Allow" 181 | protocol = "Tcp" 182 | source_port_range = "*" 183 | destination_port_range = 2222 184 | source_address_prefix = "Internet" 185 | destination_address_prefix = "*" 186 | } 187 | 188 | security_rule { 189 | name = "tcp" 190 | priority = 210 191 | direction = "Inbound" 192 | access = "Allow" 193 | protocol = "Tcp" 194 | source_port_range = "*" 195 | destination_port_range = "1024-1173" 196 | source_address_prefix = "Internet" 197 | destination_address_prefix = "*" 198 | } 199 | } 200 | 201 | # ============= Networking 202 | 203 | resource "azurerm_virtual_network" "pcf_virtual_network" { 204 | name = "${var.env_name}-virtual-network" 205 | depends_on = ["azurerm_resource_group.pcf_resource_group"] 206 | resource_group_name = "${azurerm_resource_group.pcf_resource_group.name}" 207 | address_space = "${var.pcf_virtual_network_address_space}" 208 | location = "${var.location}" 209 | } 210 | 211 | resource "azurerm_subnet" "infrastructure_subnet" { 212 | name = "${var.env_name}-infrastructure-subnet" 213 | depends_on = ["azurerm_resource_group.pcf_resource_group"] 214 | resource_group_name = "${azurerm_resource_group.pcf_resource_group.name}" 215 | virtual_network_name = "${azurerm_virtual_network.pcf_virtual_network.name}" 216 | address_prefix = "${var.pcf_infrastructure_subnet}" 217 | network_security_group_id = "${azurerm_network_security_group.ops_manager_security_group.id}" 218 | } 219 | 220 | resource "azurerm_subnet_network_security_group_association" "ops_manager_security_group" { 221 | subnet_id = "${azurerm_subnet.infrastructure_subnet.id}" 222 | network_security_group_id = "${azurerm_network_security_group.ops_manager_security_group.id}" 223 | } 224 | 225 | # ============= DNS 226 | 227 | locals { 228 | dns_subdomain = "${var.env_name}" 229 | } 230 | 231 | resource "azurerm_dns_zone" "env_dns_zone" { 232 | name = "${var.dns_subdomain != "" ? var.dns_subdomain : local.dns_subdomain}.${var.dns_suffix}" 233 | resource_group_name = "${azurerm_resource_group.pcf_resource_group.name}" 234 | } 235 | 236 | output "dns_zone_name" { 237 | value = "${azurerm_dns_zone.env_dns_zone.name}" 238 | } 239 | 240 | output "dns_zone_name_servers" { 241 | value = "${azurerm_dns_zone.env_dns_zone.name_servers}" 242 | } 243 | 244 | output "resource_group_name" { 245 | value = "${azurerm_resource_group.pcf_resource_group.name}" 246 | } 247 | 248 | output "network_name" { 249 | value = "${azurerm_virtual_network.pcf_virtual_network.name}" 250 | } 251 | 252 | output "infrastructure_subnet_id" { 253 | value = "${azurerm_subnet.infrastructure_subnet.id}" 254 | } 255 | 256 | output "infrastructure_subnet_name" { 257 | value = "${azurerm_subnet.infrastructure_subnet.name}" 258 | } 259 | 260 | output "infrastructure_subnet_cidr" { 261 | value = "${azurerm_subnet.infrastructure_subnet.address_prefix}" 262 | } 263 | 264 | output "infrastructure_subnet_gateway" { 265 | value = "${cidrhost(azurerm_subnet.infrastructure_subnet.address_prefix, 1)}" 266 | } 267 | 268 | output "security_group_id" { 269 | value = "${azurerm_network_security_group.ops_manager_security_group.id}" 270 | } 271 | 272 | output "security_group_name" { 273 | value = "${azurerm_network_security_group.ops_manager_security_group.name}" 274 | } 275 | 276 | output "bosh_deployed_vms_security_group_id" { 277 | value = "${azurerm_network_security_group.bosh_deployed_vms_security_group.id}" 278 | } 279 | 280 | output "bosh_deployed_vms_security_group_name" { 281 | value = "${azurerm_network_security_group.bosh_deployed_vms_security_group.name}" 282 | } 283 | 284 | # Deprecated 285 | 286 | output "infrastructure_subnet_cidrs" { 287 | value = ["${azurerm_subnet.infrastructure_subnet.address_prefix}"] 288 | } 289 | -------------------------------------------------------------------------------- /modules/isolation_segment/dns.tf: -------------------------------------------------------------------------------- 1 | resource "azurerm_dns_a_record" "iso" { 2 | name = "*.iso" 3 | count = "${var.count}" 4 | zone_name = "${var.dns_zone}" 5 | resource_group_name = "${var.resource_group_name}" 6 | ttl = "60" 7 | records = ["${azurerm_public_ip.iso-lb-public-ip.ip_address}"] 8 | } 9 | -------------------------------------------------------------------------------- /modules/isolation_segment/load_balancer.tf: -------------------------------------------------------------------------------- 1 | resource "azurerm_public_ip" "iso-lb-public-ip" { 2 | name = "iso-lb-public-ip" 3 | count = "${var.count}" 4 | location = "${var.location}" 5 | resource_group_name = "${var.resource_group_name}" 6 | allocation_method = "Static" 7 | sku = "Standard" 8 | } 9 | 10 | resource "azurerm_lb" "iso" { 11 | name = "${var.environment}-iso-lb" 12 | count = "${var.count}" 13 | location = "${var.location}" 14 | resource_group_name = "${var.resource_group_name}" 15 | 16 | frontend_ip_configuration = { 17 | name = "frontendip" 18 | public_ip_address_id = "${azurerm_public_ip.iso-lb-public-ip.id}" 19 | } 20 | } 21 | 22 | resource "azurerm_lb_backend_address_pool" "iso-backend-pool" { 23 | name = "iso-backend-pool" 24 | count = "${var.count}" 25 | resource_group_name = "${var.resource_group_name}" 26 | loadbalancer_id = "${azurerm_lb.iso.id}" 27 | } 28 | 29 | resource "azurerm_lb_probe" "iso-https-probe" { 30 | name = "iso-https-probe" 31 | count = "${var.count}" 32 | resource_group_name = "${var.resource_group_name}" 33 | loadbalancer_id = "${azurerm_lb.iso.id}" 34 | protocol = "TCP" 35 | port = 443 36 | } 37 | 38 | resource "azurerm_lb_rule" "iso-https-rule" { 39 | name = "iso-https-rule" 40 | count = "${var.count}" 41 | resource_group_name = "${var.resource_group_name}" 42 | loadbalancer_id = "${azurerm_lb.iso.id}" 43 | 44 | frontend_ip_configuration_name = "frontendip" 45 | protocol = "TCP" 46 | frontend_port = 443 47 | backend_port = 443 48 | 49 | backend_address_pool_id = "${azurerm_lb_backend_address_pool.iso-backend-pool.id}" 50 | probe_id = "${azurerm_lb_probe.iso-https-probe.id}" 51 | } 52 | 53 | resource "azurerm_lb_probe" "iso-http-probe" { 54 | name = "iso-http-probe" 55 | count = "${var.count}" 56 | resource_group_name = "${var.resource_group_name}" 57 | loadbalancer_id = "${azurerm_lb.iso.id}" 58 | protocol = "TCP" 59 | port = 80 60 | } 61 | 62 | resource "azurerm_lb_rule" "iso-http-rule" { 63 | name = "iso-http-rule" 64 | count = "${var.count}" 65 | resource_group_name = "${var.resource_group_name}" 66 | loadbalancer_id = "${azurerm_lb.iso.id}" 67 | 68 | frontend_ip_configuration_name = "frontendip" 69 | protocol = "TCP" 70 | frontend_port = 80 71 | backend_port = 80 72 | 73 | backend_address_pool_id = "${azurerm_lb_backend_address_pool.iso-backend-pool.id}" 74 | probe_id = "${azurerm_lb_probe.iso-http-probe.id}" 75 | } 76 | -------------------------------------------------------------------------------- /modules/isolation_segment/outputs.tf: -------------------------------------------------------------------------------- 1 | output "lb_name" { 2 | value = "${element(concat(azurerm_lb.iso.*.name, list("")), 0)}" 3 | } 4 | 5 | output "ssl_cert" { 6 | sensitive = true 7 | value = "${length(var.ssl_ca_cert) > 0 ? element(concat(tls_locally_signed_cert.ssl_cert.*.cert_pem, list("")), 0) : var.ssl_cert}" 8 | } 9 | 10 | output "ssl_private_key" { 11 | sensitive = true 12 | value = "${length(var.ssl_ca_cert) > 0 ? element(concat(tls_private_key.ssl_private_key.*.private_key_pem, list("")), 0) : var.ssl_private_key}" 13 | } 14 | -------------------------------------------------------------------------------- /modules/isolation_segment/self_signed_certs.tf: -------------------------------------------------------------------------------- 1 | resource "tls_cert_request" "ssl_csr" { 2 | key_algorithm = "RSA" 3 | private_key_pem = "${tls_private_key.ssl_private_key.private_key_pem}" 4 | 5 | dns_names = [ 6 | "*.iso.${var.dns_zone}", 7 | ] 8 | 9 | count = "${length(var.ssl_ca_cert) > 0 ? 1 : 0}" 10 | 11 | subject { 12 | common_name = "${var.dns_zone}" 13 | organization = "Pivotal" 14 | organizational_unit = "Cloudfoundry" 15 | country = "US" 16 | province = "CA" 17 | locality = "San Francisco" 18 | } 19 | } 20 | 21 | resource "tls_locally_signed_cert" "ssl_cert" { 22 | cert_request_pem = "${tls_cert_request.ssl_csr.cert_request_pem}" 23 | ca_key_algorithm = "RSA" 24 | ca_private_key_pem = "${var.ssl_ca_private_key}" 25 | ca_cert_pem = "${var.ssl_ca_cert}" 26 | 27 | count = "${length(var.ssl_ca_cert) > 0 ? 1 : 0}" 28 | 29 | validity_period_hours = 8760 # 1year 30 | 31 | allowed_uses = [ 32 | "key_encipherment", 33 | "digital_signature", 34 | "server_auth", 35 | ] 36 | } 37 | 38 | resource "tls_private_key" "ssl_private_key" { 39 | algorithm = "RSA" 40 | rsa_bits = "2048" 41 | 42 | count = "${length(var.ssl_ca_cert) > 0 ? 1 : 0}" 43 | } 44 | -------------------------------------------------------------------------------- /modules/isolation_segment/variables.tf: -------------------------------------------------------------------------------- 1 | variable "count" {} 2 | 3 | variable "location" { 4 | type = "string" 5 | } 6 | 7 | variable "environment" { 8 | type = "string" 9 | } 10 | 11 | variable "resource_group_name" { 12 | type = "string" 13 | } 14 | 15 | variable "dns_zone" { 16 | type = "string" 17 | } 18 | 19 | variable "ssl_cert" { 20 | type = "string" 21 | description = "the contents of an SSL certificate which should be passed to the isoseg gorouter, optional if `ssl_ca_cert` is provided" 22 | default = "" 23 | } 24 | 25 | variable "ssl_private_key" { 26 | type = "string" 27 | description = "the contents of an SSL private key which should be passed to the isoseg gorouter, optional if `ssl_ca_cert` is provided" 28 | default = "" 29 | } 30 | 31 | variable "ssl_ca_cert" { 32 | type = "string" 33 | description = "the contents of a CA public key to be used to sign a generated certificate for isoseg gorouter, optional if `ssl_cert` is provided" 34 | default = "" 35 | } 36 | 37 | variable "ssl_ca_private_key" { 38 | type = "string" 39 | description = "the contents of a CA private key to be used to sign a generated certificate for isoseg gorouter, optional if `ssl_cert` is provided" 40 | default = "" 41 | } 42 | -------------------------------------------------------------------------------- /modules/ops_manager/ops_manager.tf: -------------------------------------------------------------------------------- 1 | # ==================== Storage 2 | 3 | resource "azurerm_storage_account" "ops_manager_storage_account" { 4 | name = "${random_string.ops_manager_storage_account_name.result}" 5 | resource_group_name = "${var.resource_group_name}" 6 | location = "${var.location}" 7 | account_tier = "Standard" 8 | account_replication_type = "LRS" 9 | 10 | tags = { 11 | environment = "${var.env_name}" 12 | account_for = "ops-manager" 13 | } 14 | } 15 | 16 | resource "azurerm_storage_container" "ops_manager_storage_container" { 17 | name = "opsmanagerimage" 18 | depends_on = ["azurerm_storage_account.ops_manager_storage_account"] 19 | storage_account_name = "${azurerm_storage_account.ops_manager_storage_account.name}" 20 | container_access_type = "private" 21 | } 22 | 23 | resource "azurerm_storage_blob" "ops_manager_image" { 24 | name = "opsman.vhd" 25 | resource_group_name = "${var.resource_group_name}" 26 | storage_account_name = "${azurerm_storage_account.ops_manager_storage_account.name}" 27 | storage_container_name = "${azurerm_storage_container.ops_manager_storage_container.name}" 28 | source_uri = "${var.ops_manager_image_uri}" 29 | count = "${local.ops_man_vm}" 30 | type = "page" 31 | } 32 | 33 | resource "azurerm_image" "ops_manager_image" { 34 | name = "ops_manager_image" 35 | location = "${var.location}" 36 | resource_group_name = "${var.resource_group_name}" 37 | count = "${local.ops_man_vm}" 38 | 39 | os_disk { 40 | os_type = "Linux" 41 | os_state = "Generalized" 42 | blob_uri = "${azurerm_storage_blob.ops_manager_image.url}" 43 | size_gb = 150 44 | } 45 | } 46 | 47 | # ==================== DNS 48 | 49 | resource "azurerm_dns_a_record" "ops_manager_dns" { 50 | name = "pcf" 51 | zone_name = "${var.dns_zone_name}" 52 | resource_group_name = "${var.resource_group_name}" 53 | ttl = "60" 54 | records = ["${azurerm_public_ip.ops_manager_public_ip.ip_address}"] 55 | } 56 | 57 | resource "azurerm_dns_a_record" "optional_ops_manager_dns" { 58 | name = "pcf-optional" 59 | zone_name = "${var.dns_zone_name}" 60 | resource_group_name = "${var.resource_group_name}" 61 | ttl = "60" 62 | records = ["${azurerm_public_ip.optional_ops_manager_public_ip.ip_address}"] 63 | count = "${local.optional_ops_man_vm}" 64 | } 65 | 66 | # ==================== VMs 67 | 68 | resource "azurerm_public_ip" "ops_manager_public_ip" { 69 | name = "${var.env_name}-ops-manager-public-ip" 70 | location = "${var.location}" 71 | resource_group_name = "${var.resource_group_name}" 72 | allocation_method = "Static" 73 | idle_timeout_in_minutes = 30 74 | sku = "Standard" 75 | } 76 | 77 | resource "azurerm_network_interface" "ops_manager_nic" { 78 | name = "${var.env_name}-ops-manager-nic" 79 | depends_on = ["azurerm_public_ip.ops_manager_public_ip"] 80 | location = "${var.location}" 81 | resource_group_name = "${var.resource_group_name}" 82 | network_security_group_id = "${var.security_group_id}" 83 | count = "${local.ops_man_vm}" 84 | 85 | ip_configuration { 86 | name = "${var.env_name}-ops-manager-ip-config" 87 | subnet_id = "${var.subnet_id}" 88 | private_ip_address_allocation = "static" 89 | private_ip_address = "${var.ops_manager_private_ip}" 90 | public_ip_address_id = "${azurerm_public_ip.ops_manager_public_ip.id}" 91 | } 92 | } 93 | 94 | resource "azurerm_virtual_machine" "ops_manager_vm" { 95 | name = "${var.env_name}-ops-manager-vm" 96 | depends_on = ["azurerm_network_interface.ops_manager_nic"] 97 | location = "${var.location}" 98 | resource_group_name = "${var.resource_group_name}" 99 | network_interface_ids = ["${azurerm_network_interface.ops_manager_nic.id}"] 100 | vm_size = "${var.ops_manager_vm_size}" 101 | delete_os_disk_on_termination = "true" 102 | count = "${local.ops_man_vm}" 103 | 104 | storage_image_reference { 105 | id = "${azurerm_image.ops_manager_image.id}" 106 | } 107 | 108 | storage_os_disk { 109 | name = "opsman-disk.vhd" 110 | caching = "ReadWrite" 111 | os_type = "linux" 112 | create_option = "FromImage" 113 | disk_size_gb = "150" 114 | managed_disk_type = "Premium_LRS" 115 | } 116 | 117 | os_profile { 118 | computer_name = "${var.env_name}-ops-manager" 119 | admin_username = "ubuntu" 120 | } 121 | 122 | os_profile_linux_config { 123 | disable_password_authentication = true 124 | 125 | ssh_keys { 126 | path = "/home/ubuntu/.ssh/authorized_keys" 127 | key_data = "${tls_private_key.ops_manager.public_key_openssh}" 128 | } 129 | } 130 | } 131 | 132 | # ==================== OPTIONAL 133 | 134 | resource "azurerm_public_ip" "optional_ops_manager_public_ip" { 135 | name = "${var.env_name}-optional-ops-manager-public-ip" 136 | location = "${var.location}" 137 | resource_group_name = "${var.resource_group_name}" 138 | allocation_method = "static" 139 | count = "${local.optional_ops_man_vm}" 140 | sku = "Standard" 141 | } 142 | 143 | resource "azurerm_network_interface" "optional_ops_manager_nic" { 144 | name = "${var.env_name}-optional-ops-manager-nic" 145 | depends_on = ["azurerm_public_ip.optional_ops_manager_public_ip"] 146 | location = "${var.location}" 147 | resource_group_name = "${var.resource_group_name}" 148 | network_security_group_id = "${var.security_group_id}" 149 | count = "${local.optional_ops_man_vm}" 150 | 151 | ip_configuration { 152 | name = "${var.env_name}-optional-ops-manager-ip-config" 153 | subnet_id = "${var.subnet_id}" 154 | private_ip_address_allocation = "static" 155 | private_ip_address = "10.0.8.5" 156 | public_ip_address_id = "${azurerm_public_ip.optional_ops_manager_public_ip.id}" 157 | } 158 | } 159 | 160 | resource "azurerm_virtual_machine" "optional_ops_manager_vm" { 161 | name = "${var.env_name}-optional-ops-manager-vm" 162 | depends_on = ["azurerm_network_interface.optional_ops_manager_nic"] 163 | location = "${var.location}" 164 | resource_group_name = "${var.resource_group_name}" 165 | network_interface_ids = ["${azurerm_network_interface.optional_ops_manager_nic.id}"] 166 | vm_size = "${var.ops_manager_vm_size}" 167 | count = "${local.optional_ops_man_vm}" 168 | 169 | storage_image_reference { 170 | id = "${azurerm_image.ops_manager_image.id}" 171 | } 172 | 173 | storage_os_disk { 174 | name = "optional-opsman-disk" 175 | caching = "ReadWrite" 176 | os_type = "linux" 177 | create_option = "FromImage" 178 | disk_size_gb = "150" 179 | managed_disk_type = "Premium_LRS" 180 | } 181 | 182 | os_profile { 183 | computer_name = "${var.env_name}-optional-ops-manager" 184 | admin_username = "ubuntu" 185 | } 186 | 187 | os_profile_linux_config { 188 | disable_password_authentication = true 189 | 190 | ssh_keys { 191 | path = "/home/ubuntu/.ssh/authorized_keys" 192 | key_data = "${tls_private_key.ops_manager.public_key_openssh}" 193 | } 194 | } 195 | } 196 | -------------------------------------------------------------------------------- /modules/ops_manager/outputs.tf: -------------------------------------------------------------------------------- 1 | # ==================== Outputs 2 | 3 | output "dns_name" { 4 | value = "${azurerm_dns_a_record.ops_manager_dns.name}.${azurerm_dns_a_record.ops_manager_dns.zone_name}" 5 | } 6 | 7 | output "optional_dns_name" { 8 | value = "${element(concat(azurerm_dns_a_record.optional_ops_manager_dns.*.name, list("")), 0)}.${element(concat(azurerm_dns_a_record.optional_ops_manager_dns.*.zone_name, list("")), 0)}" 9 | } 10 | 11 | output "ops_manager_private_ip" { 12 | value = "${var.ops_manager_private_ip}" 13 | } 14 | 15 | output "ops_manager_public_ip" { 16 | value = "${azurerm_public_ip.ops_manager_public_ip.ip_address}" 17 | } 18 | 19 | output "optional_ops_manager_public_ip" { 20 | value = "${element(concat(azurerm_public_ip.optional_ops_manager_public_ip.*.ip_address, list("")), 0)}" 21 | } 22 | 23 | output "ops_manager_ssh_public_key" { 24 | sensitive = true 25 | value = "${tls_private_key.ops_manager.public_key_openssh}" 26 | } 27 | 28 | output "ops_manager_ssh_private_key" { 29 | sensitive = true 30 | value = "${tls_private_key.ops_manager.private_key_pem}" 31 | } 32 | 33 | output "ops_manager_storage_account" { 34 | value = "${azurerm_storage_account.ops_manager_storage_account.name}" 35 | } 36 | -------------------------------------------------------------------------------- /modules/ops_manager/variables.tf: -------------------------------------------------------------------------------- 1 | # ==================== Variables 2 | 3 | variable "env_name" { 4 | default = "" 5 | } 6 | 7 | variable "location" { 8 | default = "" 9 | } 10 | 11 | variable "ops_manager_private_ip" { 12 | default = "" 13 | } 14 | 15 | variable "ops_manager_image_uri" { 16 | default = "" 17 | } 18 | 19 | variable "ops_manager_vm_size" { 20 | default = "" 21 | } 22 | 23 | variable "resource_group_name" { 24 | default = "" 25 | } 26 | 27 | variable "security_group_id" { 28 | default = "" 29 | } 30 | 31 | variable "subnet_id" { 32 | default = "" 33 | } 34 | 35 | variable "dns_zone_name" { 36 | default = "" 37 | } 38 | 39 | variable "optional_ops_manager_image_uri" { 40 | default = "" 41 | } 42 | 43 | resource random_string "ops_manager_storage_account_name" { 44 | length = 20 45 | special = false 46 | upper = false 47 | } 48 | 49 | resource "tls_private_key" "ops_manager" { 50 | algorithm = "RSA" 51 | rsa_bits = "4096" 52 | } 53 | 54 | locals { 55 | ops_man_vm = "${var.ops_manager_image_uri == "" ? 0 : 1}" 56 | optional_ops_man_vm = "${var.optional_ops_manager_image_uri == "" ? 0 : 1}" 57 | } 58 | -------------------------------------------------------------------------------- /modules/pas/diegosshlb.tf: -------------------------------------------------------------------------------- 1 | resource "azurerm_public_ip" "diego-ssh-lb-public-ip" { 2 | name = "diego-ssh-lb-public-ip" 3 | location = "${var.location}" 4 | resource_group_name = "${var.resource_group_name}" 5 | allocation_method = "Static" 6 | sku = "Standard" 7 | } 8 | 9 | resource "azurerm_lb" "diego-ssh" { 10 | name = "${var.env_name}-diego-ssh-lb" 11 | location = "${var.location}" 12 | resource_group_name = "${var.resource_group_name}" 13 | sku = "Standard" 14 | 15 | frontend_ip_configuration = { 16 | name = "frontendip" 17 | public_ip_address_id = "${azurerm_public_ip.diego-ssh-lb-public-ip.id}" 18 | } 19 | } 20 | 21 | resource "azurerm_lb_backend_address_pool" "diego-ssh-backend-pool" { 22 | name = "diego-ssh-backend-pool" 23 | resource_group_name = "${var.resource_group_name}" 24 | loadbalancer_id = "${azurerm_lb.diego-ssh.id}" 25 | } 26 | 27 | resource "azurerm_lb_probe" "diego-ssh-probe" { 28 | name = "diego-ssh-probe" 29 | resource_group_name = "${var.resource_group_name}" 30 | loadbalancer_id = "${azurerm_lb.diego-ssh.id}" 31 | protocol = "TCP" 32 | port = 2222 33 | } 34 | 35 | resource "azurerm_lb_rule" "diego-ssh-rule" { 36 | name = "diego-ssh-rule" 37 | resource_group_name = "${var.resource_group_name}" 38 | loadbalancer_id = "${azurerm_lb.diego-ssh.id}" 39 | 40 | frontend_ip_configuration_name = "frontendip" 41 | protocol = "TCP" 42 | frontend_port = 2222 43 | backend_port = 2222 44 | 45 | backend_address_pool_id = "${azurerm_lb_backend_address_pool.diego-ssh-backend-pool.id}" 46 | probe_id = "${azurerm_lb_probe.diego-ssh-probe.id}" 47 | } 48 | 49 | resource "azurerm_lb_rule" "diego-ssh-ntp" { 50 | name = "diego-ssh-ntp-rule" 51 | resource_group_name = "${var.resource_group_name}" 52 | loadbalancer_id = "${azurerm_lb.diego-ssh.id}" 53 | 54 | frontend_ip_configuration_name = "frontendip" 55 | protocol = "UDP" 56 | frontend_port = "123" 57 | backend_port = "123" 58 | 59 | backend_address_pool_id = "${azurerm_lb_backend_address_pool.diego-ssh-backend-pool.id}" 60 | } 61 | -------------------------------------------------------------------------------- /modules/pas/dns.tf: -------------------------------------------------------------------------------- 1 | resource "azurerm_dns_a_record" "apps" { 2 | name = "*.apps" 3 | zone_name = "${var.dns_zone_name}" 4 | resource_group_name = "${var.resource_group_name}" 5 | ttl = "60" 6 | records = ["${azurerm_public_ip.web-lb-public-ip.ip_address}"] 7 | } 8 | 9 | resource "azurerm_dns_a_record" "sys" { 10 | name = "*.sys" 11 | zone_name = "${var.dns_zone_name}" 12 | resource_group_name = "${var.resource_group_name}" 13 | ttl = "60" 14 | records = ["${azurerm_public_ip.web-lb-public-ip.ip_address}"] 15 | } 16 | 17 | resource "azurerm_dns_a_record" "ssh" { 18 | name = "ssh.sys" 19 | zone_name = "${var.dns_zone_name}" 20 | resource_group_name = "${var.resource_group_name}" 21 | ttl = "60" 22 | records = ["${azurerm_public_ip.diego-ssh-lb-public-ip.ip_address}"] 23 | } 24 | 25 | resource "azurerm_dns_a_record" "mysql" { 26 | name = "mysql" 27 | zone_name = "${var.dns_zone_name}" 28 | resource_group_name = "${var.resource_group_name}" 29 | ttl = "60" 30 | records = ["${azurerm_lb.mysql.frontend_ip_configuration.0.private_ip_address}"] 31 | } 32 | 33 | resource "azurerm_dns_a_record" "tcp" { 34 | name = "tcp" 35 | zone_name = "${var.dns_zone_name}" 36 | resource_group_name = "${var.resource_group_name}" 37 | ttl = "60" 38 | records = ["${azurerm_public_ip.tcp-lb-public-ip.ip_address}"] 39 | } 40 | -------------------------------------------------------------------------------- /modules/pas/mysqllb.tf: -------------------------------------------------------------------------------- 1 | resource "azurerm_lb" "mysql" { 2 | name = "${var.env_name}-mysql-lb" 3 | location = "${var.location}" 4 | resource_group_name = "${var.resource_group_name}" 5 | sku = "Standard" 6 | 7 | frontend_ip_configuration = { 8 | name = "frontendip" 9 | subnet_id = "${azurerm_subnet.pas_subnet.id}" 10 | } 11 | } 12 | 13 | resource "azurerm_lb_backend_address_pool" "mysql-backend-pool" { 14 | name = "mysql-backend-pool" 15 | resource_group_name = "${var.resource_group_name}" 16 | loadbalancer_id = "${azurerm_lb.mysql.id}" 17 | } 18 | 19 | resource "azurerm_lb_probe" "mysql-probe" { 20 | name = "mysql-probe" 21 | resource_group_name = "${var.resource_group_name}" 22 | loadbalancer_id = "${azurerm_lb.mysql.id}" 23 | protocol = "TCP" 24 | port = 1936 25 | } 26 | 27 | resource "azurerm_lb_rule" "mysql-rule" { 28 | name = "mysql-rule" 29 | resource_group_name = "${var.resource_group_name}" 30 | loadbalancer_id = "${azurerm_lb.mysql.id}" 31 | 32 | frontend_ip_configuration_name = "frontendip" 33 | protocol = "TCP" 34 | frontend_port = 3306 35 | backend_port = 3306 36 | 37 | backend_address_pool_id = "${azurerm_lb_backend_address_pool.mysql-backend-pool.id}" 38 | probe_id = "${azurerm_lb_probe.mysql-probe.id}" 39 | } 40 | 41 | resource "azurerm_lb_rule" "mysql-ntp" { 42 | name = "mysql-ntp-rule" 43 | resource_group_name = "${var.resource_group_name}" 44 | loadbalancer_id = "${azurerm_lb.mysql.id}" 45 | 46 | frontend_ip_configuration_name = "frontendip" 47 | protocol = "UDP" 48 | frontend_port = "123" 49 | backend_port = "123" 50 | 51 | backend_address_pool_id = "${azurerm_lb_backend_address_pool.mysql-backend-pool.id}" 52 | } 53 | -------------------------------------------------------------------------------- /modules/pas/outputs.tf: -------------------------------------------------------------------------------- 1 | output "mysql_dns" { 2 | value = "mysql.${azurerm_dns_a_record.mysql.zone_name}" 3 | } 4 | 5 | output "tcp_domain" { 6 | value = "tcp.${azurerm_dns_a_record.tcp.zone_name}" 7 | } 8 | 9 | output "sys_domain" { 10 | value = "sys.${azurerm_dns_a_record.sys.zone_name}" 11 | } 12 | 13 | output "apps_domain" { 14 | value = "apps.${azurerm_dns_a_record.apps.zone_name}" 15 | } 16 | 17 | output "web_lb_name" { 18 | value = "${azurerm_lb.web.name}" 19 | } 20 | 21 | output "diego_ssh_lb_name" { 22 | value = "${azurerm_lb.diego-ssh.name}" 23 | } 24 | 25 | output "mysql_lb_name" { 26 | value = "${azurerm_lb.mysql.name}" 27 | } 28 | 29 | output "tcp_lb_name" { 30 | value = "${azurerm_lb.tcp.name}" 31 | } 32 | 33 | # Subnets 34 | 35 | output "pas_subnet_name" { 36 | value = "${azurerm_subnet.pas_subnet.name}" 37 | } 38 | 39 | output "pas_subnet_cidr" { 40 | value = "${azurerm_subnet.pas_subnet.address_prefix}" 41 | } 42 | 43 | output "pas_subnet_gateway" { 44 | value = "${cidrhost(azurerm_subnet.pas_subnet.address_prefix, 1)}" 45 | } 46 | 47 | output "services_subnet_name" { 48 | value = "${azurerm_subnet.services_subnet.name}" 49 | } 50 | 51 | output "services_subnet_cidr" { 52 | value = "${azurerm_subnet.services_subnet.address_prefix}" 53 | } 54 | 55 | output "services_subnet_gateway" { 56 | value = "${cidrhost(azurerm_subnet.services_subnet.address_prefix, 1)}" 57 | } 58 | 59 | # Storage 60 | 61 | output "cf_storage_account_name" { 62 | value = "${azurerm_storage_account.cf_storage_account.name}" 63 | } 64 | 65 | output "cf_storage_account_access_key" { 66 | sensitive = true 67 | value = "${azurerm_storage_account.cf_storage_account.primary_access_key}" 68 | } 69 | 70 | output "cf_droplets_storage_container_name" { 71 | value = "${azurerm_storage_container.cf_droplets_storage_container.name}" 72 | } 73 | 74 | output "cf_packages_storage_container_name" { 75 | value = "${azurerm_storage_container.cf_packages_storage_container.name}" 76 | } 77 | 78 | output "cf_resources_storage_container_name" { 79 | value = "${azurerm_storage_container.cf_resources_storage_container.name}" 80 | } 81 | 82 | output "cf_buildpacks_storage_container_name" { 83 | value = "${azurerm_storage_container.cf_buildpacks_storage_container.name}" 84 | } 85 | 86 | # Deprecated 87 | 88 | output "pas_subnet_cidrs" { 89 | value = ["${azurerm_subnet.pas_subnet.address_prefix}"] 90 | } 91 | 92 | output "services_subnet_cidrs" { 93 | value = ["${azurerm_subnet.services_subnet.address_prefix}"] 94 | } 95 | -------------------------------------------------------------------------------- /modules/pas/storage.tf: -------------------------------------------------------------------------------- 1 | # Storage containers to be used as CF Blobstore 2 | 3 | resource random_string "cf_storage_account_name" { 4 | length = 20 5 | special = false 6 | upper = false 7 | } 8 | 9 | resource "azurerm_storage_account" "cf_storage_account" { 10 | name = "${random_string.cf_storage_account_name.result}" 11 | resource_group_name = "${var.resource_group_name}" 12 | location = "${var.location}" 13 | account_tier = "Standard" 14 | account_replication_type = "LRS" 15 | 16 | tags = { 17 | environment = "${var.env_name}" 18 | account_for = "cloud-foundry-blobstore" 19 | } 20 | } 21 | 22 | resource "azurerm_storage_container" "cf_buildpacks_storage_container" { 23 | name = "${var.cf_buildpacks_storage_container_name}" 24 | depends_on = ["azurerm_storage_account.cf_storage_account"] 25 | resource_group_name = "${var.resource_group_name}" 26 | storage_account_name = "${azurerm_storage_account.cf_storage_account.name}" 27 | container_access_type = "private" 28 | } 29 | 30 | resource "azurerm_storage_container" "cf_packages_storage_container" { 31 | name = "${var.cf_packages_storage_container_name}" 32 | depends_on = ["azurerm_storage_account.cf_storage_account"] 33 | resource_group_name = "${var.resource_group_name}" 34 | storage_account_name = "${azurerm_storage_account.cf_storage_account.name}" 35 | container_access_type = "private" 36 | } 37 | 38 | resource "azurerm_storage_container" "cf_droplets_storage_container" { 39 | name = "${var.cf_droplets_storage_container_name}" 40 | depends_on = ["azurerm_storage_account.cf_storage_account"] 41 | resource_group_name = "${var.resource_group_name}" 42 | storage_account_name = "${azurerm_storage_account.cf_storage_account.name}" 43 | container_access_type = "private" 44 | } 45 | 46 | resource "azurerm_storage_container" "cf_resources_storage_container" { 47 | name = "${var.cf_resources_storage_container_name}" 48 | depends_on = ["azurerm_storage_account.cf_storage_account"] 49 | resource_group_name = "${var.resource_group_name}" 50 | storage_account_name = "${azurerm_storage_account.cf_storage_account.name}" 51 | container_access_type = "private" 52 | } 53 | -------------------------------------------------------------------------------- /modules/pas/subnets.tf: -------------------------------------------------------------------------------- 1 | # ================================= Subnets ==================================== 2 | 3 | resource "azurerm_subnet" "pas_subnet" { 4 | name = "${var.env_name}-pas-subnet" 5 | 6 | // depends_on = ["${var.resource_group_name}"] 7 | resource_group_name = "${var.resource_group_name}" 8 | virtual_network_name = "${var.network_name}" 9 | address_prefix = "${var.pas_subnet_cidr}" 10 | network_security_group_id = "${var.bosh_deployed_vms_security_group_id}" 11 | } 12 | 13 | resource "azurerm_subnet_network_security_group_association" "pas_subnet" { 14 | subnet_id = "${azurerm_subnet.pas_subnet.id}" 15 | network_security_group_id = "${var.bosh_deployed_vms_security_group_id}" 16 | } 17 | 18 | resource "azurerm_subnet" "services_subnet" { 19 | name = "${var.env_name}-services-subnet" 20 | 21 | // depends_on = ["${var.resource_group_name}"] 22 | resource_group_name = "${var.resource_group_name}" 23 | virtual_network_name = "${var.network_name}" 24 | address_prefix = "${var.services_subnet_cidr}" 25 | network_security_group_id = "${var.bosh_deployed_vms_security_group_id}" 26 | } 27 | 28 | resource "azurerm_subnet_network_security_group_association" "services_subnet" { 29 | subnet_id = "${azurerm_subnet.services_subnet.id}" 30 | network_security_group_id = "${var.bosh_deployed_vms_security_group_id}" 31 | } 32 | -------------------------------------------------------------------------------- /modules/pas/tcplb.tf: -------------------------------------------------------------------------------- 1 | resource "azurerm_public_ip" "tcp-lb-public-ip" { 2 | name = "tcp-lb-public-ip" 3 | location = "${var.location}" 4 | resource_group_name = "${var.resource_group_name}" 5 | allocation_method = "Static" 6 | sku = "Standard" 7 | } 8 | 9 | resource "azurerm_lb" "tcp" { 10 | name = "${var.env_name}-tcp-lb" 11 | location = "${var.location}" 12 | resource_group_name = "${var.resource_group_name}" 13 | sku = "Standard" 14 | 15 | frontend_ip_configuration = { 16 | name = "frontendip" 17 | public_ip_address_id = "${azurerm_public_ip.tcp-lb-public-ip.id}" 18 | } 19 | } 20 | 21 | resource "azurerm_lb_backend_address_pool" "tcp-backend-pool" { 22 | name = "tcp-backend-pool" 23 | resource_group_name = "${var.resource_group_name}" 24 | loadbalancer_id = "${azurerm_lb.tcp.id}" 25 | } 26 | 27 | resource "azurerm_lb_probe" "tcp-probe" { 28 | name = "tcp-probe" 29 | resource_group_name = "${var.resource_group_name}" 30 | loadbalancer_id = "${azurerm_lb.tcp.id}" 31 | protocol = "TCP" 32 | port = 80 33 | } 34 | 35 | resource "azurerm_lb_rule" "tcp-rule" { 36 | count = 5 37 | name = "tcp-rule-${count.index + 1024}" 38 | resource_group_name = "${var.resource_group_name}" 39 | loadbalancer_id = "${azurerm_lb.tcp.id}" 40 | 41 | frontend_ip_configuration_name = "frontendip" 42 | protocol = "TCP" 43 | frontend_port = "${count.index + 1024}" 44 | backend_port = "${count.index + 1024}" 45 | 46 | backend_address_pool_id = "${azurerm_lb_backend_address_pool.tcp-backend-pool.id}" 47 | probe_id = "${azurerm_lb_probe.tcp-probe.id}" 48 | } 49 | 50 | resource "azurerm_lb_rule" "tcp-ntp" { 51 | name = "tcp-ntp-rule" 52 | resource_group_name = "${var.resource_group_name}" 53 | loadbalancer_id = "${azurerm_lb.tcp.id}" 54 | 55 | frontend_ip_configuration_name = "frontendip" 56 | protocol = "UDP" 57 | frontend_port = "123" 58 | backend_port = "123" 59 | 60 | backend_address_pool_id = "${azurerm_lb_backend_address_pool.tcp-backend-pool.id}" 61 | } 62 | -------------------------------------------------------------------------------- /modules/pas/variables.tf: -------------------------------------------------------------------------------- 1 | variable "env_name" {} 2 | variable "location" {} 3 | variable "resource_group_name" {} 4 | variable "dns_zone_name" {} 5 | 6 | variable "cf_buildpacks_storage_container_name" {} 7 | variable "cf_droplets_storage_container_name" {} 8 | variable "cf_packages_storage_container_name" {} 9 | variable "cf_resources_storage_container_name" {} 10 | variable "cf_storage_account_name" {} 11 | 12 | variable "network_name" {} 13 | variable "pas_subnet_cidr" {} 14 | variable "services_subnet_cidr" {} 15 | 16 | variable "bosh_deployed_vms_security_group_id" {} 17 | -------------------------------------------------------------------------------- /modules/pas/weblb.tf: -------------------------------------------------------------------------------- 1 | resource "azurerm_public_ip" "web-lb-public-ip" { 2 | name = "web-lb-public-ip" 3 | location = "${var.location}" 4 | resource_group_name = "${var.resource_group_name}" 5 | allocation_method = "Static" 6 | sku = "Standard" 7 | idle_timeout_in_minutes = 30 8 | } 9 | 10 | resource "azurerm_lb" "web" { 11 | name = "${var.env_name}-web-lb" 12 | location = "${var.location}" 13 | resource_group_name = "${var.resource_group_name}" 14 | sku = "Standard" 15 | 16 | frontend_ip_configuration = { 17 | name = "frontendip" 18 | public_ip_address_id = "${azurerm_public_ip.web-lb-public-ip.id}" 19 | } 20 | } 21 | 22 | resource "azurerm_lb_backend_address_pool" "web-backend-pool" { 23 | name = "web-backend-pool" 24 | resource_group_name = "${var.resource_group_name}" 25 | loadbalancer_id = "${azurerm_lb.web.id}" 26 | } 27 | 28 | resource "azurerm_lb_probe" "web-https-probe" { 29 | name = "web-https-probe" 30 | resource_group_name = "${var.resource_group_name}" 31 | loadbalancer_id = "${azurerm_lb.web.id}" 32 | protocol = "TCP" 33 | port = 443 34 | } 35 | 36 | resource "azurerm_lb_rule" "web-https-rule" { 37 | name = "web-https-rule" 38 | resource_group_name = "${var.resource_group_name}" 39 | loadbalancer_id = "${azurerm_lb.web.id}" 40 | 41 | frontend_ip_configuration_name = "frontendip" 42 | protocol = "TCP" 43 | frontend_port = 443 44 | backend_port = 443 45 | idle_timeout_in_minutes = 30 46 | 47 | backend_address_pool_id = "${azurerm_lb_backend_address_pool.web-backend-pool.id}" 48 | probe_id = "${azurerm_lb_probe.web-https-probe.id}" 49 | } 50 | 51 | resource "azurerm_lb_probe" "web-http-probe" { 52 | name = "web-http-probe" 53 | resource_group_name = "${var.resource_group_name}" 54 | loadbalancer_id = "${azurerm_lb.web.id}" 55 | protocol = "TCP" 56 | port = 80 57 | } 58 | 59 | resource "azurerm_lb_rule" "web-http-rule" { 60 | name = "web-http-rule" 61 | resource_group_name = "${var.resource_group_name}" 62 | loadbalancer_id = "${azurerm_lb.web.id}" 63 | 64 | frontend_ip_configuration_name = "frontendip" 65 | protocol = "TCP" 66 | frontend_port = 80 67 | backend_port = 80 68 | idle_timeout_in_minutes = 30 69 | 70 | backend_address_pool_id = "${azurerm_lb_backend_address_pool.web-backend-pool.id}" 71 | probe_id = "${azurerm_lb_probe.web-http-probe.id}" 72 | } 73 | 74 | resource "azurerm_lb_rule" "web-ntp" { 75 | name = "web-ntp-rule" 76 | resource_group_name = "${var.resource_group_name}" 77 | loadbalancer_id = "${azurerm_lb.web.id}" 78 | 79 | frontend_ip_configuration_name = "frontendip" 80 | protocol = "UDP" 81 | frontend_port = "123" 82 | backend_port = "123" 83 | 84 | backend_address_pool_id = "${azurerm_lb_backend_address_pool.web-backend-pool.id}" 85 | } 86 | -------------------------------------------------------------------------------- /modules/pks/firewall.tf: -------------------------------------------------------------------------------- 1 | // Security Group for PKS API Nodes 2 | 3 | resource "azurerm_application_security_group" "pks-master" { 4 | name = "${var.env_id}-pks-master-app-sec-group" 5 | location = "${var.location}" 6 | resource_group_name = "${var.resource_group_name}" 7 | } 8 | 9 | resource "azurerm_application_security_group" "pks-api" { 10 | name = "${var.env_id}-pks-api-app-sec-group" 11 | location = "${var.location}" 12 | resource_group_name = "${var.resource_group_name}" 13 | } 14 | 15 | // Allow access from the internet to the masters 16 | resource "azurerm_network_security_group" "pks-master" { 17 | name = "${var.env_id}-pks-master-sg" 18 | location = "${var.location}" 19 | resource_group_name = "${var.resource_group_name}" 20 | 21 | security_rule { 22 | name = "master" 23 | priority = 100 24 | direction = "Inbound" 25 | access = "Allow" 26 | protocol = "Tcp" 27 | source_port_range = "*" 28 | destination_port_range = "8443" 29 | source_address_prefix = "*" 30 | destination_application_security_group_ids = ["${azurerm_application_security_group.pks-master.id}"] 31 | } 32 | } 33 | 34 | // Allow access from the internet to the PKS API VM 35 | resource "azurerm_network_security_group" "pks-api" { 36 | name = "${var.env_id}-pks-api-sg" 37 | location = "${var.location}" 38 | resource_group_name = "${var.resource_group_name}" 39 | 40 | security_rule { 41 | name = "api" 42 | priority = 100 43 | direction = "Inbound" 44 | access = "Allow" 45 | protocol = "Tcp" 46 | source_port_range = "*" 47 | destination_port_ranges = ["9021", "8443"] 48 | source_address_prefix = "*" 49 | destination_application_security_group_ids = ["${azurerm_application_security_group.pks-api.id}"] 50 | } 51 | } 52 | 53 | // Allow access from the internal VMs to the internal VMs via TCP and UDP 54 | resource "azurerm_network_security_group" "pks-internal" { 55 | name = "${var.env_id}-pks-internal-sg" 56 | location = "${var.location}" 57 | resource_group_name = "${var.resource_group_name}" 58 | 59 | security_rule { 60 | name = "internal" 61 | priority = 100 62 | direction = "Inbound" 63 | access = "Allow" 64 | protocol = "*" 65 | source_port_range = "*" 66 | destination_port_range = "*" 67 | source_address_prefixes = ["${local.pks_cidr}", "${local.pks_services_cidr}"] 68 | destination_address_prefix = "*" 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /modules/pks/lb.tf: -------------------------------------------------------------------------------- 1 | resource "azurerm_public_ip" "pks-lb-ip" { 2 | name = "${var.env_id}-pks-lb-ip" 3 | location = "${var.location}" 4 | resource_group_name = "${var.resource_group_name}" 5 | allocation_method = "Static" 6 | sku = "Standard" 7 | } 8 | 9 | resource "azurerm_lb" "pks-lb" { 10 | name = "${var.env_id}-pks-lb" 11 | location = "${var.location}" 12 | sku = "Standard" 13 | resource_group_name = "${var.resource_group_name}" 14 | 15 | frontend_ip_configuration { 16 | name = "${azurerm_public_ip.pks-lb-ip.name}" 17 | public_ip_address_id = "${azurerm_public_ip.pks-lb-ip.id}" 18 | } 19 | } 20 | 21 | resource "azurerm_lb_backend_address_pool" "pks-lb-backend-pool" { 22 | name = "${var.env_id}-pks-backend-pool" 23 | resource_group_name = "${var.resource_group_name}" 24 | loadbalancer_id = "${azurerm_lb.pks-lb.id}" 25 | } 26 | 27 | resource "azurerm_lb_probe" "pks-lb-uaa-health-probe" { 28 | name = "${var.env_id}-pks-lb-uaa-health-probe" 29 | resource_group_name = "${var.resource_group_name}" 30 | loadbalancer_id = "${azurerm_lb.pks-lb.id}" 31 | protocol = "Tcp" 32 | interval_in_seconds = 5 33 | number_of_probes = 2 34 | port = 8443 35 | } 36 | 37 | resource "azurerm_lb_rule" "pks-lb-uaa-rule" { 38 | name = "${var.env_id}-pks-lb-uaa-rule" 39 | resource_group_name = "${var.resource_group_name}" 40 | loadbalancer_id = "${azurerm_lb.pks-lb.id}" 41 | protocol = "Tcp" 42 | frontend_port = 8443 43 | backend_port = 8443 44 | frontend_ip_configuration_name = "${azurerm_public_ip.pks-lb-ip.name}" 45 | probe_id = "${azurerm_lb_probe.pks-lb-uaa-health-probe.id}" 46 | backend_address_pool_id = "${azurerm_lb_backend_address_pool.pks-lb-backend-pool.id}" 47 | } 48 | 49 | resource "azurerm_lb_probe" "pks-lb-api-health-probe" { 50 | name = "${var.env_id}-pks-lb-api-health-probe" 51 | resource_group_name = "${var.resource_group_name}" 52 | loadbalancer_id = "${azurerm_lb.pks-lb.id}" 53 | protocol = "Tcp" 54 | interval_in_seconds = 5 55 | number_of_probes = 2 56 | port = 9021 57 | } 58 | 59 | resource "azurerm_lb_rule" "pks-lb-api-rule" { 60 | name = "${var.env_id}-pks-lb-api-rule" 61 | resource_group_name = "${var.resource_group_name}" 62 | loadbalancer_id = "${azurerm_lb.pks-lb.id}" 63 | protocol = "Tcp" 64 | frontend_port = 9021 65 | backend_port = 9021 66 | frontend_ip_configuration_name = "${azurerm_public_ip.pks-lb-ip.name}" 67 | probe_id = "${azurerm_lb_probe.pks-lb-api-health-probe.id}" 68 | backend_address_pool_id = "${azurerm_lb_backend_address_pool.pks-lb-backend-pool.id}" 69 | } 70 | -------------------------------------------------------------------------------- /modules/pks/networking.tf: -------------------------------------------------------------------------------- 1 | // Subnets for PKS 2 | resource "azurerm_subnet" "pks" { 3 | name = "${var.env_id}-pks-subnet" 4 | resource_group_name = "${var.resource_group_name}" 5 | virtual_network_name = "${var.network_name}" 6 | address_prefix = "${local.pks_cidr}" 7 | } 8 | 9 | resource "azurerm_subnet" "pks_services" { 10 | name = "${var.env_id}-pks-services-subnet" 11 | resource_group_name = "${var.resource_group_name}" 12 | virtual_network_name = "${var.network_name}" 13 | address_prefix = "${local.pks_services_cidr}" 14 | } 15 | 16 | resource "azurerm_subnet_network_security_group_association" "pks_services" { 17 | subnet_id = "${azurerm_subnet.pks_services.id}" 18 | network_security_group_id = "${var.bosh_deployed_vms_security_group_id}" 19 | } 20 | -------------------------------------------------------------------------------- /modules/pks/outputs.tf: -------------------------------------------------------------------------------- 1 | output "pks-master-app-sec-group" { 2 | value = "${azurerm_application_security_group.pks-master.id}" 3 | } 4 | 5 | output "pks-api-app-sec-group" { 6 | value = "${azurerm_application_security_group.pks-api.id}" 7 | } 8 | 9 | # Subnets 10 | 11 | output "pks_subnet_name" { 12 | value = "${azurerm_subnet.pks.name}" 13 | } 14 | 15 | output "pks_subnet_cidr" { 16 | value = "${azurerm_subnet.pks.address_prefix}" 17 | } 18 | 19 | output "pks_subnet_gateway" { 20 | value = "${cidrhost(azurerm_subnet.pks.address_prefix, 1)}" 21 | } 22 | 23 | output "services_subnet_name" { 24 | value = "${azurerm_subnet.pks_services.name}" 25 | } 26 | 27 | output "services_subnet_cidr" { 28 | value = "${azurerm_subnet.pks_services.address_prefix}" 29 | } 30 | 31 | output "services_subnet_gateway" { 32 | value = "${cidrhost(azurerm_subnet.pks_services.address_prefix, 1)}" 33 | } 34 | 35 | # Deprecated 36 | 37 | output "pks_subnet_cidrs" { 38 | value = ["${azurerm_subnet.pks.address_prefix}"] 39 | } 40 | 41 | output "services_subnet_cidrs" { 42 | value = ["${azurerm_subnet.pks_services.address_prefix}"] 43 | } 44 | -------------------------------------------------------------------------------- /modules/pks/variables.tf: -------------------------------------------------------------------------------- 1 | variable "env_id" {} 2 | 3 | variable "location" {} 4 | 5 | variable "resource_group_name" { 6 | type = "string" 7 | } 8 | 9 | variable "network_name" {} 10 | 11 | variable "resource_group_cidr" {} 12 | 13 | locals { 14 | pks_cidr = "${cidrsubnet(var.resource_group_cidr, 6, 3)}" 15 | pks_services_cidr = "${cidrsubnet(var.resource_group_cidr, 6, 4)}" 16 | } 17 | 18 | variable "bosh_deployed_vms_security_group_id" {} 19 | -------------------------------------------------------------------------------- /scripts/configure-director: -------------------------------------------------------------------------------- 1 | #!/bin/bash -exu 2 | authenticate_om() { 3 | export OM_TARGET="https://$(terraform output ops_manager_dns)" 4 | export OM_USERNAME="admin" 5 | export OM_PASSWORD="$1" 6 | } 7 | 8 | main() { 9 | local path=${1?"Path is required (e.g. terraforming-pas, terraforming-control-plane)"} 10 | local password=${2?"OpsManager password is required."} 11 | 12 | pushd "$PROJECT_DIR/${path}" > /dev/null 13 | RAW_JSON=$(jq -e --raw-output '.modules[0].outputs | map_values(.value)' terraform.tfstate) 14 | WITH_CERT=$(echo "${RAW_JSON}" | jq --arg terraformingca "${CA_CERT}" '. + {terraforming_ca_cert: $terraformingca}') 15 | 16 | authenticate_om "${password}" 17 | 18 | om -k configure-authentication -dp "${OM_PASSWORD}" 19 | om -k configure-director --config <(texplate execute "$PROJECT_DIR/ci/assets/template/director-config.yml" -f <(echo "${WITH_CERT}") -o yaml) 20 | popd > /dev/null 21 | } 22 | 23 | main "$@" 24 | -------------------------------------------------------------------------------- /scripts/configure-product: -------------------------------------------------------------------------------- 1 | #!/bin/bash -exu 2 | 3 | authenticate_om() { 4 | export OM_TARGET="https://$(terraform output ops_manager_dns)" 5 | export OM_USERNAME="admin" 6 | export OM_PASSWORD="$1" 7 | } 8 | 9 | main() { 10 | local path="$1" 11 | local product="$2" 12 | local password="$3" 13 | 14 | pushd "${path}" > /dev/null 15 | authenticate_om "${password}" 16 | 17 | mkdir -p /tmp/env-state 18 | jq -e --raw-output '.modules[0].outputs | map_values(.value)' terraform.tfstate > /tmp/env-state/metadata 19 | 20 | local product_template 21 | case $product in 22 | cf) 23 | product_template=$PROJECT_DIR/ci/assets/template/srt-config.yml 24 | ;; 25 | control-plane) 26 | product_template=$PROJECT_DIR/ci/assets/template/control-plane-config.yml 27 | curl -X GET 'https://www.digicert.com/CACerts/BaltimoreCyberTrustRoot.crt' -o /tmp/BaltimoreCyberTrustRoot.crt 28 | 29 | openssl x509 -inform DER -in /tmp/BaltimoreCyberTrustRoot.crt -text -out /tmp/azure.pem 30 | 31 | cat /tmp/env-state/metadata | jq --arg db_ca_cert "$(cat /tmp/azure.pem)" '. + {"db_ca_cert": $db_ca_cert}' > /tmp/env-state/metadata_tmp 32 | mv /tmp/env-state/metadata{_tmp,} 33 | ;; 34 | esac 35 | 36 | 37 | om -k configure-product \ 38 | -c <(texplate execute "${product_template}" -f /tmp/env-state/metadata -o yaml) 39 | 40 | popd > /dev/null 41 | } 42 | 43 | main "$@" 44 | -------------------------------------------------------------------------------- /terraforming-pas/main.tf: -------------------------------------------------------------------------------- 1 | provider "azurerm" { 2 | subscription_id = "${var.subscription_id}" 3 | client_id = "${var.client_id}" 4 | client_secret = "${var.client_secret}" 5 | tenant_id = "${var.tenant_id}" 6 | environment = "${var.cloud_name}" 7 | 8 | version = "~> 1.22" 9 | } 10 | 11 | terraform { 12 | required_version = "< 0.12.0" 13 | } 14 | 15 | module "infra" { 16 | source = "../modules/infra" 17 | 18 | env_name = "${var.env_name}" 19 | location = "${var.location}" 20 | dns_subdomain = "${var.dns_subdomain}" 21 | dns_suffix = "${var.dns_suffix}" 22 | pcf_infrastructure_subnet = "${var.pcf_infrastructure_subnet}" 23 | pcf_virtual_network_address_space = "${var.pcf_virtual_network_address_space}" 24 | } 25 | 26 | module "ops_manager" { 27 | source = "../modules/ops_manager" 28 | 29 | env_name = "${var.env_name}" 30 | location = "${var.location}" 31 | 32 | ops_manager_image_uri = "${var.ops_manager_image_uri}" 33 | ops_manager_vm_size = "${var.ops_manager_vm_size}" 34 | ops_manager_private_ip = "${var.ops_manager_private_ip}" 35 | 36 | optional_ops_manager_image_uri = "${var.optional_ops_manager_image_uri}" 37 | 38 | resource_group_name = "${module.infra.resource_group_name}" 39 | dns_zone_name = "${module.infra.dns_zone_name}" 40 | security_group_id = "${module.infra.security_group_id}" 41 | subnet_id = "${module.infra.infrastructure_subnet_id}" 42 | } 43 | 44 | module "pas" { 45 | source = "../modules/pas" 46 | 47 | env_name = "${var.env_name}" 48 | location = "${var.location}" 49 | 50 | pas_subnet_cidr = "${var.pcf_pas_subnet}" 51 | services_subnet_cidr = "${var.pcf_services_subnet}" 52 | 53 | cf_storage_account_name = "${var.cf_storage_account_name}" 54 | cf_buildpacks_storage_container_name = "${var.cf_buildpacks_storage_container_name}" 55 | cf_droplets_storage_container_name = "${var.cf_droplets_storage_container_name}" 56 | cf_packages_storage_container_name = "${var.cf_packages_storage_container_name}" 57 | cf_resources_storage_container_name = "${var.cf_resources_storage_container_name}" 58 | 59 | resource_group_name = "${module.infra.resource_group_name}" 60 | dns_zone_name = "${module.infra.dns_zone_name}" 61 | network_name = "${module.infra.network_name}" 62 | bosh_deployed_vms_security_group_id = "${module.infra.bosh_deployed_vms_security_group_id}" 63 | } 64 | 65 | module "certs" { 66 | source = "../modules/certs" 67 | 68 | env_name = "${var.env_name}" 69 | dns_suffix = "${var.dns_suffix}" 70 | ssl_ca_cert = "${var.ssl_ca_cert}" 71 | ssl_ca_private_key = "${var.ssl_ca_private_key}" 72 | } 73 | 74 | module "isolation_segment" { 75 | source = "../modules/isolation_segment" 76 | 77 | count = "${var.isolation_segment ? 1 : 0}" 78 | 79 | environment = "${var.env_name}" 80 | location = "${var.location}" 81 | 82 | ssl_cert = "${var.iso_seg_ssl_cert}" 83 | ssl_private_key = "${var.iso_seg_ssl_private_key}" 84 | ssl_ca_cert = "${var.iso_seg_ssl_ca_cert}" 85 | ssl_ca_private_key = "${var.iso_seg_ssl_ca_private_key}" 86 | 87 | resource_group_name = "${module.infra.resource_group_name}" 88 | dns_zone = "${module.infra.dns_zone_name}" 89 | } 90 | -------------------------------------------------------------------------------- /terraforming-pas/outputs.tf: -------------------------------------------------------------------------------- 1 | output "iaas" { 2 | value = "azure" 3 | } 4 | 5 | output "location" { 6 | value = "${var.location}" 7 | } 8 | 9 | output "subscription_id" { 10 | sensitive = true 11 | value = "${var.subscription_id}" 12 | } 13 | 14 | output "tenant_id" { 15 | sensitive = true 16 | value = "${var.tenant_id}" 17 | } 18 | 19 | output "client_id" { 20 | sensitive = true 21 | value = "${var.client_id}" 22 | } 23 | 24 | output "client_secret" { 25 | sensitive = true 26 | value = "${var.client_secret}" 27 | } 28 | 29 | output "ops_manager_dns" { 30 | value = "${module.ops_manager.dns_name}" 31 | } 32 | 33 | output "optional_ops_manager_dns" { 34 | value = "${module.ops_manager.optional_dns_name}" 35 | } 36 | 37 | output "mysql_dns" { 38 | value = "${module.pas.mysql_dns}" 39 | } 40 | 41 | output "tcp_domain" { 42 | value = "${module.pas.tcp_domain}" 43 | } 44 | 45 | output "sys_domain" { 46 | value = "${module.pas.sys_domain}" 47 | } 48 | 49 | output "apps_domain" { 50 | value = "${module.pas.apps_domain}" 51 | } 52 | 53 | output "env_dns_zone_name_servers" { 54 | value = "${module.infra.dns_zone_name_servers}" 55 | } 56 | 57 | output "ssl_cert" { 58 | sensitive = true 59 | value = "${length(module.certs.ssl_cert) > 0 ? module.certs.ssl_cert : var.ssl_cert}" 60 | } 61 | 62 | output "ssl_private_key" { 63 | sensitive = true 64 | value = "${length(module.certs.ssl_private_key) > 0 ? module.certs.ssl_private_key : var.ssl_private_key}" 65 | } 66 | 67 | output "iso_seg_ssl_cert" { 68 | sensitive = true 69 | value = "${module.isolation_segment.ssl_cert}" 70 | } 71 | 72 | output "iso_seg_ssl_private_key" { 73 | sensitive = true 74 | value = "${module.isolation_segment.ssl_private_key}" 75 | } 76 | 77 | output "web_lb_name" { 78 | value = "${module.pas.web_lb_name}" 79 | } 80 | 81 | output "diego_ssh_lb_name" { 82 | value = "${module.pas.diego_ssh_lb_name}" 83 | } 84 | 85 | output "mysql_lb_name" { 86 | value = "${module.pas.mysql_lb_name}" 87 | } 88 | 89 | output "tcp_lb_name" { 90 | value = "${module.pas.tcp_lb_name}" 91 | } 92 | 93 | output "network_name" { 94 | value = "${module.infra.network_name}" 95 | } 96 | 97 | output "infrastructure_subnet_name" { 98 | value = "${module.infra.infrastructure_subnet_name}" 99 | } 100 | 101 | output "infrastructure_subnet_cidr" { 102 | value = "${module.infra.infrastructure_subnet_cidr}" 103 | } 104 | 105 | output "infrastructure_subnet_gateway" { 106 | value = "${module.infra.infrastructure_subnet_gateway}" 107 | } 108 | 109 | # TODO(cdutra): PAS 110 | 111 | output "pas_subnet_name" { 112 | value = "${module.pas.pas_subnet_name}" 113 | } 114 | 115 | output "pas_subnet_cidr" { 116 | value = "${module.pas.pas_subnet_cidr}" 117 | } 118 | 119 | output "pas_subnet_gateway" { 120 | value = "${module.pas.pas_subnet_gateway}" 121 | } 122 | 123 | output "services_subnet_name" { 124 | value = "${module.pas.services_subnet_name}" 125 | } 126 | 127 | output "services_subnet_cidr" { 128 | value = "${module.pas.services_subnet_cidr}" 129 | } 130 | 131 | output "services_subnet_gateway" { 132 | value = "${module.pas.services_subnet_gateway}" 133 | } 134 | 135 | output "pcf_resource_group_name" { 136 | value = "${module.infra.resource_group_name}" 137 | } 138 | 139 | output "ops_manager_security_group_name" { 140 | value = "${module.infra.security_group_name}" 141 | } 142 | 143 | output "bosh_deployed_vms_security_group_name" { 144 | value = "${module.infra.bosh_deployed_vms_security_group_name}" 145 | } 146 | 147 | output "bosh_root_storage_account" { 148 | value = "${module.infra.bosh_root_storage_account}" 149 | } 150 | 151 | output "ops_manager_storage_account" { 152 | value = "${module.ops_manager.ops_manager_storage_account}" 153 | } 154 | 155 | output "cf_storage_account_name" { 156 | value = "${module.pas.cf_storage_account_name}" 157 | } 158 | 159 | output "cf_storage_account_access_key" { 160 | sensitive = true 161 | value = "${module.pas.cf_storage_account_access_key}" 162 | } 163 | 164 | output "cf_droplets_storage_container" { 165 | value = "${module.pas.cf_droplets_storage_container_name}" 166 | } 167 | 168 | output "cf_packages_storage_container" { 169 | value = "${module.pas.cf_packages_storage_container_name}" 170 | } 171 | 172 | output "cf_resources_storage_container" { 173 | value = "${module.pas.cf_resources_storage_container_name}" 174 | } 175 | 176 | output "cf_buildpacks_storage_container" { 177 | value = "${module.pas.cf_buildpacks_storage_container_name}" 178 | } 179 | 180 | output "ops_manager_ssh_public_key" { 181 | sensitive = true 182 | value = "${module.ops_manager.ops_manager_ssh_public_key}" 183 | } 184 | 185 | output "ops_manager_ssh_private_key" { 186 | sensitive = true 187 | value = "${module.ops_manager.ops_manager_ssh_private_key}" 188 | } 189 | 190 | output "ops_manager_public_ip" { 191 | value = "${module.ops_manager.ops_manager_public_ip}" 192 | } 193 | 194 | output "ops_manager_ip" { 195 | value = "${module.ops_manager.ops_manager_public_ip}" 196 | } 197 | 198 | output "optional_ops_manager_public_ip" { 199 | value = "${module.ops_manager.optional_ops_manager_public_ip}" 200 | } 201 | 202 | output "ops_manager_private_ip" { 203 | value = "${module.ops_manager.ops_manager_private_ip}" 204 | } 205 | 206 | output "isolation_segment" { 207 | value = { 208 | "lb_name" = "${module.isolation_segment.lb_name}" 209 | } 210 | } 211 | 212 | # Deprecated properties 213 | 214 | output "management_subnet_name" { 215 | value = "${module.infra.infrastructure_subnet_name}" 216 | } 217 | 218 | output "management_subnets" { 219 | value = ["${module.infra.infrastructure_subnet_name}"] 220 | } 221 | 222 | output "management_subnet_cidrs" { 223 | value = ["${module.infra.infrastructure_subnet_cidrs}"] 224 | } 225 | 226 | output "management_subnet_gateway" { 227 | value = "${module.infra.infrastructure_subnet_gateway}" 228 | } 229 | 230 | output "infrastructure_subnet_cidrs" { 231 | value = "${module.infra.infrastructure_subnet_cidrs}" 232 | } 233 | 234 | output "pas_subnet_cidrs" { 235 | value = "${module.pas.pas_subnet_cidrs}" 236 | } 237 | 238 | output "services_subnet_cidrs" { 239 | value = "${module.pas.services_subnet_cidrs}" 240 | } 241 | 242 | output "services_subnets" { 243 | value = ["${module.pas.services_subnet_name}"] 244 | } 245 | 246 | output "infrastructure_subnets" { 247 | value = ["${module.infra.infrastructure_subnet_name}"] 248 | } 249 | 250 | output "pas_subnets" { 251 | value = ["${module.pas.pas_subnet_name}"] 252 | } 253 | -------------------------------------------------------------------------------- /terraforming-pas/variables.tf: -------------------------------------------------------------------------------- 1 | variable "env_name" {} 2 | 3 | variable "cloud_name" { 4 | description = "The Azure cloud environment to use. Available values at https://www.terraform.io/docs/providers/azurerm/#environment" 5 | default = "public" 6 | } 7 | 8 | variable cf_storage_account_name { 9 | type = "string" 10 | description = "storage account name for cf" 11 | default = "cf" 12 | } 13 | 14 | variable cf_buildpacks_storage_container_name { 15 | type = "string" 16 | description = "container name for cf buildpacks" 17 | default = "buildpacks" 18 | } 19 | 20 | variable cf_packages_storage_container_name { 21 | type = "string" 22 | description = "container name for cf packages" 23 | default = "packages" 24 | } 25 | 26 | variable cf_droplets_storage_container_name { 27 | type = "string" 28 | description = "container name for cf droplets" 29 | default = "droplets" 30 | } 31 | 32 | variable cf_resources_storage_container_name { 33 | type = "string" 34 | description = "container name for cf resources" 35 | default = "resources" 36 | } 37 | 38 | variable "subscription_id" {} 39 | 40 | variable "tenant_id" {} 41 | 42 | variable "client_id" {} 43 | 44 | variable "client_secret" {} 45 | 46 | variable "location" {} 47 | 48 | variable "ssl_cert" { 49 | type = "string" 50 | description = "the contents of an SSL certificate which should be passed to the gorouter, optional if `ssl_ca_cert` is provided" 51 | default = "" 52 | } 53 | 54 | variable "ssl_private_key" { 55 | type = "string" 56 | description = "the contents of an SSL private key which should be passed to the gorouter, optional if `ssl_ca_cert` is provided" 57 | default = "" 58 | } 59 | 60 | variable "ssl_ca_cert" { 61 | type = "string" 62 | description = "the contents of a CA public key to be used to sign a generated certificate for gorouter, optional if `ssl_cert` is provided" 63 | default = "" 64 | } 65 | 66 | variable "ssl_ca_private_key" { 67 | type = "string" 68 | description = "the contents of a CA private key to be used to sign a generated certificate for gorouter, optional if `ssl_cert` is provided" 69 | default = "" 70 | } 71 | 72 | variable "ops_manager_image_uri" { 73 | type = "string" 74 | description = "Ops Manager image on Azure. Ops Manager VM will be skipped if this is empty" 75 | } 76 | 77 | variable "ops_manager_private_ip" { 78 | type = "string" 79 | description = "IP for the Ops Manager instance if not deploying in the default infrasstructure subnet" 80 | default = "10.0.8.4" 81 | } 82 | 83 | variable "optional_ops_manager_image_uri" { 84 | default = "" 85 | } 86 | 87 | variable "ops_manager_vm_size" { 88 | type = "string" 89 | default = "Standard_DS2_v2" 90 | } 91 | 92 | variable "dns_suffix" {} 93 | 94 | variable "dns_subdomain" { 95 | "type" = "string" 96 | "description" = "The base subdomain used for PCF. For example, if your dns_subdomain is `cf`, and your dns_suffix is `pivotal.io`, your PCF domain would be `cf.pivotal.io`" 97 | "default" = "" 98 | } 99 | 100 | variable "isolation_segment" { 101 | default = false 102 | } 103 | 104 | variable "iso_seg_ssl_cert" { 105 | type = "string" 106 | description = "the contents of an SSL certificate which should be passed to the iso seg gorouter, optional if `iso_seg_ssl_ca_cert` is provided" 107 | default = "" 108 | } 109 | 110 | variable "iso_seg_ssl_private_key" { 111 | type = "string" 112 | description = "the contents of an SSL private key which should be passed to the iso seg gorouter, optional if `iso_seg_ssl_ca_cert` is provided" 113 | default = "" 114 | } 115 | 116 | variable "iso_seg_ssl_ca_cert" { 117 | type = "string" 118 | description = "the contents of a CA public key to be used to sign a generated certificate for iso seg gorouter, optional if `iso_seg_ssl_cert` is provided" 119 | default = "" 120 | } 121 | 122 | variable "iso_seg_ssl_ca_private_key" { 123 | type = "string" 124 | description = "the contents of a CA private key to be used to sign a generated certificate for iso seg gorouter, optional if `iso_seg_ssl_cert` is provided" 125 | default = "" 126 | } 127 | 128 | variable "pcf_virtual_network_address_space" { 129 | type = "list" 130 | default = ["10.0.0.0/16"] 131 | } 132 | 133 | variable "pcf_infrastructure_subnet" { 134 | type = "string" 135 | default = "10.0.8.0/26" 136 | } 137 | 138 | variable "pcf_pas_subnet" { 139 | type = "string" 140 | default = "10.0.0.0/22" 141 | } 142 | 143 | variable "pcf_services_subnet" { 144 | type = "string" 145 | default = "10.0.4.0/22" 146 | } 147 | -------------------------------------------------------------------------------- /terraforming-pks/main.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = "< 0.12.0" 3 | } 4 | 5 | provider "azurerm" { 6 | subscription_id = "${var.subscription_id}" 7 | client_id = "${var.client_id}" 8 | client_secret = "${var.client_secret}" 9 | tenant_id = "${var.tenant_id}" 10 | environment = "${var.cloud_name}" 11 | 12 | version = "~> 1.32" 13 | } 14 | 15 | module "infra" { 16 | source = "../modules/infra" 17 | 18 | env_name = "${var.env_name}" 19 | location = "${var.location}" 20 | dns_subdomain = "${var.dns_subdomain}" 21 | dns_suffix = "${var.dns_suffix}" 22 | pcf_infrastructure_subnet = "${var.pcf_infrastructure_subnet}" 23 | pcf_virtual_network_address_space = "${var.pcf_virtual_network_address_space}" 24 | } 25 | 26 | module "certs" { 27 | source = "../modules/certs" 28 | 29 | env_name = "${var.env_name}" 30 | dns_suffix = "${var.dns_suffix}" 31 | ssl_ca_cert = "${var.ssl_ca_cert}" 32 | ssl_ca_private_key = "${var.ssl_ca_private_key}" 33 | } 34 | 35 | module "ops_manager" { 36 | source = "../modules/ops_manager" 37 | 38 | env_name = "${var.env_name}" 39 | location = "${var.location}" 40 | 41 | ops_manager_image_uri = "${var.ops_manager_image_uri}" 42 | ops_manager_vm_size = "${var.ops_manager_vm_size}" 43 | ops_manager_private_ip = "${var.ops_manager_private_ip}" 44 | 45 | optional_ops_manager_image_uri = "${var.optional_ops_manager_image_uri}" 46 | 47 | resource_group_name = "${module.infra.resource_group_name}" 48 | dns_zone_name = "${module.infra.dns_zone_name}" 49 | security_group_id = "${module.infra.security_group_id}" 50 | subnet_id = "${module.infra.infrastructure_subnet_id}" 51 | } 52 | 53 | module "pks" { 54 | source = "../modules/pks" 55 | 56 | env_id = "${var.env_name}" 57 | location = "${var.location}" 58 | 59 | resource_group_cidr = "10.0.0.0/16" 60 | 61 | resource_group_name = "${module.infra.resource_group_name}" 62 | network_name = "${module.infra.network_name}" 63 | bosh_deployed_vms_security_group_id = "${module.infra.bosh_deployed_vms_security_group_id}" 64 | } 65 | 66 | data "azurerm_subscription" "primary" {} 67 | 68 | resource "azurerm_role_definition" "pks_master_role" { 69 | name = "${var.env_name}-pks-master-role" 70 | scope = "${data.azurerm_subscription.primary.id}" 71 | description = "This is a custom role created via Terraform" 72 | 73 | permissions { 74 | actions = [ 75 | "Microsoft.Network/*", 76 | "Microsoft.Compute/disks/*", 77 | "Microsoft.Compute/virtualMachines/write", 78 | "Microsoft.Compute/virtualMachines/read", 79 | "Microsoft.Storage/storageAccounts/*" 80 | ] 81 | not_actions = [] 82 | } 83 | 84 | assignable_scopes = [ 85 | "${data.azurerm_subscription.primary.id}/resourceGroups/${var.env_name}", 86 | ] 87 | } 88 | 89 | resource "azurerm_role_definition" "pks_worker_role" { 90 | name = "${var.env_name}-pks-worker-role" 91 | scope = "${data.azurerm_subscription.primary.id}" 92 | description = "This is a custom role created via Terraform" 93 | 94 | permissions { 95 | actions = [ 96 | "Microsoft.Storage/storageAccounts/*" 97 | ] 98 | not_actions = [] 99 | } 100 | 101 | assignable_scopes = [ 102 | "${data.azurerm_subscription.primary.id}/resourceGroups/${var.env_name}", 103 | ] 104 | } 105 | 106 | resource "azurerm_user_assigned_identity" "pks_master_identity" { 107 | resource_group_name = "${module.infra.resource_group_name}" 108 | location = "${var.location}" 109 | 110 | name = "pks-master" 111 | } 112 | 113 | resource "azurerm_role_assignment" "master_role_assignemnt" { 114 | scope = "${data.azurerm_subscription.primary.id}/resourceGroups/${var.env_name}" 115 | role_definition_id = "${azurerm_role_definition.pks_master_role.id}" 116 | principal_id = "${azurerm_user_assigned_identity.pks_master_identity.principal_id}" 117 | } 118 | 119 | resource "azurerm_user_assigned_identity" "pks_worker_identity" { 120 | resource_group_name = "${module.infra.resource_group_name}" 121 | location = "${var.location}" 122 | 123 | name = "pks-worker" 124 | } 125 | 126 | resource "azurerm_role_assignment" "worker_role_assignemnt" { 127 | scope = "${data.azurerm_subscription.primary.id}/resourceGroups/${var.env_name}" 128 | role_definition_id = "${azurerm_role_definition.pks_worker_role.id}" 129 | principal_id = "${azurerm_user_assigned_identity.pks_worker_identity.principal_id}" 130 | } 131 | 132 | resource "azurerm_availability_set" "pks" { 133 | name = "${var.env_name}-availability-set" 134 | location = "${var.location}" 135 | resource_group_name = "${module.infra.resource_group_name}" 136 | } 137 | -------------------------------------------------------------------------------- /terraforming-pks/outputs.tf: -------------------------------------------------------------------------------- 1 | output "iaas" { 2 | value = "azure" 3 | } 4 | 5 | output "subscription_id" { 6 | sensitive = true 7 | value = "${var.subscription_id}" 8 | } 9 | 10 | output "tenant_id" { 11 | sensitive = true 12 | value = "${var.tenant_id}" 13 | } 14 | 15 | output "client_id" { 16 | sensitive = true 17 | value = "${var.client_id}" 18 | } 19 | 20 | output "client_secret" { 21 | sensitive = true 22 | value = "${var.client_secret}" 23 | } 24 | 25 | output "ops_manager_dns" { 26 | value = "${module.ops_manager.dns_name}" 27 | } 28 | 29 | output "optional_ops_manager_dns" { 30 | value = "${module.ops_manager.optional_dns_name}" 31 | } 32 | 33 | output "env_dns_zone_name_servers" { 34 | value = "${module.infra.dns_zone_name_servers}" 35 | } 36 | 37 | output "ssl_cert" { 38 | sensitive = true 39 | value = "${length(module.certs.ssl_cert) > 0 ? module.certs.ssl_cert : var.ssl_cert}" 40 | } 41 | 42 | output "ssl_private_key" { 43 | sensitive = true 44 | value = "${length(module.certs.ssl_private_key) > 0 ? module.certs.ssl_private_key : var.ssl_private_key}" 45 | } 46 | 47 | output "network_name" { 48 | value = "${module.infra.network_name}" 49 | } 50 | 51 | output "infrastructure_subnet_name" { 52 | value = "${module.infra.infrastructure_subnet_name}" 53 | } 54 | 55 | output "infrastructure_subnet_cidr" { 56 | value = "${module.infra.infrastructure_subnet_cidr}" 57 | } 58 | 59 | output "infrastructure_subnet_gateway" { 60 | value = "${module.infra.infrastructure_subnet_gateway}" 61 | } 62 | 63 | output "pcf_resource_group_name" { 64 | value = "${module.infra.resource_group_name}" 65 | } 66 | 67 | output "ops_manager_security_group_name" { 68 | value = "${module.infra.security_group_name}" 69 | } 70 | 71 | output "bosh_deployed_vms_security_group_name" { 72 | value = "${module.infra.bosh_deployed_vms_security_group_name}" 73 | } 74 | 75 | output "bosh_root_storage_account" { 76 | value = "${module.infra.bosh_root_storage_account}" 77 | } 78 | 79 | output "ops_manager_storage_account" { 80 | value = "${module.ops_manager.ops_manager_storage_account}" 81 | } 82 | 83 | output "ops_manager_ssh_public_key" { 84 | sensitive = true 85 | value = "${module.ops_manager.ops_manager_ssh_public_key}" 86 | } 87 | 88 | output "ops_manager_ssh_private_key" { 89 | sensitive = true 90 | value = "${module.ops_manager.ops_manager_ssh_private_key}" 91 | } 92 | 93 | output "ops_manager_public_ip" { 94 | value = "${module.ops_manager.ops_manager_public_ip}" 95 | } 96 | 97 | output "ops_manager_ip" { 98 | value = "${module.ops_manager.ops_manager_public_ip}" 99 | } 100 | 101 | output "optional_ops_manager_public_ip" { 102 | value = "${module.ops_manager.optional_ops_manager_public_ip}" 103 | } 104 | 105 | output "ops_manager_private_ip" { 106 | value = "${module.ops_manager.ops_manager_private_ip}" 107 | } 108 | 109 | output "pks-master-app-sec-group" { 110 | value = "${module.pks.pks-master-app-sec-group}" 111 | } 112 | 113 | # Subnets 114 | 115 | output "pks_subnet_name" { 116 | value = "${module.pks.pks_subnet_name}" 117 | } 118 | 119 | output "pks_subnet_cidr" { 120 | value = "${module.pks.pks_subnet_cidr}" 121 | } 122 | 123 | output "pks_subnet_gateway" { 124 | value = "${module.pks.pks_subnet_gateway}" 125 | } 126 | 127 | output "services_subnet_name" { 128 | value = "${module.pks.services_subnet_name}" 129 | } 130 | 131 | output "services_subnet_cidr" { 132 | value = "${module.pks.services_subnet_cidr}" 133 | } 134 | 135 | output "services_subnet_gateway" { 136 | value = "${module.pks.services_subnet_gateway}" 137 | } 138 | 139 | # Deprecated properties 140 | 141 | output "management_subnet_name" { 142 | value = "${module.infra.infrastructure_subnet_name}" 143 | } 144 | 145 | output "management_subnets" { 146 | value = ["${module.infra.infrastructure_subnet_name}"] 147 | } 148 | 149 | output "management_subnet_cidrs" { 150 | value = ["${module.infra.infrastructure_subnet_cidrs}"] 151 | } 152 | 153 | output "management_subnet_gateway" { 154 | value = "${module.infra.infrastructure_subnet_gateway}" 155 | } 156 | 157 | output "infrastructure_subnets" { 158 | value = ["${module.infra.infrastructure_subnet_name}"] 159 | } 160 | 161 | output "infrastructure_subnet_cidrs" { 162 | value = "${module.infra.infrastructure_subnet_cidrs}" 163 | } 164 | 165 | output "pks_subnet_cidrs" { 166 | value = "${module.pks.pks_subnet_cidrs}" 167 | } 168 | 169 | output "pks_subnets" { 170 | value = ["${module.pks.pks_subnet_name}"] 171 | } 172 | 173 | output "services_subnets" { 174 | value = ["${module.pks.services_subnet_name}"] 175 | } 176 | 177 | output "services_subnet_cidrs" { 178 | value = "${module.pks.services_subnet_cidrs}" 179 | } 180 | -------------------------------------------------------------------------------- /terraforming-pks/variables.tf: -------------------------------------------------------------------------------- 1 | variable "subscription_id" { 2 | default = "" 3 | } 4 | 5 | variable "client_id" { 6 | default = "" 7 | } 8 | 9 | variable "client_secret" { 10 | default = "" 11 | } 12 | 13 | variable "tenant_id" { 14 | default = "" 15 | } 16 | 17 | variable "cloud_name" { 18 | description = "The Azure cloud environment to use. Available values at https://www.terraform.io/docs/providers/azurerm/#environment" 19 | default = "public" 20 | } 21 | 22 | variable "env_name" {} 23 | 24 | variable "location" { 25 | default = "" 26 | } 27 | 28 | variable "dns_suffix" { 29 | default = "" 30 | } 31 | 32 | variable "dns_subdomain" { 33 | "type" = "string" 34 | "description" = "The base subdomain used for PCF. For example, if your dns_subdomain is `cf`, and your dns_suffix is `pivotal.io`, your PCF domain would be `cf.pivotal.io`" 35 | "default" = "" 36 | } 37 | 38 | variable "pcf_infrastructure_subnet" { 39 | type = "string" 40 | default = "10.0.8.0/26" 41 | } 42 | 43 | variable "pcf_virtual_network_address_space" { 44 | type = "list" 45 | default = ["10.0.0.0/16"] 46 | } 47 | 48 | variable "ssl_ca_cert" { 49 | type = "string" 50 | description = "the contents of a CA public key to be used to sign a generated certificate for gorouter, optional if `ssl_cert` is provided" 51 | default = "" 52 | } 53 | 54 | variable "ssl_ca_private_key" { 55 | type = "string" 56 | description = "the contents of a CA private key to be used to sign a generated certificate for gorouter, optional if `ssl_cert` is provided" 57 | default = "" 58 | } 59 | 60 | variable "ops_manager_image_uri" {} 61 | 62 | variable "ops_manager_vm_size" { 63 | type = "string" 64 | default = "Standard_DS2_v2" 65 | } 66 | 67 | variable "ops_manager_private_ip" { 68 | type = "string" 69 | description = "IP for the Ops Manager instance if not deploying in the default infrasstructure subnet" 70 | default = "10.0.8.4" 71 | } 72 | 73 | variable "optional_ops_manager_image_uri" { 74 | default = "" 75 | } 76 | 77 | variable "ssl_cert" { 78 | default = "" 79 | } 80 | 81 | variable "ssl_private_key" { 82 | default = "" 83 | } 84 | 85 | variable "azure_master_managed_identity" { 86 | type = "string" 87 | default = "pks-master" 88 | } 89 | 90 | variable "azure_worker_managed_identity" { 91 | type = "string" 92 | default = "pks-worker" 93 | } 94 | --------------------------------------------------------------------------------