├── .envrc ├── .gitignore ├── LICENSE ├── README.md ├── ci ├── assets │ └── template │ │ ├── control-plane-config.yml │ │ ├── director-config.yml │ │ ├── ist-config.yml │ │ ├── pks-config.yml │ │ └── srt-config.yml ├── configure ├── dns-override │ └── aws_dns_root_zone_override.tf ├── pipeline.yml └── tasks │ ├── custom-vm-extensions.sh │ └── custom-vm-extensions.yml ├── modules ├── acme_cert │ ├── cert.tf │ ├── outputs.tf │ └── variables.tf ├── add_ns_to_hosted_zone │ ├── main.tf │ └── variables.tf ├── calculate_subnets │ └── main.tf ├── certs │ ├── certs.tf │ ├── outputs.tf │ └── variables.tf ├── control_plane │ ├── atc_lb.tf │ ├── dns.tf │ ├── iam_server_cert.tf │ ├── network.tf │ ├── outputs.tf │ ├── shared_lbs.tf │ └── variables.tf ├── infra │ ├── dns.tf │ ├── nat.tf │ ├── networking.tf │ ├── outputs.tf │ ├── variables.tf │ └── vpc.tf ├── ops_manager │ ├── bucket.tf │ ├── dns.tf │ ├── eip.tf │ ├── iam.tf │ ├── instance.tf │ ├── keypair.tf │ ├── optional_instance.tf │ ├── outputs.tf │ ├── security_group.tf │ ├── templates │ │ └── iam_policy.json │ └── variables.tf ├── pas │ ├── dns.tf │ ├── iam.tf │ ├── isoseg.tf │ ├── lbs.tf │ ├── outputs.tf │ ├── s3.tf │ ├── subnets.tf │ ├── templates │ │ ├── iam_pas_backup_buckets_policy.json │ │ └── iam_pas_buckets_policy.json │ └── variables.tf ├── pg │ ├── template.tf │ └── variables.tf ├── pks │ ├── dns.tf │ ├── iam.tf │ ├── lb.tf │ ├── networking.tf │ ├── outputs.tf │ └── variables.tf └── rds │ ├── outputs.tf │ ├── template.tf │ └── variables.tf ├── scripts ├── configure-director ├── configure-product ├── delete-installation └── ssh ├── terraforming-control-plane ├── db │ └── create_databases.sh ├── main.tf ├── outputs.tf ├── terraform.tfvars.example └── variables.tf ├── 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 | *.tfvars 5 | *.tfplan 6 | .idea 7 | .idea/* 8 | *.pem 9 | *.pivotal 10 | *stemcell*.tgz 11 | *.generated.yml 12 | OpsManager*onAWS.yml 13 | om.key 14 | credentials.yml 15 | *control-plane-*.yml 16 | *.tgz 17 | *secrets.yml 18 | -------------------------------------------------------------------------------- /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 AWS 8 | 9 | ## What is this? 10 | 11 | Set of terraform modules for deploying Ops Manager, PAS and PKS infrastructure requirements like: 12 | 13 | - Friendly DNS entries in Route53 14 | - A RDS instance (optional) 15 | - A Virtual Private Network (VPC), subnets, Security Groups 16 | - Necessary s3 buckets 17 | - NAT Gateway services 18 | - Network Load Balancers 19 | - An IAM User with proper permissions 20 | - Tagged resources 21 | 22 | Note: This is not an exhaustive list of resources created, this will vary depending of your arguments and what you're deploying. 23 | 24 | ## Prerequisites 25 | 26 | ### Terraform CLI 27 | 28 | ```bash 29 | brew update 30 | brew install terraform 31 | ``` 32 | 33 | ### AWS Permissions 34 | - AmazonEC2FullAccess 35 | - AmazonRDSFullAccess 36 | - AmazonRoute53FullAccess 37 | - AmazonS3FullAccess 38 | - AmazonVPCFullAccess 39 | - IAMFullAccess 40 | - AWSKeyManagementServicePowerUser 41 | 42 | Note: You will also need to create a custom policy as the following and add to 43 | the same user: 44 | ``` 45 | { 46 | "Version": "2012-10-17", 47 | "Statement": [ 48 | { 49 | "Sid": "KMSKeyDeletionAndUpdate", 50 | "Effect": "Allow", 51 | "Action": [ 52 | "kms:UpdateKeyDescription", 53 | "kms:ScheduleKeyDeletion" 54 | ], 55 | "Resource": "*" 56 | } 57 | ] 58 | } 59 | ``` 60 | 61 | ## Are you using Platform Automation? 62 | Be sure to skip the creation of the Ops Manager VM. Do not include the vars listed [here](/README.md#ops-manager-optional). 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). 63 | 64 | Deployment of the infrastructure is still required. 65 | 66 | ## Deploying Infrastructure 67 | 68 | First, you'll need to clone this repo. Then, depending on if you're deploying PAS or PKS you need to perform the following steps: 69 | 70 | 1. `cd` into the proper directory: 71 | - [terraforming-pas/](terraforming-pas/) 72 | - [terraforming-pks/](terraforming-pks/) 73 | - [terraforming-control-plane/](terraforming-control-plane/) 74 | 1. Create [`terraform.tfvars`](/README.md#var-file) file 75 | 1. Populate [credentials](/README.md#credentials) file or env variables 76 | 1. Run terraform apply: 77 | ```bash 78 | terraform init 79 | terraform plan -out=pcf.tfplan 80 | terraform apply pcf.tfplan 81 | ``` 82 | 83 | ### Var File 84 | 85 | Copy the stub content below into a file called `terraform.tfvars` and put it in the root of this project. 86 | These vars will be used when you run `terraform apply`. 87 | You should fill in the stub values with the correct content. 88 | 89 | ```hcl 90 | env_name = "some-environment-name" 91 | region = "us-west-1" 92 | availability_zones = ["us-west-1a", "us-west-1c"] 93 | ops_manager_ami = "ami-4f291f2f" 94 | rds_instance_count = 1 95 | dns_suffix = "example.com" 96 | vpc_cidr = "10.0.0.0/16" 97 | use_route53 = true 98 | use_ssh_routes = true 99 | use_tcp_routes = true 100 | 101 | ssl_cert = < 0 ? local.data_dns_name_servers: local.resource_dns_name_servers)}" 11 | } 12 | 13 | data "aws_route53_zone" "pcf_zone" { 14 | count = "${var.use_route53 ? local.hosted_zone_count : 0}" 15 | 16 | name = "${var.hosted_zone}" 17 | } 18 | 19 | resource "aws_route53_zone" "pcf_zone" { 20 | count = "${var.use_route53 ? (1 - local.hosted_zone_count) : 0}" 21 | 22 | name = "${var.env_name}.${var.dns_suffix}" 23 | 24 | tags = "${merge(var.tags, map("Name", "${var.env_name}-hosted-zone"))}" 25 | } 26 | -------------------------------------------------------------------------------- /modules/infra/nat.tf: -------------------------------------------------------------------------------- 1 | resource "aws_route_table" "deployment" { 2 | count = "${length(var.availability_zones)}" 3 | vpc_id = "${aws_vpc.vpc.id}" 4 | } 5 | 6 | resource "aws_security_group" "nat_security_group" { 7 | count = "${var.internetless ? 0 : 1}" 8 | 9 | name = "nat_security_group" 10 | description = "NAT Security Group" 11 | vpc_id = "${aws_vpc.vpc.id}" 12 | 13 | ingress { 14 | cidr_blocks = ["${var.vpc_cidr}"] 15 | protocol = "-1" 16 | from_port = 0 17 | to_port = 0 18 | } 19 | 20 | egress { 21 | cidr_blocks = ["0.0.0.0/0"] 22 | protocol = "-1" 23 | from_port = 0 24 | to_port = 0 25 | } 26 | 27 | tags = "${merge(var.tags, map("Name", "${var.env_name}-nat-security-group"))}" 28 | } 29 | 30 | resource "aws_nat_gateway" "nat" { 31 | count = "${var.internetless ? 0 : length(var.availability_zones)}" 32 | allocation_id = "${element(aws_eip.nat_eip.*.id, count.index)}" 33 | subnet_id = "${element(aws_subnet.public_subnets.*.id, count.index)}" 34 | 35 | tags = "${merge(var.tags, map("Name", "${var.env_name}-nat${count.index}"))}" 36 | } 37 | 38 | resource "aws_eip" "nat_eip" { 39 | count = "${var.internetless ? 0 : length(var.availability_zones)}" 40 | 41 | vpc = true 42 | 43 | tags = "${var.tags}" 44 | } 45 | 46 | resource "aws_route" "toggle_internet" { 47 | count = "${var.internetless ? 0 : length(var.availability_zones)}" 48 | 49 | route_table_id = "${element(aws_route_table.deployment.*.id, count.index)}" 50 | nat_gateway_id = "${element(aws_nat_gateway.nat.*.id, count.index)}" 51 | destination_cidr_block = "0.0.0.0/0" 52 | } 53 | -------------------------------------------------------------------------------- /modules/infra/networking.tf: -------------------------------------------------------------------------------- 1 | # Bosh Director Subnet 2 | resource "aws_subnet" "infrastructure_subnets" { 3 | count = "${length(var.availability_zones)}" 4 | vpc_id = "${aws_vpc.vpc.id}" 5 | cidr_block = "${cidrsubnet(local.infrastructure_cidr, 2, count.index)}" 6 | availability_zone = "${element(var.availability_zones, count.index)}" 7 | 8 | tags = "${merge(var.tags, map("Name", "${var.env_name}-infrastructure-subnet${count.index}"))}" 9 | } 10 | 11 | data "template_file" "infrastructure_subnet_gateways" { 12 | # Render the template once for each availability zone 13 | count = "${length(var.availability_zones)}" 14 | template = "$${gateway}" 15 | 16 | vars { 17 | gateway = "${cidrhost(element(aws_subnet.infrastructure_subnets.*.cidr_block, count.index), 1)}" 18 | } 19 | } 20 | 21 | resource "aws_route_table_association" "route_infrastructure_subnets" { 22 | count = "${length(var.availability_zones)}" 23 | subnet_id = "${element(aws_subnet.infrastructure_subnets.*.id, count.index)}" 24 | route_table_id = "${element(aws_route_table.deployment.*.id, count.index)}" 25 | } 26 | 27 | # Ops Manager Subnet 28 | resource "aws_internet_gateway" "ig" { 29 | vpc_id = "${aws_vpc.vpc.id}" 30 | 31 | tags = "${var.tags}" 32 | } 33 | 34 | resource "aws_route_table" "public_route_table" { 35 | vpc_id = "${aws_vpc.vpc.id}" 36 | 37 | route { 38 | cidr_block = "0.0.0.0/0" 39 | gateway_id = "${aws_internet_gateway.ig.id}" 40 | } 41 | } 42 | 43 | resource "aws_subnet" "public_subnets" { 44 | count = "${length(var.availability_zones)}" 45 | vpc_id = "${aws_vpc.vpc.id}" 46 | cidr_block = "${cidrsubnet(local.public_cidr, 2, count.index)}" 47 | availability_zone = "${element(var.availability_zones, count.index)}" 48 | 49 | tags = "${merge(var.tags, map("Name", "${var.env_name}-public-subnet${count.index}"), 50 | map("kubernetes.io/role/elb", "1"), 51 | map("SubnetType", "Utility"))}" 52 | 53 | # Ignore additional tags that are added for specifying clusters. 54 | lifecycle { 55 | ignore_changes = ["tags"] 56 | } 57 | } 58 | 59 | resource "aws_route_table_association" "route_public_subnets" { 60 | count = "${length(var.availability_zones)}" 61 | subnet_id = "${element(aws_subnet.public_subnets.*.id, count.index)}" 62 | route_table_id = "${aws_route_table.public_route_table.id}" 63 | } 64 | -------------------------------------------------------------------------------- /modules/infra/outputs.tf: -------------------------------------------------------------------------------- 1 | output "vpc_id" { 2 | value = "${aws_vpc.vpc.id}" 3 | } 4 | 5 | output "public_subnet_ids" { 6 | value = ["${aws_subnet.public_subnets.*.id}"] 7 | } 8 | 9 | output "deployment_route_table_ids" { 10 | value = ["${aws_route_table.deployment.*.id}"] 11 | } 12 | 13 | output "zone_id" { 14 | value = "${local.zone_id}" 15 | } 16 | 17 | output "name_servers" { 18 | value = "${local.name_servers}" 19 | } 20 | 21 | output "vms_security_group_id" { 22 | value = "${aws_security_group.vms_security_group.id}" 23 | } 24 | 25 | output "public_subnet_availability_zones" { 26 | value = ["${aws_subnet.public_subnets.*.availability_zone}"] 27 | } 28 | 29 | output "public_subnet_cidrs" { 30 | value = ["${aws_subnet.public_subnets.*.cidr_block}"] 31 | } 32 | 33 | output "infrastructure_subnet_ids" { 34 | value = ["${aws_subnet.infrastructure_subnets.*.id}"] 35 | } 36 | 37 | output "infrastructure_subnets" { 38 | value = ["${aws_subnet.infrastructure_subnets.*.id}"] 39 | } 40 | 41 | output "infrastructure_subnet_availability_zones" { 42 | value = ["${aws_subnet.infrastructure_subnets.*.availability_zone}"] 43 | } 44 | 45 | output "infrastructure_subnet_cidrs" { 46 | value = ["${aws_subnet.infrastructure_subnets.*.cidr_block}"] 47 | } 48 | 49 | output "infrastructure_subnet_gateways" { 50 | value = ["${data.template_file.infrastructure_subnet_gateways.*.rendered}"] 51 | } 52 | 53 | output "aws_lb_interface_endpoint_ips" { 54 | value = "${data.aws_network_interface.lb_endpoints.*.private_ip}" 55 | } 56 | 57 | output "aws_ec2_interface_endpoint_ips" { 58 | value = "${data.aws_network_interface.ec2_endpoints.*.private_ip}" 59 | } 60 | -------------------------------------------------------------------------------- /modules/infra/variables.tf: -------------------------------------------------------------------------------- 1 | variable "env_name" { 2 | type = "string" 3 | } 4 | 5 | variable "region" { 6 | type = "string" 7 | } 8 | 9 | variable "hosted_zone" { 10 | type = "string" 11 | default = "" 12 | } 13 | 14 | variable "dns_suffix" { 15 | type = "string" 16 | } 17 | 18 | variable "use_route53" { 19 | } 20 | 21 | variable "availability_zones" { 22 | type = "list" 23 | } 24 | 25 | variable "vpc_cidr" { 26 | type = "string" 27 | default = "10.0.0.0/16" 28 | } 29 | 30 | variable "tags" { 31 | type = "map" 32 | default = {} 33 | description = "Key/value tags to assign to all AWS resources" 34 | } 35 | 36 | variable "internetless" {} 37 | 38 | variable "nat_ami_map" { 39 | type = "map" 40 | 41 | default = { 42 | ap-northeast-1 = "ami-0cf78ae724f63bac0" 43 | ap-northeast-2 = "ami-08cfa02141f9e9bee" 44 | ap-south-1 = "ami-0aba92643213491b9" 45 | ap-southeast-1 = "ami-0cf24653bcf894797" 46 | ap-southeast-2 = "ami-00c1445796bc0a29f" 47 | ca-central-1 = "ami-b61b96d2" 48 | eu-central-1 = "ami-06465d49ba60cf770" 49 | eu-west-1 = "ami-0ea87e2bfa81ca08a" 50 | eu-west-2 = "ami-e6768381" 51 | eu-west-3 = "ami-0050bb60cea70c5b3" 52 | sa-east-1 = "ami-09c013530239687aa" 53 | us-east-1 = "ami-0422d936d535c63b1" 54 | us-east-2 = "ami-0f9c61b5a562a16af" 55 | us-gov-west-1 = "ami-c177eba0" 56 | us-west-1 = "ami-0d4027d2cdbca669d" 57 | us-west-2 = "ami-40d1f038" 58 | } 59 | } 60 | 61 | module "cidr_lookup" { 62 | source = "../calculate_subnets" 63 | vpc_cidr = "${var.vpc_cidr}" 64 | } 65 | 66 | locals { 67 | infrastructure_cidr = "${module.cidr_lookup.infrastructure_cidr}" 68 | public_cidr = "${module.cidr_lookup.public_cidr}" 69 | } 70 | -------------------------------------------------------------------------------- /modules/infra/vpc.tf: -------------------------------------------------------------------------------- 1 | resource "aws_vpc" "vpc" { 2 | cidr_block = "${var.vpc_cidr}" 3 | instance_tenancy = "default" 4 | enable_dns_hostnames = true 5 | 6 | tags = "${merge(var.tags, map("Name", "${var.env_name}-vpc"))}" 7 | } 8 | 9 | resource "aws_security_group" "vms_security_group" { 10 | name = "vms_security_group" 11 | description = "VMs Security Group" 12 | vpc_id = "${aws_vpc.vpc.id}" 13 | 14 | ingress { 15 | cidr_blocks = ["${var.vpc_cidr}"] 16 | protocol = "-1" 17 | from_port = 0 18 | to_port = 0 19 | } 20 | 21 | egress { 22 | cidr_blocks = ["0.0.0.0/0"] 23 | protocol = "-1" 24 | from_port = 0 25 | to_port = 0 26 | } 27 | 28 | tags = "${merge(var.tags, map("Name", "${var.env_name}-vms-security-group"))}" 29 | } 30 | 31 | locals { 32 | ec2_address = "com.amazonaws.${var.region}.ec2" 33 | lb_api_address = "com.amazonaws.${var.region}.elasticloadbalancing" 34 | } 35 | 36 | resource "aws_vpc_endpoint" "ec2" { 37 | count = "${var.internetless ? 1 : 0}" 38 | 39 | vpc_id = "${aws_vpc.vpc.id}" 40 | service_name = "${local.ec2_address}" 41 | vpc_endpoint_type = "Interface" 42 | subnet_ids = ["${aws_subnet.infrastructure_subnets.*.id}"] 43 | private_dns_enabled = true 44 | security_group_ids = ["${aws_security_group.vms_security_group.id}"] 45 | } 46 | 47 | resource "aws_vpc_endpoint" "lb" { 48 | count = "${var.internetless ? 1 : 0}" 49 | 50 | vpc_id = "${aws_vpc.vpc.id}" 51 | service_name = "${local.lb_api_address}" 52 | vpc_endpoint_type = "Interface" 53 | subnet_ids = ["${aws_subnet.infrastructure_subnets.*.id}"] 54 | private_dns_enabled = true 55 | security_group_ids = ["${aws_security_group.vms_security_group.id}"] 56 | } 57 | 58 | data "aws_network_interface" "ec2_endpoints" { 59 | count = "${var.internetless ? length(var.availability_zones) : 0}" 60 | 61 | id = "${element(aws_vpc_endpoint.ec2.0.network_interface_ids, count.index)}" 62 | } 63 | 64 | data "aws_network_interface" "lb_endpoints" { 65 | count = "${var.internetless ? length(var.availability_zones) : 0}" 66 | 67 | id = "${element(aws_vpc_endpoint.lb.0.network_interface_ids, count.index)}" 68 | } 69 | -------------------------------------------------------------------------------- /modules/ops_manager/bucket.tf: -------------------------------------------------------------------------------- 1 | resource "aws_s3_bucket" "ops_manager_bucket" { 2 | bucket = "${var.env_name}-ops-manager-bucket-${var.bucket_suffix}" 3 | force_destroy = true 4 | 5 | tags = "${merge(var.tags, map("Name", "Ops Manager S3 Bucket"))}" 6 | } 7 | -------------------------------------------------------------------------------- /modules/ops_manager/dns.tf: -------------------------------------------------------------------------------- 1 | resource "aws_route53_record" "ops_manager_attached_eip" { 2 | name = "pcf.${var.env_name}.${var.dns_suffix}" 3 | zone_id = "${var.zone_id}" 4 | type = "A" 5 | ttl = 300 6 | count = "${var.use_route53 ? local.ops_man_vm : 0}" 7 | 8 | records = ["${coalesce(join("", aws_eip.ops_manager_attached.*.public_ip), aws_instance.ops_manager.private_ip)}"] 9 | } 10 | 11 | resource "aws_route53_record" "ops_manager_unattached_eip" { 12 | name = "pcf.${var.env_name}.${var.dns_suffix}" 13 | zone_id = "${var.zone_id}" 14 | type = "A" 15 | ttl = 300 16 | count = "${var.use_route53 && (local.ops_man_vm < 1) ? 1 : 0}" 17 | 18 | records = ["${aws_eip.ops_manager_unattached.*.public_ip}"] 19 | } 20 | 21 | resource "aws_route53_record" "optional_ops_manager" { 22 | name = "pcf-optional.${var.env_name}.${var.dns_suffix}" 23 | zone_id = "${var.zone_id}" 24 | type = "A" 25 | ttl = 300 26 | count = "${var.use_route53 ? local.optional_ops_man_vm : 0}" 27 | 28 | records = ["${coalesce(join("", aws_eip.optional_ops_manager.*.public_ip), aws_instance.optional_ops_manager.private_ip)}"] 29 | } 30 | -------------------------------------------------------------------------------- /modules/ops_manager/eip.tf: -------------------------------------------------------------------------------- 1 | resource "aws_eip" "ops_manager_attached" { 2 | instance = "${aws_instance.ops_manager.id}" 3 | count = "${var.private ? 0 : local.ops_man_vm }" 4 | vpc = true 5 | 6 | tags = "${merge(var.tags, map("Name", "${var.env_name}-om-eip"))}" 7 | } 8 | 9 | resource "aws_eip" "ops_manager_unattached" { 10 | count = "${var.private || (local.ops_man_vm > 0) ? 0 : 1}" 11 | vpc = true 12 | 13 | tags = "${merge(var.tags, map("Name", "${var.env_name}-om-eip"))}" 14 | } 15 | 16 | resource "aws_eip" "optional_ops_manager" { 17 | instance = "${aws_instance.optional_ops_manager.id}" 18 | count = "${var.private ? 0 : local.optional_ops_man_vm}" 19 | vpc = true 20 | 21 | tags = "${merge(var.tags, map("Name", "${var.env_name}-optional-om-eip"))}" 22 | } 23 | -------------------------------------------------------------------------------- /modules/ops_manager/iam.tf: -------------------------------------------------------------------------------- 1 | data "template_file" "ops_manager" { 2 | template = "${file("${path.module}/templates/iam_policy.json")}" 3 | 4 | vars { 5 | iam_instance_profile_arn = "${aws_iam_instance_profile.ops_manager.arn}" 6 | ops_manager_bucket_arn = "${aws_s3_bucket.ops_manager_bucket.arn}" 7 | iam_ops_manager_role_arn = "${aws_iam_role.ops_manager.arn}" 8 | } 9 | } 10 | 11 | data "aws_iam_policy_document" "ops_manager" { 12 | source_json = "${data.template_file.ops_manager.rendered}" 13 | 14 | statement { 15 | sid = "AllowToCreateInstanceWithCurrentInstanceProfile" 16 | effect = "Allow" 17 | actions = ["iam:PassRole"] 18 | 19 | resources = [ 20 | "${compact(concat(list(aws_iam_role.ops_manager.arn), var.additional_iam_roles_arn))}", 21 | ] 22 | } 23 | 24 | statement { 25 | sid = "AllowOperationsForCreatingOpsMan" 26 | effect = "Allow" 27 | actions = ["ec2:ModifyVolume", "ec2:StopInstances", "ec2:StartInstances"] 28 | 29 | resources = [ 30 | "*", 31 | ] 32 | } 33 | } 34 | 35 | resource "aws_iam_policy" "ops_manager_role" { 36 | name = "${var.env_name}_ops_manager_role" 37 | policy = "${data.aws_iam_policy_document.ops_manager.json}" 38 | } 39 | 40 | resource "aws_iam_role_policy_attachment" "ops_manager_policy" { 41 | role = "${aws_iam_role.ops_manager.name}" 42 | policy_arn = "${aws_iam_policy.ops_manager_role.arn}" 43 | } 44 | 45 | resource "aws_iam_policy" "ops_manager_user" { 46 | name = "${var.env_name}_ops_manager_user" 47 | policy = "${data.aws_iam_policy_document.ops_manager.json}" 48 | 49 | count = "${var.iam_users}" 50 | } 51 | 52 | resource "aws_iam_user_policy_attachment" "ops_manager" { 53 | user = "${aws_iam_user.ops_manager.name}" 54 | policy_arn = "${aws_iam_policy.ops_manager_user.arn}" 55 | 56 | count = "${var.iam_users}" 57 | } 58 | 59 | resource "aws_iam_user" "ops_manager" { 60 | name = "${var.env_name}_om_user" 61 | 62 | count = "${var.iam_users}" 63 | } 64 | 65 | resource "aws_iam_access_key" "ops_manager" { 66 | user = "${aws_iam_user.ops_manager.name}" 67 | 68 | count = "${var.iam_users}" 69 | } 70 | 71 | resource "aws_iam_role" "ops_manager" { 72 | name = "${var.env_name}_om_role" 73 | 74 | lifecycle { 75 | create_before_destroy = true 76 | } 77 | 78 | assume_role_policy = < /dev/null 14 | RAW_JSON=$(jq -e --raw-output '.modules[0].outputs | map_values(.value)' terraform.tfstate) 15 | WITH_CERT=$(echo "${RAW_JSON}" | jq --arg terraformingca "${CA_CERT}" '. + {terraforming_ca_cert: $terraformingca}') 16 | 17 | authenticate_om "${password}" 18 | 19 | om -k configure-authentication -dp "${OM_PASSWORD}" 20 | om -k configure-director --config <(texplate execute "$PROJECT_DIR/ci/assets/template/director-config.yml" -f <(echo "${WITH_CERT}") -o yaml) 21 | popd > /dev/null 22 | } 23 | 24 | main "$@" 25 | -------------------------------------------------------------------------------- /scripts/configure-product: -------------------------------------------------------------------------------- 1 | #!/bin/bash -exu 2 | 3 | authenticate_om() { 4 | export OM_TARGET 5 | 6 | OM_TARGET="https://$(terraform output ops_manager_dns)" 7 | export OM_USERNAME="admin" 8 | export OM_PASSWORD="$1" 9 | } 10 | 11 | main() { 12 | local path=${1?"Path is required (e.g. terraforming-pas, terraforming-pks, terraforming-control-plane)"} 13 | local product=${2?"Product slug is required (e.g. cf, pivotal-container-service, control-plane)"} 14 | local password=${3?"OpsManager password is required."} 15 | 16 | local product_template 17 | case $product in 18 | cf) 19 | product_template=$PROJECT_DIR/ci/assets/template/srt-config.yml 20 | ;; 21 | pivotal-container-service) 22 | product_template=$PROJECT_DIR/ci/assets/template/pks-config.yml 23 | ;; 24 | control-plane) 25 | product_template=$PROJECT_DIR/ci/assets/template/control-plane-config.yml 26 | ;; 27 | p-isolation-segment) 28 | product_template=$PROJECT_DIR/ci/assets/template/ist-config.yml 29 | ;; 30 | esac 31 | 32 | 33 | pushd $PROJECT_DIR/$path > /dev/null 34 | authenticate_om "${password}" 35 | 36 | mkdir -p /tmp/env-state 37 | jq -e --raw-output '.modules[0].outputs | map_values(.value)' terraform.tfstate > /tmp/env-state/metadata 38 | 39 | local rds_ca_cert 40 | rds_ca_cert="$(curl -X GET 'https://s3.amazonaws.com/rds-downloads/rds-ca-2015-root.pem')" 41 | 42 | cat /tmp/env-state/metadata | jq --arg rds_ca_cert "$rds_ca_cert" '. + {"rds_ca_cert": $rds_ca_cert}' > /tmp/env-state/metadata_tmp 43 | mv /tmp/env-state/metadata{_tmp,} 44 | 45 | export PRODUCT=${product} 46 | 47 | om -k configure-product \ 48 | -c <(texplate execute "${product_template}" -f /tmp/env-state/metadata -o yaml) 49 | popd > /dev/null 50 | } 51 | 52 | main "$@" 53 | -------------------------------------------------------------------------------- /scripts/delete-installation: -------------------------------------------------------------------------------- 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?"Path is required (e.g. terraforming-pas, terraforming-pks, terraforming-control-plane)"} 11 | local password=${2?"OpsManager password is required."} 12 | 13 | pushd $PROJECT_DIR/$path > /dev/null 14 | authenticate_om "${password}" 15 | 16 | om -k delete-installation 17 | terraform destroy 18 | popd > /dev/null 19 | } 20 | 21 | main "$@" 22 | -------------------------------------------------------------------------------- /scripts/ssh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -exu 2 | 3 | main(){ 4 | local path=${1?"Path is required (e.g. terraforming-pas, terraforming-pks, terraforming-control-plane)"} 5 | local url 6 | 7 | pushd ${path} > /dev/null 8 | terraform output ops_manager_ssh_private_key > /tmp/key 9 | chmod 600 /tmp/key 10 | url="$(terraform output ops_manager_dns)" 11 | popd 12 | 13 | ssh -i /tmp/key "ubuntu@${url}" 14 | } 15 | 16 | main "$@" 17 | 18 | -------------------------------------------------------------------------------- /terraforming-control-plane/db/create_databases.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euox pipefail 4 | 5 | command -v psql >/dev/null 2>&1 || { echo >&2 "I require psql but it's not installed. Aborting."; exit 1; } 6 | 7 | ssh_socket=/tmp/session1 8 | 9 | function cleanup() { 10 | # https://unix.stackexchange.com/questions/24005/how-to-close-kill-ssh-controlmaster-connections-manually 11 | # https://unix.stackexchange.com/questions/83806/how-to-kill-ssh-session-that-was-started-with-the-f-option-run-in-background 12 | ssh -S "${ssh_socket}" -O exit "indubitably" 13 | } 14 | 15 | function main() { 16 | echo 'Creating Databases' 17 | 18 | local opsman_ssh_key_path=/tmp/opsman_ssh_key 19 | echo "${OPSMAN_PRIVATE_KEY}" > "${opsman_ssh_key_path}" 20 | chmod 600 "${opsman_ssh_key_path}" 21 | 22 | local port=5432 23 | 24 | trap cleanup EXIT 25 | 26 | ssh -fNg -M -S "${ssh_socket}" -L "${port}":"${RDS_ADDRESS}":"${RDS_PORT}" -i "${opsman_ssh_key_path}" -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no "ubuntu@${OPSMAN_URL}" 27 | 28 | sleep 5 29 | 30 | PGPASSWORD="${RDS_PASSWORD}" psql --host="127.0.0.1" --port="${port}" --username="${RDS_USERNAME}" --dbname="postgres" <<'EOF' 31 | CREATE DATABASE atc; 32 | CREATE DATABASE credhub; 33 | CREATE DATABASE uaa; 34 | EOF 35 | } 36 | 37 | main "$@" 38 | -------------------------------------------------------------------------------- /terraforming-control-plane/main.tf: -------------------------------------------------------------------------------- 1 | provider "aws" { 2 | access_key = "${var.access_key}" 3 | secret_key = "${var.secret_key}" 4 | region = "${var.region}" 5 | 6 | version = "~> 1.60" 7 | } 8 | 9 | terraform { 10 | required_version = "< 0.12.0" 11 | } 12 | 13 | provider "random" { 14 | version = "~> 2.0" 15 | } 16 | 17 | provider "template" { 18 | version = "~> 1.0" 19 | } 20 | 21 | provider "tls" { 22 | version = "~> 1.2" 23 | } 24 | 25 | resource "random_integer" "bucket" { 26 | min = 1 27 | max = 100000 28 | } 29 | 30 | module "infra" { 31 | source = "../modules/infra" 32 | 33 | region = "${var.region}" 34 | env_name = "${var.env_name}" 35 | availability_zones = "${var.availability_zones}" 36 | vpc_cidr = "${var.vpc_cidr}" 37 | 38 | hosted_zone = "${var.hosted_zone}" 39 | dns_suffix = "${var.dns_suffix}" 40 | use_route53 = "${var.use_route53}" 41 | 42 | internetless = false 43 | tags = "${local.actual_tags}" 44 | } 45 | 46 | module "add_ns_to_hosted_zone" { 47 | source = "../modules/add_ns_to_hosted_zone" 48 | top_level_zone_id = "${var.top_level_zone_id}" 49 | zone_name = "${var.env_name}.${var.dns_suffix}" 50 | name_servers = "${module.infra.name_servers}" 51 | } 52 | 53 | module "ops_manager" { 54 | source = "../modules/ops_manager" 55 | 56 | subnet_id = "${local.ops_man_subnet_id}" 57 | 58 | env_name = "${var.env_name}" 59 | region = "${var.region}" 60 | ami = "${var.ops_manager_ami}" 61 | optional_ami = "${var.optional_ops_manager_ami}" 62 | instance_type = "${var.ops_manager_instance_type}" 63 | private = "${var.ops_manager_private}" 64 | vpc_id = "${module.infra.vpc_id}" 65 | vpc_cidr = "${var.vpc_cidr}" 66 | dns_suffix = "${var.dns_suffix}" 67 | zone_id = "${module.infra.zone_id}" 68 | use_route53 = "${var.use_route53}" 69 | 70 | bucket_suffix = "${local.bucket_suffix}" 71 | 72 | tags = "${local.actual_tags}" 73 | } 74 | 75 | module "control_plane" { 76 | source = "../modules/control_plane" 77 | vpc_id = "${module.infra.vpc_id}" 78 | env_name = "${var.env_name}" 79 | availability_zones = "${var.availability_zones}" 80 | vpc_cidr = "${var.vpc_cidr}" 81 | public_subnet_ids = "${module.infra.public_subnet_ids}" 82 | private_route_table_ids = "${module.infra.deployment_route_table_ids}" 83 | tags = "${local.actual_tags}" 84 | region = "${var.region}" 85 | dns_suffix = "${var.dns_suffix}" 86 | zone_id = "${module.infra.zone_id}" 87 | use_route53 = "${var.use_route53}" 88 | 89 | lb_cert_pem = "${var.tls_wildcard_certificate}" 90 | lb_issuer = "${var.tls_ca_certificate}" 91 | lb_private_key_pem = "${var.tls_private_key}" 92 | } 93 | 94 | module "rds" { 95 | source = "../modules/rds" 96 | 97 | rds_db_username = "${var.rds_db_username}" 98 | rds_instance_class = "${var.rds_instance_class}" 99 | rds_instance_count = "${var.rds_instance_count}" 100 | 101 | engine = "postgres" 102 | engine_version = "9.6.10" 103 | db_port = 5432 104 | 105 | env_name = "${var.env_name}" 106 | availability_zones = "${var.availability_zones}" 107 | vpc_cidr = "${var.vpc_cidr}" 108 | vpc_id = "${module.infra.vpc_id}" 109 | 110 | tags = "${local.actual_tags}" 111 | } 112 | 113 | resource "null_resource" "create_databases" { 114 | count = "${var.rds_instance_count == 1 ? 1 : 0}" 115 | 116 | provisioner "local-exec" { 117 | command = "./db/create_databases.sh" 118 | interpreter = ["bash", "-c"] 119 | 120 | environment { 121 | OPSMAN_URL = "${module.ops_manager.public_ip}" 122 | OPSMAN_PRIVATE_KEY = "${module.ops_manager.ssh_private_key}" 123 | 124 | RDS_DB_NAME = "${module.rds.rds_db_name}" 125 | RDS_PORT = "${module.rds.rds_port}" 126 | RDS_ADDRESS = "${module.rds.rds_address}" 127 | RDS_USERNAME = "${module.rds.rds_username}" 128 | RDS_PASSWORD = "${module.rds.rds_password}" 129 | } 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /terraforming-control-plane/outputs.tf: -------------------------------------------------------------------------------- 1 | output "iaas" { 2 | value = "aws" 3 | } 4 | 5 | output "region" { 6 | value = "${var.region}" 7 | } 8 | 9 | output "azs" { 10 | value = "${var.availability_zones}" 11 | } 12 | 13 | output "dns_zone_id" { 14 | value = "${module.infra.zone_id}" 15 | } 16 | 17 | output "env_dns_zone_name_servers" { 18 | value = "${module.infra.name_servers}" 19 | } 20 | 21 | output "vms_security_group_id" { 22 | value = "${module.infra.vms_security_group_id}" 23 | } 24 | 25 | output "public_subnet_ids" { 26 | value = "${module.infra.public_subnet_ids}" 27 | } 28 | 29 | output "public_subnets" { 30 | value = "${module.infra.public_subnet_ids}" 31 | } 32 | 33 | output "public_subnet_availability_zones" { 34 | value = "${module.infra.public_subnet_availability_zones}" 35 | } 36 | 37 | output "public_subnet_cidrs" { 38 | value = "${module.infra.public_subnet_cidrs}" 39 | } 40 | 41 | output "infrastructure_subnet_ids" { 42 | value = "${module.infra.infrastructure_subnet_ids}" 43 | } 44 | 45 | output "infrastructure_subnets" { 46 | value = "${module.infra.infrastructure_subnets}" 47 | } 48 | 49 | output "infrastructure_subnet_availability_zones" { 50 | value = "${module.infra.infrastructure_subnet_availability_zones}" 51 | } 52 | 53 | output "infrastructure_subnet_cidrs" { 54 | value = "${module.infra.infrastructure_subnet_cidrs}" 55 | } 56 | 57 | output "infrastructure_subnet_gateways" { 58 | value = "${module.infra.infrastructure_subnet_gateways}" 59 | } 60 | 61 | output "vpc_id" { 62 | value = "${module.infra.vpc_id}" 63 | } 64 | 65 | output "network_name" { 66 | value = "${module.infra.vpc_id}" 67 | } 68 | 69 | /************** 70 | * Ops Manager * 71 | ***************/ 72 | output "ops_manager_bucket" { 73 | value = "${module.ops_manager.bucket}" 74 | } 75 | 76 | output "ops_manager_public_ip" { 77 | value = "${module.ops_manager.public_ip}" 78 | } 79 | 80 | output "ops_manager_dns" { 81 | value = "${module.ops_manager.dns}" 82 | } 83 | 84 | output "optional_ops_manager_dns" { 85 | value = "${module.ops_manager.optional_dns}" 86 | } 87 | 88 | output "ops_manager_iam_instance_profile_name" { 89 | value = "${module.ops_manager.ops_manager_iam_instance_profile_name}" 90 | } 91 | 92 | output "ops_manager_iam_user_name" { 93 | value = "${module.ops_manager.ops_manager_iam_user_name}" 94 | } 95 | 96 | output "ops_manager_iam_user_access_key" { 97 | value = "${module.ops_manager.ops_manager_iam_user_access_key}" 98 | } 99 | 100 | output "ops_manager_iam_user_secret_key" { 101 | value = "${module.ops_manager.ops_manager_iam_user_secret_key}" 102 | sensitive = true 103 | } 104 | 105 | output "ops_manager_security_group_id" { 106 | value = "${module.ops_manager.security_group_id}" 107 | } 108 | 109 | output "ops_manager_private_ip" { 110 | value = "${module.ops_manager.ops_manager_private_ip}" 111 | } 112 | 113 | output "ops_manager_ssh_private_key" { 114 | sensitive = true 115 | value = "${module.ops_manager.ssh_private_key}" 116 | } 117 | 118 | output "ops_manager_ssh_public_key_name" { 119 | value = "${module.ops_manager.ssh_public_key_name}" 120 | } 121 | 122 | output "ops_manager_ssh_public_key" { 123 | value = "${module.ops_manager.ssh_public_key}" 124 | } 125 | 126 | output "ops_manager_subnet_id" { 127 | value = "${local.ops_man_subnet_id}" 128 | } 129 | 130 | /****** 131 | * RDS * 132 | *******/ 133 | output "rds_address" { 134 | value = "${module.rds.rds_address}" 135 | } 136 | 137 | output "rds_port" { 138 | value = "${module.rds.rds_port}" 139 | } 140 | 141 | output "rds_username" { 142 | value = "${module.rds.rds_username}" 143 | } 144 | 145 | output "rds_password" { 146 | sensitive = true 147 | value = "${module.rds.rds_password}" 148 | } 149 | 150 | /**************** 151 | * Control Plane * 152 | *****************/ 153 | output "control_plane_domain" { 154 | value = "${module.control_plane.domain}" 155 | } 156 | 157 | output "control_plane_root_domain" { 158 | value = "${var.env_name}.${var.dns_suffix}" 159 | } 160 | 161 | output "control_plane_subnet_ids" { 162 | value = "${module.control_plane.subnet_ids}" 163 | } 164 | 165 | output "control_plane_subnet_gateways" { 166 | value = "${module.control_plane.subnet_gateways}" 167 | } 168 | 169 | output "control_plane_subnet_cidrs" { 170 | value = "${module.control_plane.subnet_cidrs}" 171 | } 172 | 173 | output "control_plane_subnet_availability_zones" { 174 | value = "${module.control_plane.subnet_availability_zones}" 175 | } 176 | 177 | output "control_plane_credhub_target_group" { 178 | value = "${module.control_plane.credhub_lb_target_group}" 179 | } 180 | 181 | output "control_plane_credhub_security_group" { 182 | value = "${module.control_plane.credhub_security_group}" 183 | } 184 | 185 | output "control_plane_uaa_target_group" { 186 | value = "${module.control_plane.uaa_lb_target_group}" 187 | } 188 | 189 | output "control_plane_uaa_security_group" { 190 | value = "${module.control_plane.uaa_security_group}" 191 | } 192 | 193 | output "control_plane_web_target_group" { 194 | value = "${module.control_plane.atc_lb_target_group}" 195 | } 196 | 197 | output "control_plane_web_security_group" { 198 | value = "${module.control_plane.atc_security_group}" 199 | } 200 | 201 | output "control_plane_lb_ca_cert" { 202 | value = "${var.tls_ca_certificate}" 203 | } 204 | -------------------------------------------------------------------------------- /terraforming-control-plane/terraform.tfvars.example: -------------------------------------------------------------------------------- 1 | env_name = "some-environment-name" 2 | region = "us-west-1" 3 | availability_zones = ["us-west-1a", "us-west-1c"] 4 | ops_manager_ami = "ami-4f291f2f" 5 | rds_instance_count = 1 6 | dns_suffix = "example.com" 7 | vpc_cidr = "10.0.0.0/16" 8 | use_route53 = true 9 | 10 | tls_ca_certificate = <