├── .gitignore ├── LICENSE.txt ├── README.md ├── block.tf ├── bootstrap └── install_deps.sh ├── bosh-key-gen.sh ├── boshclivars.tf ├── compute.tf ├── datasources.tf ├── env-vars.example ├── identity.tf ├── keys └── README.md ├── network.tf ├── outputs.tf ├── providers.tf └── variables.tf /.gitignore: -------------------------------------------------------------------------------- 1 | *.DS_Store 2 | *.swp 3 | .terraform/ 4 | env-vars 5 | bootstrap/director-env-vars.yml 6 | bootstrap/my-env-vars.yml 7 | keys/bosh-api-fingerprint 8 | keys/bosh-api-private-key.pem 9 | keys/bosh-api-public-key.pem 10 | keys/bosh-ssh.pem 11 | keys/bosh-ssh.pub 12 | keys/bosh-ssh 13 | keys/lb-ssl.key 14 | keys/lb-ssl.crt 15 | keys/lb-ssl.csr 16 | terraform.tfstate 17 | terraform.tfstate.backup 18 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. 2 | 3 | This software is dual-licensed to you under the Universal Permissive License 4 | (UPL) and Apache License 2.0. See below for license terms. You may choose 5 | either license, or both. 6 | ____________________________ 7 | The Universal Permissive License (UPL), Version 1.0 8 | Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. 9 | 10 | Subject to the condition set forth below, permission is hereby granted to any 11 | person obtaining a copy of this software, associated documentation and/or data 12 | (collectively the "Software"), free of charge and under any and all copyright 13 | rights in the Software, and any and all patent rights owned or freely 14 | licensable by each licensor hereunder covering either (i) the unmodified 15 | Software as contributed to or provided by such licensor, or (ii) the Larger 16 | Works (as defined below), to deal in both 17 | 18 | (a) the Software, and 19 | (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if 20 | one is included with the Software (each a "Larger Work" to which the Software 21 | is contributed by such licensors), 22 | 23 | without restriction, including without limitation the rights to copy, create 24 | derivative works of, display, perform, and distribute the Software and make, 25 | use, sell, offer for sale, import, export, have made, and have sold the 26 | Software and the Larger Work(s), and to sublicense the foregoing rights on 27 | either these or other terms. 28 | 29 | This license is subject to the following condition: 30 | 31 | The above copyright notice and either this complete permission notice or at a 32 | minimum a reference to the UPL must be included in all copies or substantial 33 | portions of the Software. 34 | 35 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 36 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 37 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 38 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 39 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 40 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 41 | SOFTWARE. 42 | 43 | The Apache Software License, Version 2.0 44 | Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. 45 | 46 | Licensed under the Apache License, Version 2.0 (the "License"); You may not 47 | use this product except in compliance with the License. You may obtain a copy 48 | of the License at http://www.apache.org/licenses/LICENSE-2.0. A copy of the 49 | license is also reproduced below. Unless required by applicable law or agreed 50 | to in writing, software distributed under the License is distributed on an "AS 51 | IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 52 | implied. See the License for the specific language governing permissions and 53 | limitations under the License. 54 | 55 | Apache License 56 | 57 | Version 2.0, January 2004 58 | 59 | http://www.apache.org/licenses/ 60 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 61 | 1. Definitions. 62 | "License" shall mean the terms and conditions for use, reproduction, and 63 | distribution as defined by Sections 1 through 9 of this document. 64 | "Licensor" shall mean the copyright owner or entity authorized by the 65 | copyright owner that is granting the License. 66 | "Legal Entity" shall mean the union of the acting entity and all other 67 | entities that control, are controlled by, or are under common control with 68 | that entity. For the purposes of this definition, "control" means (i) the 69 | power, direct or indirect, to cause the direction or management of such 70 | entity, whether by contract or otherwise, or (ii) ownership of fifty percent 71 | (50%) or more of the outstanding shares, or (iii) beneficial ownership of such 72 | entity. 73 | "You" (or "Your") shall mean an individual or Legal Entity exercising 74 | permissions granted by this License. 75 | "Source" form shall mean the preferred form for making modifications, 76 | including but not limited to software source code, documentation source, and 77 | configuration files. 78 | "Object" form shall mean any form resulting from mechanical transformation or 79 | translation of a Source form, including but not limited to compiled object 80 | code, generated documentation, and conversions to other media types. 81 | "Work" shall mean the work of authorship, whether in Source or Object form, 82 | made available under the License, as indicated by a copyright notice that is 83 | included in or attached to the work (an example is provided in the Appendix 84 | below). 85 | "Derivative Works" shall mean any work, whether in Source or Object form, that 86 | is based on (or derived from) the Work and for which the editorial revisions, 87 | annotations, elaborations, or other modifications represent, as a whole, an 88 | original work of authorship. For the purposes of this License, Derivative 89 | Works shall not include works that remain separable from, or merely link (or 90 | bind by name) to the interfaces of, the Work and Derivative Works thereof. 91 | "Contribution" shall mean any work of authorship, including the original 92 | version of the Work and any modifications or additions to that Work or 93 | Derivative Works thereof, that is intentionally submitted to Licensor for 94 | inclusion in the Work by the copyright owner or by an individual or Legal 95 | Entity authorized to submit on behalf of the copyright owner. For the purposes 96 | of this definition, "submitted" means any form of electronic, verbal, or 97 | written communication sent to the Licensor or its representatives, including 98 | but not limited to communication on electronic mailing lists, source code 99 | control systems, and issue tracking systems that are managed by, or on behalf 100 | of, the Licensor for the purpose of discussing and improving the Work, but 101 | excluding communication that is conspicuously marked or otherwise designated 102 | in writing by the copyright owner as "Not a Contribution." 103 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf 104 | of whom a Contribution has been received by Licensor and subsequently 105 | incorporated within the Work. 106 | 2. Grant of Copyright License. Subject to the terms and conditions of this 107 | License, each Contributor hereby grants to You a perpetual, worldwide, 108 | non-exclusive, no-charge, royalty-free, irrevocable copyright license to 109 | reproduce, prepare Derivative Works of, publicly display, publicly perform, 110 | sublicense, and distribute the Work and such Derivative Works in Source or 111 | Object form. 112 | 3. Grant of Patent License. Subject to the terms and conditions of this 113 | License, each Contributor hereby grants to You a perpetual, worldwide, 114 | non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this 115 | section) patent license to make, have made, use, offer to sell, sell, import, 116 | and otherwise transfer the Work, where such license applies only to those 117 | patent claims licensable by such Contributor that are necessarily infringed by 118 | their Contribution(s) alone or by combination of their Contribution(s) with 119 | the Work to which such Contribution(s) was submitted. If You institute patent 120 | litigation against any entity (including a cross-claim or counterclaim in a 121 | lawsuit) alleging that the Work or a Contribution incorporated within the Work 122 | constitutes direct or contributory patent infringement, then any patent 123 | licenses granted to You under this License for that Work shall terminate as of 124 | the date such litigation is filed. 125 | 4. Redistribution. You may reproduce and distribute copies of the Work or 126 | Derivative Works thereof in any medium, with or without modifications, and in 127 | Source or Object form, provided that You meet the following conditions: 128 | You must give any other recipients of the Work or Derivative Works a copy of 129 | this License; and 130 | You must cause any modified files to carry prominent notices stating that You 131 | changed the files; and 132 | You must retain, in the Source form of any Derivative Works that You 133 | distribute, all copyright, patent, trademark, and attribution notices from the 134 | Source form of the Work, excluding those notices that do not pertain to any 135 | part of the Derivative Works; and 136 | If the Work includes a "NOTICE" text file as part of its distribution, then 137 | any Derivative Works that You distribute must include a readable copy of the 138 | attribution notices contained within such NOTICE file, excluding those notices 139 | that do not pertain to any part of the Derivative Works, in at least one of 140 | the following places: within a NOTICE text file distributed as part of the 141 | Derivative Works; within the Source form or documentation, if provided along 142 | with the Derivative Works; or, within a display generated by the Derivative 143 | Works, if and wherever such third-party notices normally appear. The contents 144 | of the NOTICE file are for informational purposes only and do not modify the 145 | License. You may add Your own attribution notices within Derivative Works that 146 | You distribute, alongside or as an addendum to the NOTICE text from the Work, 147 | provided that such additional attribution notices cannot be construed as 148 | modifying the License. 149 | 150 | You may add Your own copyright statement to Your modifications and may provide 151 | additional or different license terms and conditions for use, reproduction, or 152 | distribution of Your modifications, or for any such Derivative Works as a 153 | whole, provided Your use, reproduction, and distribution of the Work otherwise 154 | complies with the conditions stated in this License. 155 | 5. Submission of Contributions. Unless You explicitly state otherwise, any 156 | Contribution intentionally submitted for inclusion in the Work by You to the 157 | Licensor shall be under the terms and conditions of this License, without any 158 | additional terms or conditions. Notwithstanding the above, nothing herein 159 | shall supersede or modify the terms of any separate license agreement you may 160 | have executed with Licensor regarding such Contributions. 161 | 6. Trademarks. This License does not grant permission to use the trade names, 162 | trademarks, service marks, or product names of the Licensor, except as 163 | required for reasonable and customary use in describing the origin of the Work 164 | and reproducing the content of the NOTICE file. 165 | 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in 166 | writing, Licensor provides the Work (and each Contributor provides its 167 | Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 168 | KIND, either express or implied, including, without limitation, any warranties 169 | or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 170 | PARTICULAR PURPOSE. You are solely responsible for determining the 171 | appropriateness of using or redistributing the Work and assume any risks 172 | associated with Your exercise of permissions under this License. 173 | 8. Limitation of Liability. In no event and under no legal theory, whether in 174 | tort (including negligence), contract, or otherwise, unless required by 175 | applicable law (such as deliberate and grossly negligent acts) or agreed to in 176 | writing, shall any Contributor be liable to You for damages, including any 177 | direct, indirect, special, incidental, or consequential damages of any 178 | character arising as a result of this License or out of the use or inability 179 | to use the Work (including but not limited to damages for loss of goodwill, 180 | work stoppage, computer failure or malfunction, or any and all other 181 | commercial damages or losses), even if such Contributor has been advised of 182 | the possibility of such damages. 183 | 9. Accepting Warranty or Additional Liability. While redistributing the Work 184 | or Derivative Works thereof, You may choose to offer, and charge a fee for, 185 | acceptance of support, warranty, indemnity, or other liability obligations 186 | and/or rights consistent with this License. However, in accepting such 187 | obligations, You may act only on Your own behalf and on Your sole 188 | responsibility, not on behalf of any other Contributor, and only if You agree 189 | to indemnify, defend, and hold each Contributor harmless for any liability 190 | incurred by, or claims asserted against, such Contributor by reason of your 191 | accepting any such warranty or additional liability. 192 | END OF TERMS AND CONDITIONS 193 | 194 | APPENDIX: How to apply the Apache License to your work. 195 | 196 | To apply the Apache License to your work, attach the following 197 | boilerplate notice, with the fields enclosed by brackets "[]" 198 | replaced with your own identifying information. (Don't include 199 | the brackets!) The text should be enclosed in the appropriate 200 | comment syntax for the file format. We also recommend that a 201 | file or class name and description of purpose be included on the 202 | same "printed page" as the copyright notice for easier 203 | identification within third-party archives. 204 | 205 | Copyright [yyyy] [name of copyright owner] 206 | 207 | Licensed under the Apache License, Version 2.0 (the "License"); 208 | you may not use this file except in compliance with the License. 209 | You may obtain a copy of the License at 210 | 211 | http://www.apache.org/licenses/LICENSE-2.0 212 | 213 | Unless required by applicable law or agreed to in writing, software 214 | distributed under the License is distributed on an "AS IS" BASIS, 215 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 216 | See the License for the specific language governing permissions and 217 | limitations under the License. 218 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ___ ____ _ ____ _ _____ 2 | # / _ \| _ \ / \ / ___| | | ____| 3 | # | | | | |_) | / _ \| | | | | _| 4 | # | |_| | _ < / ___ | |___| |___| |___ 5 | # \___/|_| \_/_/ \_\____|_____|_____| 6 | *** 7 | 8 | ## Initializing a Cloud Foundry / BOSH deployment 9 | 10 | This project exists to simplify the configuration and deployment of Cloud Foundry and BOSH on 11 | Oracle Cloud Infrastructure. It will configure the following: 12 | * VCN and Subnets 13 | * Public, Private and Bastion Subnets in 3 Availability Domains 14 | * A Bastion server with BOSH CLI for deploying BOSH Director and Cloud Foundry. 15 | 16 | ### Configuring Terraform to work with OCI 17 | 18 | First, install Terraform v0.11.10 or later. On OSX, you can use HomeBrew: 19 | 20 | $ brew install terraform 21 | 22 | Next, use `terraform init` to download Terraform OCI provider 23 | 24 | $ terraform init 25 | 26 | 27 | ### Using this project 28 | 29 | * Update env-var with the required information. 30 | * Source env-var 31 | * `$ . env-var` 32 | 33 | ### Configuring the OCI API Key 34 | 35 | In order to use Terraform with OCI, you will need to configure an API Key. You must 36 | generate a public key in PEM format and obtain its fingerprint. Follow this guide here for more 37 | information: 38 | 39 | https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/apisigningkey.htm 40 | 41 | ### Deploying the BOSH Bastion using Terraform 42 | 43 | ###### Create an API signing key, SSH key pair, and SSL certificates for Load Balancers. 44 | 45 | First, you will want to run the included script `bosh-key-gen.sh`. This is a 46 | separate key from the OCI API Key mentioned above, which is used by Terraform to communicate with 47 | OCI. This script generates the keys that BOSH will use to communicate with OCI, as well as 48 | an SSH key pair for shell access to the bastion instance, and SSL certificates that will be 49 | installed for the Load Balancers. 50 | 51 | As part of the process to create SSL certificates, you will be prompted for a passphrase. 52 | You may enter what you like, but keep in mind it will ask you for the password again later 53 | in the process. 54 | 55 | Once all the steps above are completed your environment variables have been configured, you may run `terraform 56 | apply` to have Terraform deploy the environment. 57 | 58 | ###### Login to the BOSH Bastion using SSH 59 | 60 | The IP address of the instance will be output at the end of a successful `terraform apply`. Use this address 61 | and the SSH key pair we generated earlier to access the instance: 62 | 63 | `ssh -i keys/bosh-ssh ubuntu@` 64 | 65 | ###### Post Provisioning 66 | 67 | The bastion VM will come a script to install the BOSH v2 CLI, and will also manage the iSCSI connection for the 68 | block device. In order to preserve data in case of a failure and subsequent `terraform apply` run, no effort 69 | is taken to format the attached block device, which is at `/dev/sdb`. Upon successful deployment of the bastion 70 | VM, you may format and mount the block device manually. 71 | 72 | ```bash 73 | $ ./install_deps.sh 74 | $ sudo mkfs.ext4 /dev/sdb 75 | $ sudo mount -a 76 | ``` 77 | 78 | In the home directory, the `bosh` folder points to the mounted block device, so you may keep your releases, 79 | stemcells and deployments there for safe keeping. 80 | -------------------------------------------------------------------------------- /block.tf: -------------------------------------------------------------------------------- 1 | resource "oci_core_volume" "bosh_cli_vol" { 2 | availability_domain = "${lookup(data.oci_identity_availability_domains.ADs.availability_domains[var.bastion_ad - 1], "name")}" 3 | compartment_id = "${oci_identity_compartment.bosh_compartment.id}" 4 | display_name = "bosh_cli_vol" 5 | size_in_gbs = "${var.256GB}" 6 | } 7 | 8 | resource "oci_core_volume_attachment" "bosh_cli_vol_attach" { 9 | attachment_type = "iscsi" 10 | compartment_id = "${oci_identity_compartment.bosh_compartment.id}" 11 | instance_id = "${oci_core_instance.bosh_cli.id}" 12 | volume_id = "${oci_core_volume.bosh_cli_vol.id}" 13 | } 14 | -------------------------------------------------------------------------------- /bootstrap/install_deps.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | while fuser /var/lib/dpkg/lock >/dev/null 2>&1 ; do 5 | sleep 0.5 6 | done 7 | 8 | sudo apt-get update -y 9 | sudo apt-get install -y make ruby 10 | sudo curl -o /usr/local/bin/bosh https://s3.amazonaws.com/bosh-cli-artifacts/bosh-cli-2.0.39-linux-amd64 11 | sudo chmod +x /usr/local/bin/bosh 12 | -------------------------------------------------------------------------------- /bosh-key-gen.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | # Generate SSH keypair for shell access to bastion instance. 5 | ssh-keygen -f keys/bosh-ssh 6 | 7 | # Generate OCI API Key for bosh user. 8 | openssl genrsa -out ./keys/bosh-api-private-key.pem 2048 9 | chmod go-r ./keys/bosh-api-private-key.pem 10 | openssl rsa -pubout -in ./keys/bosh-api-private-key.pem -out ./keys/bosh-api-public-key.pem 11 | openssl rsa -pubout -outform DER -in ./keys/bosh-api-private-key.pem | openssl md5 -c > ./keys/bosh-api-fingerprint 12 | 13 | # Generate SSL Certificates for Load Balancers. 14 | openssl genrsa -des3 -out ./keys/lb-ssl.key 2048 15 | openssl rsa -in ./keys/lb-ssl.key -out ./keys/lb-ssl.key 16 | openssl req -new -key ./keys/lb-ssl.key -out ./keys/lb-ssl.csr 17 | openssl x509 -req -days 365 -in ./keys/lb-ssl.csr -signkey ./keys/lb-ssl.key -out ./keys/lb-ssl.crt 18 | -------------------------------------------------------------------------------- /boshclivars.tf: -------------------------------------------------------------------------------- 1 | resource "local_file" bosh_cli_env_vars { 2 | depends_on = [ 3 | "oci_core_instance.bosh_cli"] 4 | 5 | filename = "./bootstrap/my-env-vars.yml" 6 | content = <> ~/.bashrc", 45 | "sudo mkdir /mnt/bosh", 46 | "sudo chown -R ubuntu:ubuntu /mnt/bosh", 47 | "sudo ln -s /mnt/bosh /home/ubuntu/bosh", 48 | "echo '/dev/sdb /mnt/bosh ext4 defaults,noatime,_netdev 0 2' | sudo tee --append /etc/fstab > /dev/null", 49 | "chmod +x ~/install_deps.sh", 50 | "sudo mount -a"] 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /datasources.tf: -------------------------------------------------------------------------------- 1 | # Gets a list of Availability Domains 2 | data "oci_identity_availability_domains" "ADs" { 3 | compartment_id = "${var.oci_tenancy_ocid}" 4 | } 5 | 6 | # Gets a list of vNIC attachments on the instance 7 | data "oci_core_vnic_attachments" "InstanceVnics" { 8 | compartment_id = "${oci_identity_compartment.bosh_compartment.id}" 9 | availability_domain = "${lookup(data.oci_identity_availability_domains.ADs.availability_domains[var.bastion_ad - 1], "name")}" 10 | instance_id = "${oci_core_instance.bosh_cli.id}" 11 | } 12 | 13 | # Gets the OCID of the first (default) vNIC 14 | data "oci_core_vnic" "InstanceVnic" { 15 | vnic_id = "${lookup(data.oci_core_vnic_attachments.InstanceVnics.vnic_attachments[0], "vnic_id")}" 16 | } 17 | -------------------------------------------------------------------------------- /env-vars.example: -------------------------------------------------------------------------------- 1 | ### Authentication details 2 | export TF_VAR_oci_tenancy_ocid="" 3 | export TF_VAR_oci_user_ocid="" 4 | export TF_VAR_oci_fingerprint="" 5 | export TF_VAR_oci_private_key_path="" 6 | -------------------------------------------------------------------------------- /identity.tf: -------------------------------------------------------------------------------- 1 | resource "oci_identity_compartment" "bosh_compartment" { 2 | name = "${var.bosh_compartment_name}" 3 | description = "${var.bosh_compartment_name}" 4 | } 5 | 6 | resource "oci_identity_group" "bosh_group" { 7 | name = "${var.bosh_group_name}" 8 | description = "${var.bosh_group_name}" 9 | } 10 | 11 | resource "oci_identity_user" "bosh_user" { 12 | name = "${var.bosh_user_name}" 13 | description = "${var.bosh_user_name}" 14 | } 15 | 16 | resource "oci_identity_user_group_membership" "bosh_user_group_membership" { 17 | compartment_id = "${oci_identity_compartment.bosh_compartment.id}" 18 | user_id = "${oci_identity_user.bosh_user.id}" 19 | group_id = "${oci_identity_group.bosh_group.id}" 20 | } 21 | 22 | resource "oci_identity_api_key" "bosh_api_key" { 23 | user_id = "${oci_identity_user.bosh_user.id}" 24 | key_value = "${file(var.bosh_api_public_key)}" 25 | } 26 | 27 | resource "oci_identity_policy" "bosh_policy" { 28 | compartment_id = "${var.oci_tenancy_ocid}" 29 | name = "${oci_identity_group.bosh_group.name}-policy" 30 | description = "bosh policies" 31 | statements = [ 32 | "allow group ${oci_identity_group.bosh_group.name} to manage instance-family in tenancy", 33 | "allow group ${oci_identity_group.bosh_group.name} to manage volume-family in tenancy", 34 | "allow group ${oci_identity_group.bosh_group.name} to manage object-family in tenancy", 35 | "allow group ${oci_identity_group.bosh_group.name} to manage virtual-network-family in tenancy", 36 | "allow group ${oci_identity_group.bosh_group.name} to manage load-balancers in tenancy" 37 | ] 38 | } 39 | -------------------------------------------------------------------------------- /keys/README.md: -------------------------------------------------------------------------------- 1 | # ___ ____ _ ____ _ _____ 2 | # / _ \| _ \ / \ / ___| | | ____| 3 | # | | | | |_) | / _ \| | | | | _| 4 | # | |_| | _ < / ___ | |___| |___| |___ 5 | # \___/|_| \_/_/ \_\____|_____|_____| 6 | *** 7 | 8 | ## API and SSH Keys 9 | 10 | This folder is for storing autogenerated keys used to SSH to the BOSH Bastion as well as to 11 | generate the BMC API Keys to be used by BOSH. These keys are not managed by source control 12 | and should be protected as you would any other important key. 13 | -------------------------------------------------------------------------------- /network.tf: -------------------------------------------------------------------------------- 1 | resource "oci_core_virtual_network" "cloudfoundry_vcn" { 2 | cidr_block = "${var.vpc_cidr}" 3 | compartment_id = "${oci_identity_compartment.bosh_compartment.id}" 4 | display_name = "cloudfoundry_vcn" 5 | dns_label = "cfvcn" 6 | } 7 | 8 | resource "oci_core_internet_gateway" "cloudfoundry_ig" { 9 | compartment_id = "${oci_identity_compartment.bosh_compartment.id}" 10 | display_name = "cloudfoundry_ig" 11 | vcn_id = "${oci_core_virtual_network.cloudfoundry_vcn.id}" 12 | } 13 | 14 | resource "oci_core_route_table" "cloudfoundry_route_table" { 15 | compartment_id = "${oci_identity_compartment.bosh_compartment.id}" 16 | vcn_id = "${oci_core_virtual_network.cloudfoundry_vcn.id}" 17 | display_name = "cloudfoundry_route_table" 18 | route_rules { 19 | cidr_block = "0.0.0.0/0" 20 | network_entity_id = "${oci_core_internet_gateway.cloudfoundry_ig.id}" 21 | } 22 | } 23 | 24 | resource "oci_core_security_list" "public_subnet" { 25 | compartment_id = "${oci_identity_compartment.bosh_compartment.id}" 26 | display_name = "public_all" 27 | vcn_id = "${oci_core_virtual_network.cloudfoundry_vcn.id}" 28 | egress_security_rules = [{ 29 | destination = "0.0.0.0/0" 30 | protocol = "all" 31 | }] 32 | ingress_security_rules = [{ 33 | tcp_options { 34 | "max" = 80 35 | "min" = 80 36 | } 37 | protocol = "6" 38 | source = "0.0.0.0/0" 39 | }, 40 | { 41 | tcp_options { 42 | "max" = 443 43 | "min" = 443 44 | } 45 | protocol = "6" 46 | source = "0.0.0.0/0" 47 | }, 48 | { 49 | tcp_options { 50 | "max" = 4443 51 | "min" = 4443 52 | } 53 | protocol = "6" 54 | source = "0.0.0.0/0" 55 | }, 56 | { 57 | protocol = "6" 58 | source = "${var.vpc_cidr}" 59 | }, 60 | { 61 | tcp_options { 62 | "max" = 2222 63 | "min" = 2222 64 | } 65 | protocol = "6" 66 | source = "0.0.0.0/0" 67 | }] 68 | } 69 | 70 | resource "oci_core_security_list" "bastion_subnet" { 71 | compartment_id = "${oci_identity_compartment.bosh_compartment.id}" 72 | display_name = "bastion_all" 73 | vcn_id = "${oci_core_virtual_network.cloudfoundry_vcn.id}" 74 | egress_security_rules = [{ 75 | protocol = "all" 76 | destination = "0.0.0.0/0" 77 | }] 78 | ingress_security_rules = [{ 79 | tcp_options { 80 | "max" = 22 81 | "min" = 22 82 | } 83 | protocol = "6" 84 | source = "0.0.0.0/0" 85 | }, 86 | { 87 | protocol = "6" 88 | source = "${var.vpc_cidr}" 89 | }, 90 | { 91 | tcp_options { 92 | "max" = 6901 93 | "min" = 6901 94 | } 95 | protocol = "6" 96 | source = "${var.director_subnet_ad1_cidr}" 97 | }, 98 | { 99 | protocol = "1" 100 | source = "${var.vpc_cidr}" 101 | }] 102 | } 103 | 104 | resource "oci_core_security_list" "director_subnet" { 105 | compartment_id = "${oci_identity_compartment.bosh_compartment.id}" 106 | display_name = "director_all" 107 | vcn_id = "${oci_core_virtual_network.cloudfoundry_vcn.id}" 108 | egress_security_rules = [{ 109 | protocol = "all" 110 | destination = "0.0.0.0/0" 111 | }] 112 | ingress_security_rules = [{ 113 | protocol = "6" 114 | source = "${var.director_subnet_ad1_cidr}" 115 | }, 116 | { 117 | protocol = "1" 118 | source = "${var.vpc_cidr}" 119 | }, 120 | { 121 | tcp_options { 122 | "max" = 22 123 | "min" = 22 124 | } 125 | protocol = "6" 126 | source = "${var.bastion_subnet_ad1_cidr}" 127 | }, 128 | { 129 | tcp_options { 130 | "max" = 4222 131 | "min" = 4222 132 | } 133 | protocol = "6" 134 | source = "${var.vpc_cidr}" 135 | }, 136 | { 137 | tcp_options { 138 | "max" = 6868 139 | "min" = 6868 140 | } 141 | protocol = "6" 142 | source = "${var.vpc_cidr}" 143 | }, 144 | { 145 | tcp_options { 146 | "max" = 8443 147 | "min" = 8443 148 | } 149 | protocol = "6" 150 | source = "${var.vpc_cidr}" 151 | }, 152 | { 153 | tcp_options { 154 | "max" = 25250 155 | "min" = 25250 156 | } 157 | protocol = "6" 158 | source = "${var.vpc_cidr}" 159 | }, 160 | { 161 | tcp_options { 162 | "max" = 25555 163 | "min" = 25555 164 | } 165 | protocol = "6" 166 | source = "${var.vpc_cidr}" 167 | }, 168 | { 169 | tcp_options { 170 | "max" = 25777 171 | "min" = 25777 172 | } 173 | protocol = "6" 174 | source = "${var.vpc_cidr}" 175 | }] 176 | } 177 | 178 | resource "oci_core_security_list" "private_subnet" { 179 | compartment_id = "${oci_identity_compartment.bosh_compartment.id}" 180 | display_name = "private_all" 181 | vcn_id = "${oci_core_virtual_network.cloudfoundry_vcn.id}" 182 | egress_security_rules = [{ 183 | protocol = "all" 184 | destination = "0.0.0.0/0" 185 | }] 186 | 187 | ingress_security_rules = [{ 188 | protocol = "1" 189 | source = "${var.vpc_cidr}" 190 | }, 191 | { 192 | protocol = "all" 193 | source = "${var.private_subnet_ad1_cidr}" 194 | }, 195 | { 196 | protocol = "all" 197 | source = "${var.private_subnet_ad2_cidr}" 198 | }, 199 | { 200 | protocol = "all" 201 | source = "${var.private_subnet_ad3_cidr}" 202 | }, 203 | { 204 | tcp_options { 205 | "max" = 22 206 | "min" = 22 207 | } 208 | protocol = "6" 209 | source = "${var.bastion_subnet_ad1_cidr}" 210 | }, 211 | { 212 | tcp_options { 213 | "max" = 22 214 | "min" = 22 215 | } 216 | protocol = "6" 217 | source = "${var.director_subnet_ad1_cidr}" 218 | }, 219 | { 220 | tcp_options { 221 | "max" = 6868 222 | "min" = 6868 223 | } 224 | protocol = "6" 225 | source = "${var.director_subnet_ad1_cidr}" 226 | }, 227 | { 228 | tcp_options { 229 | "max" = 80 230 | "min" = 80 231 | } 232 | protocol = "6" 233 | source = "${var.public_subnet_ad1_cidr}" 234 | }, 235 | { 236 | tcp_options { 237 | "max" = 443 238 | "min" = 443 239 | } 240 | protocol = "6" 241 | source = "${var.public_subnet_ad1_cidr}" 242 | }, 243 | { 244 | tcp_options { 245 | "max" = 2222 246 | "min" = 2222 247 | } 248 | protocol = "6" 249 | source = "${var.public_subnet_ad1_cidr}" 250 | }, 251 | { 252 | tcp_options { 253 | "max" = 4443 254 | "min" = 4443 255 | } 256 | protocol = "6" 257 | source = "${var.public_subnet_ad1_cidr}" 258 | }, 259 | { 260 | tcp_options { 261 | "max" = 8080 262 | "min" = 8080 263 | } 264 | protocol = "6" 265 | source = "${var.public_subnet_ad1_cidr}" 266 | }, 267 | { 268 | tcp_options { 269 | "max" = 80 270 | "min" = 80 271 | } 272 | protocol = "6" 273 | source = "${var.public_subnet_ad2_cidr}" 274 | }, 275 | { 276 | tcp_options { 277 | "max" = 443 278 | "min" = 443 279 | } 280 | protocol = "6" 281 | source = "${var.public_subnet_ad2_cidr}" 282 | }, 283 | { 284 | tcp_options { 285 | "max" = 2222 286 | "min" = 2222 287 | } 288 | protocol = "6" 289 | source = "${var.public_subnet_ad2_cidr}" 290 | }, 291 | { 292 | tcp_options { 293 | "max" = 4443 294 | "min" = 4443 295 | } 296 | protocol = "6" 297 | source = "${var.public_subnet_ad2_cidr}" 298 | }, 299 | { 300 | tcp_options { 301 | "max" = 8080 302 | "min" = 8080 303 | } 304 | protocol = "6" 305 | source = "${var.public_subnet_ad2_cidr}" 306 | }] 307 | } 308 | 309 | resource "oci_core_subnet" "public_subnet_ad1" { 310 | availability_domain = "${lookup(data.oci_identity_availability_domains.ADs.availability_domains[0], "name")}" 311 | cidr_block = "${var.public_subnet_ad1_cidr}" 312 | display_name = "public_subnet_ad1" 313 | dhcp_options_id = "${oci_core_virtual_network.cloudfoundry_vcn.default_dhcp_options_id}" 314 | dns_label = "cfwebad1" 315 | compartment_id = "${oci_identity_compartment.bosh_compartment.id}" 316 | vcn_id = "${oci_core_virtual_network.cloudfoundry_vcn.id}" 317 | route_table_id = "${oci_core_route_table.cloudfoundry_route_table.id}" 318 | security_list_ids = ["${oci_core_security_list.public_subnet.id}"] 319 | prohibit_public_ip_on_vnic = false 320 | } 321 | 322 | resource "oci_core_subnet" "bastion_subnet_ad1" { 323 | availability_domain = "${lookup(data.oci_identity_availability_domains.ADs.availability_domains[0], "name")}" 324 | cidr_block = "${var.bastion_subnet_ad1_cidr}" 325 | display_name = "bastion_subnet_ad1" 326 | dhcp_options_id = "${oci_core_virtual_network.cloudfoundry_vcn.default_dhcp_options_id}" 327 | dns_label = "cfbstad1" 328 | compartment_id = "${oci_identity_compartment.bosh_compartment.id}" 329 | vcn_id = "${oci_core_virtual_network.cloudfoundry_vcn.id}" 330 | route_table_id = "${oci_core_route_table.cloudfoundry_route_table.id}" 331 | security_list_ids = ["${oci_core_security_list.bastion_subnet.id}"] 332 | prohibit_public_ip_on_vnic = false 333 | } 334 | 335 | resource "oci_core_subnet" "director_subnet_ad1" { 336 | availability_domain = "${lookup(data.oci_identity_availability_domains.ADs.availability_domains[0], "name")}" 337 | cidr_block = "${var.director_subnet_ad1_cidr}" 338 | display_name = "director_subnet_ad1" 339 | dhcp_options_id = "${oci_core_virtual_network.cloudfoundry_vcn.default_dhcp_options_id}" 340 | dns_label = "cfdirad1" 341 | compartment_id = "${oci_identity_compartment.bosh_compartment.id}" 342 | vcn_id = "${oci_core_virtual_network.cloudfoundry_vcn.id}" 343 | route_table_id = "${oci_core_route_table.cloudfoundry_route_table.id}" 344 | security_list_ids = ["${oci_core_security_list.director_subnet.id}"] 345 | prohibit_public_ip_on_vnic = false 346 | } 347 | 348 | resource "oci_core_subnet" "private_subnet_ad1" { 349 | availability_domain = "${lookup(data.oci_identity_availability_domains.ADs.availability_domains[0], "name")}" 350 | cidr_block = "${var.private_subnet_ad1_cidr}" 351 | display_name = "private_subnet_ad1" 352 | dhcp_options_id = "${oci_core_virtual_network.cloudfoundry_vcn.default_dhcp_options_id}" 353 | dns_label = "cfprvad1" 354 | compartment_id = "${oci_identity_compartment.bosh_compartment.id}" 355 | vcn_id = "${oci_core_virtual_network.cloudfoundry_vcn.id}" 356 | route_table_id = "${oci_core_route_table.cloudfoundry_route_table.id}" 357 | security_list_ids = ["${oci_core_security_list.private_subnet.id}"] 358 | prohibit_public_ip_on_vnic = false 359 | } 360 | 361 | resource "oci_core_subnet" "public_subnet_ad2" { 362 | availability_domain = "${lookup(data.oci_identity_availability_domains.ADs.availability_domains[1], "name")}" 363 | cidr_block = "${var.public_subnet_ad2_cidr}" 364 | display_name = "public_subnet_ad2" 365 | dhcp_options_id = "${oci_core_virtual_network.cloudfoundry_vcn.default_dhcp_options_id}" 366 | dns_label = "cfwebad2" 367 | compartment_id = "${oci_identity_compartment.bosh_compartment.id}" 368 | vcn_id = "${oci_core_virtual_network.cloudfoundry_vcn.id}" 369 | route_table_id = "${oci_core_route_table.cloudfoundry_route_table.id}" 370 | security_list_ids = ["${oci_core_security_list.public_subnet.id}"] 371 | prohibit_public_ip_on_vnic = false 372 | } 373 | 374 | resource "oci_core_subnet" "private_subnet_ad2" { 375 | availability_domain = "${lookup(data.oci_identity_availability_domains.ADs.availability_domains[1], "name")}" 376 | cidr_block = "${var.private_subnet_ad2_cidr}" 377 | display_name = "private_subnet_ad2" 378 | dhcp_options_id = "${oci_core_virtual_network.cloudfoundry_vcn.default_dhcp_options_id}" 379 | dns_label = "cfprvad2" 380 | compartment_id = "${oci_identity_compartment.bosh_compartment.id}" 381 | vcn_id = "${oci_core_virtual_network.cloudfoundry_vcn.id}" 382 | route_table_id = "${oci_core_route_table.cloudfoundry_route_table.id}" 383 | security_list_ids = ["${oci_core_security_list.private_subnet.id}"] 384 | prohibit_public_ip_on_vnic = false 385 | } 386 | 387 | resource "oci_core_subnet" "private_subnet_ad3" { 388 | availability_domain = "${lookup(data.oci_identity_availability_domains.ADs.availability_domains[2], "name")}" 389 | cidr_block = "${var.private_subnet_ad3_cidr}" 390 | display_name = "private_subnet_ad3" 391 | dhcp_options_id = "${oci_core_virtual_network.cloudfoundry_vcn.default_dhcp_options_id}" 392 | dns_label = "cfprvad3" 393 | compartment_id = "${oci_identity_compartment.bosh_compartment.id}" 394 | vcn_id = "${oci_core_virtual_network.cloudfoundry_vcn.id}" 395 | route_table_id = "${oci_core_route_table.cloudfoundry_route_table.id}" 396 | security_list_ids = ["${oci_core_security_list.private_subnet.id}"] 397 | prohibit_public_ip_on_vnic = false 398 | } 399 | -------------------------------------------------------------------------------- /outputs.tf: -------------------------------------------------------------------------------- 1 | output "CompartmentOCID" { 2 | value = ["${oci_identity_compartment.bosh_compartment.id}"] 3 | } 4 | 5 | output "InstancePrivateIP" { 6 | value = ["${data.oci_core_vnic.InstanceVnic.private_ip_address}"] 7 | } 8 | 9 | output "InstancePublicIP" { 10 | value = ["${data.oci_core_vnic.InstanceVnic.public_ip_address}"] 11 | } 12 | -------------------------------------------------------------------------------- /providers.tf: -------------------------------------------------------------------------------- 1 | provider "oci" { 2 | version = ">= 3.0.0" 3 | region = "${var.oci_region}" 4 | tenancy_ocid = "${var.oci_tenancy_ocid}" 5 | user_ocid = "${var.oci_user_ocid}" 6 | fingerprint = "${var.oci_fingerprint}" 7 | private_key_path = "${var.oci_private_key_path}" 8 | } 9 | -------------------------------------------------------------------------------- /variables.tf: -------------------------------------------------------------------------------- 1 | # Authentication 2 | variable "oci_tenancy_ocid" {} 3 | variable "oci_user_ocid" {} 4 | variable "oci_fingerprint" {} 5 | variable "oci_private_key_path" {} 6 | variable "oci_region" { 7 | default = "us-phoenix-1" 8 | } 9 | 10 | # Identity 11 | variable "bosh_compartment_name" { 12 | default = "bosh" 13 | } 14 | variable "bosh_user_name" { 15 | default = "bosh" 16 | } 17 | variable "bosh_group_name" { 18 | default = "bosh" 19 | } 20 | 21 | variable "bosh_api_public_key" { 22 | default = "./keys/bosh-api-public-key.pem" 23 | } 24 | 25 | variable "bosh_api_private_key" { 26 | default = "./keys/bosh-api-private-key.pem" 27 | } 28 | 29 | variable "bosh_api_fingerprint" { 30 | default = "./keys/bosh-api-fingerprint" 31 | } 32 | 33 | variable "bosh_ssh_public_key" { 34 | default = "./keys/bosh-ssh.pub" 35 | } 36 | variable "bosh_ssh_private_key" { 37 | default = "./keys/bosh-ssh" 38 | } 39 | variable "bosh_ssh_username" { 40 | default = "vcap" 41 | } 42 | 43 | # Networking 44 | 45 | variable "vpc_cidr" { 46 | default = "10.0.0.0/16" 47 | } 48 | 49 | variable "public_subnet_ad1_cidr" { 50 | default = "10.0.1.0/24" 51 | } 52 | 53 | variable "bastion_subnet_ad1_cidr" { 54 | default = "10.0.2.0/24" 55 | } 56 | variable "director_subnet_ad1_cidr" { 57 | default = "10.0.3.0/24" 58 | } 59 | 60 | variable "private_subnet_ad1_cidr" { 61 | default = "10.0.4.0/24" 62 | } 63 | 64 | variable "public_subnet_ad2_cidr" { 65 | default = "10.0.5.0/24" 66 | } 67 | 68 | variable "private_subnet_ad2_cidr" { 69 | default = "10.0.6.0/24" 70 | } 71 | 72 | variable "private_subnet_ad3_cidr" { 73 | default = "10.0.7.0/24" 74 | } 75 | 76 | # Bastion VM 77 | 78 | # Choose an Availability Domain for the Bastion instance. 79 | variable "bastion_ad" { 80 | default = "1" 81 | } 82 | 83 | variable "bastion_image_id" { 84 | default = "ocid1.image.oc1.phx.aaaaaaaaxsufrpzn72dvhry5swbuwnuldcn3eko3cx6g7z4tw4qfwkq2zkra" 85 | } 86 | 87 | variable "bastion_boot_timeout_minutes" { 88 | default = 5 89 | } 90 | 91 | variable "bastion_instance_shape" { 92 | default = "VM.Standard1.1" 93 | } 94 | 95 | variable "bastion_instance_os" { 96 | default = "Ubuntu" 97 | } 98 | 99 | variable "bastion_instance_os_version" { 100 | default = "16.04" 101 | } 102 | 103 | variable "256GB" { 104 | default = "256" 105 | } 106 | 107 | variable "bastion_bootstrap_file" { 108 | default = "./userdata/bootstrap" 109 | } 110 | --------------------------------------------------------------------------------