This Terraform Module launches a single VPC meant to house applications. By contrast, DevOps-related services such as
Jenkins or InfluxDB should be in a "mgmt" VPC. (See the vpc-mgmt module.)
A VPC or Virtual Private Cloud is a logically isolated section of your AWS cloud. Each
VPC defines a virtual network within which you run your AWS resources, as well as rules for what can go in and out of
that network. This includes subnets, route tables that tell those subnets how to route inbound and outbound traffic,
security groups, access controls lists for the network (NACLs), and any other network components such as VPN connections.
Three Subnet Tiers
This VPC defines three "tiers" of subnets:
Public Subnets: Resources in these subnets are directly addressable from the Internet. Only public-facing
resources (typically just load balancers) should be put here.
Private/App Subnets: Resources in these subnets are NOT directly addressable from the Internet but they can make
outbound connections to the Internet through a NAT Gateway. You can connect to the resources in this subnet only from
resources within the VPC, so you should put your app servers here and allow the load balancers in the Public Subnet
to route traffic to them.
Private/Persistence Subnets: Resources in these subnets are neither directly addressable from the Internet nor
able to make outbound Internet connections. You can connect to the resources in this subnet only from within the VPC,
so you should put your databases, cache servers, and other stateful resources here and allow your apps to talk to
them.
VPC Architecture
The three-tier VPC is inspired by the VPC Architecture described by Ben Whaley in his blog post A Reference
VPC Architecture. That blog post proposed the
following VPC structure:
To summarize:
Each environment (prod, stage, etc.) is represented by a separate VPC.
Each VPC has three "tiers" of subnets to allow AWS resources to be publicly addressable, addressable only from the
public tier, or only from the private/app tier.
In a given subnet tier, there are usually three or four actual subnets, one for each Availability Zone.
Therefore, if we created a single VPC in the us-west-2 region, which has Availability Zones us-west-2a,us-west-2b,
and us-west-2c, each subnet tier would have three subnets (one per Availability Zone) for a total of 9 subnets in all.
The only way to reach this VPC is from the public Internet via a publicly exposed sevice, or via the mgmt VPC,
which uses VPC Peering to make this VPC accessible from the mgmt VPC.
Philosophically, everything in a VPC should be isolated from all resources in any other VPC. In particular, we want
to ensure that our stage environment is completely independent from prod. This architecture helps to reinforce that.
Throughout our diagrams and examples we recommend a /16 CIDR range for VPCs. The reason for this is that a /16 makes
CIDR math quite straightforward. If using the 10.0.0.0/8 RFC1918 address space,
this allows for 256 VPCs (10.0.0.0/16-10.255.255.255/16) with 65,534 IP addresses per VPC. This should be sufficient for
nearly all use-cases, and is consistent with many examples and existing documentation found elsewhere.
Gotchas
If the num_availability_zones variable in the mgmt VPC and the num_availability_zones variable in the app VPC don't match, there are problems with the routes that are created between the two VPCs as part of setting up VPC Peering. If your use case requires different numbers of Availability Zones for each of these VPCs, please let us know and we'll investigate further!
{"treedata":{"name":"root","toggled":true,"children":[{"name":".circleci","children":[{"name":"config.yml","path":".circleci/config.yml","sha":"1fcd50caa3c5aaa29bf7ce0ead6191e70c9687ad"}]},{"name":".gitignore","path":".gitignore","sha":"b4d646276b2bd09ca0637874dedb1e03dc831406"},{"name":".pre-commit-config.yaml","path":".pre-commit-config.yaml","sha":"49ee828ed16f55335ac4dcc74331f190366b1858"},{"name":"CODEOWNERS","path":"CODEOWNERS","sha":"c19c648a9fdcb79b477d2b38566355ad09c9aef5"},{"name":"LICENSE.txt","path":"LICENSE.txt","sha":"f4e3d9bd4717a044ed31ad847a300eee74371a78"},{"name":"README.md","path":"README.md","sha":"6c045e80c802bd4e7140daaee8ba6e063047ea6f"},{"name":"examples","children":[{"name":"vpc-app-custom-az-ids","children":[{"name":"main.tf","path":"examples/vpc-app-custom-az-ids/main.tf","sha":"2bec058941b6821ef31bee74eba851adaf16227a"},{"name":"output.tf","path":"examples/vpc-app-custom-az-ids/output.tf","sha":"2d75b1b5b85d9aac1c4004dde2579ad5443833ef"},{"name":"variables.tf","path":"examples/vpc-app-custom-az-ids/variables.tf","sha":"871d1b624b399695b8cdee793b25e2406b17e617"}]},{"name":"vpc-app-no-nat-gateway","children":[{"name":"README.md","path":"examples/vpc-app-no-nat-gateway/README.md","sha":"ea0486fef279cbb8aced2c65a39a350a65be725f"},{"name":"main.tf","path":"examples/vpc-app-no-nat-gateway/main.tf","sha":"489690ce241039320a21be3259b8626e2c57369e"},{"name":"outputs.tf","path":"examples/vpc-app-no-nat-gateway/outputs.tf","sha":"e5fe2a9caaa3168dd704ef17ca49fbba76b3ede7"},{"name":"variables.tf","path":"examples/vpc-app-no-nat-gateway/variables.tf","sha":"20dea2995e4f8e7b697b2d7395a7b61ab02261ac"}]},{"name":"vpc-app-subnets-disabled","children":[{"name":"README.md","path":"examples/vpc-app-subnets-disabled/README.md","sha":"67df57551702a809167ca70b61c95b62e08991f0"},{"name":"main.tf","path":"examples/vpc-app-subnets-disabled/main.tf","sha":"00856478ad9d2b0ef762464a25eb7626c1f1c617"},{"name":"outputs.tf","path":"examples/vpc-app-subnets-disabled/outputs.tf","sha":"6630dcfe2cf399866778a70b9f5530d99d5fc886"},{"name":"variables.tf","path":"examples/vpc-app-subnets-disabled/variables.tf","sha":"d29c3a45b54bb5e7e549d9a46d228ce7e427ad6d"}]},{"name":"vpc-app-with-endpoint","children":[{"name":"README.md","path":"examples/vpc-app-with-endpoint/README.md","sha":"d156678fe7d97d89370b1f95cf0558bf3d2a6430"},{"name":"main.tf","path":"examples/vpc-app-with-endpoint/main.tf","sha":"4ee79b8b4bd39082516e0c62d90e67f5ad7e723c"},{"name":"outputs.tf","path":"examples/vpc-app-with-endpoint/outputs.tf","sha":"36e21a8b972bd561cbc3bdaea7b21b8982d6a662"},{"name":"variables.tf","path":"examples/vpc-app-with-endpoint/variables.tf","sha":"be23cd1bfd3a29beb63724612f6bb9a7e5bd3d25"}]},{"name":"vpc-app-with-inbound-network","children":[{"name":"README.md","path":"examples/vpc-app-with-inbound-network/README.md","sha":"25dde99ed73bd19243e09131bc94cfd05fa0214d"},{"name":"main.tf","path":"examples/vpc-app-with-inbound-network/main.tf","sha":"9c638e243a4f1b8a0b9171aa59dd39a294f85eef"},{"name":"outputs.tf","path":"examples/vpc-app-with-inbound-network/outputs.tf","sha":"729e7cb3afd8cfee49d4dde4ca3ba20f88ad930f"},{"name":"variables.tf","path":"examples/vpc-app-with-inbound-network/variables.tf","sha":"20dea2995e4f8e7b697b2d7395a7b61ab02261ac"}]},{"name":"vpc-app","children":[{"name":"README.md","path":"examples/vpc-app/README.md","sha":"ea0486fef279cbb8aced2c65a39a350a65be725f"},{"name":"main.tf","path":"examples/vpc-app/main.tf","sha":"6544286b9f0af3013028fb138ed86ff964667784"},{"name":"outputs.tf","path":"examples/vpc-app/outputs.tf","sha":"e5fe2a9caaa3168dd704ef17ca49fbba76b3ede7"},{"name":"variables.tf","path":"examples/vpc-app/variables.tf","sha":"20dea2995e4f8e7b697b2d7395a7b61ab02261ac"}]},{"name":"vpc-custom-cidr-blocks","children":[{"name":"README.md","path":"examples/vpc-custom-cidr-blocks/README.md","sha":"aef7de470f10d0d215966842b737bd41a33c98a5"},{"name":"main.tf","path":"examples/vpc-custom-cidr-blocks/main.tf","sha":"c132eb2ca9bc50ed6c2e45b33a12c135e7ff739d"},{"name":"outputs.tf","path":"examples/vpc-custom-cidr-blocks/outputs.tf","sha":"e5fe2a9caaa3168dd704ef17ca49fbba76b3ede7"},{"name":"variables.tf","path":"examples/vpc-custom-cidr-blocks/variables.tf","sha":"56d3e0ca50ded5ea2535c71f3568f3728106a42b"}]},{"name":"vpc-flow-logs","children":[{"name":"README.md","path":"examples/vpc-flow-logs/README.md","sha":"75f78906088bbfb2be1e016e11958776b9a5f474"},{"name":"main.tf","path":"examples/vpc-flow-logs/main.tf","sha":"caaed76c00fdd1a8833303945cabd6e55eb889fd"},{"name":"outputs.tf","path":"examples/vpc-flow-logs/outputs.tf","sha":"1832dd649235eb4f917497c2772299c761d39dad"},{"name":"variables.tf","path":"examples/vpc-flow-logs/variables.tf","sha":"3ac7ead850b612a5973fd4c58192dc6b856330df"}]},{"name":"vpc-mgmt-no-nat-gateway","children":[{"name":"README.md","path":"examples/vpc-mgmt-no-nat-gateway/README.md","sha":"31e1e6c333d42951a9929d3c1d2c4bf391a47794"},{"name":"main.tf","path":"examples/vpc-mgmt-no-nat-gateway/main.tf","sha":"5b3e307374e1886099f253a7b4d18b79b730d18b"},{"name":"outputs.tf","path":"examples/vpc-mgmt-no-nat-gateway/outputs.tf","sha":"c11cde7873d030ed8e8e44a726ee2ea19d65fcd6"},{"name":"variables.tf","path":"examples/vpc-mgmt-no-nat-gateway/variables.tf","sha":"bf7cddc01e2b42855c9c435e5c2751e010e6a435"}]},{"name":"vpc-mgmt","children":[{"name":"README.md","path":"examples/vpc-mgmt/README.md","sha":"31e1e6c333d42951a9929d3c1d2c4bf391a47794"},{"name":"main.tf","path":"examples/vpc-mgmt/main.tf","sha":"0e3c60831c1ecdda0c18c24a71a9a335d25b763b"},{"name":"outputs.tf","path":"examples/vpc-mgmt/outputs.tf","sha":"c11cde7873d030ed8e8e44a726ee2ea19d65fcd6"},{"name":"variables.tf","path":"examples/vpc-mgmt/variables.tf","sha":"59225eb0320c7af08fa4cade7bbeaf10bdeac295"}]},{"name":"vpc-network-acls","children":[{"name":"README.md","path":"examples/vpc-network-acls/README.md","sha":"dba18c12b6ba20ddecbc23aa2d89c7ade17c5680"},{"name":"main.tf","path":"examples/vpc-network-acls/main.tf","sha":"d60d4bf6538ce675f4539bba9da1f47646b77c1c"},{"name":"outputs.tf","path":"examples/vpc-network-acls/outputs.tf","sha":"5f59a828f7128b7bd7e52599fa794abd0f760293"},{"name":"variables.tf","path":"examples/vpc-network-acls/variables.tf","sha":"a19ecd5a9d56e8127d6dbd39ea9594b0ef49a696"}]},{"name":"vpc-peering-cross-accounts","children":[{"name":"README.md","path":"examples/vpc-peering-cross-accounts/README.md","sha":"7baa79096261d7b159a702c81fad0da76e0ed6a2"},{"name":"accepter.tf","path":"examples/vpc-peering-cross-accounts/accepter.tf","sha":"e53c83a1d3a4af5c0348176531eee8161ca23248"},{"name":"dependencies.tf","path":"examples/vpc-peering-cross-accounts/dependencies.tf","sha":"e5a5292d4e9ac44f072f4c88b8e5bc16861a67e5"},{"name":"outputs.tf","path":"examples/vpc-peering-cross-accounts/outputs.tf","sha":"5257d0521e3fa33b514cb90f55a811416141c9a2"},{"name":"providers.tf","path":"examples/vpc-peering-cross-accounts/providers.tf","sha":"e1e3cb4875ae9d9484ef965ad5ced9fa05bce6be"},{"name":"requester.tf","path":"examples/vpc-peering-cross-accounts/requester.tf","sha":"04db526f10d09196303216287992c78a9b7c4ebc"},{"name":"variables.tf","path":"examples/vpc-peering-cross-accounts/variables.tf","sha":"a3af170a52ebe3617c5cbdbc751924c2ef77560a"},{"name":"versions.tf","path":"examples/vpc-peering-cross-accounts/versions.tf","sha":"82a145a3e270c8eb9b858b54dca3a7ded32c8a6d"}]},{"name":"vpc-peering-external","children":[{"name":"README.md","path":"examples/vpc-peering-external/README.md","sha":"2ab2674e3ec16b14c9b79ef96ca808078549ff5d"},{"name":"main.tf","path":"examples/vpc-peering-external/main.tf","sha":"16f95803e9c9952512a0b03ecbea6f04884ea9ae"},{"name":"outputs.tf","path":"examples/vpc-peering-external/outputs.tf","sha":"5239df47a80d13f33ea58412eb73a83f4ff431ed"},{"name":"variables.tf","path":"examples/vpc-peering-external/variables.tf","sha":"891f648219c644354f932af309fa3dffb0de3bd5"}]},{"name":"vpc-peering","children":[{"name":"README.md","path":"examples/vpc-peering/README.md","sha":"72acac0226368d798bc1f29623e61749d84af87a"},{"name":"main.tf","path":"examples/vpc-peering/main.tf","sha":"e37fb34f12dc924fae4a21a0a67682fb34d0b65c"},{"name":"outputs.tf","path":"examples/vpc-peering/outputs.tf","sha":"85acf3fc320ca7969f57133d94515e80150f7c79"},{"name":"variables.tf","path":"examples/vpc-peering/variables.tf","sha":"6a8eb9ed4db5427a9eddb3205cfca9fc7386c085"}]}]},{"name":"modules","children":[{"name":"_docs","children":[{"name":"vpc-core-concepts.md","path":"modules/_docs/vpc-core-concepts.md","sha":"6c5780d57f69364b702bbaa5337aa3a1d693370d"},{"name":"vpc_app_architecture.png","path":"modules/_docs/vpc_app_architecture.png","sha":"1cb6d726e1a35614b27be9f3d45b9752589b9683"}]},{"name":"network-acl-inbound","children":[{"name":"README.md","path":"modules/network-acl-inbound/README.md","sha":"3784f45a817ccb73f2e8254c22c674eb77f29a8d"},{"name":"main.tf","path":"modules/network-acl-inbound/main.tf","sha":"530add09357b14eb47860122f121673974febdd4"},{"name":"variables.tf","path":"modules/network-acl-inbound/variables.tf","sha":"5bb3140cec48ca71ebc09ac664fca09c115ad77b"}]},{"name":"network-acl-outbound","children":[{"name":"README.md","path":"modules/network-acl-outbound/README.md","sha":"b0a204c8f1e30c99da43158c231436b018e53db6"},{"name":"main.tf","path":"modules/network-acl-outbound/main.tf","sha":"b8dd29fdcae2a7446a873bb6f8ba5d9ca1300c06"},{"name":"variables.tf","path":"modules/network-acl-outbound/variables.tf","sha":"a36ad2e23d0bab06dc5f2333203c2e9092f5e741"}]},{"name":"vpc-app-network-acls","children":[{"name":"README.md","path":"modules/vpc-app-network-acls/README.md","sha":"a62b6da2a3356593be8ee02968f223ddbb6971a0"},{"name":"main.tf","path":"modules/vpc-app-network-acls/main.tf","sha":"eba5bf48f18d2db32c3d0d520f1c10b20fa2da87"},{"name":"outputs.tf","path":"modules/vpc-app-network-acls/outputs.tf","sha":"1e48debceed70b0444a7f7c8fc4c6f90d7cd49d3"},{"name":"variables.tf","path":"modules/vpc-app-network-acls/variables.tf","sha":"0b7fbc4e788afeb21a70041485d8d7fef7f2476b"}]},{"name":"vpc-app","children":[{"name":"README.md","path":"modules/vpc-app/README.md","sha":"f9ddd8e96b790701e2fdfd9d80e57dae010dadfe","toggled":true},{"name":"main.tf","path":"modules/vpc-app/main.tf","sha":"76534e6b4138e49a5956ec32ab8a83f0f105ca5c"},{"name":"outputs.tf","path":"modules/vpc-app/outputs.tf","sha":"63f0af5207271c7ab7aace8ea035f85e33c2dab2"},{"name":"variables.tf","path":"modules/vpc-app/variables.tf","sha":"39eb080e7a5ee43bc667d1df4bb8904b1ddc8046"}],"toggled":true},{"name":"vpc-dns-forwarder-rules","children":[{"name":"README.md","path":"modules/vpc-dns-forwarder-rules/README.md","sha":"e61361e740adf9b6c95de03ee3ee4044162f57b8"},{"name":"main.tf","path":"modules/vpc-dns-forwarder-rules/main.tf","sha":"286622602a562e64a7dcc0ba3d21fa2e607f5b51"},{"name":"variables.tf","path":"modules/vpc-dns-forwarder-rules/variables.tf","sha":"b5baaad0819ce7c23d47d1292fe0798dee12cdf5"}]},{"name":"vpc-dns-forwarder","children":[{"name":"README.md","path":"modules/vpc-dns-forwarder/README.md","sha":"0d0b4fffb15431758fd436c7cdc474bace686b7e"},{"name":"main.tf","path":"modules/vpc-dns-forwarder/main.tf","sha":"61cca39fc12c762fd145aaa90d4d40182bf466cf"},{"name":"outputs.tf","path":"modules/vpc-dns-forwarder/outputs.tf","sha":"382b7f3ae80e99cfd8325c9b4de404110e4d85ef"},{"name":"variables.tf","path":"modules/vpc-dns-forwarder/variables.tf","sha":"3c27308d90da5517d686c5bfb901801ba65637c0"}]},{"name":"vpc-flow-logs","children":[{"name":"README.md","path":"modules/vpc-flow-logs/README.md","sha":"09fa1ba0a3b308bb305f2652e11b6160edf9bce0"},{"name":"main.tf","path":"modules/vpc-flow-logs/main.tf","sha":"a418ec4afcf22e121482296270ca3e0822fddba9"},{"name":"outputs.tf","path":"modules/vpc-flow-logs/outputs.tf","sha":"029e23b76b63c324e836a69891a7cb452da99a06"},{"name":"variables.tf","path":"modules/vpc-flow-logs/variables.tf","sha":"7a29a3e5792d69d9edc3a33edd6f3bf254b7a01b"}]},{"name":"vpc-interface-endpoint","children":[{"name":"README.md","path":"modules/vpc-interface-endpoint/README.md","sha":"5c65f1eec3964b3cc00637270f252406f9247a8a"},{"name":"main.tf","path":"modules/vpc-interface-endpoint/main.tf","sha":"f80ec6d6f471350a9691a1d23e7ade1827e6ed9e"},{"name":"outputs.tf","path":"modules/vpc-interface-endpoint/outputs.tf","sha":"cabaade4036421a8e46d53626e3fa19080d69c8f"},{"name":"variables.tf","path":"modules/vpc-interface-endpoint/variables.tf","sha":"4bfa9450ec8eae88f12ffa47ef7178eb8d7d8b78"}]},{"name":"vpc-mgmt-network-acls","children":[{"name":"README.md","path":"modules/vpc-mgmt-network-acls/README.md","sha":"5afe5e9c3b7b4f371b36780e0d3be6ad73a74452"},{"name":"main.tf","path":"modules/vpc-mgmt-network-acls/main.tf","sha":"7751d2d62c1d55b7aab3e3737906f2c18268bb34"},{"name":"outputs.tf","path":"modules/vpc-mgmt-network-acls/outputs.tf","sha":"a5e4effa3263fe4789957fb3058477f0419f65ab"},{"name":"variables.tf","path":"modules/vpc-mgmt-network-acls/variables.tf","sha":"6181036ea5629d4effc3ac95c149709ad8a15b0e"}]},{"name":"vpc-mgmt","children":[{"name":"README.md","path":"modules/vpc-mgmt/README.md","sha":"18cff22e07bd6f1ea1a4446c9ad1d0698ec9f7ab"},{"name":"main.tf","path":"modules/vpc-mgmt/main.tf","sha":"e4136aacf2830bbdbdda54119a3aaff955aaeb9a"},{"name":"outputs.tf","path":"modules/vpc-mgmt/outputs.tf","sha":"defdf79928efddcc6f7de1fa9a2492decc654a49"},{"name":"variables.tf","path":"modules/vpc-mgmt/variables.tf","sha":"682342efa6eed7bf896181063983ca4b6d6e1ebc"}]},{"name":"vpc-peering-cross-accounts-accepter","children":[{"name":"README.md","path":"modules/vpc-peering-cross-accounts-accepter/README.md","sha":"d404e5ac5e400defe8aba3d7f79d0f66870b4d3f"},{"name":"main.tf","path":"modules/vpc-peering-cross-accounts-accepter/main.tf","sha":"501f1631fbe22fa19591194cbbe39f660df3e050"},{"name":"outputs.tf","path":"modules/vpc-peering-cross-accounts-accepter/outputs.tf","sha":"905c5efb879537848fd4df0d0f47465a4cf6c87c"},{"name":"variables.tf","path":"modules/vpc-peering-cross-accounts-accepter/variables.tf","sha":"3f174a39f50ae6485daf74dbf29233a9c9047483"},{"name":"versions.tf","path":"modules/vpc-peering-cross-accounts-accepter/versions.tf","sha":"82a145a3e270c8eb9b858b54dca3a7ded32c8a6d"}]},{"name":"vpc-peering-cross-accounts-requester","children":[{"name":"README.md","path":"modules/vpc-peering-cross-accounts-requester/README.md","sha":"bca1ccf011064f52f80c6cafca8a1eb8aed17c29"},{"name":"main.tf","path":"modules/vpc-peering-cross-accounts-requester/main.tf","sha":"ea30c0e53c2213cc41004d0ba2bffe79b4ba8602"},{"name":"outputs.tf","path":"modules/vpc-peering-cross-accounts-requester/outputs.tf","sha":"dc15d00e21644f86600bedb6359954e3bbc20f54"},{"name":"variables.tf","path":"modules/vpc-peering-cross-accounts-requester/variables.tf","sha":"686cba3dbcfc62d15d4fd6bc43ffc435db5844ea"},{"name":"versions.tf","path":"modules/vpc-peering-cross-accounts-requester/versions.tf","sha":"82a145a3e270c8eb9b858b54dca3a7ded32c8a6d"}]},{"name":"vpc-peering-external","children":[{"name":"README.md","path":"modules/vpc-peering-external/README.md","sha":"3a7b91706130c0901ee5f523633318a21fbe9483"},{"name":"main.tf","path":"modules/vpc-peering-external/main.tf","sha":"23fc1e64829a4f343cef7208e4136bd410e5de1e"},{"name":"variables.tf","path":"modules/vpc-peering-external/variables.tf","sha":"b7a9760c9a22524b8452e83d68495b31e3af18dc"}]},{"name":"vpc-peering","children":[{"name":"README.md","path":"modules/vpc-peering/README.md","sha":"5f10e61c54fd9e175d18f4fdf5f8ae0ae8217d47"},{"name":"main.tf","path":"modules/vpc-peering/main.tf","sha":"a5226bafc5b3fbc7e2f3e5299e4d5223514b5c3e"},{"name":"variables.tf","path":"modules/vpc-peering/variables.tf","sha":"60502cffac1867fa48a5f68ef6ef0aa566cef21e"}]}],"toggled":true},{"name":"terraform-cloud-enterprise-private-module-registry-placeholder.tf","path":"terraform-cloud-enterprise-private-module-registry-placeholder.tf","sha":"ae586c0fe830819580e1009d41a9074f16e65bed"},{"name":"test","children":[{"name":"README.md","path":"test/README.md","sha":"ef26d3851db2fff0b36dfa61379724c0db9ff281"},{"name":"go.mod","path":"test/go.mod","sha":"2c978d8011d79787a79d0817b1452848d0b25331"},{"name":"go.sum","path":"test/go.sum","sha":"26a9de4c5e22e7f032c7f64869adb0853aa920e9"},{"name":"test_helpers.go","path":"test/test_helpers.go","sha":"d3490024195bf4ad7536e865e150b310e53f241e"},{"name":"validation","children":[{"name":"validate_all_modules_and_examples_test.go","path":"test/validation/validate_all_modules_and_examples_test.go","sha":"74c928d0cbc2914e5cd708277bd857cb2375b660"}]},{"name":"vpc_app_custom_az_id_test.go","path":"test/vpc_app_custom_az_id_test.go","sha":"fb0c00c72a9828a4c68c64c274b33b64063758ef"},{"name":"vpc_app_no_nat_gateway_test.go","path":"test/vpc_app_no_nat_gateway_test.go","sha":"c23d6186a6ebb7de534c9dcc73f74a8e278cf4c2"},{"name":"vpc_app_subnets_disabled_test.go","path":"test/vpc_app_subnets_disabled_test.go","sha":"09d13233dec81215f8e92645ec9ffadc43aa0f6a"},{"name":"vpc_app_test.go","path":"test/vpc_app_test.go","sha":"3ad6acdd5a51dcb7a6c531db9f367d759dea19a2"},{"name":"vpc_app_with_endpoint_test.go","path":"test/vpc_app_with_endpoint_test.go","sha":"7d0308586c09b36ff78fce285c765cb340a78e02"},{"name":"vpc_app_with_inbound_network_test.go","path":"test/vpc_app_with_inbound_network_test.go","sha":"13b78ced82ed45618e5b74399f19e3a79a2d9322"},{"name":"vpc_custom_cidr_blocks_test.go","path":"test/vpc_custom_cidr_blocks_test.go","sha":"056710e3d1fc6d6affc28f23caef27cac9042519"},{"name":"vpc_flow_logs_test.go","path":"test/vpc_flow_logs_test.go","sha":"c7462ba92c39088663fafb522ddbf4117355c490"},{"name":"vpc_mgmt_no_nat_gateway_test.go","path":"test/vpc_mgmt_no_nat_gateway_test.go","sha":"98a5b6189e3651267f7038f906deaa0304fcc699"},{"name":"vpc_mgmt_test.go","path":"test/vpc_mgmt_test.go","sha":"4df8061bd0de902e3ef3d1ff56e4e32758fb8ad8"},{"name":"vpc_network_acls_test.go","path":"test/vpc_network_acls_test.go","sha":"5ed930679340c81ea7549b0a26e94566e18ce660"},{"name":"vpc_peering_cross_accounts_test.go","path":"test/vpc_peering_cross_accounts_test.go","sha":"8b1b13de36acd9dc77fa28c2a2daeacb383ee7c5"},{"name":"vpc_peering_external_test.go","path":"test/vpc_peering_external_test.go","sha":"2ce81263d16d2b5f7387993404bea2849ca60698"},{"name":"vpc_peering_test.go","path":"test/vpc_peering_test.go","sha":"fde78ff0e98bfcd42213e5e44d4d2913458ed59c"}]}]},"detailsContent":"<h1 class=\"preview__body--title\" id=\"vpc-app-terraform-module\">VPC-App Terraform Module</h1><div class=\"preview__body--border\"></div><p>This Terraform Module launches a single VPC meant to house applications. By contrast, DevOps-related services such as\nJenkins or InfluxDB should be in a "mgmt" VPC. (See the <a href=\"/repos/v0.18.7/terraform-aws-vpc/modules/vpc-mgmt\" class=\"preview__body--description--blue\">vpc-mgmt</a> module.)</p>\n<h2 class=\"preview__body--subtitle\" id=\"how-do-you-use-this-module\">How do you use this module?</h2>\n<p>Check out the <a href=\"/repos/v0.18.7/terraform-aws-vpc/examples\" class=\"preview__body--description--blue\">examples folder</a>.</p>\n<h2 class=\"preview__body--subtitle\" id=\"whats-a-vpc\">What's a VPC?</h2>\n<p>A <a href=\"https://aws.amazon.com/vpc/\" class=\"preview__body--description--blue\" target=\"_blank\">VPC</a> or Virtual Private Cloud is a logically isolated section of your AWS cloud. Each\nVPC defines a virtual network within which you run your AWS resources, as well as rules for what can go in and out of\nthat network. This includes subnets, route tables that tell those subnets how to route inbound and outbound traffic,\nsecurity groups, access controls lists for the network (NACLs), and any other network components such as VPN connections.</p>\n<h2 class=\"preview__body--subtitle\" id=\"three-subnet-tiers\">Three Subnet Tiers</h2>\n<p>This VPC defines three "tiers" of subnets:</p>\n<ul>\n<li><strong>Public Subnets</strong>: Resources in these subnets are directly addressable from the Internet. Only public-facing\nresources (typically just load balancers) should be put here.</li>\n<li><strong>Private/App Subnets</strong>: Resources in these subnets are NOT directly addressable from the Internet but they can make\noutbound connections to the Internet through a NAT Gateway. You can connect to the resources in this subnet only from\nresources within the VPC, so you should put your app servers here and allow the load balancers in the Public Subnet\nto route traffic to them.</li>\n<li><strong>Private/Persistence Subnets</strong>: Resources in these subnets are neither directly addressable from the Internet nor\nable to make outbound Internet connections. You can connect to the resources in this subnet only from within the VPC,\nso you should put your databases, cache servers, and other stateful resources here and allow your apps to talk to\nthem.</li>\n</ul>\n<h2 class=\"preview__body--subtitle\" id=\"vpc-architecture\">VPC Architecture</h2>\n<p>The three-tier VPC is inspired by the VPC Architecture described by Ben Whaley in his blog post <a href=\"https://www.whaletech.co/2014/10/02/reference-vpc-architecture.html\" class=\"preview__body--description--blue\" target=\"_blank\">A Reference\nVPC Architecture</a>. That blog post proposed the\nfollowing VPC structure:</p>\n<p><img src=\"/repos/images/v0.18.7/terraform-aws-vpc/modules/_docs/vpc_app_architecture.png\" alt=\"VPC Diagram\" class=\"preview__body--diagram\"></p>\n<p>To summarize:</p>\n<ul>\n<li>Each environment (prod, stage, etc.) is represented by a separate VPC.</li>\n<li>Each VPC has three "tiers" of subnets to allow AWS resources to be publicly addressable, addressable only from the\npublic tier, or only from the private/app tier.</li>\n<li>In a given subnet tier, there are usually three or four actual subnets, one for each Availability Zone.</li>\n<li>Therefore, if we created a single VPC in the <code>us-west-2</code> region, which has Availability Zones <code>us-west-2a</code>,<code>us-west-2b</code>,\nand <code>us-west-2c</code>, each subnet tier would have three subnets (one per Availability Zone) for a total of 9 subnets in all.</li>\n<li>The only way to reach this VPC is from the public Internet via a publicly exposed sevice, or via the <a href=\"/repos/v0.18.7/terraform-aws-vpc/modules/vpc-mgmt\" class=\"preview__body--description--blue\">mgmt VPC</a>,\nwhich uses <a href=\"/repos/v0.18.7/terraform-aws-vpc/modules/vpc-peering\" class=\"preview__body--description--blue\">VPC Peering</a> to make this VPC accessible from the mgmt VPC.</li>\n<li>Philosophically, everything in a VPC should be isolated from all resources in any other VPC. In particular, we want\nto ensure that our stage environment is completely independent from prod. This architecture helps to reinforce that.</li>\n</ul>\n<p>Throughout our diagrams and examples we recommend a /16 CIDR range for VPCs. The reason for this is that a /16 makes\nCIDR math quite straightforward. If using the 10.0.0.0/8 <a href=\"http://www.faqs.org/rfcs/rfc1918.html\" class=\"preview__body--description--blue\" target=\"_blank\">RFC1918</a> address space,\nthis allows for 256 VPCs (10.0.0.0/16-10.255.255.255/16) with 65,534 IP addresses per VPC. This should be sufficient for\nnearly all use-cases, and is consistent with many examples and existing documentation found elsewhere.</p>\n<h2 class=\"preview__body--subtitle\" id=\"gotchas\">Gotchas</h2>\n<ul>\n<li>If the <code>num_availability_zones</code> variable in the mgmt VPC and the <code>num_availability_zones</code> variable in the app VPC don't match, there are problems with the routes that are created between the two VPCs as part of setting up VPC Peering. If your use case requires different numbers of Availability Zones for each of these VPCs, please let us know and we'll investigate further!</li>\n</ul>\n<h2 class=\"preview__body--subtitle\" id=\"other-vpc-core-concepts\">Other VPC Core Concepts</h2>\n<p>Learn about <a href=\"/repos/v0.18.7/terraform-aws-vpc/modules/_docs/vpc-core-concepts.md\" class=\"preview__body--description--blue\">Other VPC Core Concepts</a> like subnets, NAT Gateways, and VPC Endpoints.</p>\n","repoName":"terraform-aws-vpc","repoRef":"v0.18.0","serviceDescriptor":{"serviceName":"Virtual Private Cloud (VPC)","serviceRepoName":"terraform-aws-vpc","serviceRepoOrg":"gruntwork-io","cloudProviders":["aws"],"description":"Create a Virtual Private Cloud (VPC). Includes multiple subnet tiers, NACLs, NAT gateways, Internet Gateways, and VPC peering.","imageUrl":"vpc.png","licenseType":"subscriber","technologies":["Terraform"],"compliance":[],"tags":[""]},"serviceCategoryName":"Networking","fileName":"README.md","filePath":"/modules/vpc-app","title":"Repo Browser: Virtual Private Cloud (VPC)","description":"Browse the repos in the Gruntwork Infrastructure as Code Library."}