├── .github
├── CODEOWNERS
└── workflows
│ └── main.yml
├── .gitignore
├── .pre-commit-config.yaml
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE
├── Makefile
├── README.md
├── README.tfdoc.hcl
├── db_subnet_group.tf
├── elasticache_subnet_group.tf
├── examples
├── README.md
└── complete-example
│ ├── README.md
│ └── main.tf
├── go.mod
├── go.sum
├── intra_routing.tf
├── main.tf
├── outputs.tf
├── private_routing.tf
├── public_routing.tf
├── subnets.tf
├── test
├── README.md
├── unit-complete
│ └── main.tf
├── unit-disabled
│ └── main.tf
├── unit-minimal
│ └── main.tf
├── unit_complete_test.go
├── unit_disabled_test.go
└── unit_minimal_test.go
├── variables.tf
└── versions.tf
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | * @mariux @mineiros-io/terraform-service-catalog
2 |
--------------------------------------------------------------------------------
/.github/workflows/main.yml:
--------------------------------------------------------------------------------
1 | name: CI/CD Pipeline
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 | pull_request:
8 | branches:
9 | - master
10 |
11 | env:
12 | AWS_SECRET_ACCESS_KEY: ${{ secrets.MINEIROS_TESTING_AWS_SECRET_ACCESS_KEY }}
13 | AWS_ACCESS_KEY_ID: ${{ secrets.MINEIROS_TESTING_AWS_ACCESS_KEY_ID }}
14 |
15 | jobs:
16 | pre-commit:
17 | runs-on: ubuntu-latest
18 | name: Static Analysis
19 | steps:
20 | - name: Checkout
21 | uses: actions/checkout@v2
22 | - name: Run pre-commit
23 | run: make test/pre-commit
24 |
25 | unit-tests:
26 | runs-on: ubuntu-latest
27 | name: Unit Tests
28 | steps:
29 | - name: Checkout
30 | uses: actions/checkout@v2
31 | - name: Run Unit Tests
32 | run: make test/unit-tests
33 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # IntelliJ files
2 | .idea_modules
3 | *.iml
4 | *.iws
5 | *.ipr
6 | .idea/
7 | build/
8 | */build/
9 | out/
10 |
11 | # macOS files
12 | .history
13 | .DS_Store
14 |
15 | # Local .terraform directories
16 | **/.terraform/*
17 |
18 | # .tfstate files
19 | *.tfstate
20 | *.tfstate.*
21 |
22 | # Ignore any .tfvars files that are generated automatically for each Terraform run. Most
23 | # .tfvars files are managed as part of configuration and so should be included in
24 | # version control.
25 | #
26 | # example.tfvars
27 |
28 | # Ignore override files as they are usually used to override resources locally and so
29 | # are not checked in
30 | override.tf
31 | override.tf.json
32 | *_override.tf
33 | *_override.tf.json
34 |
35 | # Include override files you do wish to add to version control using negated pattern
36 | #
37 | # !example_override.tf
38 |
39 | # Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan
40 | # example: *tfplan*
41 |
42 | # Go best practices dictate that libraries should not include the vendor directory
43 | vendor
44 |
45 | # Terratest directory used to store temporary data
46 | .test-data
47 |
48 | .terraform.lock.hcl
49 |
50 |
--------------------------------------------------------------------------------
/.pre-commit-config.yaml:
--------------------------------------------------------------------------------
1 | repos:
2 | - repo: https://github.com/mineiros-io/pre-commit-hooks
3 | rev: v0.3.1
4 | hooks:
5 | - id: terraform-fmt
6 | - id: terraform-validate
7 | exclude: ^examples|.terraform/
8 | - id: tflint
9 | - id: golangci-lint
10 | - id: phony-targets
11 | - id: markdown-link-check
12 | args: ['-p'] # When adding the -p flag, markdown-link-check will always with an exit code 0, even if dead links are found
13 | verbose: true # Forces the output of the hook to be printed even when the hook passes.
14 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file.
4 |
5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7 |
8 | ## [Unreleased]
9 |
10 | ## [0.7.1]
11 |
12 | ### Fixed
13 |
14 | - Fix calculation of zone name
15 |
16 | ## [0.7.0]
17 |
18 | ### Added
19 |
20 | - Add `nat_gateway_single_mode_zone` to be able to set a fixed zone for single NAT gateway deployments.
21 | - Add `nat_gateway_eip_allocation_ids` to allow bringing external EIPs instead of creating them with the module.
22 |
23 | ## [0.6.0]
24 |
25 | ### Added
26 |
27 | - Add tags for easier data-sourcing
28 | - Add support for elasticache subnet groups
29 |
30 | ## [0.5.0]
31 |
32 | ### Added
33 |
34 | - Add support for db subnet groups
35 | - Add support terraform `v1.x`
36 |
37 | ## [0.4.0]
38 |
39 | ### Added
40 |
41 | - Add terraform `v0.15` support
42 |
43 | ## [0.3.0]
44 |
45 | ### BREAKING CHANGES
46 |
47 | - updating will recreate routes to nat gateways using a new resource key as terraform address
48 |
49 | ### Added
50 |
51 | - Add support for terraform `v0.14`
52 |
53 | ### Fixed
54 |
55 | - BREAKING: Fix terraform route modification behavior when switching nat_gateway_mode
56 |
57 | ## [0.2.0]
58 |
59 | ### Added
60 |
61 | - Add support for Terraform AWS Provider v3.x
62 | - Add support for Terraform v0.13.x
63 | - Prepare support for Terraform v0.14.x
64 |
65 | ## [0.1.0] - 2020-07-06
66 |
67 | ### Added
68 |
69 | - THIS RELEASE IS BREAKING BACKWARD COMPATIBILITY.
70 | - Add support to move subnets between subnet classes without recreation (public, private, intra).
71 | - Add CHANGELOG.md, CONTIBUTING.md and test/README.md.
72 | - Add new input variables to support dynamic subnets.
73 | - Ensure cidr_blocks are align to network address.
74 | - Document all input arguments and output attributes.
75 | - Add minimal and module_enabled tests
76 |
77 | ### Changed
78 |
79 | - THIS RELEASE IS BREAKING BACKWARD COMPATIBILITY.
80 | - Refactor the full module while keeping the same basic feature set.
81 | - Refactor test to deploy VPC with all NAT gateway Modes (single, one_per_az, none).
82 | - Update build-system.
83 |
84 | ### Removed
85 |
86 | - THIS RELEASE IS BREAKING BACKWARD COMPATIBILITY.
87 | - Remove routing to the internet from subnets of class 'intra'.
88 | - Remove flags to allow and disallow internet access for private and intra subnets.
89 | - Remove support for static network classes.
90 | - Remove most input variables related to defining subnets.
91 |
92 | ## [0.0.3] - 2020-06-20
93 |
94 | ### Changed
95 |
96 | - Update build-system
97 | - Update documentation
98 |
99 | ### Fixed
100 |
101 | - Set tenancy to "default"
102 | - Instance tenancy defaulted to "dedicated" which is very costly when running instances in the VPC for non production workloads on scale. If you used v0.0.1 or v0.0.2 please check that you did not start any dedicated instances and review your costs and recreate any started instances to run on shared hardware with default tenenacy. Note: Those are still pre-releases and not meant to run workloads yet.
103 |
104 | ### Removed
105 |
106 | - Unpublish v0.0.1 and v0.0.2 due to expensive dedicated tenancy
107 |
108 | ## [0.0.2] - 2020-06-04
109 |
110 | ### Changed
111 |
112 | - Update build-system
113 | - Update documentation
114 |
115 | ## [0.0.1] - 2020-02-17
116 |
117 | ### Added
118 |
119 | - Add support for three subnet classes (public, private, intra)
120 | - Add support for multiple NAT gateway modes (none, single, one_per_az)
121 | - Implement support for `aws_vpc` resource
122 | - Implement support for `aws_subnet` resource
123 | - Implement support for `aws_route_table` resource
124 | - Implement support for `aws_route_table_association` resource
125 | - Implement support for `aws_route` resource
126 | - Implement support for `aws_internet_gateway` resource
127 | - Implement support for `aws_eip` resource
128 | - Implement support for `aws_nat_gateway` resource
129 | - Document the usage of the module in README.md
130 | - Document the usage of examples
131 | - Add unit tests for basic use cases
132 |
133 | [unreleased]: https://github.com/mineiros-io/terraform-aws-vpc/compare/v0.7.1...HEAD
134 | [0.7.1]: https://github.com/mineiros-io/terraform-aws-vpc/compare/v0.7.0...v0.7.1
135 | [0.7.0]: https://github.com/mineiros-io/terraform-aws-vpc/compare/v0.6.0...v0.7.0
136 | [0.6.0]: https://github.com/mineiros-io/terraform-aws-vpc/compare/v0.5.0...v0.6.0
137 | [0.5.0]: https://github.com/mineiros-io/terraform-aws-vpc/compare/v0.4.0...v0.5.0
138 | [0.4.0]: https://github.com/mineiros-io/terraform-aws-vpc/compare/v0.3.0...v0.4.0
139 | [0.3.0]: https://github.com/mineiros-io/terraform-aws-vpc/compare/v0.2.0...v0.3.0
140 | [0.2.0]: https://github.com/mineiros-io/terraform-aws-vpc/compare/v0.1.0...v0.2.0
141 | [0.1.0]: https://github.com/mineiros-io/terraform-aws-vpc/compare/v0.0.3...v0.1.0
142 | [0.0.3]: https://github.com/mineiros-io/terraform-aws-vpc/compare/55347bd0db3b37ad2d2bcebdf11ed1ea666ad788...v0.0.3
143 | [0.0.2]: https://github.com/mineiros-io/terraform-aws-vpc/compare/0608a9123de5d1c02a6fcd0a2ee8e4f5216c1a49...55347bd0db3b37ad2d2bcebdf11ed1ea666ad788
144 | [0.0.1]: https://github.com/mineiros-io/terraform-aws-vpc/commit/0608a9123de5d1c02a6fcd0a2ee8e4f5216c1a49
145 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contribution Guidelines
2 |
3 | First and foremost, we'd like to express our gratitude to you for taking the time to contribute.
4 | We welcome and appreciate any and all contributions via
5 | [Pull Requests] along the [GitHub Flow].
6 |
7 | 1. [Open a GitHub issue](#open-a-github-issue)
8 | 2. [Fork the repository on GitHub](#fork-the-repository-on-github)
9 | 3. [Install the pre-commit hooks](#install-the-pre-commit-hooks)
10 | 4. [Update the documentation](#update-the-documentation)
11 | 5. [Update the tests](#update-the-tests)
12 | 6. [Update the code](#update-the-code)
13 | 7. [Create a pull request](#create-a-pull-request)
14 | 8. [Merge and release](#merge-and-release)
15 |
16 | ## Open a GitHub issue
17 |
18 | For bug reports or requests, please submit your issue in the appropriate repository.
19 |
20 | We advise that you open an issue and ask the
21 | [CODEOWNERS] and community prior to starting a contribution.
22 | This is your chance to ask questions and receive feedback before
23 | writing (potentially wrong) code. We value the direct contact with our community
24 | a lot, so don't hesitate to ask any questions.
25 |
26 | ## Fork the repository on GitHub
27 |
28 | [Fork] the repository into your own GitHub account and [create a new branch] as
29 | described in the [GitHub Flow].
30 |
31 | ## Install the pre-commit hooks
32 |
33 | If the repository you're working on ships with a
34 | [`.pre-commit-config.yaml`][pre-commit-file],
35 | make sure the necessary hooks have been installed before you begin working
36 | (e.g. a `pre-commit install`).
37 |
38 | ## Update the documentation
39 |
40 | We encourage you to update the documentation before writing any code (please see
41 | [Readme Driven Development]. This ensures the
42 | documentation stays up to date and allows you to think through the problem fully before you begin implementing any
43 | changes.
44 |
45 | ## Update the tests
46 |
47 | We also recommend updating the automated tests before updating any code
48 | (see [Test Driven Development].
49 |
50 | That means that you should add or update a test case, run all tests and verify
51 | that the new test fails with a clear error message and then start implementing
52 | the code changes to get that test to pass.
53 |
54 | The test folder in every repository will have documentation on how to run the
55 | tests locally.
56 |
57 | ## Update the code
58 |
59 | At this point, make your code changes and constantly test again your new test case to make sure that everything working
60 | properly. Do [commit] early and often and make useful commit messages.
61 |
62 | If a backwards incompatible change cannot be avoided, please make sure to call that out when you submit a pull request,
63 | explaining why the change is absolutely necessary.
64 |
65 | ## Create a pull request
66 |
67 | [Create a pull request] with your changes.
68 | Please make sure to include the following:
69 |
70 | 1. A description of the change, including a link to your GitHub issue.
71 | 1. Any notes on backwards incompatibility or downtime.
72 |
73 | ## Merge and release
74 |
75 | The [CODEOWNERS] of the repository will review your code and provide feedback.
76 | If everything looks good, they will merge the code and release a new version while following the principles of [Semantic Versioning (SemVer)].
77 |
78 |
79 |
80 | [Pull Requests]: https://github.com/mineiros-io/terraform-aws-vpc/pulls
81 | [pre-commit-file]: https://github.com/mineiros-io/terraform-aws-vpc/blob/master/.pre-commit-config.yaml
82 |
83 | [Github Flow]: https://guides.github.com/introduction/flow/
84 | [CODEOWNERS]: https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners
85 | [Fork]: https://help.github.com/en/github/getting-started-with-github/fork-a-repo
86 | [create a new branch]: https://guides.github.com/introduction/flow/
87 | [Readme Driven Development]: https://tom.preston-werner.com/2010/08/23/readme-driven-development.html
88 | [commit]: https://help.github.com/en/desktop/contributing-to-projects/committing-and-reviewing-changes-to-your-project
89 | [create a pull request]: https://help.github.com/articles/creating-a-pull-request/
90 | [Semantic Versioning (SemVer)]: https://semver.org/
91 | [Test Driven Development]: https://en.wikipedia.org/wiki/Test-driven_development
92 |
--------------------------------------------------------------------------------
/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 [2020] [Mineiros GmbH]
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 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | # Set default shell to bash
2 | SHELL := /bin/bash -o pipefail
3 |
4 | BUILD_TOOLS_VERSION ?= v0.13.0
5 | BUILD_TOOLS_DOCKER_REPO ?= mineiros/build-tools
6 | BUILD_TOOLS_DOCKER_IMAGE ?= ${BUILD_TOOLS_DOCKER_REPO}:${BUILD_TOOLS_VERSION}
7 |
8 | # Some CI providers such as GitHub Actions, CircleCI, and TravisCI are setting
9 | # the CI environment variable to a non-empty value by default to indicate that
10 | # the current workflow is running in a Continuous Integration environment.
11 | #
12 | # If TF_IN_AUTOMATION is set to any non-empty value, Terraform adjusts its
13 | # output to avoid suggesting specific commands to run next.
14 | # https://www.terraform.io/docs/commands/environment-variables.html#tf_in_automation
15 | #
16 | # We are using GNU style quiet commands to disable set V to non-empty e.g. V=1
17 | # https://www.gnu.org/software/automake/manual/html_node/Debugging-Make-Rules.html
18 | #
19 | ifdef CI
20 | TF_IN_AUTOMATION ?= yes
21 | export TF_IN_AUTOMATION
22 |
23 | V ?= 1
24 | endif
25 |
26 | ifndef NOCOLOR
27 | GREEN := $(shell tput -Txterm setaf 2)
28 | YELLOW := $(shell tput -Txterm setaf 3)
29 | WHITE := $(shell tput -Txterm setaf 7)
30 | RESET := $(shell tput -Txterm sgr0)
31 | endif
32 |
33 | GIT_TOPLEVEl = $(shell git rev-parse --show-toplevel)
34 |
35 | # Generic docker run flags
36 | DOCKER_RUN_FLAGS += -v ${GIT_TOPLEVEl}:/build
37 | DOCKER_RUN_FLAGS += --rm
38 | DOCKER_RUN_FLAGS += -e TF_IN_AUTOMATION
39 | # If TF_VERSION is defined, TFSwitch will switch to the desired version on
40 | # container startup. If TF_VERSION is omitted, the default version installed
41 | # inside the docker image will be used.
42 | DOCKER_RUN_FLAGS += -e TF_VERSION
43 |
44 | # If SSH_AUTH_SOCK is set, we forward the SSH agent of the host system into
45 | # the docker container. This is useful when working with private repositories
46 | # and dependencies that might need to be cloned inside the container (e.g.
47 | # private Terraform modules).
48 | ifdef SSH_AUTH_SOCK
49 | DOCKER_SSH_FLAGS += -e SSH_AUTH_SOCK=/ssh-agent
50 | DOCKER_SSH_FLAGS += -v ${SSH_AUTH_SOCK}:/ssh-agent
51 | endif
52 |
53 | # If AWS_ACCESS_KEY_ID is defined, we are likely running inside an AWS provider
54 | # module. To enable AWS authentication inside the docker container, we inject
55 | # the relevant environment variables.
56 | ifdef AWS_ACCESS_KEY_ID
57 | DOCKER_AWS_FLAGS += -e AWS_ACCESS_KEY_ID
58 | DOCKER_AWS_FLAGS += -e AWS_SECRET_ACCESS_KEY
59 | DOCKER_AWS_FLAGS += -e AWS_SESSION_TOKEN
60 | endif
61 |
62 | # If GITHUB_OWNER is defined, we are likely running inside a GitHub provider
63 | # module. To enable GitHub authentication inside the docker container,
64 | # we inject the relevant environment variables.
65 | ifdef GITHUB_OWNER
66 | DOCKER_GITHUB_FLAGS += -e GITHUB_TOKEN
67 | DOCKER_GITHUB_FLAGS += -e GITHUB_OWNER
68 | endif
69 |
70 | .PHONY: default
71 | default: help
72 |
73 | # Not exposed as a callable target by `make help`, since this is a one-time shot to simplify the development of this module.
74 | .PHONY: template/adjust
75 | template/adjust: FILTER = -path ./.git -prune -a -type f -o -type f -not -name Makefile
76 | template/adjust:
77 | @find . $(FILTER) -exec sed -i -e "s,terraform-module-template,$${PWD##*/},g" {} \;
78 |
79 | ## Run pre-commit hooks inside a build-tools docker container.
80 | .PHONY: test/pre-commit
81 | test/pre-commit: DOCKER_FLAGS += ${DOCKER_SSH_FLAGS}
82 | test/pre-commit:
83 | $(call docker-run,pre-commit run -a)
84 |
85 | ## Run all Go tests inside a build-tools docker container. This is complementary to running 'go test ./test/...'.
86 | .PHONY: test/unit-tests
87 | test/unit-tests: DOCKER_FLAGS += ${DOCKER_SSH_FLAGS}
88 | test/unit-tests: DOCKER_FLAGS += ${DOCKER_GITHUB_FLAGS}
89 | test/unit-tests: DOCKER_FLAGS += ${DOCKER_AWS_FLAGS}
90 | test/unit-tests: DOCKER_FLAGS += -e TF_DATA_DIR=.terratest
91 | test/unit-tests: TEST ?= "TestUnit"
92 | test/unit-tests:
93 | @echo "${YELLOW}[TEST] ${GREEN}Start Running Go Tests in Docker Container.${RESET}"
94 | $(call go-test,./test -run $(TEST))
95 |
96 | ## Clean up cache and temporary files
97 | .PHONY: clean
98 | clean:
99 | $(call rm-command,.terraform)
100 | $(call rm-command,.terraform.lock.hcl)
101 | $(call rm-command,*.tfplan)
102 | $(call rm-command,*/*/.terraform)
103 | $(call rm-command,*/*/*.tfplan)
104 | $(call rm-command,*/*/.terraform.lock.hcl)
105 |
106 | ## Display help for all targets
107 | .PHONY: help
108 | help:
109 | @awk '/^.PHONY: / { \
110 | msg = match(lastLine, /^## /); \
111 | if (msg) { \
112 | cmd = substr($$0, 9, 100); \
113 | msg = substr(lastLine, 4, 1000); \
114 | printf " ${GREEN}%-30s${RESET} %s\n", cmd, msg; \
115 | } \
116 | } \
117 | { lastLine = $$0 }' $(MAKEFILE_LIST)
118 |
119 | ## Generate README.md with Terradoc
120 | .PHONY: terradoc
121 | terradoc:
122 | $(call quiet-command,terradoc -o README.md README.tfdoc.hcl)
123 |
124 | # Define helper functions
125 | DOCKER_FLAGS += ${DOCKER_RUN_FLAGS}
126 | DOCKER_RUN_CMD = docker run ${DOCKER_FLAGS} ${BUILD_TOOLS_DOCKER_IMAGE}
127 |
128 | quiet-command = $(if ${V},${1},$(if ${2},@echo ${2} && ${1}, @${1}))
129 | docker-run = $(call quiet-command,${DOCKER_RUN_CMD} ${1} | cat,"${YELLOW}[DOCKER RUN] ${GREEN}${1}${RESET}")
130 | go-test = $(call quiet-command,${DOCKER_RUN_CMD} go test -v -count 1 -timeout 45m -parallel 1 ${1} | cat,"${YELLOW}[TEST] ${GREEN}${1}${RESET}")
131 | rm-command = $(call quiet-command,rm -rf ${1},"${YELLOW}[CLEAN] ${GREEN}${1}${RESET}")
132 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [
](https://mineiros.io/?ref=terraform-aws-vpc)
2 |
3 | [](https://github.com/mineiros-io/terraform-aws-vpc/actions)
4 | [](https://github.com/mineiros-io/terraform-aws-vpc/releases)
5 | [](https://github.com/hashicorp/terraform/releases)
6 | [](https://github.com/terraform-providers/terraform-provider-aws/releases)
7 | [](https://mineiros.io/slack)
8 |
9 | # terraform-aws-vpc
10 |
11 | A [Terraform] base module for managing an
12 | [Amazon Virtual Private Cloud](https://aws.amazon.com/de/vpc/) on
13 | [Amazon Web Services (AWS)][aws].
14 |
15 | ***This module supports Terraform v0.15, v0.14, v0.13, as well as v0.12.20 and above
16 | and is compatible with the terraform AWS provider v3 as well as v2.45 and above.***
17 |
18 | This module is part of our Infrastructure as Code (IaC) framework
19 | that enables our users and customers to easily deploy and manage reusable,
20 | secure, and production-grade cloud infrastructure.
21 |
22 |
23 | - [Module Features](#module-features)
24 | - [Getting Started](#getting-started)
25 | - [Module Argument Reference](#module-argument-reference)
26 | - [Main Resource Configuration](#main-resource-configuration)
27 | - [VPC](#vpc)
28 | - [Extended Resource Configuration](#extended-resource-configuration)
29 | - [Subnets](#subnets)
30 | - [Internet Gateway](#internet-gateway)
31 | - [NAT Gateways](#nat-gateways)
32 | - [Subnet Routing](#subnet-routing)
33 | - [Module Configuration](#module-configuration)
34 | - [Module Outputs](#module-outputs)
35 | - [Computed Attributes](#computed-attributes)
36 | - [Full Resource Objects](#full-resource-objects)
37 | - [Module Attributes](#module-attributes)
38 | - [External Documentation](#external-documentation)
39 | - [AWS Documentation VPC](#aws-documentation-vpc)
40 | - [Terraform AWS Provider Documentation:](#terraform-aws-provider-documentation)
41 | - [Module Versioning](#module-versioning)
42 | - [Backwards compatibility in `0.0.z` and `0.y.z` version](#backwards-compatibility-in-00z-and-0yz-version)
43 | - [About Mineiros](#about-mineiros)
44 | - [Reporting Issues](#reporting-issues)
45 | - [Contributing](#contributing)
46 | - [Makefile Targets](#makefile-targets)
47 | - [License](#license)
48 |
49 | ## Module Features
50 |
51 | This module implements the following Terraform resources
52 |
53 | - `aws_region`
54 | - `aws_vpc`
55 | - `aws_subnet`
56 | - `aws_eip`
57 | - `aws_nat_gateway`
58 | - `aws_route_table`
59 | - `aws_route_table_association`
60 | - `aws_route`
61 | - `aws_internet_gateway`
62 | - `aws_route_table`
63 | - `aws_route_table_association`
64 | - `aws_route`
65 | - `aws_elasticache_subnet_group`
66 | - `aws_db_subnet_group`
67 |
68 | ## Getting Started
69 |
70 | Most basic usage just setting required arguments:
71 |
72 | ```hcl
73 | module "terraform-aws-vpc" {
74 | source = "mineiros-io/vpc/aws"
75 | version = "~> 0.7.0"
76 | }
77 | ```
78 |
79 | ## Module Argument Reference
80 |
81 | See [variables.tf] and [examples/] for details and use-cases.
82 |
83 | ### Main Resource Configuration
84 |
85 | #### VPC
86 |
87 | - [**`vpc_name`**](#var-vpc_name): *(Optional `string`)*
88 |
89 | The name of the VPC. This will be used to tag resources with names
90 | by default.
91 |
92 | Default is `"main"`.
93 |
94 | - [**`cidr_block`**](#var-cidr_block): *(Optional `string`)*
95 |
96 | The CIDR block for the VPC.
97 |
98 | Default is `"10.0.0.0/16"`.
99 |
100 | - [**`instance_tenancy`**](#var-instance_tenancy): *(Optional `string`)*
101 |
102 | A tenancy option for instances launched into the VPC.
103 | Setting the tenancy to `dedicated` will create additional costs: See
104 | https://aws.amazon.com/ec2/pricing/dedicated-instances/ for details.
105 |
106 | Default is `"default"`.
107 |
108 | - [**`enable_dns_support`**](#var-enable_dns_support): *(Optional `bool`)*
109 |
110 | A boolean flag to enable/disable DNS support in the VPC.
111 |
112 | Default is `true`.
113 |
114 | - [**`enable_dns_hostnames`**](#var-enable_dns_hostnames): *(Optional `bool`)*
115 |
116 | A boolean flag to enable/disable DNS hostnames in the VPC.
117 |
118 | Default is `false`.
119 |
120 | - [**`enable_classiclink`**](#var-enable_classiclink): *(Optional `bool`)*
121 |
122 | A boolean flag to enable/disable ClassicLink for the VPC. Only valid
123 | in regions and accounts that support EC2 Classic. See the
124 | ClassicLink documentation for more information.
125 |
126 | Default is `false`.
127 |
128 | - [**`enable_classiclink_dns_support`**](#var-enable_classiclink_dns_support): *(Optional `bool`)*
129 |
130 | A boolean flag to enable/disable ClassicLink DNS Support for the
131 | VPC. Only valid in regions and accounts that support EC2 Classic.
132 |
133 | Default is `false`.
134 |
135 | - [**`assign_generated_ipv6_cidr_block`**](#var-assign_generated_ipv6_cidr_block): *(Optional `bool`)*
136 |
137 | Requests an Amazon-provided IPv6 CIDR block with a /56 prefix length
138 | for the VPC. You cannot specify the range of IP addresses, or the
139 | size of the CIDR block.
140 |
141 | Default is `false`.
142 |
143 | - [**`vpc_tags`**](#var-vpc_tags): *(Optional `string`)*
144 |
145 | A map of tags to assign to the vpc resource.
146 | To set the Name and add the capability to be used in data sources
147 | the `vpc_tags` will always be merged with:
148 |
149 | Default is `"{}"`.
150 |
151 | Example:
152 |
153 | ```hcl
154 | {
155 | Name = "{vpc_name}"
156 | "mineiros-io/aws/vpc/vpc-name" = "{vpc_name}"
157 | }
158 | ```
159 |
160 | ### Extended Resource Configuration
161 |
162 | #### Subnets
163 |
164 | - [**`subnets`**](#var-subnets): *(Optional `list(subnet)`)*
165 |
166 | A List of `subnet` objects that defined the subnet setup within the
167 | VPC.
168 |
169 | Default is `[]`.
170 |
171 | Example:
172 |
173 | ```hcl
174 | subnets = [
175 | {
176 | group = "main"
177 | class = "public"
178 |
179 | map_public_ip_on_launch = true
180 |
181 | cidr_block = cidrsubnet("10.0.0.0/16", 4, 0)
182 | newbits = 4
183 |
184 | netnums_by_az = {
185 | a = [0] # "10.0.0.0/24"
186 | b = [1] # "10.0.1.0/24"
187 | }
188 | tags = {}
189 | },
190 | {
191 | group = "main"
192 | class = "private"
193 |
194 | map_public_ip_on_launch = false
195 |
196 | cidr_block = cidrsubnet("10.0.0.0/16", 4, 1)
197 | newbits = 4
198 |
199 | netnums_by_az = {
200 | a = [0] # "10.0.16.0/24"
201 | b = [1] # "10.0.17.0/24"
202 | }
203 | },
204 | ]
205 | ```
206 |
207 | Each `subnet` object in the list accepts the following attributes:
208 |
209 | - [**`group`**](#attr-subnets-group): *(Optional `string`)*
210 |
211 | A group name for the subnets. This can be any string. This
212 | information is used to group and tag resources within the subnets.
213 | The combination of `group` and `class` needs to be unique over all
214 | subnets defined. This can be changed at any time and will change
215 | the tags applied to resources by default.
216 |
217 | Default is `"main"`.
218 |
219 | - [**`class`**](#attr-subnets-class): *(Optional `string`)*
220 |
221 | The class of the subnet. This can be `"public"`, `"private"`, or
222 | "`intra`". This can be changed at any time and will change the
223 | routing of the subnet instead of recreating the subnet resource.
224 |
225 | - "public" defines a set of subnets where deployed components are
226 | reachable via the public Internet.
227 | - "private" defines a set of subnets where components are not
228 | publicly reachable but can reach the Internet.
229 | - "intra" defines a set of subnets that have no connectivity to
230 | the public Internet.
231 |
232 | Default is `"private"`.
233 |
234 | - [**`map_public_ip_on_launch`**](#attr-subnets-map_public_ip_on_launch): *(Optional `bool`)*
235 |
236 | Whether resources deployed into the subnet will be assigned a
237 | public IPv4 address when launched.
238 |
239 | Default is `true`.
240 |
241 | - [**`cidr_block`**](#attr-subnets-cidr_block): *(Optional `string`)*
242 |
243 | Define the base CIDR Block of the subnets and the parameters to
244 | calculate each CIDR Block.
245 |
246 | Default is the CIDR Block of the VPC (`cidr_block`).
247 |
248 | - [**`newbits`**](#attr-subnets-newbits): *(Optional `number`)*
249 |
250 | How many bits should be added when calculating the subnets CIDR
251 | Blocks.
252 |
253 | Default is `8`.
254 |
255 | - [**`netnums_by_az`**](#attr-subnets-netnums_by_az): *(**Required** `map(netnums_by_az)`)*
256 |
257 | Type is map(list(number)).
258 |
259 | A map of subnets keyed by availability zone suffix (a,b,c,d,e,f).
260 | The numbers define the network number with in the CIDR Block.
261 | See https://www.terraform.io/docs/configuration/functions/cidrsubnet.html
262 | for details on how this is calculated internally.
263 |
264 | Note: When adjusting cidr_block or newbits you might also need to
265 | adjust the netnums.
266 | The example shows how to deploy one subnet in availability zone
267 | `a` (`10.0.0.0/24`) and one subnet in availability zone `b`
268 | (`10.0.1.0/24`).
269 |
270 | Example:
271 |
272 | ```hcl
273 | cidr_block = "10.0.0.0/16"
274 | newbits = 8
275 |
276 | netnums_by_az = {
277 | a = [0] # "10.0.0.0/24"
278 | b = [1] # "10.0.1.0/24"
279 | }
280 | ```
281 |
282 | - [**`db_subnet_group_name`**](#attr-subnets-db_subnet_group_name): *(Optional `string`)*
283 |
284 | The name of a db subnet group to create for all netnum ranges in
285 | this subnet.
286 | The `db_subnet_group_name` resource tags will be cloned from the
287 | subnets.
288 |
289 | - [**`elasticache_subnet_group_name`**](#attr-subnets-elasticache_subnet_group_name): *(Optional `string`)*
290 |
291 | The name of a elasticache subnet group to create for all netnum
292 | ranges in this subnet.
293 | The `elasticache_subnet_group_name` resource tags will be cloned
294 | from the subnets.
295 |
296 | - [**`tags`**](#attr-subnets-tags): *(Optional `map(string)`)*
297 |
298 | A map of tags that will be applied to each subnet in this
299 | group-class combination.
300 | Those tags will be merged with a `Name` tag, `module_tags`,
301 | `subnet_tags` and tags for the subnet class
302 | `public_subnet_tags`, `private_subnet_tags`, or
303 | `intra_subnet_tags`.
304 |
305 | To set the Name and add the capability to be used in data
306 | sources the `subnet_tags` will always be merged with:
307 |
308 | ```hcl
309 | {
310 | Name = "{vpc_name}-{subnet.group}-{subnet.class}-{az}-{idx}"
311 | "mineiros-io/aws/vpc/vpc-name" = "{vpc_name}"
312 | "mineiros-io/aws/vpc/subnet-name" = "{vpc_name}-{subnet.group}-{subnet.class}-{az}-{idx}"
313 | "mineiros-io/aws/vpc/subnet-group" = "{subnet.group}"
314 | "mineiros-io/aws/vpc/subnet-class" = "{subnet.class}"
315 | }
316 | ```
317 |
318 | Default is `{}`.
319 |
320 | - [**`subnet_tags`**](#var-subnet_tags): *(Optional `map(string)`)*
321 |
322 | Tags applied to each subnet resource.
323 |
324 | Default is `{}`.
325 |
326 | - [**`public_subnet_tags`**](#var-public_subnet_tags): *(Optional `map(string)`)*
327 |
328 | Tags applied to each public subnet.
329 |
330 | Default is `{}`.
331 |
332 | - [**`private_subnet_tags`**](#var-private_subnet_tags): *(Optional `map(string)`)*
333 |
334 | Tags applied to each private subnet.
335 |
336 | Default is `{}`.
337 |
338 | - [**`intra_subnet_tags`**](#var-intra_subnet_tags): *(Optional `map(string)`)*
339 |
340 | Tags applied to each intra subnet.
341 |
342 | Default is `{}`.
343 |
344 | #### Internet Gateway
345 |
346 | - [**`internet_gateway_tags`**](#var-internet_gateway_tags): *(Optional `map(string)`)*
347 |
348 | A map of tags to apply to the created Internet Gateway.
349 | An Internet Gateway is created if a public subnet is defined.
350 | All public egress and ingress traffic of all public subnets will be
351 | routed through the same Internet Gateway.
352 |
353 | To set the Name and add the capability to be used in data sources
354 | the `internet_gateway_tags` will always be merged with:
355 |
356 | ```hcl
357 | {
358 | Name = "{vpc_name}"
359 | "mineiros-io/aws/vpc/vpc-name" = "{vpc_name}"
360 | "mineiros-io/aws/vpc/igw-name" = "{vpc_name}"
361 | }
362 | ```
363 |
364 | Default is `{}`.
365 |
366 | #### NAT Gateways
367 |
368 | > **A Note on pricing:** AWS charges for each provisioned NAT
369 | Gateway. Please see https://aws.amazon.com/vpc/pricing/ for details.
370 | > To save costs you can use `nat_gateway_mode` to define the number
371 | of NAT Gateways you want to deploy.
372 | > The best practice is to deploy one NAT Gateway per Availability
373 | Zone for higher reliability on production environments
374 | (`one_per_az`), while you can save some costs on staging and testing
375 | environments by deploying a single NAT Gateway (`single`).
376 |
377 | - [**`nat_gateway_mode`**](#var-nat_gateway_mode): *(Optional `string`)*
378 |
379 | Set the mode for the NAT Gateways. NAT Gateways will only be created
380 | when private subnets are defined.
381 | Each private subnet needs at least one configured public subnet in
382 | the same availability zone.
383 | Each NAT gateway will be assigned an Elastic IP Address.
384 | When changing the mode, NAT Gateways and Elastic IP Addresses will
385 | be created or destroyed.
386 | All public egress traffic of all private subnets will be routed
387 | through the same set of NAT Gateways.
388 | Possible modes are `none`, `single`, or `one_per_az`. Choose
389 |
390 | - `"none"` to create no NAT Gateways at all (use for debugging only),
391 | - `"single"` to create a single NAT Gateway inside the first defined
392 | Public Subnet, or
393 | - `"one_per_az"` to create one NAT Gateway inside the first Public
394 | Subnet in each Availability Zone.
395 |
396 | Default is `"single"`.
397 |
398 | - [**`nat_gateway_single_mode_zone`**](#var-nat_gateway_single_mode_zone): *(Optional `string`)*
399 |
400 | Define the zone (short name) of the NAT gateway when nat_gateway_mode is "single" (e.g. "a", "b", or "c").
401 | The AWS region will be added as a prefix.
402 |
403 | Default is `"a random zone"`.
404 |
405 | - [**`nat_gateway_eip_allocation_ids`**](#var-nat_gateway_eip_allocation_ids): *(Optional `map(string)`)*
406 |
407 | A map of EIP allocation ids to use for nat gateways keyed by short zone name (e.g. "a", "b", or "c").
408 | If set no EIPs will be created by the module. If unset, the module will create the needed number of EIPs.
409 |
410 | Default is `{}`.
411 |
412 | - [**`nat_gateway_tags`**](#var-nat_gateway_tags): *(Optional `map(string)`)*
413 |
414 | A map of tags to apply to the created NAT Gateways.
415 |
416 | To set the Name and add the capability to be used in data sources
417 | the `nat_gateway_tags` will always be merged with:
418 |
419 | ```hcl
420 | {
421 | Name = "{vpc_name}-{zone}"
422 | "mineiros-io/aws/vpc/vpc-name" = "{vpc_name}"
423 | "mineiros-io/aws/vpc/natgw-name" = "{vpc_name}-{zone}"
424 | }
425 | ```
426 |
427 | Default is `{}`.
428 |
429 | - [**`eip_tags`**](#var-eip_tags): *(Optional `map(string)`)*
430 |
431 | A map of tags to apply to the created NAT Gateway Elastic IP
432 | Addresses.
433 |
434 | To set the Name and add the capability to be used in data sources
435 | the `eip_tags` will always be merged with:
436 |
437 | ```hcl
438 | {
439 | Name = "{vpc_name}-nat-private-{zone}"
440 | "mineiros-io/aws/vpc/vpc-name" = "{vpc_name}"
441 | "mineiros-io/aws/vpc/natgw-name" = "{vpc_name}-{zone}"
442 | "mineiros-io/aws/vpc/eip-name" = "{vpc_name}-nat-private-{zone}"
443 | }
444 | ```
445 |
446 | Default is `{}`.
447 |
448 | #### Subnet Routing
449 |
450 | - [**`route_table_tags`**](#var-route_table_tags): *(Optional `map(string)`)*
451 |
452 | A map of tags to apply to all created Route Tables.
453 |
454 | Default is `{}`.
455 |
456 | - [**`public_route_table_tags`**](#var-public_route_table_tags): *(Optional `map(string)`)*
457 |
458 | A map of tags to apply to the created Public Route Tables.
459 |
460 | To set the Name and add the capability to be used in data sources
461 | the `public_route_table_tags` will always be merged with:
462 |
463 | ```hcl
464 | {
465 | Name = "{vpc_name}-public-{group}"
466 | "mineiros-io/aws/vpc/vpc-name" = "{vpc_name}"
467 | "mineiros-io/aws/vpc/routetable-name" = "{vpc_name}-public-{group}"
468 | "mineiros-io/aws/vpc/routetable-class" = "public"
469 | }
470 | ```
471 |
472 | Default is `{}`.
473 |
474 | - [**`private_route_table_tags`**](#var-private_route_table_tags): *(Optional `map(string)`)*
475 |
476 | A map of tags to apply to the created Private Route Tables.
477 |
478 | To set the Name and add the capability to be used in data sources
479 | the `private_route_table_tags` will always be merged with:
480 |
481 | ```hcl
482 | {
483 | Name = "{vpc_name}-private-{group}-{zone}"
484 | "mineiros-io/aws/vpc/vpc-name" = "{vpc_name}"
485 | "mineiros-io/aws/vpc/routetable-name" = "{vpc_name}-private-{group}-{zone}"
486 | "mineiros-io/aws/vpc/routetable-class" = "private"
487 | }
488 | ```
489 |
490 | Default is `{}`.
491 |
492 | - [**`intra_route_table_tags`**](#var-intra_route_table_tags): *(Optional `map(string)`)*
493 |
494 | A map of tags to apply to the created Intra Route Tables.
495 |
496 | To set the Name and add the capability to be used in data sources
497 | the `intra_route_table_tags` will always be merged with:
498 |
499 | ```hcl
500 | {
501 | Name = "{vpc_name}-intra-{group}"
502 | "mineiros-io/aws/vpc/vpc-name" = "{vpc_name}"
503 | "mineiros-io/aws/vpc/routetable-name" = "{vpc_name}-intra-{group}"
504 | "mineiros-io/aws/vpc/routetable-class" = "intra"
505 | }
506 | ```
507 |
508 | Default is `{}`.
509 |
510 | ## Module Configuration
511 |
512 | - [**`module_enabled`**](#var-module_enabled): *(Optional `bool`)*
513 |
514 | Specifies whether resources in the module will be created.
515 |
516 | Default is `true`.
517 |
518 | - [**`module_tags`**](#var-module_tags): *(Optional `map(string)`)*
519 |
520 | A map of tags that will be applied to all created resources that
521 | accept tags. Tags defined with 'module_tags' can be
522 | overwritten by resource-specific tags.
523 |
524 | Default is `{}`.
525 |
526 | - [**`module_depends_on`**](#var-module_depends_on): *(Optional `list(dependency)`)*
527 |
528 | A list of dependencies. Any object can be _assigned_ to this list to
529 | define a hidden external dependency.
530 |
531 | ## Module Outputs
532 |
533 | The following attributes are exported by the module:
534 |
535 | ### Computed Attributes
536 |
537 | - [**`public_subnets_by_group`**](#output-public_subnets_by_group): *(`map(public_subnets_by_group)`)*
538 |
539 | A map of lists of public subnets keyed by group. (`aws_subnet`)
540 |
541 | - [**`public_route_table_ids_by_group`**](#output-public_route_table_ids_by_group): *(`map(public_route_table_ids_by_group)`)*
542 |
543 | A map of lists of public route table IDs keyed by group.
544 |
545 | - [**`public_subnet_ids_by_group`**](#output-public_subnet_ids_by_group): *(`map(public_subnet_ids_by_group)`)*
546 |
547 | A map of lists of public subnet IDs keyed by group.
548 |
549 | - [**`private_subnets_by_group`**](#output-private_subnets_by_group): *(`map(private_subnets_by_group)`)*
550 |
551 | A map of lists of private subnets keyed by group. (`aws_subnet`)
552 |
553 | - [**`private_route_table_ids_by_group`**](#output-private_route_table_ids_by_group): *(`map(private_route_table_ids_by_group)`)*
554 |
555 | A map of lists of private route table IDs keyed by group.
556 |
557 | - [**`private_subnet_ids_by_group`**](#output-private_subnet_ids_by_group): *(`map(private_subnet_ids_by_group)`)*
558 |
559 | A map of lists of private subnet IDs keyed by group.
560 |
561 | - [**`intra_subnets_by_group`**](#output-intra_subnets_by_group): *(`map(intra_subnets_by_group)`)*
562 |
563 | A map of lists of intra aws_subnet keyed by group. (`aws_subnet`)
564 |
565 | - [**`intra_route_table_ids_by_group`**](#output-intra_route_table_ids_by_group): *(`map(intra_route_table_ids_by_group)`)*
566 |
567 | A map of lists of intra route table IDs keyed by group.
568 |
569 | - [**`intra_subnet_ids_by_group`**](#output-intra_subnet_ids_by_group): *(`map(intra_subnet_ids_by_group)`)*
570 |
571 | A map of lists of intra subnet IDs keyed by group.
572 |
573 | ### Full Resource Objects
574 |
575 | - [**`vpc`**](#output-vpc): *(`object(vpc)`)*
576 |
577 | The VPC. (`aws_vpc`)
578 |
579 | - [**`intra_route_tables`**](#output-intra_route_tables): *(`map(intra_route_tables)`)*
580 |
581 | A map of intra route tables keyed by group. (`aws_route_table`)
582 |
583 | - [**`intra_route_table_associations`**](#output-intra_route_table_associations): *(`map(intra_route_table_associations)`)*
584 |
585 | A map of intra route table associations keyed by the subnets CIDR
586 | Blocks. (`aws_route_table_association`)
587 |
588 | - [**`eips`**](#output-eips): *(`map(eips)`)*
589 |
590 | A map of Elastic IP Adresses (EIPs) keyed by availability zone.
591 | (`aws_eip`)
592 |
593 | - [**`nat_gateways`**](#output-nat_gateways): *(`map(nat_gateways)`)*
594 |
595 | A map of NAT gatweways keyed by availability zone.
596 | (`aws_nat_gateway`)
597 |
598 | - [**`private_route_tables`**](#output-private_route_tables): *(`map(private_route_tables)`)*
599 |
600 | A map of private route tables keyed by group. (`aws_route_table`)
601 |
602 | - [**`private_route_table_associations`**](#output-private_route_table_associations): *(`map(private_route_table_associations)`)*
603 |
604 | A map of private route table associations keyed by the subnets CIDR
605 | Blocks. (`aws_route_table_association`)
606 |
607 | - [**`routes_to_nat_gateways`**](#output-routes_to_nat_gateways): *(`map(routes_to_nat_gateways)`)*
608 |
609 | A map of routes to the NAT Gateways keyed by group. (`aws_route`)
610 |
611 | - [**`internet_gateway`**](#output-internet_gateway): *(`object(internet_gateway)`)*
612 |
613 | The Internet Gateway. (`aws_internet_gateway`)
614 |
615 | - [**`public_route_tables`**](#output-public_route_tables): *(`map(public_route_tables)`)*
616 |
617 | A map of public route tables keyed by group. (`aws_route_table`)
618 |
619 | - [**`public_route_table_associations`**](#output-public_route_table_associations): *(`map(public_route_table_associations)`)*
620 |
621 | A map of public route table associations keyed by the subnets CIDR
622 | Blocks. (`aws_route_table_association`)
623 |
624 | - [**`routes_to_internet_gateway`**](#output-routes_to_internet_gateway): *(`map(routes_to_internet_gateway)`)*
625 |
626 | A map of routes to the Internet Gateway keyed by group. (`aws_route`)
627 |
628 | - [**`subnets`**](#output-subnets): *(`map(subnets)`)*
629 |
630 | A map of subnets keyed by CIDR Blocks. (`aws_subnet`)
631 |
632 | ### Module Attributes
633 |
634 | - [**`module_inputs`**](#output-module_inputs): *(`map(module_inputs)`)*
635 |
636 | A map of all module arguments. Set to the provided values or calculated default values.
637 |
638 | - [**`module_enabled`**](#output-module_enabled): *(`bool`)*
639 |
640 | Whether this module is enabled.
641 |
642 | - [**`module_tags`**](#output-module_tags): *(`map(string)`)*
643 |
644 | The map of tags that are being applied to all created resources that accept tags.
645 |
646 | ## External Documentation
647 |
648 | ### AWS Documentation VPC
649 |
650 | - https://aws.amazon.com/de/vpc/
651 |
652 | ### Terraform AWS Provider Documentation:
653 |
654 | - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc
655 | - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/subnet
656 | - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/internet_gateway
657 | - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/nat_gateway
658 | - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table
659 | - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table_association
660 | - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route
661 |
662 | ## Module Versioning
663 |
664 | This Module follows the principles of [Semantic Versioning (SemVer)].
665 |
666 | Given a version number `MAJOR.MINOR.PATCH`, we increment the:
667 |
668 | 1. `MAJOR` version when we make incompatible changes,
669 | 2. `MINOR` version when we add functionality in a backwards compatible manner, and
670 | 3. `PATCH` version when we make backwards compatible bug fixes.
671 |
672 | ### Backwards compatibility in `0.0.z` and `0.y.z` version
673 |
674 | - Backwards compatibility in versions `0.0.z` is **not guaranteed** when `z` is increased. (Initial development)
675 | - Backwards compatibility in versions `0.y.z` is **not guaranteed** when `y` is increased. (Pre-release)
676 |
677 | ## About Mineiros
678 |
679 | [Mineiros][homepage] is a remote-first company headquartered in Berlin, Germany
680 | that solves development, automation and security challenges in cloud infrastructure.
681 |
682 | Our vision is to massively reduce time and overhead for teams to manage and
683 | deploy production-grade and secure cloud infrastructure.
684 |
685 | We offer commercial support for all of our modules and encourage you to reach out
686 | if you have any questions or need help. Feel free to email us at [hello@mineiros.io] or join our
687 | [Community Slack channel][slack].
688 |
689 | ## Reporting Issues
690 |
691 | We use GitHub [Issues] to track community reported issues and missing features.
692 |
693 | ## Contributing
694 |
695 | Contributions are always encouraged and welcome! For the process of accepting changes, we use
696 | [Pull Requests]. If you'd like more information, please see our [Contribution Guidelines].
697 |
698 | ## Makefile Targets
699 |
700 | This repository comes with a handy [Makefile].
701 | Run `make help` to see details on each available target.
702 |
703 | ## License
704 |
705 | [![license][badge-license]][apache20]
706 |
707 | This module is licensed under the Apache License Version 2.0, January 2004.
708 | Please see [LICENSE] for full details.
709 |
710 | Copyright © 2019-2022 [Mineiros GmbH][homepage]
711 |
712 |
713 |
714 |
715 | [homepage]: https://mineiros.io/?ref=terraform-aws-vpc
716 | [hello@mineiros.io]: mailto:hello@mineiros.io
717 | [badge-build]: https://github.com/mineiros-io/terraform-aws-vpc/workflows/CI/CD%20Pipeline/badge.svg
718 | [badge-semver]: https://img.shields.io/github/v/tag/mineiros-io/terraform-aws-vpc.svg?label=latest&sort=semver
719 | [badge-license]: https://img.shields.io/badge/license-Apache%202.0-brightgreen.svg
720 | [badge-terraform]: https://img.shields.io/badge/terraform-1.x%20|%200.15%20|%200.14%20|%200.13%20|%200.12.20+-623CE4.svg?logo=terraform
721 | [badge-slack]: https://img.shields.io/badge/slack-@mineiros--community-f32752.svg?logo=slack
722 | [build-status]: https://github.com/mineiros-io/terraform-aws-vpc/actions
723 | [releases-github]: https://github.com/mineiros-io/terraform-aws-vpc/releases
724 | [badge-tf-aws]: https://img.shields.io/badge/AWS-3%20and%202.45+-F8991D.svg?logo=terraform
725 | [releases-aws-provider]: https://github.com/terraform-providers/terraform-provider-aws/releases
726 | [releases-terraform]: https://github.com/hashicorp/terraform/releases
727 | [apache20]: https://opensource.org/licenses/Apache-2.0
728 | [slack]: https://join.slack.com/t/mineiros-community/shared_invite/zt-ehidestg-aLGoIENLVs6tvwJ11w9WGg
729 | [terraform]: https://www.terraform.io
730 | [aws]: https://aws.amazon.com/
731 | [semantic versioning (semver)]: https://semver.org/
732 | [variables.tf]: https://github.com/mineiros-io/terraform-aws-vpc/blob/master/variables.tf
733 | [examples/]: https://github.com/mineiros-io/terraform-aws-vpc/blob/master/examples
734 | [issues]: https://github.com/mineiros-io/terraform-aws-vpc/issues
735 | [license]: https://github.com/mineiros-io/terraform-aws-vpc/blob/master/LICENSE
736 | [makefile]: https://github.com/mineiros-io/terraform-aws-vpc/blob/master/Makefile
737 | [pull requests]: https://github.com/mineiros-io/terraform-aws-vpc/pulls
738 | [contribution guidelines]: https://github.com/mineiros-io/terraform-aws-vpc/blob/master/CONTRIBUTING.md
739 |
--------------------------------------------------------------------------------
/README.tfdoc.hcl:
--------------------------------------------------------------------------------
1 | header {
2 | image = "https://raw.githubusercontent.com/mineiros-io/brand/3bffd30e8bdbbde32c143e2650b2faa55f1df3ea/mineiros-primary-logo.svg"
3 | url = "https://mineiros.io/?ref=terraform-aws-vpc"
4 |
5 | badge "build" {
6 | image = "https://github.com/mineiros-io/terraform-aws-vpc/workflows/CI/CD%20Pipeline/badge.svg"
7 | url = "https://github.com/mineiros-io/terraform-aws-vpc/actions"
8 | text = "Build Status"
9 | }
10 |
11 | badge "semver" {
12 | image = "https://img.shields.io/github/v/tag/mineiros-io/terraform-aws-vpc.svg?label=latest&sort=semver"
13 | url = "https://github.com/mineiros-io/terraform-aws-vpc/releases"
14 | text = "GitHub tag (latest SemVer)"
15 | }
16 |
17 | badge "terraform" {
18 | image = "https://img.shields.io/badge/terraform-1.x%20|%200.15%20|%200.14%20|%200.13%20|%200.12.20+-623CE4.svg?logo=terraform"
19 | url = "https://github.com/hashicorp/terraform/releases"
20 | text = "Terraform Version"
21 | }
22 |
23 | badge "tf-aws-provider" {
24 | image = "https://img.shields.io/badge/AWS-3%20and%202.45+-F8991D.svg?logo=terraform"
25 | url = "https://github.com/terraform-providers/terraform-provider-aws/releases"
26 | text = "AWS Provider Version"
27 | }
28 |
29 | badge "slack" {
30 | image = "https://img.shields.io/badge/slack-@mineiros--community-f32752.svg?logo=slack"
31 | url = "https://mineiros.io/slack"
32 | text = "Join Slack"
33 | }
34 | }
35 |
36 | section {
37 | title = "terraform-aws-vpc"
38 | toc = true
39 | content = <<-END
40 | A [Terraform] base module for managing an
41 | [Amazon Virtual Private Cloud](https://aws.amazon.com/de/vpc/) on
42 | [Amazon Web Services (AWS)][aws].
43 |
44 | ***This module supports Terraform v0.15, v0.14, v0.13, as well as v0.12.20 and above
45 | and is compatible with the terraform AWS provider v3 as well as v2.45 and above.***
46 |
47 | This module is part of our Infrastructure as Code (IaC) framework
48 | that enables our users and customers to easily deploy and manage reusable,
49 | secure, and production-grade cloud infrastructure.
50 | END
51 |
52 | section {
53 | title = "Module Features"
54 | content = <<-END
55 | This module implements the following Terraform resources
56 |
57 | - `aws_region`
58 | - `aws_vpc`
59 | - `aws_subnet`
60 | - `aws_eip`
61 | - `aws_nat_gateway`
62 | - `aws_route_table`
63 | - `aws_route_table_association`
64 | - `aws_route`
65 | - `aws_internet_gateway`
66 | - `aws_route_table`
67 | - `aws_route_table_association`
68 | - `aws_route`
69 | - `aws_elasticache_subnet_group`
70 | - `aws_db_subnet_group`
71 | END
72 | }
73 |
74 | section {
75 | title = "Getting Started"
76 | content = <<-END
77 | Most basic usage just setting required arguments:
78 |
79 | ```hcl
80 | module "terraform-aws-vpc" {
81 | source = "mineiros-io/vpc/aws"
82 | version = "~> 0.7.0"
83 | }
84 | ```
85 | END
86 | }
87 |
88 | section {
89 | title = "Module Argument Reference"
90 | content = <<-END
91 | See [variables.tf] and [examples/] for details and use-cases.
92 | END
93 |
94 | section {
95 | title = "Main Resource Configuration"
96 |
97 | section {
98 | title = "VPC"
99 |
100 | variable "vpc_name" {
101 | type = string
102 | default = "main"
103 | description = <<-END
104 | The name of the VPC. This will be used to tag resources with names
105 | by default.
106 | END
107 | }
108 |
109 | variable "cidr_block" {
110 | type = string
111 | default = "10.0.0.0/16"
112 | description = <<-END
113 | The CIDR block for the VPC.
114 | END
115 | }
116 |
117 | variable "instance_tenancy" {
118 | type = string
119 | default = "default"
120 | description = <<-END
121 | A tenancy option for instances launched into the VPC.
122 | Setting the tenancy to `dedicated` will create additional costs: See
123 | https://aws.amazon.com/ec2/pricing/dedicated-instances/ for details.
124 | END
125 | }
126 |
127 | variable "enable_dns_support" {
128 | type = bool
129 | default = true
130 | description = <<-END
131 | A boolean flag to enable/disable DNS support in the VPC.
132 | END
133 | }
134 |
135 | variable "enable_dns_hostnames" {
136 | type = bool
137 | default = false
138 | description = <<-END
139 | A boolean flag to enable/disable DNS hostnames in the VPC.
140 | END
141 | }
142 |
143 | variable "enable_classiclink" {
144 | type = bool
145 | default = false
146 | description = <<-END
147 | A boolean flag to enable/disable ClassicLink for the VPC. Only valid
148 | in regions and accounts that support EC2 Classic. See the
149 | ClassicLink documentation for more information.
150 | END
151 | }
152 |
153 | variable "enable_classiclink_dns_support" {
154 | type = bool
155 | default = false
156 | description = <<-END
157 | A boolean flag to enable/disable ClassicLink DNS Support for the
158 | VPC. Only valid in regions and accounts that support EC2 Classic.
159 | END
160 | }
161 |
162 | variable "assign_generated_ipv6_cidr_block" {
163 | type = bool
164 | default = false
165 | description = <<-END
166 | Requests an Amazon-provided IPv6 CIDR block with a /56 prefix length
167 | for the VPC. You cannot specify the range of IP addresses, or the
168 | size of the CIDR block.
169 | END
170 | }
171 |
172 | variable "vpc_tags" {
173 | type = string
174 | default = "{}"
175 | description = <<-END
176 | A map of tags to assign to the vpc resource.
177 | To set the Name and add the capability to be used in data sources
178 | the `vpc_tags` will always be merged with:
179 | END
180 | readme_example = <<-END
181 | {
182 | Name = "{vpc_name}"
183 | "mineiros-io/aws/vpc/vpc-name" = "{vpc_name}"
184 | }
185 | END
186 | }
187 | }
188 | }
189 |
190 | section {
191 | title = "Extended Resource Configuration"
192 |
193 | section {
194 | title = "Subnets"
195 |
196 | variable "subnets" {
197 | type = list(subnet)
198 | default = []
199 | description = <<-END
200 | A List of `subnet` objects that defined the subnet setup within the
201 | VPC.
202 | END
203 | readme_example = <<-END
204 | subnets = [
205 | {
206 | group = "main"
207 | class = "public"
208 |
209 | map_public_ip_on_launch = true
210 |
211 | cidr_block = cidrsubnet("10.0.0.0/16", 4, 0)
212 | newbits = 4
213 |
214 | netnums_by_az = {
215 | a = [0] # "10.0.0.0/24"
216 | b = [1] # "10.0.1.0/24"
217 | }
218 | tags = {}
219 | },
220 | {
221 | group = "main"
222 | class = "private"
223 |
224 | map_public_ip_on_launch = false
225 |
226 | cidr_block = cidrsubnet("10.0.0.0/16", 4, 1)
227 | newbits = 4
228 |
229 | netnums_by_az = {
230 | a = [0] # "10.0.16.0/24"
231 | b = [1] # "10.0.17.0/24"
232 | }
233 | },
234 | ]
235 | END
236 |
237 | attribute "group" {
238 | type = string
239 | default = "main"
240 | description = <<-END
241 | A group name for the subnets. This can be any string. This
242 | information is used to group and tag resources within the subnets.
243 | The combination of `group` and `class` needs to be unique over all
244 | subnets defined. This can be changed at any time and will change
245 | the tags applied to resources by default.
246 | END
247 | }
248 |
249 | attribute "class" {
250 | type = string
251 | default = "private"
252 | description = <<-END
253 | The class of the subnet. This can be `"public"`, `"private"`, or
254 | "`intra`". This can be changed at any time and will change the
255 | routing of the subnet instead of recreating the subnet resource.
256 |
257 | - "public" defines a set of subnets where deployed components are
258 | reachable via the public Internet.
259 | - "private" defines a set of subnets where components are not
260 | publicly reachable but can reach the Internet.
261 | - "intra" defines a set of subnets that have no connectivity to
262 | the public Internet.
263 | END
264 | }
265 |
266 | attribute "map_public_ip_on_launch" {
267 | type = bool
268 | default = true
269 | description = <<-END
270 | Whether resources deployed into the subnet will be assigned a
271 | public IPv4 address when launched.
272 | END
273 | }
274 |
275 | attribute "cidr_block" {
276 | type = string
277 | description = <<-END
278 | Define the base CIDR Block of the subnets and the parameters to
279 | calculate each CIDR Block.
280 |
281 | Default is the CIDR Block of the VPC (`cidr_block`).
282 | END
283 | }
284 |
285 | attribute "newbits" {
286 | type = number
287 | default = 8
288 | description = <<-END
289 | How many bits should be added when calculating the subnets CIDR
290 | Blocks.
291 | END
292 | }
293 |
294 | attribute "netnums_by_az" {
295 | required = true
296 | type = map(netnums_by_az)
297 | description = <<-END
298 | Type is map(list(number)).
299 |
300 | A map of subnets keyed by availability zone suffix (a,b,c,d,e,f).
301 | The numbers define the network number with in the CIDR Block.
302 | See https://www.terraform.io/docs/configuration/functions/cidrsubnet.html
303 | for details on how this is calculated internally.
304 |
305 | Note: When adjusting cidr_block or newbits you might also need to
306 | adjust the netnums.
307 | The example shows how to deploy one subnet in availability zone
308 | `a` (`10.0.0.0/24`) and one subnet in availability zone `b`
309 | (`10.0.1.0/24`).
310 | END
311 | readme_example = <<-END
312 | cidr_block = "10.0.0.0/16"
313 | newbits = 8
314 |
315 | netnums_by_az = {
316 | a = [0] # "10.0.0.0/24"
317 | b = [1] # "10.0.1.0/24"
318 | }
319 | END
320 | }
321 |
322 | attribute "db_subnet_group_name" {
323 | type = string
324 | description = <<-END
325 | The name of a db subnet group to create for all netnum ranges in
326 | this subnet.
327 | The `db_subnet_group_name` resource tags will be cloned from the
328 | subnets.
329 | END
330 | }
331 |
332 | attribute "elasticache_subnet_group_name" {
333 | type = string
334 | description = <<-END
335 | The name of a elasticache subnet group to create for all netnum
336 | ranges in this subnet.
337 | The `elasticache_subnet_group_name` resource tags will be cloned
338 | from the subnets.
339 | END
340 | }
341 |
342 | attribute "tags" {
343 | type = map(string)
344 | default = {}
345 | description = <<-END
346 | A map of tags that will be applied to each subnet in this
347 | group-class combination.
348 | Those tags will be merged with a `Name` tag, `module_tags`,
349 | `subnet_tags` and tags for the subnet class
350 | `public_subnet_tags`, `private_subnet_tags`, or
351 | `intra_subnet_tags`.
352 |
353 | To set the Name and add the capability to be used in data
354 | sources the `subnet_tags` will always be merged with:
355 |
356 | ```hcl
357 | {
358 | Name = "{vpc_name}-{subnet.group}-{subnet.class}-{az}-{idx}"
359 | "mineiros-io/aws/vpc/vpc-name" = "{vpc_name}"
360 | "mineiros-io/aws/vpc/subnet-name" = "{vpc_name}-{subnet.group}-{subnet.class}-{az}-{idx}"
361 | "mineiros-io/aws/vpc/subnet-group" = "{subnet.group}"
362 | "mineiros-io/aws/vpc/subnet-class" = "{subnet.class}"
363 | }
364 | ```
365 | END
366 | }
367 | }
368 |
369 | variable "subnet_tags" {
370 | type = map(string)
371 | default = {}
372 | description = <<-END
373 | Tags applied to each subnet resource.
374 | END
375 | }
376 |
377 | variable "public_subnet_tags" {
378 | type = map(string)
379 | default = {}
380 | description = <<-END
381 | Tags applied to each public subnet.
382 | END
383 | }
384 |
385 | variable "private_subnet_tags" {
386 | type = map(string)
387 | default = {}
388 | description = <<-END
389 | Tags applied to each private subnet.
390 | END
391 | }
392 |
393 | variable "intra_subnet_tags" {
394 | type = map(string)
395 | default = {}
396 | description = <<-END
397 | Tags applied to each intra subnet.
398 | END
399 | }
400 | }
401 |
402 | section {
403 | title = "Internet Gateway"
404 |
405 | variable "internet_gateway_tags" {
406 | type = map(string)
407 | default = {}
408 | description = <<-END
409 | A map of tags to apply to the created Internet Gateway.
410 | An Internet Gateway is created if a public subnet is defined.
411 | All public egress and ingress traffic of all public subnets will be
412 | routed through the same Internet Gateway.
413 |
414 | To set the Name and add the capability to be used in data sources
415 | the `internet_gateway_tags` will always be merged with:
416 |
417 | ```hcl
418 | {
419 | Name = "{vpc_name}"
420 | "mineiros-io/aws/vpc/vpc-name" = "{vpc_name}"
421 | "mineiros-io/aws/vpc/igw-name" = "{vpc_name}"
422 | }
423 | ```
424 | END
425 | }
426 | }
427 |
428 | section {
429 | title = "NAT Gateways"
430 | content = <<-END
431 | > **A Note on pricing:** AWS charges for each provisioned NAT
432 | Gateway. Please see https://aws.amazon.com/vpc/pricing/ for details.
433 | > To save costs you can use `nat_gateway_mode` to define the number
434 | of NAT Gateways you want to deploy.
435 | > The best practice is to deploy one NAT Gateway per Availability
436 | Zone for higher reliability on production environments
437 | (`one_per_az`), while you can save some costs on staging and testing
438 | environments by deploying a single NAT Gateway (`single`).
439 | END
440 |
441 | variable "nat_gateway_mode" {
442 | type = string
443 | default = "single"
444 | description = <<-END
445 | Set the mode for the NAT Gateways. NAT Gateways will only be created
446 | when private subnets are defined.
447 | Each private subnet needs at least one configured public subnet in
448 | the same availability zone.
449 | Each NAT gateway will be assigned an Elastic IP Address.
450 | When changing the mode, NAT Gateways and Elastic IP Addresses will
451 | be created or destroyed.
452 | All public egress traffic of all private subnets will be routed
453 | through the same set of NAT Gateways.
454 | Possible modes are `none`, `single`, or `one_per_az`. Choose
455 |
456 | - `"none"` to create no NAT Gateways at all (use for debugging only),
457 | - `"single"` to create a single NAT Gateway inside the first defined
458 | Public Subnet, or
459 | - `"one_per_az"` to create one NAT Gateway inside the first Public
460 | Subnet in each Availability Zone.
461 | END
462 | }
463 |
464 | variable "nat_gateway_single_mode_zone" {
465 | type = string
466 | default = "a random zone"
467 | description = <<-END
468 | Define the zone (short name) of the NAT gateway when nat_gateway_mode is "single" (e.g. "a", "b", or "c").
469 | The AWS region will be added as a prefix.
470 | END
471 | }
472 |
473 | variable "nat_gateway_eip_allocation_ids" {
474 | type = map(string)
475 | description = <<-END
476 | A map of EIP allocation ids to use for nat gateways keyed by short zone name (e.g. "a", "b", or "c").
477 | If set no EIPs will be created by the module. If unset, the module will create the needed number of EIPs.
478 | END
479 | default = {}
480 | }
481 |
482 | variable "nat_gateway_tags" {
483 | type = map(string)
484 | default = {}
485 | description = <<-END
486 | A map of tags to apply to the created NAT Gateways.
487 |
488 | To set the Name and add the capability to be used in data sources
489 | the `nat_gateway_tags` will always be merged with:
490 |
491 | ```hcl
492 | {
493 | Name = "{vpc_name}-{zone}"
494 | "mineiros-io/aws/vpc/vpc-name" = "{vpc_name}"
495 | "mineiros-io/aws/vpc/natgw-name" = "{vpc_name}-{zone}"
496 | }
497 | ```
498 | END
499 | }
500 |
501 | variable "eip_tags" {
502 | type = map(string)
503 | default = {}
504 | description = <<-END
505 | A map of tags to apply to the created NAT Gateway Elastic IP
506 | Addresses.
507 |
508 | To set the Name and add the capability to be used in data sources
509 | the `eip_tags` will always be merged with:
510 |
511 | ```hcl
512 | {
513 | Name = "{vpc_name}-nat-private-{zone}"
514 | "mineiros-io/aws/vpc/vpc-name" = "{vpc_name}"
515 | "mineiros-io/aws/vpc/natgw-name" = "{vpc_name}-{zone}"
516 | "mineiros-io/aws/vpc/eip-name" = "{vpc_name}-nat-private-{zone}"
517 | }
518 | ```
519 | END
520 | }
521 | }
522 |
523 | section {
524 | title = "Subnet Routing"
525 |
526 | variable "route_table_tags" {
527 | type = map(string)
528 | default = {}
529 | description = <<-END
530 | A map of tags to apply to all created Route Tables.
531 | END
532 | }
533 |
534 | variable "public_route_table_tags" {
535 | type = map(string)
536 | default = {}
537 | description = <<-END
538 | A map of tags to apply to the created Public Route Tables.
539 |
540 | To set the Name and add the capability to be used in data sources
541 | the `public_route_table_tags` will always be merged with:
542 |
543 | ```hcl
544 | {
545 | Name = "{vpc_name}-public-{group}"
546 | "mineiros-io/aws/vpc/vpc-name" = "{vpc_name}"
547 | "mineiros-io/aws/vpc/routetable-name" = "{vpc_name}-public-{group}"
548 | "mineiros-io/aws/vpc/routetable-class" = "public"
549 | }
550 | ```
551 | END
552 | }
553 |
554 | variable "private_route_table_tags" {
555 | type = map(string)
556 | default = {}
557 | description = <<-END
558 | A map of tags to apply to the created Private Route Tables.
559 |
560 | To set the Name and add the capability to be used in data sources
561 | the `private_route_table_tags` will always be merged with:
562 |
563 | ```hcl
564 | {
565 | Name = "{vpc_name}-private-{group}-{zone}"
566 | "mineiros-io/aws/vpc/vpc-name" = "{vpc_name}"
567 | "mineiros-io/aws/vpc/routetable-name" = "{vpc_name}-private-{group}-{zone}"
568 | "mineiros-io/aws/vpc/routetable-class" = "private"
569 | }
570 | ```
571 | END
572 | }
573 |
574 | variable "intra_route_table_tags" {
575 | type = map(string)
576 | default = {}
577 | description = <<-END
578 | A map of tags to apply to the created Intra Route Tables.
579 |
580 | To set the Name and add the capability to be used in data sources
581 | the `intra_route_table_tags` will always be merged with:
582 |
583 | ```hcl
584 | {
585 | Name = "{vpc_name}-intra-{group}"
586 | "mineiros-io/aws/vpc/vpc-name" = "{vpc_name}"
587 | "mineiros-io/aws/vpc/routetable-name" = "{vpc_name}-intra-{group}"
588 | "mineiros-io/aws/vpc/routetable-class" = "intra"
589 | }
590 | ```
591 | END
592 | }
593 | }
594 | }
595 | }
596 |
597 | section {
598 | title = "Module Configuration"
599 |
600 | variable "module_enabled" {
601 | type = bool
602 | default = true
603 | description = <<-END
604 | Specifies whether resources in the module will be created.
605 | END
606 | }
607 |
608 | variable "module_tags" {
609 | type = map(string)
610 | default = {}
611 | description = <<-END
612 | A map of tags that will be applied to all created resources that
613 | accept tags. Tags defined with 'module_tags' can be
614 | overwritten by resource-specific tags.
615 | END
616 | }
617 |
618 | variable "module_depends_on" {
619 | type = list(dependency)
620 | description = <<-END
621 | A list of dependencies. Any object can be _assigned_ to this list to
622 | define a hidden external dependency.
623 | END
624 | }
625 | }
626 |
627 | section {
628 | title = "Module Outputs"
629 | content = <<-END
630 | The following attributes are exported by the module:
631 | END
632 |
633 | section {
634 | title = "Computed Attributes"
635 |
636 | output "public_subnets_by_group" {
637 | type = map(public_subnets_by_group)
638 | description = <<-END
639 | A map of lists of public subnets keyed by group. (`aws_subnet`)
640 | END
641 | }
642 |
643 | output "public_route_table_ids_by_group" {
644 | type = map(public_route_table_ids_by_group)
645 | description = <<-END
646 | A map of lists of public route table IDs keyed by group.
647 | END
648 | }
649 |
650 | output "public_subnet_ids_by_group" {
651 | type = map(public_subnet_ids_by_group)
652 | description = <<-END
653 | A map of lists of public subnet IDs keyed by group.
654 | END
655 | }
656 |
657 | output "private_subnets_by_group" {
658 | type = map(private_subnets_by_group)
659 | description = <<-END
660 | A map of lists of private subnets keyed by group. (`aws_subnet`)
661 | END
662 | }
663 |
664 | output "private_route_table_ids_by_group" {
665 | type = map(private_route_table_ids_by_group)
666 | description = <<-END
667 | A map of lists of private route table IDs keyed by group.
668 | END
669 | }
670 |
671 | output "private_subnet_ids_by_group" {
672 | type = map(private_subnet_ids_by_group)
673 | description = <<-END
674 | A map of lists of private subnet IDs keyed by group.
675 | END
676 | }
677 |
678 | output "intra_subnets_by_group" {
679 | type = map(intra_subnets_by_group)
680 | description = <<-END
681 | A map of lists of intra aws_subnet keyed by group. (`aws_subnet`)
682 | END
683 | }
684 |
685 | output "intra_route_table_ids_by_group" {
686 | type = map(intra_route_table_ids_by_group)
687 | description = <<-END
688 | A map of lists of intra route table IDs keyed by group.
689 | END
690 | }
691 |
692 | output "intra_subnet_ids_by_group" {
693 | type = map(intra_subnet_ids_by_group)
694 | description = <<-END
695 | A map of lists of intra subnet IDs keyed by group.
696 | END
697 | }
698 | }
699 |
700 | section {
701 | title = "Full Resource Objects"
702 |
703 | output "vpc" {
704 | type = object(vpc)
705 | description = <<-END
706 | The VPC. (`aws_vpc`)
707 | END
708 | }
709 |
710 | output "intra_route_tables" {
711 | type = map(intra_route_tables)
712 | description = <<-END
713 | A map of intra route tables keyed by group. (`aws_route_table`)
714 | END
715 | }
716 |
717 | output "intra_route_table_associations" {
718 | type = map(intra_route_table_associations)
719 | description = <<-END
720 | A map of intra route table associations keyed by the subnets CIDR
721 | Blocks. (`aws_route_table_association`)
722 | END
723 | }
724 |
725 | output "eips" {
726 | type = map(eips)
727 | description = <<-END
728 | A map of Elastic IP Adresses (EIPs) keyed by availability zone.
729 | (`aws_eip`)
730 | END
731 | }
732 |
733 | output "nat_gateways" {
734 | type = map(nat_gateways)
735 | description = <<-END
736 | A map of NAT gatweways keyed by availability zone.
737 | (`aws_nat_gateway`)
738 | END
739 | }
740 |
741 | output "private_route_tables" {
742 | type = map(private_route_tables)
743 | description = <<-END
744 | A map of private route tables keyed by group. (`aws_route_table`)
745 | END
746 | }
747 |
748 | output "private_route_table_associations" {
749 | type = map(private_route_table_associations)
750 | description = <<-END
751 | A map of private route table associations keyed by the subnets CIDR
752 | Blocks. (`aws_route_table_association`)
753 | END
754 | }
755 |
756 | output "routes_to_nat_gateways" {
757 | type = map(routes_to_nat_gateways)
758 | description = <<-END
759 | A map of routes to the NAT Gateways keyed by group. (`aws_route`)
760 | END
761 | }
762 |
763 | output "internet_gateway" {
764 | type = object(internet_gateway)
765 | description = <<-END
766 | The Internet Gateway. (`aws_internet_gateway`)
767 | END
768 | }
769 |
770 | output "public_route_tables" {
771 | type = map(public_route_tables)
772 | description = <<-END
773 | A map of public route tables keyed by group. (`aws_route_table`)
774 | END
775 | }
776 |
777 | output "public_route_table_associations" {
778 | type = map(public_route_table_associations)
779 | description = <<-END
780 | A map of public route table associations keyed by the subnets CIDR
781 | Blocks. (`aws_route_table_association`)
782 | END
783 | }
784 |
785 | output "routes_to_internet_gateway" {
786 | type = map(routes_to_internet_gateway)
787 | description = <<-END
788 | A map of routes to the Internet Gateway keyed by group. (`aws_route`)
789 | END
790 | }
791 |
792 | output "subnets" {
793 | type = map(subnets)
794 | description = <<-END
795 | A map of subnets keyed by CIDR Blocks. (`aws_subnet`)
796 | END
797 | }
798 | }
799 |
800 | section {
801 | title = "Module Attributes"
802 |
803 | output "module_inputs" {
804 | type = map(module_inputs)
805 | description = <<-END
806 | A map of all module arguments. Set to the provided values or calculated default values.
807 | END
808 | }
809 |
810 | output "module_enabled" {
811 | type = bool
812 | description = <<-END
813 | Whether this module is enabled.
814 | END
815 | }
816 |
817 | output "module_tags" {
818 | type = map(string)
819 | description = <<-END
820 | The map of tags that are being applied to all created resources that accept tags.
821 | END
822 | }
823 | }
824 | }
825 |
826 | section {
827 | title = "External Documentation"
828 |
829 | section {
830 | title = "AWS Documentation VPC"
831 | content = <<-END
832 | - https://aws.amazon.com/de/vpc/
833 | END
834 | }
835 |
836 | section {
837 | title = "Terraform AWS Provider Documentation:"
838 | content = <<-END
839 | - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc
840 | - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/subnet
841 | - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/internet_gateway
842 | - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/nat_gateway
843 | - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table
844 | - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table_association
845 | - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route
846 | END
847 | }
848 | }
849 |
850 | section {
851 | title = "Module Versioning"
852 | content = <<-END
853 | This Module follows the principles of [Semantic Versioning (SemVer)].
854 |
855 | Given a version number `MAJOR.MINOR.PATCH`, we increment the:
856 |
857 | 1. `MAJOR` version when we make incompatible changes,
858 | 2. `MINOR` version when we add functionality in a backwards compatible manner, and
859 | 3. `PATCH` version when we make backwards compatible bug fixes.
860 | END
861 |
862 | section {
863 | title = "Backwards compatibility in `0.0.z` and `0.y.z` version"
864 | content = <<-END
865 | - Backwards compatibility in versions `0.0.z` is **not guaranteed** when `z` is increased. (Initial development)
866 | - Backwards compatibility in versions `0.y.z` is **not guaranteed** when `y` is increased. (Pre-release)
867 | END
868 | }
869 | }
870 |
871 | section {
872 | title = "About Mineiros"
873 | content = <<-END
874 | [Mineiros][homepage] is a remote-first company headquartered in Berlin, Germany
875 | that solves development, automation and security challenges in cloud infrastructure.
876 |
877 | Our vision is to massively reduce time and overhead for teams to manage and
878 | deploy production-grade and secure cloud infrastructure.
879 |
880 | We offer commercial support for all of our modules and encourage you to reach out
881 | if you have any questions or need help. Feel free to email us at [hello@mineiros.io] or join our
882 | [Community Slack channel][slack].
883 | END
884 | }
885 |
886 | section {
887 | title = "Reporting Issues"
888 | content = <<-END
889 | We use GitHub [Issues] to track community reported issues and missing features.
890 | END
891 | }
892 |
893 | section {
894 | title = "Contributing"
895 | content = <<-END
896 | Contributions are always encouraged and welcome! For the process of accepting changes, we use
897 | [Pull Requests]. If you'd like more information, please see our [Contribution Guidelines].
898 | END
899 | }
900 |
901 | section {
902 | title = "Makefile Targets"
903 | content = <<-END
904 | This repository comes with a handy [Makefile].
905 | Run `make help` to see details on each available target.
906 | END
907 | }
908 |
909 | section {
910 | title = "License"
911 | content = <<-END
912 | [![license][badge-license]][apache20]
913 |
914 | This module is licensed under the Apache License Version 2.0, January 2004.
915 | Please see [LICENSE] for full details.
916 |
917 | Copyright © 2019-2022 [Mineiros GmbH][homepage]
918 | END
919 | }
920 | }
921 |
922 | references {
923 | ref "homepage" {
924 | value = "https://mineiros.io/?ref=terraform-aws-vpc"
925 | }
926 | ref "hello@mineiros.io" {
927 | value = "mailto:hello@mineiros.io"
928 | }
929 | ref "badge-build" {
930 | value = "https://github.com/mineiros-io/terraform-aws-vpc/workflows/CI/CD%20Pipeline/badge.svg"
931 | }
932 | ref "badge-semver" {
933 | value = "https://img.shields.io/github/v/tag/mineiros-io/terraform-aws-vpc.svg?label=latest&sort=semver"
934 | }
935 | ref "badge-license" {
936 | value = "https://img.shields.io/badge/license-Apache%202.0-brightgreen.svg"
937 | }
938 | ref "badge-terraform" {
939 | value = "https://img.shields.io/badge/terraform-1.x%20|%200.15%20|%200.14%20|%200.13%20|%200.12.20+-623CE4.svg?logo=terraform"
940 | }
941 | ref "badge-slack" {
942 | value = "https://img.shields.io/badge/slack-@mineiros--community-f32752.svg?logo=slack"
943 | }
944 | ref "build-status" {
945 | value = "https://github.com/mineiros-io/terraform-aws-vpc/actions"
946 | }
947 | ref "releases-github" {
948 | value = "https://github.com/mineiros-io/terraform-aws-vpc/releases"
949 | }
950 | ref "badge-tf-aws" {
951 | value = "https://img.shields.io/badge/AWS-3%20and%202.45+-F8991D.svg?logo=terraform"
952 | }
953 | ref "releases-aws-provider" {
954 | value = "https://github.com/terraform-providers/terraform-provider-aws/releases"
955 | }
956 | ref "releases-terraform" {
957 | value = "https://github.com/hashicorp/terraform/releases"
958 | }
959 | ref "apache20" {
960 | value = "https://opensource.org/licenses/Apache-2.0"
961 | }
962 | ref "slack" {
963 | value = "https://join.slack.com/t/mineiros-community/shared_invite/zt-ehidestg-aLGoIENLVs6tvwJ11w9WGg"
964 | }
965 | ref "terraform" {
966 | value = "https://www.terraform.io"
967 | }
968 | ref "aws" {
969 | value = "https://aws.amazon.com/"
970 | }
971 | ref "semantic versioning (semver)" {
972 | value = "https://semver.org/"
973 | }
974 | ref "variables.tf" {
975 | value = "https://github.com/mineiros-io/terraform-aws-vpc/blob/master/variables.tf"
976 | }
977 | ref "examples/" {
978 | value = "https://github.com/mineiros-io/terraform-aws-vpc/blob/master/examples"
979 | }
980 | ref "issues" {
981 | value = "https://github.com/mineiros-io/terraform-aws-vpc/issues"
982 | }
983 | ref "license" {
984 | value = "https://github.com/mineiros-io/terraform-aws-vpc/blob/master/LICENSE"
985 | }
986 | ref "makefile" {
987 | value = "https://github.com/mineiros-io/terraform-aws-vpc/blob/master/Makefile"
988 | }
989 | ref "pull requests" {
990 | value = "https://github.com/mineiros-io/terraform-aws-vpc/pulls"
991 | }
992 | ref "contribution guidelines" {
993 | value = "https://github.com/mineiros-io/terraform-aws-vpc/blob/master/CONTRIBUTING.md"
994 | }
995 | }
996 |
--------------------------------------------------------------------------------
/db_subnet_group.tf:
--------------------------------------------------------------------------------
1 | locals {
2 | subnets_with_db_subnet_group = { for subnet in var.subnets : subnet.db_subnet_group_name => subnet if can(subnet.db_subnet_group_name) }
3 | }
4 |
5 | resource "aws_db_subnet_group" "db_subnet_group" {
6 | for_each = local.subnets_with_db_subnet_group
7 |
8 | name = each.key
9 | subnet_ids = [for subnet in local.subnets : aws_subnet.subnet[subnet.cidr_block].id if subnet.db_subnet_group_name == each.key]
10 | description = try(each.value.description, "Managed by mineiros-io/vpc/aws Terraform Module")
11 |
12 | tags = merge(var.module_tags, try(each.value.tags, {}))
13 | }
14 |
--------------------------------------------------------------------------------
/elasticache_subnet_group.tf:
--------------------------------------------------------------------------------
1 | locals {
2 | subnets_with_elasticache_subnet_group = { for subnet in var.subnets : subnet.elasticache_subnet_group_name => subnet if can(subnet.elasticache_subnet_group_name) }
3 | }
4 |
5 | resource "aws_elasticache_subnet_group" "elasticache_subnet_group" {
6 | for_each = local.subnets_with_elasticache_subnet_group
7 |
8 | name = each.key
9 | subnet_ids = [for subnet in local.subnets : aws_subnet.subnet[subnet.cidr_block].id if subnet.elasticache_subnet_group_name == each.key]
10 | description = try(each.value.description, "Managed by mineiros-io/vpc/aws Terraform Module")
11 |
12 | tags = merge(var.module_tags, try(each.value.tags, {}))
13 | }
14 |
--------------------------------------------------------------------------------
/examples/README.md:
--------------------------------------------------------------------------------
1 | [
][homepage]
2 |
3 | [![GitHub tag (latest SemVer)][badge-semver]][releases-github]
4 | [![license][badge-license]][apache20]
5 | [![Terraform Version][badge-terraform]][releases-terraform]
6 | [![Join Slack][badge-slack]][slack]
7 |
8 | # Examples for using this Mineiros module
9 |
10 | - [complete-example/] Deploy a VPC with a private and public subnet spanned over two availability zones.
11 |
12 |
13 | [complete-example/]: https://github.com/mineiros-io/terraform-aws-vpc/blob/master/examples/complete-example
14 |
15 | [homepage]: https://mineiros.io/?ref=terraform-aws-vpc
16 |
17 | [badge-license]: https://img.shields.io/badge/license-Apache%202.0-brightgreen.svg
18 | [badge-terraform]: https://img.shields.io/badge/terraform-1.x%20|%200.15%20|%200.14%20|%200.13%20|%200.12.20+-623CE4.svg?logo=terraform
19 | [badge-slack]: https://img.shields.io/badge/slack-@mineiros--community-f32752.svg?logo=slack
20 | [badge-semver]: https://img.shields.io/github/v/tag/mineiros-io/terraform-aws-vpc.svg?label=latest&sort=semver
21 |
22 | [releases-github]: https://github.com/mineiros-io/terraform-aws-vpc/releases
23 | [releases-terraform]: https://github.com/hashicorp/terraform/releases
24 | [apache20]: https://opensource.org/licenses/Apache-2.0
25 | [slack]: https://join.slack.com/t/mineiros-community/shared_invite/zt-ehidestg-aLGoIENLVs6tvwJ11w9WGg
26 |
--------------------------------------------------------------------------------
/examples/complete-example/README.md:
--------------------------------------------------------------------------------
1 | [
][homepage]
2 |
3 | [![license][badge-license]][apache20]
4 | [![Terraform Version][badge-terraform]][releases-terraform]
5 | [![Join Slack][badge-slack]][slack]
6 |
7 | # What this example shows
8 |
9 | This example shows how to deploy a VPC with a private and public subnet spanned over two availability zones.
10 |
11 | ## Basic usage
12 |
13 | See the code in [main.tf] to see the implementation details.
14 |
15 | ## Running the example
16 |
17 | ### Cloning the repository
18 |
19 | ```bash
20 | git clone https://github.com/mineiros-io/terraform-aws-vpc.git
21 | cd terraform-aws-vpc/examples/complete-example
22 | ```
23 |
24 | ### Initializing Terraform
25 |
26 | Run `terraform init` to initialize the example and download providers and the module.
27 |
28 | ### Planning the example
29 |
30 | Run `terraform plan` to see a plan of the changes.
31 |
32 | ### Applying the example
33 |
34 | Run `terraform apply` to create the resources.
35 | You will see a plan of the changes and Terraform will prompt you for approval to actually apply the changes.
36 |
37 | ### Destroying the example
38 |
39 | Run `terraform destroy` to destroy all resources again.
40 |
41 |
42 |
43 | [main.tf]: https://github.com/mineiros-io/terraform-aws-vpc/blob/master/examples/complete-example/main.tf
44 |
45 | [homepage]: https://mineiros.io/?ref=terraform-aws-vpc
46 |
47 | [badge-license]: https://img.shields.io/badge/license-Apache%202.0-brightgreen.svg
48 | [badge-terraform]: https://img.shields.io/badge/terraform-1.x%20|%200.15%20|%200.14%20|%200.13%20|%200.12.20+-623CE4.svg?logo=terraform
49 | [badge-slack]: https://img.shields.io/badge/slack-@mineiros--community-f32752.svg?logo=slack
50 |
51 | [releases-terraform]: https://github.com/hashicorp/terraform/releases
52 | [apache20]: https://opensource.org/licenses/Apache-2.0
53 | [slack]: https://join.slack.com/t/mineiros-community/shared_invite/zt-ehidestg-aLGoIENLVs6tvwJ11w9WGg
54 |
--------------------------------------------------------------------------------
/examples/complete-example/main.tf:
--------------------------------------------------------------------------------
1 | # ---------------------------------------------------------------------------------------------------------------------
2 | # CREATE AN EXAMPLE VPC WITH SUBNETS, INTERNET- AND NAT GATEWAYS
3 | # ---------------------------------------------------------------------------------------------------------------------
4 |
5 | locals {
6 | cidr_block = "10.0.0.0/16"
7 | }
8 |
9 | module "vpc" {
10 | source = "mineiros-io/vpc/aws"
11 | version = "~> 0.7.0"
12 |
13 | module_enabled = true
14 |
15 | vpc_name = "main"
16 | cidr_block = local.cidr_block
17 |
18 | # Define a mode on how to deploy NAT gateways for private networks.
19 | # Valid values are:
20 | # - "single" to create a single NAT gateway in the first availability zone to route all private traffic to
21 | # - "one_per_az" to create a NAT gateway per availability zone that has a private subnet. This needs a public subnets in the same AZs.
22 | nat_gateway_mode = "single"
23 |
24 | nat_gateway_single_mode_zone = "a"
25 |
26 | subnets = [
27 | {
28 | # define a group name for the subnets. This can be any string. Default is "main".
29 | group = "main"
30 |
31 | # Class of the subnet: Default is "private".
32 | # - "public" defines a set of subnets where deployed components can be reachable via the public internet.
33 | # - "private" defines a set subnets where components are not publicly reachable but can reach the internet.
34 | # - "intra" (in development) defines a set of subnets that has not connectivity to the public internet.
35 | class = "public"
36 |
37 | # defines whether components deployed into the subnet will be assigned a public IPv4 address when launched.
38 | map_public_ip_on_launch = true
39 |
40 | # Define the base CIDR Block of the subnets and the parameters to calculate each CIDR Block. Default is the VPC CIDR Block.
41 | # This example: devide the VPC CIDR Block into 2^4 = 16 blocks and use the first block as a base for all subnets
42 | # Add 4 bits to the prefix of "10.0.0.0/16" results in "10.0.0.0/20".
43 | cidr_block = cidrsubnet(local.cidr_block, 4, 0)
44 |
45 | # How many bits should be added when calculating the subnets CIDR Blocks. Default is 8.
46 | # This example: For each subnet add another 4 bits to the prefix, so each netnum will result in:
47 | # netnum=0 => subnet_cidr_block="10.0.0.0/24"
48 | # netnum=1 => subnet_cidr_block="10.0.1.0/24"
49 | # ...
50 | # netnum=15 => subnet_cidr_block="10.0.15.0/24"
51 | newbits = 4
52 |
53 | # A map of subnets keyed by availability zone suffix. The Number defined the network number with in the CIDR Block.
54 | # see https://www.terraform.io/docs/configuration/functions/cidrsubnet.html for details on how this is calculated internally
55 | # Note: When adjusting cidr_block or newbits you might also need to adjust the netnums.
56 | # This Example: Deploy one subnet in availability zone "a" ("10.0.0.0/24") and one subnet in availability zone "b" ("10.0.1.0/24")
57 | netnums_by_az = {
58 | a = [0] # "10.0.0.0/24"
59 | b = [1] # "10.0.1.0/24"
60 | }
61 |
62 | # A map of tags that will be applied to this Subnet.
63 | # A "Name" tag of the format '----' (idx is the index in the list of netnums)
64 | # will be applied automatically but can be overwritten.
65 | # The Name tag will be merged with var.module_tags, var.subnet_tags, tags
66 | tags = {
67 | }
68 | },
69 | {
70 | group = "main"
71 | class = "private"
72 |
73 | # use the second network block for private subnets: "10.0.16.0/20"
74 | #
75 | cidr_block = cidrsubnet(local.cidr_block, 4, 1)
76 |
77 | # Add another 4 bits when calculatin actual subnet cidr blocks (see above)
78 | newbits = 4
79 |
80 | # create four private networks in three availability zones
81 | # AZ a: "10.0.16.0/24"
82 | # AZ b: "10.0.17.0/24" and "10.0.20.0/24"
83 | # AZ c: "10.0.18.0/24"
84 | netnums_by_az = {
85 | a = [0]
86 | b = [1, 4]
87 | c = [2]
88 | }
89 | },
90 | ]
91 | }
92 |
93 | provider "aws" {
94 | region = "eu-west-1"
95 | }
96 |
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/mineiros-io/terraform-module-vpc
2 |
3 | go 1.14
4 |
5 | require (
6 | github.com/gruntwork-io/terratest v0.37.0
7 | github.com/stretchr/testify v1.4.0
8 | )
9 |
10 |
--------------------------------------------------------------------------------
/go.sum:
--------------------------------------------------------------------------------
1 | cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
2 | cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
3 | cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
4 | cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
5 | cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
6 | cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
7 | cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
8 | cloud.google.com/go v0.51.0/go.mod h1:hWtGJ6gnXH+KgDv+V0zFGDvpi07n3z8ZNj3T1RW0Gcw=
9 | cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
10 | cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
11 | cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
12 | cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
13 | dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
14 | github.com/Azure/azure-sdk-for-go v35.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
15 | github.com/Azure/azure-sdk-for-go v38.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
16 | github.com/Azure/azure-sdk-for-go v46.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
17 | github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
18 | github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
19 | github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
20 | github.com/Azure/go-autorest/autorest v0.9.3/go.mod h1:GsRuLYvwzLjjjRoWEIyMUaYq8GNUx2nRB378IPt/1p0=
21 | github.com/Azure/go-autorest/autorest v0.9.6/go.mod h1:/FALq9T/kS7b5J5qsQ+RSTUdAmGFqi0vUdVNNx8q630=
22 | github.com/Azure/go-autorest/autorest v0.11.0/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw=
23 | github.com/Azure/go-autorest/autorest v0.11.5/go.mod h1:foo3aIXRQ90zFve3r0QiDsrjGDUwWhKl0ZOQy1CT14k=
24 | github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
25 | github.com/Azure/go-autorest/autorest/adal v0.8.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc=
26 | github.com/Azure/go-autorest/autorest/adal v0.8.1/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q=
27 | github.com/Azure/go-autorest/autorest/adal v0.8.2/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q=
28 | github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg=
29 | github.com/Azure/go-autorest/autorest/adal v0.9.2/go.mod h1:/3SMAM86bP6wC9Ev35peQDUeqFZBMH07vvUOmg4z/fE=
30 | github.com/Azure/go-autorest/autorest/azure/auth v0.5.1/go.mod h1:ea90/jvmnAwDrSooLH4sRIehEPtG/EPUXavDh31MnA4=
31 | github.com/Azure/go-autorest/autorest/azure/cli v0.4.0/go.mod h1:JljT387FplPzBA31vUcvsetLKF3pec5bdAxjVU4kI2s=
32 | github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA=
33 | github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g=
34 | github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74=
35 | github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
36 | github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
37 | github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM=
38 | github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
39 | github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
40 | github.com/Azure/go-autorest/autorest/to v0.2.0/go.mod h1:GunWKJp1AEqgMaGLV+iocmRAJWqST1wQYhyyjXJ3SJc=
41 | github.com/Azure/go-autorest/autorest/to v0.3.0/go.mod h1:MgwOyqaIuKdG4TL/2ywSsIWKAfJfgHDo8ObuUk3t5sA=
42 | github.com/Azure/go-autorest/autorest/validation v0.1.0/go.mod h1:Ha3z/SqBeaalWQvokg3NZAlQTalVMtOIAs1aGK7G6u8=
43 | github.com/Azure/go-autorest/autorest/validation v0.3.0/go.mod h1:yhLgjC0Wda5DYXl6JAsWyUe4KVNffhoDhG0zVzUMo3E=
44 | github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc=
45 | github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
46 | github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
47 | github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
48 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
49 | github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
50 | github.com/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20190822182118-27a4ced34534/go.mod h1:iroGtC8B3tQiqtds1l+mgk/BBOrxbqjH+eUfFQYRc14=
51 | github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
52 | github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
53 | github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
54 | github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
55 | github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
56 | github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
57 | github.com/agext/levenshtein v1.2.1 h1:QmvMAjj2aEICytGiWzmxoE0x2KZvE0fvmqMOfy2tjT8=
58 | github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
59 | github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
60 | github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
61 | github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM=
62 | github.com/apparentlymart/go-textseg v1.0.0 h1:rRmlIsPEEhUTIKQb7T++Nz/A5Q6C9IuX2wFoYVvnCs0=
63 | github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk=
64 | github.com/apparentlymart/go-textseg/v12 v12.0.0 h1:bNEQyAGak9tojivJNkoqWErVCQbjdL7GzRt3F8NvfJ0=
65 | github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec=
66 | github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
67 | github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
68 | github.com/aws/aws-sdk-go v1.16.26/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
69 | github.com/aws/aws-sdk-go v1.27.1/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
70 | github.com/aws/aws-sdk-go v1.38.28/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
71 | github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
72 | github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
73 | github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
74 | github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
75 | github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
76 | github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
77 | github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
78 | github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
79 | github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
80 | github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
81 | github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
82 | github.com/containerd/containerd v1.3.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
83 | github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
84 | github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
85 | github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
86 | github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
87 | github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
88 | github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
89 | github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
90 | github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
91 | github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
92 | github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
93 | github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
94 | github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
95 | github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
96 | github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
97 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
98 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
99 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
100 | github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
101 | github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8=
102 | github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
103 | github.com/docker/cli v0.0.0-20191017083524-a8ff7f821017/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
104 | github.com/docker/cli v0.0.0-20200109221225-a4f60165b7a3/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
105 | github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
106 | github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
107 | github.com/docker/docker v1.4.2-0.20190924003213-a8608b5b67c7/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
108 | github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y=
109 | github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
110 | github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
111 | github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
112 | github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
113 | github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
114 | github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
115 | github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
116 | github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
117 | github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
118 | github.com/elazarl/goproxy v0.0.0-20190911111923-ecfe977594f1/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM=
119 | github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8=
120 | github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
121 | github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
122 | github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
123 | github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
124 | github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
125 | github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
126 | github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
127 | github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
128 | github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
129 | github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
130 | github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
131 | github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
132 | github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
133 | github.com/go-errors/errors v1.0.2-0.20180813162953-d98b870cc4e0/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
134 | github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
135 | github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
136 | github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
137 | github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
138 | github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
139 | github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0=
140 | github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
141 | github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
142 | github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg=
143 | github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
144 | github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
145 | github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc=
146 | github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
147 | github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I=
148 | github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
149 | github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
150 | github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
151 | github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
152 | github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
153 | github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
154 | github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
155 | github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
156 | github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
157 | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
158 | github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
159 | github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
160 | github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
161 | github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
162 | github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
163 | github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
164 | github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
165 | github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
166 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
167 | github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
168 | github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
169 | github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
170 | github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
171 | github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
172 | github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
173 | github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
174 | github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
175 | github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
176 | github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
177 | github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
178 | github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
179 | github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
180 | github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
181 | github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
182 | github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
183 | github.com/google/go-containerregistry v0.0.0-20200110202235-f4fb41bf00a3/go.mod h1:2wIuQute9+hhWqvL3vEI7YB0EKluF4WcPzI1eAliazk=
184 | github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
185 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
186 | github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
187 | github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
188 | github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
189 | github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
190 | github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
191 | github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
192 | github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
193 | github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
194 | github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
195 | github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
196 | github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
197 | github.com/googleapis/gnostic v0.2.2/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
198 | github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg=
199 | github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
200 | github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
201 | github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
202 | github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
203 | github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
204 | github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
205 | github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
206 | github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
207 | github.com/gruntwork-io/go-commons v0.8.0/go.mod h1:gtp0yTtIBExIZp7vyIV9I0XQkVwiQZze678hvDXof78=
208 | github.com/gruntwork-io/terratest v0.37.0 h1:sID4/hCjcF5vmjXiU0y71bMQVO458ylYFZk/mxDBTxo=
209 | github.com/gruntwork-io/terratest v0.37.0/go.mod h1:3zzDkmFBGDcSwQRaXS/LKnobwnff09oo5z/B6SVwRy8=
210 | github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
211 | github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
212 | github.com/hashicorp/go-multierror v1.1.0 h1:B9UzwGQJehnUY1yNrnwREHc3fGbC2xefo8g4TbElacI=
213 | github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA=
214 | github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
215 | github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
216 | github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
217 | github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
218 | github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
219 | github.com/hashicorp/hcl/v2 v2.8.2 h1:wmFle3D1vu0okesm8BTLVDyJ6/OL9DCLUwn0b2OptiY=
220 | github.com/hashicorp/hcl/v2 v2.8.2/go.mod h1:bQTN5mpo+jewjJgh8jr0JUguIi7qPHUF6yIfAEN3jqY=
221 | github.com/hashicorp/terraform-json v0.12.0 h1:8czPgEEWWPROStjkWPUnTQDXmpmZPlkQAwYYLETaTvw=
222 | github.com/hashicorp/terraform-json v0.12.0/go.mod h1:pmbq9o4EuL43db5+0ogX10Yofv1nozM+wskr/bGFJpI=
223 | github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
224 | github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
225 | github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
226 | github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
227 | github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
228 | github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a h1:zPPuIq2jAWWPTrGt70eK/BSch+gFAGrNzecsoENgu2o=
229 | github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a/go.mod h1:yL958EeXv8Ylng6IfnvG4oflryUi3vgA3xPs9hmII1s=
230 | github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
231 | github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
232 | github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
233 | github.com/joefitzgerald/rainbow-reporter v0.1.0/go.mod h1:481CNgqmVHQZzdIbN52CupLJyoVwB10FQ/IQlF1pdL8=
234 | github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
235 | github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
236 | github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
237 | github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
238 | github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
239 | github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
240 | github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
241 | github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
242 | github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
243 | github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
244 | github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
245 | github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
246 | github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
247 | github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
248 | github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
249 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
250 | github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
251 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
252 | github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
253 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
254 | github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k=
255 | github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
256 | github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
257 | github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
258 | github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
259 | github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
260 | github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
261 | github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
262 | github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
263 | github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
264 | github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
265 | github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
266 | github.com/mattn/go-zglob v0.0.1/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo=
267 | github.com/mattn/go-zglob v0.0.2-0.20190814121620-e3c945676326/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo=
268 | github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
269 | github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88Jz2VyhSmden33/aXg4oVIY=
270 | github.com/miekg/dns v1.1.31/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
271 | github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
272 | github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
273 | github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 h1:DpOJ2HYzCv8LZP15IdmG+YdwD2luVPHITV96TkirNBM=
274 | github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
275 | github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
276 | github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
277 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
278 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
279 | github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
280 | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
281 | github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
282 | github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
283 | github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
284 | github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
285 | github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
286 | github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
287 | github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
288 | github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
289 | github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
290 | github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
291 | github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
292 | github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
293 | github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
294 | github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
295 | github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
296 | github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
297 | github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
298 | github.com/oracle/oci-go-sdk v7.1.0+incompatible/go.mod h1:VQb79nF8Z2cwLkLS35ukwStZIg5F66tcBccjip/j888=
299 | github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
300 | github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
301 | github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
302 | github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
303 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
304 | github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
305 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
306 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
307 | github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
308 | github.com/pquerna/otp v1.2.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg=
309 | github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
310 | github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
311 | github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
312 | github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
313 | github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
314 | github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
315 | github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
316 | github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
317 | github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M=
318 | github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
319 | github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc=
320 | github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
321 | github.com/rubiojr/go-vhd v0.0.0-20160810183302-0bfd3b39853c/go.mod h1:DM5xW0nvfNNm2uytzsvhI3OnX8uzaRAg8UX/CnDqbto=
322 | github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
323 | github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
324 | github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
325 | github.com/sclevine/spec v1.2.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24q7p+U=
326 | github.com/sebdah/goldie v1.0.0/go.mod h1:jXP4hmWywNEwZzhMuv2ccnqTSFpuq8iyQhtQdkkZBH4=
327 | github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
328 | github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
329 | github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
330 | github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
331 | github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
332 | github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
333 | github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
334 | github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
335 | github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
336 | github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
337 | github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
338 | github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
339 | github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
340 | github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
341 | github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
342 | github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
343 | github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
344 | github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
345 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
346 | github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
347 | github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
348 | github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
349 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
350 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
351 | github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
352 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
353 | github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
354 | github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
355 | github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
356 | github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
357 | github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
358 | github.com/vdemeester/k8s-pkg-credentialprovider v0.0.0-20200107171650-7c61ffa44238/go.mod h1:JwQJCMWpUDqjZrB5jpw0f5VbN7U95zxFy1ZDpoEarGo=
359 | github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
360 | github.com/vmware/govmomi v0.20.3/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU=
361 | github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
362 | github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
363 | github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
364 | github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8=
365 | github.com/zclconf/go-cty v1.2.1 h1:vGMsygfmeCl4Xb6OA5U5XVAaQZ69FvoG7X2jUtQujb8=
366 | github.com/zclconf/go-cty v1.2.1/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8=
367 | go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
368 | go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
369 | go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
370 | go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
371 | go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
372 | go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
373 | go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
374 | go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
375 | golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
376 | golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
377 | golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
378 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
379 | golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
380 | golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
381 | golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
382 | golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
383 | golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
384 | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
385 | golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
386 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
387 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
388 | golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
389 | golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
390 | golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
391 | golang.org/x/exp v0.0.0-20190312203227-4b39c73a6495/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
392 | golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
393 | golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
394 | golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
395 | golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
396 | golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
397 | golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
398 | golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
399 | golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
400 | golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
401 | golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
402 | golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
403 | golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
404 | golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
405 | golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
406 | golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
407 | golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
408 | golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
409 | golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
410 | golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
411 | golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
412 | golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
413 | golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
414 | golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
415 | golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
416 | golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
417 | golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
418 | golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
419 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
420 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
421 | golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
422 | golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
423 | golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
424 | golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
425 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
426 | golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
427 | golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
428 | golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
429 | golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
430 | golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
431 | golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
432 | golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
433 | golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
434 | golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
435 | golang.org/x/net v0.0.0-20201110031124-69a78807bb2b h1:uwuIcX0g4Yl1NC5XAz37xsr2lTtcqevgzYNVt49waME=
436 | golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
437 | golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
438 | golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
439 | golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
440 | golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
441 | golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
442 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
443 | golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
444 | golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
445 | golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
446 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
447 | golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
448 | golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
449 | golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
450 | golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
451 | golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
452 | golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
453 | golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
454 | golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
455 | golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
456 | golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
457 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
458 | golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
459 | golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
460 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
461 | golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
462 | golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
463 | golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
464 | golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
465 | golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
466 | golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
467 | golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
468 | golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
469 | golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
470 | golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
471 | golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
472 | golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
473 | golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
474 | golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
475 | golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
476 | golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
477 | golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
478 | golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA=
479 | golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
480 | golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
481 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
482 | golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
483 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
484 | golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
485 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
486 | golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
487 | golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
488 | golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
489 | golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
490 | golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
491 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
492 | golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
493 | golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
494 | golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
495 | golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
496 | golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
497 | golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
498 | golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
499 | golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
500 | golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
501 | golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
502 | golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
503 | golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
504 | golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
505 | golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
506 | golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
507 | golang.org/x/tools v0.0.0-20190706070813-72ffa07ba3db/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI=
508 | golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
509 | golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
510 | golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
511 | golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
512 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
513 | golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
514 | golang.org/x/tools v0.0.0-20191205215504-7b8c8591a921/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
515 | golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
516 | golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
517 | golang.org/x/tools v0.0.0-20201110201400-7099162a900a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
518 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
519 | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
520 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
521 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
522 | gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0=
523 | gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
524 | gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ=
525 | google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
526 | google.golang.org/api v0.6.1-0.20190607001116-5213b8090861/go.mod h1:btoxGiFvQNVUZQ8W08zLtrVS08CNpINPEfxXxgJL1Q4=
527 | google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
528 | google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
529 | google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
530 | google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
531 | google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
532 | google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
533 | google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
534 | google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
535 | google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
536 | google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
537 | google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
538 | google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
539 | google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
540 | google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
541 | google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
542 | google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
543 | google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
544 | google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
545 | google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
546 | google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
547 | google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
548 | google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
549 | google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
550 | google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
551 | google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA=
552 | google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
553 | google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
554 | google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
555 | google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
556 | google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
557 | google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
558 | google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
559 | google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
560 | google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
561 | google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
562 | google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
563 | gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
564 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
565 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
566 | gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
567 | gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
568 | gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
569 | gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
570 | gopkg.in/gcfg.v1 v1.2.0/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
571 | gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
572 | gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
573 | gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
574 | gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
575 | gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
576 | gopkg.in/warnings.v0 v0.1.1/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
577 | gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
578 | gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
579 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
580 | gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
581 | gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
582 | gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
583 | gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
584 | honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
585 | honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
586 | honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
587 | honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
588 | honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
589 | k8s.io/api v0.17.0/go.mod h1:npsyOePkeP0CPwyGfXDHxvypiYMJxBWAMpQxCaJ4ZxI=
590 | k8s.io/api v0.19.3/go.mod h1:VF+5FT1B74Pw3KxMdKyinLo+zynBaMBiAfGMuldcNDs=
591 | k8s.io/apimachinery v0.17.0/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg=
592 | k8s.io/apimachinery v0.19.3/go.mod h1:DnPGDnARWFvYa3pMHgSxtbZb7gpzzAZ1pTfaUNDVlmA=
593 | k8s.io/apiserver v0.17.0/go.mod h1:ABM+9x/prjINN6iiffRVNCBR2Wk7uY4z+EtEGZD48cg=
594 | k8s.io/client-go v0.17.0/go.mod h1:TYgR6EUHs6k45hb6KWjVD6jFZvJV4gHDikv/It0xz+k=
595 | k8s.io/client-go v0.19.3/go.mod h1:+eEMktZM+MG0KO+PTkci8xnbCZHvj9TqR6Q1XDUIJOM=
596 | k8s.io/cloud-provider v0.17.0/go.mod h1:Ze4c3w2C0bRsjkBUoHpFi+qWe3ob1wI2/7cUn+YQIDE=
597 | k8s.io/code-generator v0.0.0-20191121015212-c4c8f8345c7e/go.mod h1:DVmfPQgxQENqDIzVR2ddLXMH34qeszkKSdH/N+s+38s=
598 | k8s.io/component-base v0.17.0/go.mod h1:rKuRAokNMY2nn2A6LP/MiwpoaMRHpfRnrPaUJJj1Yoc=
599 | k8s.io/csi-translation-lib v0.17.0/go.mod h1:HEF7MEz7pOLJCnxabi45IPkhSsE/KmxPQksuCrHKWls=
600 | k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
601 | k8s.io/gengo v0.0.0-20190822140433-26a664648505/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
602 | k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
603 | k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
604 | k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
605 | k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
606 | k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
607 | k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
608 | k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E=
609 | k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o=
610 | k8s.io/legacy-cloud-providers v0.17.0/go.mod h1:DdzaepJ3RtRy+e5YhNtrCYwlgyK87j/5+Yfp0L9Syp8=
611 | k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
612 | k8s.io/utils v0.0.0-20200729134348-d5654de09c73/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
613 | modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw=
614 | modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk=
615 | modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k=
616 | modernc.org/strutil v1.0.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs=
617 | modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I=
618 | rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
619 | sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
620 | sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06/go.mod h1:/ULNhyfzRopfcjskuui0cTITekDduZ7ycKN3oUT9R18=
621 | sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
622 | sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
623 | sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
624 |
--------------------------------------------------------------------------------
/intra_routing.tf:
--------------------------------------------------------------------------------
1 | # ---------------------------------------------------------------------------------------------------------------------
2 | # CREATE intra ROUTING AND AN INTERNET GATEWAY IF A intra SUBNETS IS DEFINED
3 | # ---------------------------------------------------------------------------------------------------------------------
4 |
5 | locals {
6 | intra_subnets = [for subnet in local.subnets : subnet if subnet.class == "intra"]
7 |
8 | intra_groups = try(distinct(local.intra_subnets.*.group), [])
9 |
10 | intra_subnets_by_group = {
11 | for group in local.intra_groups : group => [
12 | for subnet in local.intra_subnets : subnet if subnet.group == group
13 | ]
14 | }
15 | }
16 |
17 | resource "aws_route_table" "intra" {
18 | for_each = var.module_enabled ? local.intra_subnets_by_group : {}
19 |
20 | vpc_id = aws_vpc.vpc[0].id
21 |
22 | # propagating_vgws = try(local.subnets[each.key].propagating_vgws, null)
23 |
24 | tags = merge(
25 | {
26 | Name = "${var.vpc_name}-intra-${each.key}"
27 |
28 | # special mineiros.io tags that can be used in data sources
29 | "mineiros-io/aws/vpc/vpc-name" = var.vpc_name
30 | "mineiros-io/aws/vpc/routetable-name" = "${var.vpc_name}-intra-${each.key}"
31 | "mineiros-io/aws/vpc/routetable-class" = "intra"
32 | },
33 | var.module_tags,
34 | var.route_table_tags,
35 | var.intra_route_table_tags,
36 | )
37 |
38 | depends_on = [var.module_depends_on]
39 | }
40 |
41 | resource "aws_route_table_association" "intra" {
42 | for_each = var.module_enabled ? {
43 | for subnet in flatten(values(local.intra_subnets_by_group)) : subnet.cidr_block => subnet
44 | } : {}
45 |
46 | subnet_id = aws_subnet.subnet[each.key].id
47 | route_table_id = aws_route_table.intra[each.value.group].id
48 |
49 | depends_on = [var.module_depends_on]
50 | }
51 |
--------------------------------------------------------------------------------
/main.tf:
--------------------------------------------------------------------------------
1 | # ---------------------------------------------------------------------------------------------------------------------
2 | # DEPLOY AND MANAGE A VPC
3 | # ---------------------------------------------------------------------------------------------------------------------
4 |
5 | # ---------------------------------------------------------------------------------------------------------------------
6 | # When you create a VPC, we recommend that you specify a CIDR block (of /16 or smaller) from the private IPv4 address
7 | # ranges as specified in RFC 1918 (http://www.faqs.org/rfcs/rfc1918.html):
8 | # - 10.0.0.0 - 10.255.255.255 (10/8 prefix)
9 | # - 172.16.0.0 - 172.31.255.255 (172.16/12 prefix)
10 | # - 192.168.0.0 - 192.168.255.255 (192.168/16 prefix)
11 | #
12 | # The first four IP addresses and the last IP address in each subnet CIDR block are not available for you to use, and
13 | # cannot be assigned to an instance. For example, in a subnet with CIDR block 10.0.0.0/24, the following five IP
14 | # addresses are reserved:
15 | # - 10.0.0.0: Network address.
16 | # - 10.0.0.1: Reserved by AWS for the VPC router.
17 | # - 10.0.0.2: Reserved by AWS. The IP address of the DNS server is the base of the VPC network range plus two.
18 | # ---------------------------------------------------------------------------------------------------------------------
19 |
20 | data "aws_region" "region" {
21 | count = var.module_enabled ? 1 : 0
22 | }
23 |
24 | locals {
25 | region = try(data.aws_region.region[0].name, "")
26 | }
27 |
28 | resource "aws_vpc" "vpc" {
29 | count = var.module_enabled ? 1 : 0
30 |
31 | # We convert the cidr_block to its cannonical form because AWS would do it in the API anyway
32 | # and we want to ensure this is not showing a constant change when planning.
33 | # We will do the same for all created subnets.
34 | # We will do the same for all created routes.
35 | cidr_block = cidrsubnet(var.cidr_block, 0, 0)
36 |
37 | instance_tenancy = var.instance_tenancy
38 | enable_dns_support = var.enable_dns_support
39 | enable_dns_hostnames = var.enable_dns_hostnames
40 | enable_classiclink = var.enable_classiclink
41 | enable_classiclink_dns_support = var.enable_classiclink_dns_support
42 | assign_generated_ipv6_cidr_block = var.assign_generated_ipv6_cidr_block
43 |
44 | tags = merge(
45 | {
46 | Name = var.vpc_name
47 |
48 | # special mineiros.io tags that can be used in data sources
49 | "mineiros-io/aws/vpc/vpc-name" = var.vpc_name
50 | },
51 | var.module_tags,
52 | var.vpc_tags,
53 | )
54 |
55 | depends_on = [var.module_depends_on]
56 | }
57 |
--------------------------------------------------------------------------------
/outputs.tf:
--------------------------------------------------------------------------------
1 | # ----------------------------------------------------------------------------------------------------------------------
2 | # OUTPUT CALCULATED VARIABLES (prefer full objects)
3 | # ----------------------------------------------------------------------------------------------------------------------
4 |
5 | locals {
6 | public_aws_subnets_by_group = {
7 | for group, subnets in local.public_subnets_by_group : group => [
8 | for subnet in aws_subnet.subnet : subnet if contains(subnets.*.cidr_block, subnet.cidr_block)
9 | ]
10 | }
11 |
12 | private_aws_subnets_by_group = {
13 | for group, subnets in local.private_subnets_by_group : group => [
14 | for subnet in aws_subnet.subnet : subnet if contains(subnets.*.cidr_block, subnet.cidr_block)
15 | ]
16 | }
17 |
18 | intra_aws_subnets_by_group = {
19 | for group, subnets in local.intra_subnets_by_group : group => [
20 | for subnet in aws_subnet.subnet : subnet if contains(subnets.*.cidr_block, subnet.cidr_block)
21 | ]
22 | }
23 |
24 | public_subnet_ids_by_group = {
25 | for group, subnets in local.public_aws_subnets_by_group : group => subnets.*.id
26 | }
27 |
28 | private_subnet_ids_by_group = {
29 | for group, subnets in local.private_aws_subnets_by_group : group => subnets.*.id
30 | }
31 |
32 | intra_subnet_ids_by_group = {
33 | for group, subnets in local.intra_aws_subnets_by_group : group => subnets.*.id
34 | }
35 |
36 | public_route_table_ids_by_group = {
37 | for group, subnet_ids in local.public_subnet_ids_by_group : group => distinct([
38 | for rta in try(values(aws_route_table_association.public), []) :
39 | rta.route_table_id if contains(subnet_ids, rta.subnet_id)
40 | ])
41 | }
42 |
43 | private_route_table_ids_by_group = {
44 | for group, subnet_ids in local.private_subnet_ids_by_group : group => distinct([
45 | for rta in try(values(aws_route_table_association.private), []) :
46 | rta.route_table_id if contains(subnet_ids, rta.subnet_id)
47 | ])
48 | }
49 |
50 | intra_route_table_ids_by_group = {
51 | for group, subnet_ids in local.intra_subnet_ids_by_group : group => distinct([
52 | for rta in try(values(aws_route_table_association.intra), []) :
53 | rta.route_table_id if contains(subnet_ids, rta.subnet_id)
54 | ])
55 | }
56 | }
57 |
58 |
59 | output "public_subnets_by_group" {
60 | description = "A map of lists of public subnets keyed by group. (aws_subnet)"
61 | value = local.public_aws_subnets_by_group
62 | }
63 |
64 | output "public_route_table_ids_by_group" {
65 | description = "A map of lists of public route table IDs keyed by group."
66 | value = local.public_route_table_ids_by_group
67 | }
68 |
69 | output "public_subnet_ids_by_group" {
70 | description = "A map of lists of public subnet IDs keyed by group."
71 | value = local.public_subnet_ids_by_group
72 | }
73 |
74 | output "private_subnets_by_group" {
75 | description = "A map of lists of private subnets keyed by group. (aws_subnet)"
76 | value = local.private_aws_subnets_by_group
77 | }
78 |
79 | output "private_route_table_ids_by_group" {
80 | description = "A map of lists of private route table IDs keyed by group."
81 | value = local.private_route_table_ids_by_group
82 | }
83 |
84 | output "private_subnet_ids_by_group" {
85 | description = "A map of lists of private subnet IDs keyed by group."
86 | value = local.private_subnet_ids_by_group
87 | }
88 |
89 | output "intra_subnets_by_group" {
90 | description = "A map of lists of intra aws_subnet keyed by group. (aws_subnet)"
91 | value = local.intra_aws_subnets_by_group
92 | }
93 |
94 | output "intra_route_table_ids_by_group" {
95 | description = "A map of lists of intra route table IDs keyed by group."
96 | value = local.intra_route_table_ids_by_group
97 | }
98 |
99 | output "intra_subnet_ids_by_group" {
100 | description = "A map of lists of intra subnet IDs keyed by group."
101 | value = local.intra_subnet_ids_by_group
102 | }
103 |
104 | # ----------------------------------------------------------------------------------------------------------------------
105 | # OUTPUT ALL RESOURCES AS FULL OBJECTS
106 | # ----------------------------------------------------------------------------------------------------------------------
107 |
108 | output "vpc" {
109 | description = "The VPC. (aws_vpc)"
110 | value = try(aws_vpc.vpc[0], null)
111 | }
112 |
113 | output "intra_route_tables" {
114 | description = "A map of intra route tables keyed by group. (aws_route_table)"
115 | value = try(aws_route_table.intra, null)
116 | }
117 |
118 | output "intra_route_table_associations" {
119 | description = "A map of intra route table associations keyed by the subnets CIDR Blocks. (aws_route_table_association)"
120 | value = try(aws_route_table_association.intra, null)
121 | }
122 |
123 | output "eips" {
124 | description = "A map of Elastic IP Adresses (EIPs) keyed by availability zone. (aws_eip)"
125 | value = try(aws_eip.eip, null)
126 | }
127 |
128 | output "nat_gateways" {
129 | description = "A map of NAT gatweways keyed by availability zone. (aws_nat_gateway)"
130 | value = try(aws_nat_gateway.nat_gateway, null)
131 | }
132 |
133 | output "private_route_tables" {
134 | description = "A map of private route tables keyed by group. (aws_route_table)"
135 | value = try(aws_route_table.private, null)
136 | }
137 |
138 | output "private_route_table_associations" {
139 | description = "A map of private route table associations keyed by the subnets CIDR Blocks. (aws_route_table_association)"
140 | value = try(aws_route_table_association.private, null)
141 | }
142 |
143 | output "routes_to_nat_gateways" {
144 | description = "A map of routes to the NAT Gateways keyed by group. (aws_route)"
145 | value = try(aws_route.nat_gateway, null)
146 | }
147 |
148 | output "internet_gateway" {
149 | description = "The Internet Gateway. (aws_internet_gateway)"
150 | value = try(aws_internet_gateway.internet_gateway[0], null)
151 | }
152 |
153 | output "public_route_tables" {
154 | description = "A map of public route tables keyed by group. (aws_route_table)"
155 | value = try(aws_route_table.public, null)
156 | }
157 |
158 | output "public_route_table_associations" {
159 | description = "A map of public route table associations keyed by the subnets CIDR Blocks. (aws_route_table_association)"
160 | value = try(aws_route_table_association.public, null)
161 | }
162 |
163 | output "routes_to_internet_gateway" {
164 | description = "A map of routes to the Internet Gateway keyed by group. (aws_route)"
165 | value = try(aws_route.internet_gateway, null)
166 | }
167 |
168 | output "subnets" {
169 | description = "A map of subnets keyed by CIDR Blocks. (aws_subnet)"
170 | value = try(aws_subnet.subnet, null)
171 | }
172 |
173 | # ----------------------------------------------------------------------------------------------------------------------
174 | # OUTPUT ALL INPUT VARIABLES
175 | # ----------------------------------------------------------------------------------------------------------------------
176 |
177 | output "module_inputs" {
178 | description = "A map of all module arguments. Set to the provided values or calculated default values."
179 | value = {
180 | vpc_name = var.vpc_name
181 | cidr_block = var.cidr_block
182 | assign_generated_ipv6_cidr_block = var.assign_generated_ipv6_cidr_block
183 | enable_classiclink = var.enable_classiclink
184 | enable_classiclink_dns_support = var.enable_classiclink_dns_support
185 | enable_dns_support = var.enable_dns_support
186 | enable_dns_hostnames = var.enable_dns_hostnames
187 | instance_tenancy = var.instance_tenancy
188 |
189 | subnets = var.subnets
190 |
191 | nat_gateway_mode = var.nat_gateway_mode
192 |
193 | vpc_tags = merge(var.module_tags, var.vpc_tags)
194 | internet_gateway_tags = merge(var.module_tags, var.internet_gateway_tags)
195 | eip_tags = merge(var.module_tags, var.eip_tags)
196 | nat_gateway_tags = merge(var.module_tags, var.nat_gateway_tags)
197 |
198 | subnet_tags = merge(var.module_tags, var.subnet_tags)
199 | public_subnet_tags = merge(var.module_tags, var.subnet_tags, var.public_subnet_tags)
200 | private_subnet_tags = merge(var.module_tags, var.subnet_tags, var.private_subnet_tags)
201 | intra_subnet_tags = merge(var.module_tags, var.subnet_tags, var.intra_subnet_tags)
202 |
203 | route_table_tags = merge(var.module_tags, var.route_table_tags)
204 | public_route_table_tags = merge(var.module_tags, var.route_table_tags, var.public_route_table_tags)
205 | private_route_table_tags = merge(var.module_tags, var.route_table_tags, var.private_route_table_tags)
206 | intra_route_table_tags = merge(var.module_tags, var.route_table_tags, var.intra_route_table_tags)
207 | }
208 | }
209 |
210 | # ----------------------------------------------------------------------------------------------------------------------
211 | # OUTPUT MODULE CONFIGURATION
212 | # ----------------------------------------------------------------------------------------------------------------------
213 |
214 | output "module_enabled" {
215 | description = "Whether the module is enabled."
216 | value = var.module_enabled
217 | }
218 |
219 | output "module_tags" {
220 | description = "A map of tags that will be applied to all created resources that accept tags."
221 | value = var.module_tags
222 | }
223 |
--------------------------------------------------------------------------------
/private_routing.tf:
--------------------------------------------------------------------------------
1 | # ---------------------------------------------------------------------------------------------------------------------
2 | # CREATE PRIVATE ROUTING AND NAT GATEWAYS IF A PRIVATE SUBNETS IS DEFINED
3 | # ---------------------------------------------------------------------------------------------------------------------
4 |
5 | locals {
6 | private_subnets = [for subnet in local.subnets : subnet if subnet.class == "private"]
7 |
8 | private_group_azs = try(distinct(local.private_subnets.*.group_az), [])
9 |
10 | public_azs = try(distinct(local.public_subnets.*.availability_zone), [])
11 | private_azs = try(distinct(local.private_subnets.*.availability_zone), [])
12 |
13 | private_groups = try(distinct(local.private_subnets.*.group), [])
14 |
15 | private_subnets_by_group = {
16 | for group in local.private_groups : group => [
17 | for subnet in local.private_subnets : subnet if subnet.group == group
18 | ]
19 | }
20 |
21 | private_subnets_by_group_az = {
22 | for group_az in local.private_group_azs : group_az => [
23 | for subnet in local.private_subnets : subnet if subnet.group_az == group_az
24 | ]
25 | }
26 |
27 | public_subnets_by_az = {
28 | for az in local.public_azs : az => [
29 | for subnet in local.public_subnets : subnet if subnet.availability_zone == az
30 | ]
31 | }
32 |
33 | # hacky assertion
34 | assert_each_private_subnet_has_a_public_in_same_az = {
35 | for az in local.missing_public_subnet_azs[var.nat_gateway_mode] : "Missing public subnet in az" => local.public_subnets_by_az[az]
36 | }
37 |
38 | nat_gateway_single_zones = var.nat_gateway_single_mode_zone != null ? ["${local.region}${var.nat_gateway_single_mode_zone}"] : try([local.matching_azs[0]], [])
39 |
40 | matching_azs = sort(setintersection(local.public_azs, local.private_azs))
41 | nat_azs = {
42 | one_per_az = local.matching_azs
43 | single = local.nat_gateway_single_zones
44 | none = []
45 | }
46 |
47 | nat_azs_set = toset(local.nat_azs[var.nat_gateway_mode])
48 |
49 | create_eips = length(keys(var.nat_gateway_eip_allocation_ids)) == 0
50 |
51 | missing_public_subnet_azs = {
52 | one_per_az = sort(setsubtract(local.private_azs, local.public_azs))
53 | single = length(local.matching_azs) == 0 ? sort(setsubtract(local.private_azs, local.public_azs)) : []
54 | none = []
55 | }
56 | }
57 |
58 | resource "aws_eip" "eip" {
59 | for_each = var.module_enabled && local.create_eips ? local.nat_azs_set : []
60 |
61 | vpc = true
62 |
63 | tags = merge(
64 | {
65 | Name = "${var.vpc_name}-nat-private-${each.key}"
66 |
67 | # special mineiros.io tags that can be used in data sources
68 | "mineiros-io/aws/vpc/vpc-name" = var.vpc_name
69 | "mineiros-io/aws/vpc/natgw-name" = "${var.vpc_name}-${each.key}"
70 | "mineiros-io/aws/vpc/eip-name" = "${var.vpc_name}-nat-private-${each.key}"
71 | },
72 | var.module_tags,
73 | var.eip_tags,
74 | )
75 |
76 | depends_on = [var.module_depends_on]
77 | }
78 |
79 | locals {
80 | nat_gateway_eip_allocation_ids = { for k, v in var.nat_gateway_eip_allocation_ids : "${local.region}${k}" => v }
81 |
82 | eip_allocation_ids = { for k, v in aws_eip.eip : k => v.id }
83 |
84 | allocation_ids = local.create_eips ? local.eip_allocation_ids : local.nat_gateway_eip_allocation_ids
85 | }
86 |
87 | resource "aws_nat_gateway" "nat_gateway" {
88 | for_each = var.module_enabled ? local.nat_azs_set : []
89 |
90 | allocation_id = local.allocation_ids[each.key]
91 | subnet_id = aws_subnet.subnet[local.public_subnets_by_az[each.key][0].cidr_block].id
92 |
93 | tags = merge(
94 | {
95 | Name = "${var.vpc_name}-${each.key}"
96 |
97 | # special mineiros.io tags that can be used in data sources
98 | "mineiros-io/aws/vpc/vpc-name" = var.vpc_name
99 | "mineiros-io/aws/vpc/natgw-name" = "${var.vpc_name}-${each.key}"
100 | },
101 | var.module_tags,
102 | var.nat_gateway_tags,
103 | )
104 |
105 | depends_on = [var.module_depends_on]
106 | }
107 |
108 | resource "aws_route_table" "private" {
109 | for_each = var.module_enabled ? local.private_subnets_by_group_az : {}
110 |
111 | vpc_id = aws_vpc.vpc[0].id
112 |
113 | # propagating_vgws = try(local.subnets[each.key].propagating_vgws, null)
114 |
115 | tags = merge(
116 | {
117 | Name = "${var.vpc_name}-private-${each.key}"
118 |
119 | # special mineiros.io tags that can be used in data sources
120 | "mineiros-io/aws/vpc/vpc-name" = var.vpc_name
121 | "mineiros-io/aws/vpc/routetable-name" = "${var.vpc_name}-private-${each.key}"
122 | "mineiros-io/aws/vpc/routetable-class" = "private"
123 | },
124 | var.module_tags,
125 | var.route_table_tags,
126 | var.private_route_table_tags,
127 | )
128 |
129 | depends_on = [var.module_depends_on]
130 | }
131 |
132 | resource "aws_route_table_association" "private" {
133 | for_each = var.module_enabled ? {
134 | for subnet in flatten(values(local.private_subnets_by_group_az)) : subnet.cidr_block => subnet
135 | } : {}
136 |
137 | subnet_id = aws_subnet.subnet[each.key].id
138 | route_table_id = aws_route_table.private[each.value.group_az].id
139 |
140 | depends_on = [var.module_depends_on]
141 | }
142 |
143 | locals {
144 | nat_routes = { for k, v in aws_route_table.private : "${var.nat_gateway_mode}/${k}" => v }
145 | }
146 |
147 | resource "aws_route" "nat_gateway" {
148 | for_each = length(local.nat_azs_set) > 0 ? local.nat_routes : {}
149 |
150 | route_table_id = each.value.id
151 | destination_cidr_block = "0.0.0.0/0"
152 | nat_gateway_id = try(
153 | aws_nat_gateway.nat_gateway[local.private_subnets_by_group_az[each.key][0].availability_zone].id,
154 | element(values(aws_nat_gateway.nat_gateway)[*].id, 0),
155 | null,
156 | )
157 |
158 | # Workaround for https://github.com/terraform-providers/terraform-provider-aws/issues/338
159 | timeouts {
160 | create = "10m"
161 | }
162 |
163 | # we depend on nat gateways to be available for setting and updating routes
164 | # the implicit dependency does not work, when changing nat gateway mode as we will
165 | # only depend on the new gateway implictly and not on the one being removed.
166 | # (e.g. when switching nat_gateway_mode)
167 | depends_on = [
168 | var.module_depends_on,
169 | aws_nat_gateway.nat_gateway,
170 | ]
171 | }
172 |
--------------------------------------------------------------------------------
/public_routing.tf:
--------------------------------------------------------------------------------
1 | # ---------------------------------------------------------------------------------------------------------------------
2 | # CREATE PUBLIC ROUTING AND AN INTERNET GATEWAY IF A PUBLIC SUBNET IS DEFINED
3 | # ---------------------------------------------------------------------------------------------------------------------
4 |
5 | locals {
6 | public_subnets = [for subnet in local.subnets : subnet if subnet.class == "public"]
7 |
8 | public_groups = try(distinct(local.public_subnets.*.group), [])
9 |
10 | public_subnets_by_group = {
11 | for group in local.public_groups : group => [
12 | for subnet in local.public_subnets : subnet if subnet.group == group
13 | ]
14 | }
15 | }
16 |
17 | resource "aws_internet_gateway" "internet_gateway" {
18 | count = var.module_enabled && length(local.public_subnets) > 0 ? 1 : 0
19 |
20 | vpc_id = aws_vpc.vpc[0].id
21 |
22 | tags = merge(
23 | {
24 | Name = var.vpc_name
25 |
26 | # special mineiros.io tags that can be used in data sources
27 | "mineiros-io/aws/vpc/vpc-name" = var.vpc_name
28 | "mineiros-io/aws/vpc/igw-name" = var.vpc_name
29 | },
30 | var.module_tags,
31 | var.internet_gateway_tags,
32 | )
33 |
34 | depends_on = [var.module_depends_on]
35 | }
36 |
37 | resource "aws_route_table" "public" {
38 | for_each = var.module_enabled ? local.public_subnets_by_group : {}
39 |
40 | vpc_id = aws_vpc.vpc[0].id
41 |
42 | # propagating_vgws = try(local.subnets[each.key].propagating_vgws, null)
43 |
44 | tags = merge(
45 | {
46 | Name = "${var.vpc_name}-public-${each.key}"
47 |
48 | # special mineiros.io tags that can be used in data sources
49 | "mineiros-io/aws/vpc/vpc-name" = var.vpc_name
50 | "mineiros-io/aws/vpc/routetable-name" = "${var.vpc_name}-public-${each.key}"
51 | "mineiros-io/aws/vpc/routetable-class" = "public"
52 | },
53 | var.module_tags,
54 | var.route_table_tags,
55 | var.public_route_table_tags,
56 | )
57 |
58 | depends_on = [var.module_depends_on]
59 | }
60 |
61 | resource "aws_route_table_association" "public" {
62 | for_each = var.module_enabled ? {
63 | for subnet in flatten(values(local.public_subnets_by_group)) : subnet.cidr_block => subnet
64 | } : {}
65 |
66 | subnet_id = aws_subnet.subnet[each.key].id
67 | route_table_id = aws_route_table.public[each.value.group].id
68 |
69 | depends_on = [var.module_depends_on]
70 | }
71 |
72 | resource "aws_route" "internet_gateway" {
73 | for_each = aws_route_table.public
74 |
75 | route_table_id = each.value.id
76 | destination_cidr_block = "0.0.0.0/0"
77 | gateway_id = aws_internet_gateway.internet_gateway[0].id
78 |
79 | # Workaround for https://github.com/terraform-providers/terraform-provider-aws/issues/338
80 | timeouts {
81 | create = "10m"
82 | }
83 |
84 | depends_on = [var.module_depends_on]
85 | }
86 |
--------------------------------------------------------------------------------
/subnets.tf:
--------------------------------------------------------------------------------
1 | # ---------------------------------------------------------------------------------------------------------------------
2 | # CREATE PUBLIC, PRIVATE, AND INTRA SUBNETS WITHIN THE VPC
3 | # ---------------------------------------------------------------------------------------------------------------------
4 |
5 | locals {
6 |
7 | # hacky assertion
8 | assert_subnet_have_unique_group_class_combination = {
9 | for subnet in var.subnets :
10 | "${subnet.group}-${subnet.class}" => "class/group combination must be unique in all subnets. See the module's README.md for details."
11 | }
12 |
13 | subnet_tags = {
14 | public = var.public_subnet_tags
15 | private = var.private_subnet_tags
16 | intra = var.intra_subnet_tags
17 | }
18 |
19 | # The following creates a list of subnets by constructing multi-level lists and flattening them in the end.
20 | subnets_tmp = flatten(
21 | [
22 | for subnet in var.subnets : [
23 | for az, netnums in subnet.netnums_by_az : [
24 | for idx, netnum in netnums : {
25 | cidr_block = cidrsubnet(try(subnet.cidr_block, var.cidr_block), try(subnet.newbits, 8), netnum)
26 | availability_zone = "${local.region}${az}"
27 |
28 | map_public_ip_on_launch = try(subnet.map_public_ip_on_launch, subnet.class == "public", false)
29 |
30 | group_az = "${try(subnet.group, "default")}-${local.region}${az}"
31 |
32 | group = try(subnet.group, "default")
33 | class = try(subnet.class, "private")
34 |
35 | db_subnet_group_name = try(subnet.db_subnet_group_name, null)
36 | elasticache_subnet_group_name = try(subnet.elasticache_subnet_group_name, null)
37 |
38 | # routes = try(subnet.routes, [])
39 |
40 | tags = merge(
41 | {
42 | Name = "${var.vpc_name}-${subnet.group}-${subnet.class}-${az}-${idx}"
43 |
44 | # special mineiros.io tags that can be used in data sources
45 | "mineiros-io/aws/vpc/vpc-name" = var.vpc_name
46 | "mineiros-io/aws/vpc/subnet-name" = "${var.vpc_name}-${try(subnet.group, "default")}-${try(subnet.class, "private")}-${az}-${idx}"
47 | "mineiros-io/aws/vpc/subnet-group" = try(subnet.group, "default")
48 | "mineiros-io/aws/vpc/subnet-class" = try(subnet.class, "private")
49 | },
50 | local.subnet_tags[try(subnet.class, "private")],
51 | try(subnet.tags, {}),
52 | )
53 | }
54 | ]
55 | ]
56 | ]
57 | )
58 |
59 | subnets = {
60 | for subnet in local.subnets_tmp : subnet.cidr_block => subnet
61 | }
62 | }
63 |
64 | resource "aws_subnet" "subnet" {
65 | for_each = var.module_enabled ? local.subnets : {}
66 |
67 | vpc_id = aws_vpc.vpc[0].id
68 |
69 | # We convert the cidr_block to its cannonical form. This is actually not needed as we
70 | # already calculate the cidr_block, but to be future proof we do it again anyway.
71 | cidr_block = cidrsubnet(each.value.cidr_block, 0, 0)
72 |
73 | availability_zone = each.value.availability_zone
74 | map_public_ip_on_launch = each.value.map_public_ip_on_launch
75 |
76 | ipv6_cidr_block = try(cidrsubnet(each.value.ipv6_cidr_block, 0, 0), null)
77 | assign_ipv6_address_on_creation = try(each.value.assign_ipv6_address_on_creation, null)
78 |
79 | tags = merge(
80 | var.module_tags,
81 | var.subnet_tags,
82 | each.value.tags,
83 | )
84 |
85 | depends_on = [var.module_depends_on]
86 | }
87 |
--------------------------------------------------------------------------------
/test/README.md:
--------------------------------------------------------------------------------
1 | [
][homepage]
2 |
3 | [![license][badge-license]][apache20]
4 | [![Terraform Version][badge-terraform]][releases-terraform]
5 | [![Join Slack][badge-slack]][slack]
6 |
7 | # Tests
8 |
9 | This directory contains a number of automated tests that cover the functionality
10 | of the modules that ship with this repository.
11 |
12 | ## Introduction
13 |
14 | We are using [Terratest] for automated tests that are located in the
15 | [`test/` directory][Testdirectory]. Terratest deploys _real_ infrastructure
16 | (e.g., servers) in a _real_ environment (e.g., AWS).
17 |
18 | The basic usage pattern for writing automated tests with Terratest is to:
19 |
20 | 1. Write tests using Go's built-in [package testing]: you create a file ending
21 | in `_test.go` and run tests with the `go test` command.
22 | 2. Use Terratest to execute your _real_ IaC tools (e.g., Terraform, Packer, etc.)
23 | to deploy _real_ infrastructure (e.g., servers) in a _real_ environment (e.g., AWS).
24 | 3. Validate that the infrastructure works correctly in that environment by
25 | making HTTP requests, API calls, SSH connections, etc.
26 | 4. Undeploy everything at the end of the test.
27 |
28 | **Note #1**: Many of these tests create real resources in an AWS account.
29 | That means they cost money to run, especially if you don't clean up after
30 | yourself. Please be considerate of the resources you create and take extra care
31 | to clean everything up when you're done!
32 |
33 | **Note #2**: Never hit `CTRL + C` or cancel a build once tests are running or
34 | the cleanup tasks won't run!
35 |
36 | **Note #3**: We set `-timeout 45m` on all tests not because they necessarily
37 | take 45 minutes, but because Go has a default test timeout of 10 minutes, after
38 | which it does a `SIGQUIT`, preventing the tests from properly cleaning up after
39 | themselves. Therefore, we set a timeout of 45 minutes to make sure all tests
40 | have enough time to finish and cleanup.
41 |
42 | ## How to run the tests
43 |
44 | This repository comes with a [Makefile], that helps you to run the
45 | tests in a convenient way.
46 | Alternatively, you can also run the tests without Docker.
47 |
48 | ### Run the tests with Docker
49 |
50 | 1. Install [Docker]
51 | 2. Set your AWS credentials as environment variables: `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`
52 | 3. Run `make docker-run-tests`
53 |
54 | ### Run the tests without Docker
55 |
56 | 1. Install the latest version of [Go].
57 | 2. Install [Terraform].
58 | 3. Set your AWS credentials as environment variables: `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`
59 | 4. Install go dependencies: `go mod download`
60 | 5. Run all tests: `go test -v -count 1 -timeout 45m -parallel 128 ./test/...`
61 | or use the convenient `make test/unit-tests` Makefile target.
62 | 6. Run a specific test: `go test -count 1 -v -timeout 45m -parallel 128 test/example_test.go`
63 |
64 |
65 |
66 | [Makefile]: https://github.com/mineiros-io/terraform-aws-vpc/blob/master/Makefile
67 | [Testdirectory]: https://github.com/mineiros-io/terraform-aws-vpc/tree/master/test
68 |
69 | [homepage]: https://mineiros.io/?ref=terraform-aws-vpc
70 | [Terratest]: https://github.com/gruntwork-io/terratest
71 | [package testing]: https://golang.org/pkg/testing/
72 | [Docker]: https://docs.docker.com/get-started/
73 | [Go]: https://golang.org/
74 | [Terraform]: https://www.terraform.io/downloads.html
75 | [badge-license]: https://img.shields.io/badge/license-Apache%202.0-brightgreen.svg
76 | [badge-terraform]: https://img.shields.io/badge/terraform-1.x%20|%200.15%20|%200.14%20|%200.13%20|%200.12.20+-623CE4.svg?logo=terraform
77 | [badge-slack]: https://img.shields.io/badge/slack-@mineiros--community-f32752.svg?logo=slack
78 |
79 | [releases-terraform]: https://github.com/hashicorp/terraform/releases
80 | [apache20]: https://opensource.org/licenses/Apache-2.0
81 | [slack]: https://join.slack.com/t/mineiros-community/shared_invite/zt-ehidestg-aLGoIENLVs6tvwJ11w9WGg
82 |
--------------------------------------------------------------------------------
/test/unit-complete/main.tf:
--------------------------------------------------------------------------------
1 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 | # COMPLETE FEATURES UNIT TEST
3 | # This module tests a complete set of most/all non-exclusive features
4 | # The purpose is to activate everything the module offers, but trying to keep execution time and costs minimal.
5 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6 |
7 | variable "aws_region" {
8 | description = "(Optional) The AWS region in which all resources will be created."
9 | type = string
10 | default = "eu-west-1"
11 | }
12 |
13 | variable "module_enabled" {
14 | description = "(Optional) Test module_enabled feature. Can be true or false."
15 | type = bool
16 | default = true
17 | }
18 |
19 | variable "nat_gateway_mode" {
20 | description = "(Optional) Test nat_gateway_mode feature. Can be single, one_per_az, or none."
21 | type = string
22 | default = "single"
23 | }
24 |
25 | provider "aws" {
26 | region = var.aws_region
27 | }
28 |
29 | locals {
30 | cidr_block = "192.168.0.0/16"
31 | }
32 |
33 | module "test" {
34 | source = "../.."
35 |
36 | module_enabled = true
37 |
38 | vpc_name = "test"
39 | cidr_block = local.cidr_block
40 | nat_gateway_mode = var.nat_gateway_mode
41 |
42 | subnets = [
43 | {
44 | group = "test"
45 | class = "public"
46 |
47 | netnums_by_az = {
48 | a = [0]
49 | b = [1]
50 | }
51 | },
52 | {
53 | group = "test"
54 | class = "private"
55 |
56 | netnums_by_az = {
57 | a = [2]
58 | b = [3]
59 | }
60 | },
61 | {
62 | group = "test"
63 | class = "intra"
64 |
65 | netnums_by_az = {
66 | a = [128]
67 | b = [129]
68 | }
69 | },
70 | {
71 | group = "db"
72 | class = "intra"
73 |
74 | db_subnet_group_name = "my-db-subnet-group"
75 |
76 | tags = {
77 | "foo" = "bar"
78 | }
79 |
80 | netnums_by_az = {
81 | a = [130]
82 | b = [131]
83 | }
84 | },
85 | ]
86 |
87 | module_tags = {
88 | Environment = "unknown"
89 | }
90 |
91 | module_depends_on = ["nothing"]
92 | }
93 |
--------------------------------------------------------------------------------
/test/unit-disabled/main.tf:
--------------------------------------------------------------------------------
1 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 | # EMPTY FEATURES (DISABLED) UNIT TEST
3 | # This module tests an empty set of features.
4 | # The purpose is to verify no resources are created when the module is disabled.
5 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6 |
7 | variable "aws_region" {
8 | description = "(Required) The AWS region in which all resources will be created."
9 | type = string
10 | default = "eu-west-1"
11 | }
12 |
13 | provider "aws" {
14 | region = var.aws_region
15 | }
16 |
17 | module "test" {
18 | source = "../.."
19 |
20 | module_enabled = false
21 | }
22 |
--------------------------------------------------------------------------------
/test/unit-minimal/main.tf:
--------------------------------------------------------------------------------
1 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 | # MINIMAL FEATURES UNIT TEST
3 | # This module tests a minimal set of features.
4 | # The purpose is to test all defaults for optional arguments and just provide the required arguments.
5 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6 |
7 | variable "aws_region" {
8 | description = "(Optional) The AWS region in which all resources will be created."
9 | type = string
10 | default = "eu-west-1"
11 | }
12 |
13 | provider "aws" {
14 | region = var.aws_region
15 | }
16 |
17 | module "test" {
18 | source = "../.."
19 | }
20 |
--------------------------------------------------------------------------------
/test/unit_complete_test.go:
--------------------------------------------------------------------------------
1 | package test
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/gruntwork-io/terratest/modules/terraform"
7 | "github.com/stretchr/testify/assert"
8 | )
9 |
10 | func TestUnitComplete(t *testing.T) {
11 | t.Parallel()
12 |
13 | // deploy initial example with one nat gateway per az
14 | terraformOptions := &terraform.Options{
15 | TerraformDir: "unit-complete",
16 | Upgrade: true,
17 | Vars: map[string]interface{}{
18 | "nat_gateway_mode": "one_per_az",
19 | },
20 | }
21 |
22 | defer terraform.Destroy(t, terraformOptions)
23 |
24 | terraform.InitAndPlan(t, terraformOptions)
25 | terraform.Apply(t, terraformOptions)
26 |
27 | stdout := terraform.Plan(t, terraformOptions)
28 |
29 | resourceCount := terraform.GetResourceCount(t, stdout)
30 | assert.Equal(t, 0, resourceCount.Add, "No resources should have been created. Found %d instead.", resourceCount.Add)
31 | assert.Equal(t, 0, resourceCount.Change, "No resources should have been changed. Found %d instead.", resourceCount.Change)
32 | assert.Equal(t, 0, resourceCount.Destroy, "No resources should have been destroyed. Found %d instead.", resourceCount.Destroy)
33 |
34 | // deploy upgraded example with single nat gateway
35 | terraformOptions = &terraform.Options{
36 | TerraformDir: "unit-complete",
37 | Upgrade: true,
38 | Vars: map[string]interface{}{
39 | "nat_gateway_mode": "single",
40 | },
41 | }
42 | terraform.Plan(t, terraformOptions)
43 | terraform.Apply(t, terraformOptions)
44 |
45 | stdout = terraform.Plan(t, terraformOptions)
46 |
47 | resourceCount = terraform.GetResourceCount(t, stdout)
48 | assert.Equal(t, 0, resourceCount.Add, "No resources should have been created. Found %d instead.", resourceCount.Add)
49 | assert.Equal(t, 0, resourceCount.Change, "No resources should have been changed. Found %d instead.", resourceCount.Change)
50 | assert.Equal(t, 0, resourceCount.Destroy, "No resources should have been destroyed. Found %d instead.", resourceCount.Destroy)
51 |
52 | // deploy upgraded example with no nat gateways
53 | terraformOptions = &terraform.Options{
54 | TerraformDir: "unit-complete",
55 | Upgrade: true,
56 | Vars: map[string]interface{}{
57 | "nat_gateway_mode": "none",
58 | },
59 | }
60 | terraform.Plan(t, terraformOptions)
61 | terraform.Apply(t, terraformOptions)
62 |
63 | stdout = terraform.Plan(t, terraformOptions)
64 |
65 | resourceCount = terraform.GetResourceCount(t, stdout)
66 | assert.Equal(t, 0, resourceCount.Add, "No resources should have been created. Found %d instead.", resourceCount.Add)
67 | assert.Equal(t, 0, resourceCount.Change, "No resources should have been changed. Found %d instead.", resourceCount.Change)
68 | assert.Equal(t, 0, resourceCount.Destroy, "No resources should have been destroyed. Found %d instead.", resourceCount.Destroy)
69 | }
70 |
--------------------------------------------------------------------------------
/test/unit_disabled_test.go:
--------------------------------------------------------------------------------
1 | package test
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/gruntwork-io/terratest/modules/terraform"
7 | "github.com/stretchr/testify/assert"
8 | )
9 |
10 | func TestUnitDisabled(t *testing.T) {
11 | t.Parallel()
12 |
13 | terraformOptions := &terraform.Options{
14 | TerraformDir: "unit-disabled",
15 | Vars: map[string]interface{}{
16 | "aws_region": "eu-west-1",
17 | },
18 | Upgrade: true,
19 | }
20 |
21 | defer terraform.Destroy(t, terraformOptions)
22 |
23 | terraform.InitAndPlan(t, terraformOptions)
24 | stdout := terraform.ApplyAndIdempotent(t, terraformOptions)
25 |
26 | resourceCount := terraform.GetResourceCount(t, stdout)
27 | assert.Equal(t, 0, resourceCount.Add, "No resources should have been created. Found %d instead.", resourceCount.Add)
28 | assert.Equal(t, 0, resourceCount.Change, "No resources should have been changed. Found %d instead.", resourceCount.Change)
29 | assert.Equal(t, 0, resourceCount.Destroy, "No resources should have been destroyed. Found %d instead.", resourceCount.Destroy)
30 | }
31 |
--------------------------------------------------------------------------------
/test/unit_minimal_test.go:
--------------------------------------------------------------------------------
1 | package test
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/gruntwork-io/terratest/modules/terraform"
7 | "github.com/stretchr/testify/assert"
8 | )
9 |
10 | func TestUnitMinimal(t *testing.T) {
11 | t.Parallel()
12 |
13 | terraformOptions := &terraform.Options{
14 | TerraformDir: "unit-minimal",
15 | Vars: map[string]interface{}{
16 | "aws_region": "eu-west-1",
17 | },
18 | Upgrade: true,
19 | }
20 |
21 | defer terraform.Destroy(t, terraformOptions)
22 |
23 | terraform.InitAndPlan(t, terraformOptions)
24 | terraform.Apply(t, terraformOptions)
25 |
26 | stdout := terraform.Plan(t, terraformOptions)
27 |
28 | resourceCount := terraform.GetResourceCount(t, stdout)
29 | assert.Equal(t, 0, resourceCount.Add, "No resources should have been created. Found %d instead.", resourceCount.Add)
30 | assert.Equal(t, 0, resourceCount.Change, "No resources should have been changed. Found %d instead.", resourceCount.Change)
31 | assert.Equal(t, 0, resourceCount.Destroy, "No resources should have been destroyed. Found %d instead.", resourceCount.Destroy)
32 | }
33 |
--------------------------------------------------------------------------------
/variables.tf:
--------------------------------------------------------------------------------
1 | # ----------------------------------------------------------------------------------------------------------------------
2 | # REQUIRED PARAMETERS
3 | # These variables must be set when using this module.
4 | # ----------------------------------------------------------------------------------------------------------------------
5 |
6 | # ----------------------------------------------------------------------------------------------------------------------
7 | # OPTIONAL PARAMETERS
8 | # These variables have defaults, but may be overridden.
9 | # ----------------------------------------------------------------------------------------------------------------------
10 |
11 | variable "vpc_name" {
12 | description = "(Optional) The name of the VPC. Default is \"main\"."
13 | type = string
14 | default = "main"
15 | }
16 |
17 | variable "cidr_block" {
18 | description = "(Optional) The CIDR block for the VPC. The permissible size of the block ranges between a /16 netmask and a /28 netmask. We advice you to use a CIDR block reserved for private address space as recommended in RFC 1918 http://www.faqs.org/rfcs/rfc1918.html. Default is \"10.0.0.0/16\""
19 | type = string
20 | default = "10.0.0.0/16"
21 | }
22 |
23 | variable "assign_generated_ipv6_cidr_block" {
24 | description = "(Optional) Requests an AWS-provided IPv6 CIDR block with a /56 prefix length for the VPC. You cannot specify the range of IP addresses, or the size of the CIDR block. Default is false."
25 | type = bool
26 | default = false
27 | }
28 |
29 | variable "enable_classiclink" {
30 | description = "(Optional) Whether or not to enable ClassicLink for the VPC. Only valid in regions and accounts that support EC2 Classic. Read more: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/vpc-classiclink.html. Default is false."
31 | type = bool
32 | default = false
33 | }
34 |
35 | variable "enable_classiclink_dns_support" {
36 | description = "(Optional) Whether or not to enable ClassicLink DNS Support for the VPC. Only valid in regions and accounts that support EC2 Classic. Default is false."
37 | type = bool
38 | default = false
39 | }
40 |
41 | variable "enable_dns_support" {
42 | description = "(Optional) Whether or not to enable DNS support in the VPC. Default is true."
43 | type = bool
44 | default = true
45 | }
46 |
47 | variable "enable_dns_hostnames" {
48 | description = "(Optional) Whether or not to enable DNS hostnames in the VPC. Default is false."
49 | type = bool
50 | default = false
51 | }
52 |
53 | variable "instance_tenancy" {
54 | description = "(Optional) A tenancy option for instances launched into the VPC. Default is \"default\"."
55 | type = string
56 | default = "default"
57 | }
58 |
59 | variable "vpc_tags" {
60 | description = "(Optional) A map of tags to apply to the created VPC. Default is {}."
61 | type = map(string)
62 | default = {}
63 | }
64 |
65 | variable "subnets" {
66 | description = "(Optional) List of subnet definitions. See README.md for details. Default is []."
67 | type = any
68 | default = []
69 | }
70 |
71 | variable "subnet_tags" {
72 | description = "(Optional) A map of tags to apply to the created Subnet. Default is {}."
73 | type = map(string)
74 | default = {}
75 | }
76 |
77 | variable "public_subnet_tags" {
78 | description = "(Optional) A map of tags to apply to the created Public Subnets. Default is {}."
79 | type = map(string)
80 | default = {}
81 | }
82 |
83 | variable "private_subnet_tags" {
84 | description = "(Optional) A map of tags to apply to the created Private Subnets. Default is {}."
85 | type = map(string)
86 | default = {}
87 | }
88 |
89 | variable "intra_subnet_tags" {
90 | description = "(Optional) A map of tags to apply to the created Intra Subnets. Default is {}."
91 | type = map(string)
92 | default = {}
93 | }
94 |
95 | variable "route_table_tags" {
96 | description = "(Optional) A map of tags to apply to the created Public Route Table. Default is {}."
97 | type = map(string)
98 | default = {}
99 | }
100 |
101 | variable "public_route_table_tags" {
102 | description = "(Optional) A map of tags to apply to the created Public Route Table. Default is {}."
103 | type = map(string)
104 | default = {}
105 | }
106 |
107 | variable "private_route_table_tags" {
108 | description = "(Optional) A map of tags to apply to the created Private Route Table. Default is {}."
109 | type = map(string)
110 | default = {}
111 | }
112 |
113 | variable "intra_route_table_tags" {
114 | description = "(Optional) A map of tags to apply to the created Intra Route Table. Default is {}."
115 | type = map(string)
116 | default = {}
117 | }
118 |
119 | variable "nat_gateway_mode" {
120 | description = "(Optional) Set the mode for the NAT Gateways. Possible inputs are \"none\" (create no NAT Gateways at all), \"single\" (create a single NAT Gateway inside the first defined Public Subnet) and \"one_per_az\" (create one NAT Gateway inside the first Public Subnet in each Availability Zone). Default is \"single\"."
121 | type = string
122 | default = "single"
123 | }
124 |
125 | variable "nat_gateway_single_mode_zone" {
126 | description = "(Optional) Define the zone (short name) of the NAT gateway when nat_gateway_mode is \"single\" (e.g. \"a\", \"b\", or \"c\"). The AWS region will be added as a prefix. Defaults to a random zone."
127 | type = string
128 | default = null
129 | }
130 |
131 | variable "nat_gateway_eip_allocation_ids" {
132 | description = "(Optional) A map of EIP allocation ids to use for nat gateways keyed by short zone name (e.g. \"a\", \"b\", or \"c\")."
133 | type = map(string)
134 | default = {}
135 | }
136 |
137 | variable "nat_gateway_tags" {
138 | description = "(Optional) A map of tags to apply to the created NAT Gateways. Default is {}."
139 | type = map(string)
140 | default = {}
141 | }
142 |
143 | variable "eip_tags" {
144 | description = "(Optional) A map of tags to apply to the created NAT Gateway Elastic IP Addresses. Default is {}."
145 | type = map(string)
146 | default = {}
147 | }
148 |
149 | variable "internet_gateway_tags" {
150 | description = "(Optional) A map of tags to apply to the created Internet Gateway. Default is {}."
151 | type = map(string)
152 | default = {}
153 | }
154 |
155 |
156 | # ----------------------------------------------------------------------------------------------------------------------
157 | # MODULE CONFIGURATION PARAMETERS
158 | # These variables are used to configure the module.
159 | # See https://medium.com/mineiros/the-ultimate-guide-on-how-to-write-terraform-modules-part-1-81f86d31f024
160 | # ----------------------------------------------------------------------------------------------------------------------
161 |
162 | variable "module_enabled" {
163 | type = bool
164 | description = "(Optional) Whether to create resources within the module or not. Default is true."
165 | default = true
166 | }
167 |
168 | variable "module_depends_on" {
169 | type = any
170 | description = "(Optional) A list of external resources the module depends_on. Default is []."
171 | default = []
172 | }
173 |
174 | variable "module_tags" {
175 | description = "(Optional) A map of default tags to apply to all resources created which support tags. Default is {}."
176 | type = map(string)
177 | default = {}
178 | }
179 |
--------------------------------------------------------------------------------
/versions.tf:
--------------------------------------------------------------------------------
1 | # ----------------------------------------------------------------------------------------------------------------------
2 | # SET TERRAFORM AND PROVIDER REQUIREMENTS FOR RUNNING THIS MODULE
3 | # ----------------------------------------------------------------------------------------------------------------------
4 |
5 | terraform {
6 | required_version = ">= 0.12.20, < 2.0"
7 |
8 | required_providers {
9 | aws = {
10 | source = "hashicorp/aws"
11 | version = ">= 2.45, < 4.0"
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------