├── .editorconfig
├── .github
├── CODEOWNERS
├── dependabot.yml
├── labeler.yaml
├── labels.yaml
└── workflows
│ ├── pull-request-labeler.yaml
│ ├── sync-labels.yaml
│ ├── terraform.integration.yaml
│ ├── welcome.yaml
│ └── yaml.integration.yaml
├── .gitignore
├── .pre-commit-config.yaml
├── .tflint.hcl
├── .yamllint.yaml
├── LICENSE
├── README.md
├── VERSION
├── examples
├── nat-gateway-private-secondary-ip-addresses
│ ├── main.tf
│ ├── outputs.tf
│ └── versions.tf
├── nat-gateway-private
│ ├── main.tf
│ ├── outputs.tf
│ └── versions.tf
├── nat-gateway-public
│ ├── main.tf
│ ├── outputs.tf
│ └── versions.tf
├── security-group-simple
│ ├── main.tf
│ ├── outputs.tf
│ └── versions.tf
├── security-group-with-ipv4-cidrs
│ ├── main.tf
│ ├── outputs.tf
│ └── versions.tf
├── vpc-full
│ ├── main.tf
│ ├── nacls.tf
│ ├── nat-gateways.tf
│ ├── outputs.tf
│ ├── route-tables.tf
│ ├── subnet-groups.tf
│ └── versions.tf
├── vpc-ipv4-secondary-cidrs
│ ├── main.tf
│ ├── outputs.tf
│ └── versions.tf
├── vpc-ipv6-cidrs
│ ├── main.tf
│ ├── outputs.tf
│ └── versions.tf
├── vpc-simple
│ ├── main.tf
│ ├── outputs.tf
│ └── versions.tf
└── vpc-with-ipam
│ ├── ipam.tf
│ ├── main.tf
│ ├── outputs.tf
│ └── versions.tf
└── modules
├── nacl
├── README.md
├── main.tf
├── migrations.tf
├── outputs.tf
├── resource-group.tf
├── variables.tf
└── versions.tf
├── nat-gateway
├── README.md
├── main.tf
├── migrations.tf
├── outputs.tf
├── resource-group.tf
├── variables.tf
└── versions.tf
├── route-table
├── README.md
├── main.tf
├── migrations.tf
├── outputs.tf
├── resource-group.tf
├── routes.tf
├── variables.tf
└── versions.tf
├── security-group
├── README.md
├── main.tf
├── migrations.tf
├── outputs.tf
├── resource-group.tf
├── rules.tf
├── variables.tf
└── versions.tf
├── subnet-group
├── README.md
├── integrations.tf
├── main.tf
├── migrations.tf
├── outputs.tf
├── ram-share.tf
├── resource-group.tf
├── variables.tf
└── versions.tf
└── vpc
├── README.md
├── defaults.tf
├── dhcp-options.tf
├── gateways.tf
├── main.tf
├── migrations.tf
├── outputs.tf
├── resource-group.tf
├── route53.tf
├── variables.tf
└── versions.tf
/.editorconfig:
--------------------------------------------------------------------------------
1 | # Top-most EditorConfig file
2 | root = true
3 |
4 | [*]
5 | charset = utf-8
6 | end_of_line = lf
7 | indent_style = space
8 | indent_size = 2
9 | trim_trailing_whitespace = true
10 | insert_final_newline = true
11 | max_line_length = 150
12 |
13 | [*.{tf,tfvars}]
14 | indent_size = 2
15 | indent_style = space
16 |
17 | [*.md]
18 | max_line_length = 0
19 |
20 | [COMMIT_EDITMSG]
21 | max_line_length = 0
22 |
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | * @posquit0
2 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: github-actions
4 | directory: /
5 | schedule:
6 | interval: daily
7 |
8 | - package-ecosystem: terraform
9 | directories:
10 | - /modules/*
11 | schedule:
12 | interval: weekly
13 |
--------------------------------------------------------------------------------
/.github/labeler.yaml:
--------------------------------------------------------------------------------
1 | # Modules
2 | ":floppy_disk: nacl":
3 | - changed-files:
4 | - any-glob-to-any-file:
5 | - modules/nacl/**/*
6 |
7 | ":floppy_disk: nat-gateway":
8 | - changed-files:
9 | - any-glob-to-any-file:
10 | - modules/nat-gateway/**/*
11 |
12 | ":floppy_disk: route-table":
13 | - changed-files:
14 | - any-glob-to-any-file:
15 | - modules/route-table/**/*
16 |
17 | ":floppy_disk: security-group":
18 | - changed-files:
19 | - any-glob-to-any-file:
20 | - modules/security-group/**/*
21 |
22 | ":floppy_disk: subnet-group":
23 | - changed-files:
24 | - any-glob-to-any-file:
25 | - modules/subnet-group/**/*
26 |
27 | ":floppy_disk: vpc":
28 | - changed-files:
29 | - any-glob-to-any-file:
30 | - modules/vpc/**/*
31 |
--------------------------------------------------------------------------------
/.github/labels.yaml:
--------------------------------------------------------------------------------
1 | # Warning
2 | - color: "ee0701"
3 | description: "Categorize bug reports."
4 | name: ":warning: bug"
5 | - color: "ee0701"
6 | description: "Categorize vulnerability reports."
7 | name: ":warning: vulnerability"
8 |
9 | # Highlight
10 | - color: "0e8a16"
11 | description: "Good for newcomers."
12 | name: ":fire: good first issue"
13 | - color: "0e8a16"
14 | description: "Extra attention is needed."
15 | name: ":fire: help wanted"
16 |
17 | # Cancel
18 | - color: "b60205"
19 | description: "This issue or pull request already exists."
20 | name: ":pray: duplicate"
21 | - color: "b60205"
22 | description: "This will not be worked on."
23 | name: ":pray: wontfix"
24 |
25 | # Size
26 | - color: "cfd3d7"
27 | description: "Extra Small size issue or PR."
28 | name: "size/XS"
29 | - color: "cfd3d7"
30 | description: "Small size issue or PR."
31 | name: "size/S"
32 | - color: "cfd3d7"
33 | description: "Medium size issue or PR."
34 | name: "size/M"
35 | - color: "cfd3d7"
36 | description: "Large size issue or PR."
37 | name: "size/L"
38 | - color: "cfd3d7"
39 | description: "Extra Large size issue or PR."
40 | name: "size/XL"
41 |
42 | # Modules
43 | - color: "fbca04"
44 | description: "This issue or pull request is related to nacl module."
45 | name: ":floppy_disk: nacl"
46 | - color: "fbca04"
47 | description: "This issue or pull request is related to nat-gateway module."
48 | name: ":floppy_disk: nat-gateway"
49 | - color: "fbca04"
50 | description: "This issue or pull request is related to route-table module."
51 | name: ":floppy_disk: route-table"
52 | - color: "fbca04"
53 | description: "This issue or pull request is related to security-group module."
54 | name: ":floppy_disk: security-group"
55 | - color: "fbca04"
56 | description: "This issue or pull request is related to subnet-group module."
57 | name: ":floppy_disk: subnet-group"
58 | - color: "fbca04"
59 | description: "This issue or pull request is related to vpc module."
60 | name: ":floppy_disk: vpc"
61 |
--------------------------------------------------------------------------------
/.github/workflows/pull-request-labeler.yaml:
--------------------------------------------------------------------------------
1 | name: Label Pull Requests
2 |
3 | on:
4 | - pull_request_target
5 |
6 | jobs:
7 | label-pr:
8 | runs-on: ubuntu-latest
9 |
10 | permissions:
11 | contents: read
12 | pull-requests: write
13 |
14 | steps:
15 | - name: Add Labels for PR
16 | uses: actions/labeler@v5
17 | with:
18 | repo-token: "${{ secrets.GITHUB_TOKEN }}"
19 | configuration-path: .github/labeler.yaml
20 | dot: true
21 | sync-labels: true
22 |
23 | - name: Add PR Size Labels for PR
24 | uses: codelytv/pr-size-labeler@v1
25 | with:
26 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
27 | xs_label: 'size/XS'
28 | xs_max_size: '20'
29 | s_label: 'size/S'
30 | s_max_size: '50'
31 | m_label: 'size/M'
32 | m_max_size: '150'
33 | l_label: 'size/L'
34 | l_max_size: '300'
35 | xl_label: 'size/XL'
36 | fail_if_xl: 'false'
37 | message_if_xl: >
38 | 'This PR has too many changes.
39 | Please make sure you are NOT addressing multiple issues with one PR.'
40 |
--------------------------------------------------------------------------------
/.github/workflows/sync-labels.yaml:
--------------------------------------------------------------------------------
1 | name: Sync labels
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 | paths:
8 | - .github/labels.yaml
9 | workflow_dispatch: {}
10 |
11 | jobs:
12 | sync-labels:
13 | runs-on: ubuntu-latest
14 |
15 | steps:
16 | - name: Checkout
17 | uses: actions/checkout@v4
18 |
19 | - name: Sync labels
20 | uses: crazy-max/ghaction-github-labeler@v5
21 | with:
22 | github-token: ${{ secrets.GITHUB_TOKEN }}
23 | yaml-file: .github/labels.yaml
24 | skip-delete: false
25 | dry-run: false
26 | # exclude: |
27 |
--------------------------------------------------------------------------------
/.github/workflows/terraform.integration.yaml:
--------------------------------------------------------------------------------
1 | name: Integration (Terraform)
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 | pull_request: {}
8 |
9 | concurrency:
10 | group: terraform-integration-${{ github.ref }}
11 | cancel-in-progress: true
12 |
13 | jobs:
14 | changed:
15 | name: Filter Changed Files and Directories
16 | runs-on: ubuntu-latest
17 |
18 | outputs:
19 | changed: ${{ steps.set-outputs.outputs.changed }}
20 | modified: ${{ steps.set-outputs.outputs.modified }}
21 | changed_files: ${{ steps.set-outputs.outputs.changed_files }}
22 | modified_files: ${{ steps.set-outputs.outputs.modified_files }}
23 | changed_directories: ${{ steps.set-outputs.outputs.changed_directories }}
24 | modified_directories: ${{ steps.set-outputs.outputs.modified_directories }}
25 |
26 | steps:
27 | - name: Checkout
28 | uses: actions/checkout@v4
29 | with:
30 | fetch-depth: 0
31 |
32 | - name: Get Changed Files
33 | id: changed-files
34 | uses: tj-actions/changed-files@v44
35 | with:
36 | files: |
37 | modules/**
38 | examples/**
39 | json: true
40 |
41 | - name: Get Changed Directories
42 | id: changed-directories
43 | uses: tj-actions/changed-files@v44
44 | with:
45 | files: |
46 | modules/**
47 | examples/**
48 | dir_names: "true"
49 | dir_names_max_depth: 2
50 | json: true
51 |
52 | - name: Set outputs
53 | id: set-outputs
54 | run: |
55 | echo "changed=${{ steps.changed-directories.outputs.any_changed }}" >> $GITHUB_OUTPUT
56 | echo "modified=${{ steps.changed-directories.outputs.any_modified }}" >> $GITHUB_OUTPUT
57 |
58 | echo "changed_files=${{ steps.changed-files.outputs.all_changed_files }}" >> $GITHUB_OUTPUT
59 | echo "modified_files=${{ steps.changed-files.outputs.all_modified_files }}" >> $GITHUB_OUTPUT
60 |
61 | echo "changed_directories=${{ steps.changed-directories.outputs.all_changed_files }}" >> $GITHUB_OUTPUT
62 | echo "modified_directories=${{ steps.changed-directories.outputs.all_modified_files }}" >> $GITHUB_OUTPUT
63 |
64 |
65 | terraform:
66 | name: Lint (terraform)
67 | needs:
68 | - changed
69 | if: ${{ needs.changed.outputs.modified == 'true' }}
70 | uses: tedilabs/.github/.github/workflows/terraform.terraform.yaml@main
71 |
72 | strategy:
73 | matrix:
74 | path: ${{ fromJson(needs.changed.outputs.modified_directories) }}
75 |
76 | with:
77 | terraform_target_dir: ${{ matrix.path }}
78 | terraform_version: latest
79 | terraform_host: app.terraform.io
80 | secrets:
81 | gh_token: ${{ secrets.GITHUB_TOKEN }}
82 | token: ${{ secrets.GITHUB_TOKEN }}
83 | terraform_token: ${{ secrets.TERRAFORM_TOKEN }}
84 |
85 |
86 | tflint:
87 | name: Lint (tflint)
88 | needs:
89 | - changed
90 | if: ${{ needs.changed.outputs.modified == 'true' }}
91 | uses: tedilabs/.github/.github/workflows/terraform.tflint.yaml@main
92 |
93 | strategy:
94 | matrix:
95 | path: ${{ fromJson(needs.changed.outputs.modified_directories) }}
96 |
97 | with:
98 | tflint_version: latest
99 | tflint_config_file: .tflint.hcl
100 | tflint_target_dir: ${{ matrix.path }}
101 | tflint_recursive_enabled: false
102 | tflint_terraform_init_enabled: true
103 | terraform_version: latest
104 | terraform_host: app.terraform.io
105 | secrets:
106 | gh_token: ${{ secrets.GITHUB_TOKEN }}
107 | token: ${{ secrets.GITHUB_TOKEN }}
108 | terraform_token: ${{ secrets.TERRAFORM_TOKEN }}
109 |
--------------------------------------------------------------------------------
/.github/workflows/welcome.yaml:
--------------------------------------------------------------------------------
1 | name: Welcome for First Issue or Pull Request
2 |
3 | on:
4 | pull_request_target:
5 | types:
6 | - opened
7 | issues:
8 | types:
9 | - opened
10 |
11 | jobs:
12 | welcome:
13 | runs-on: ubuntu-latest
14 |
15 | steps:
16 | - name: Welcome for First Issue or Pull Request
17 | uses: actions/first-interaction@v1
18 | with:
19 | repo-token: ${{ secrets.GITHUB_TOKEN }}
20 | issue-message: |
21 | ### :wave: Welcome! Looks like this is your first issue.
22 |
23 | Hey, thanks for your contribution! Please give us a bit of time to review it. 😄
24 |
25 | **Be sure to follow the issue template!**
26 | pr-message: |
27 | ### :wave: Welcome! Looks like this is your first pull request.
28 |
29 | Hey, thanks for your contribution! Please give us a bit of time to review it. 😄
30 |
31 | **Please check out our contributing guidelines.**
32 |
--------------------------------------------------------------------------------
/.github/workflows/yaml.integration.yaml:
--------------------------------------------------------------------------------
1 | name: Integration (YAML)
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 | pull_request: {}
8 |
9 | concurrency:
10 | group: yaml-integration-${{ github.ref }}
11 | cancel-in-progress: true
12 |
13 | jobs:
14 | changed:
15 | name: Filter Changed Files and Directories
16 | runs-on: ubuntu-latest
17 |
18 | outputs:
19 | changed: ${{ steps.set-outputs.outputs.changed }}
20 | modified: ${{ steps.set-outputs.outputs.modified }}
21 | changed_files: ${{ steps.set-outputs.outputs.changed_files }}
22 | modified_files: ${{ steps.set-outputs.outputs.modified_files }}
23 |
24 | steps:
25 | - name: Checkout
26 | uses: actions/checkout@v4
27 | with:
28 | fetch-depth: 0
29 |
30 | - name: Get Changed Files
31 | id: changed-files
32 | uses: tj-actions/changed-files@v44
33 | with:
34 | files: |
35 | **/*.yaml
36 | **/*.yml
37 | json: true
38 |
39 | - name: Set outputs
40 | id: set-outputs
41 | run: |
42 | echo "changed=${{ steps.changed-files.outputs.any_changed }}" >> $GITHUB_OUTPUT
43 | echo "modified=${{ steps.changed-files.outputs.any_modified }}" >> $GITHUB_OUTPUT
44 |
45 | echo "changed_files=${{ steps.changed-files.outputs.all_changed_files }}" >> $GITHUB_OUTPUT
46 | echo "modified_files=${{ steps.changed-files.outputs.all_modified_files }}" >> $GITHUB_OUTPUT
47 |
48 | lint:
49 | name: Lint (yamllint)
50 | needs:
51 | - changed
52 | if: ${{ needs.changed.outputs.modified == 'true' }}
53 | uses: tedilabs/.github/.github/workflows/yaml.yamllint.yaml@main
54 |
55 | with:
56 | yamllint_version: latest
57 | yamllint_config_file: .yamllint.yaml
58 | yamllint_target_dir: ./
59 | secrets:
60 | token: ${{ secrets.GITHUB_TOKEN }}
61 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ### OSX ###
2 | # General
3 | .DS_Store
4 | .AppleDouble
5 | .LSOverride
6 |
7 | # Icon must end with two \r
8 | Icon
9 |
10 | # Thumbnails
11 | ._*
12 |
13 | # Files that might appear in the root of a volume
14 | .DocumentRevisions-V100
15 | .fseventsd
16 | .Spotlight-V100
17 | .TemporaryItems
18 | .Trashes
19 | .VolumeIcon.icns
20 | .com.apple.timemachine.donotpresent
21 |
22 | # Directories potentially created on remote AFP share
23 | .AppleDB
24 | .AppleDesktop
25 | Network Trash Folder
26 | Temporary Items
27 | .apdisk
28 |
29 |
30 | ### Terraform ###
31 | # Lock file
32 | .terraform.lock.hcl
33 |
34 | # Local .terraform directories
35 | **/.terraform/*
36 |
37 | # .tfstate files
38 | *.tfstate
39 | *.tfstate.*
40 |
41 | # Crash log files
42 | crash.log
43 |
44 | # Ignore any .tfvars files that are generated automatically for each Terraform run. Most
45 | # .tfvars files are managed as part of configuration and so should be included in
46 | # version control.
47 | #
48 | # example.tfvars
49 |
50 | # Ignore override files as they are usually used to override resources locally and so
51 | # are not checked in
52 | override.tf
53 | override.tf.json
54 | *_override.tf
55 | *_override.tf.json
56 |
57 | # Include override files you do wish to add to version control using negated pattern
58 | # !example_override.tf
59 |
60 | # Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan
61 | # example: *tfplan*
62 |
63 |
64 | ### Vim ###
65 | # Swap
66 | [._]*.s[a-v][a-z]
67 | !*.svg # comment out if you don't need vector files
68 | [._]*.sw[a-p]
69 | [._]s[a-rt-v][a-z]
70 | [._]ss[a-gi-z]
71 | [._]sw[a-p]
72 |
73 | # Session
74 | Session.vim
75 | Sessionx.vim
76 |
77 | # Temporary
78 | .netrwhist
79 | *~
80 | # Auto-generated tag files
81 | tags
82 | # Persistent undo
83 | [._]*.un~
84 |
--------------------------------------------------------------------------------
/.pre-commit-config.yaml:
--------------------------------------------------------------------------------
1 | default_install_hook_types:
2 | - pre-commit
3 | - commit-msg
4 |
5 | repos:
6 | - repo: https://github.com/antonbabenko/pre-commit-terraform
7 | rev: v1.97.4
8 | hooks:
9 | - id: terraform_fmt
10 | name: (terraform) Format .tf files with `terraform fmt`
11 | args:
12 | - --args=-diff
13 | - id: terraform_validate
14 | name: (terraform) Check with `terraform validate`
15 | args:
16 | - --hook-config=--retry-once-with-cleanup=true
17 | - --tf-init-args=-upgrade
18 | - id: terraform_tflint
19 | name: (terraform) Check with `tflint`
20 | args:
21 | - --args=--config=__GIT_WORKING_DIR__/.tflint.hcl
22 | files: ^modules/
23 | - id: terraform_docs
24 | name: (terraform) Generate docs with `terraform-docs`
25 | args: ["--args=--sort-by required"]
26 |
27 | - repo: https://github.com/adrienverge/yamllint
28 | rev: v1.36.2
29 | hooks:
30 | - id: yamllint
31 | name: (yaml) Check with `yamllint`
32 |
33 | - repo: https://github.com/compilerla/conventional-pre-commit
34 | rev: v4.0.0
35 | hooks:
36 | - id: conventional-pre-commit
37 | name: (commit-message) Check conventional commit
38 | stages: [commit-msg]
39 | args: []
40 |
--------------------------------------------------------------------------------
/.tflint.hcl:
--------------------------------------------------------------------------------
1 | config {
2 | plugin_dir = "~/.tflint.d/plugins"
3 |
4 | format = "compact"
5 | call_module_type = "local"
6 | force = false
7 | disabled_by_default = false
8 |
9 | ignore_module = {}
10 | }
11 |
12 |
13 | ###################################################
14 | # Rule Sets - Terraform
15 | ###################################################
16 |
17 | plugin "terraform" {
18 | enabled = true
19 | preset = "recommended"
20 | }
21 |
22 | rule "terraform_comment_syntax" {
23 | enabled = true
24 | }
25 |
26 | rule "terraform_documented_variables" {
27 | enabled = true
28 | }
29 |
30 | rule "terraform_documented_outputs" {
31 | enabled = true
32 | }
33 |
34 | rule "terraform_naming_convention" {
35 | enabled = true
36 | format = "snake_case"
37 |
38 | custom_formats = {
39 | extended_snake_case = {
40 | description = "Extended snake_case Format which allows double underscore like `a__b`."
41 | regex = "^[a-z][a-z0-9]+([_]{1,2}[a-z0-9]+)*$"
42 | }
43 | }
44 |
45 | module {
46 | format = "extended_snake_case"
47 | }
48 |
49 | resource {
50 | format = "extended_snake_case"
51 | }
52 |
53 | data {
54 | format = "extended_snake_case"
55 | }
56 | }
57 |
58 | rule "terraform_unused_declarations" {
59 | enabled = false
60 | }
61 |
62 | rule "terraform_unused_required_providers" {
63 | enabled = true
64 | }
65 |
66 |
67 | ###################################################
68 | # Rule Sets - AWS
69 | ###################################################
70 |
71 | plugin "aws" {
72 | source = "github.com/terraform-linters/tflint-ruleset-aws"
73 | version = "0.38.0"
74 |
75 | enabled = true
76 | deep_check = false
77 | }
78 |
--------------------------------------------------------------------------------
/.yamllint.yaml:
--------------------------------------------------------------------------------
1 | yaml-files:
2 | - '*.yaml'
3 | - '*.yml'
4 |
5 | rules:
6 | braces:
7 | min-spaces-inside: 0
8 | max-spaces-inside: 1
9 | min-spaces-inside-empty: 0
10 | max-spaces-inside-empty: 0
11 | brackets:
12 | min-spaces-inside: 0
13 | max-spaces-inside: 1
14 | min-spaces-inside-empty: 0
15 | max-spaces-inside-empty: 0
16 | colons:
17 | max-spaces-before: 0
18 | max-spaces-after: 1
19 | commas:
20 | max-spaces-before: 0
21 | comments:
22 | level: warning
23 | require-starting-space: true
24 | min-spaces-from-content: 1
25 | comments-indentation: disable
26 | document-end: disable
27 | document-start: disable
28 | empty-lines:
29 | level: warning
30 | max: 2
31 | max-start: 0
32 | max-end: 1
33 | empty-values:
34 | forbid-in-block-mappings: true
35 | forbid-in-flow-mappings: true
36 | hyphens:
37 | max-spaces-after: 1
38 | indentation:
39 | spaces: consistent
40 | indent-sequences: false
41 | key-duplicates: enable
42 | key-ordering: disable
43 | line-length: disable
44 | new-line-at-end-of-file: enable
45 | # Use UNIX new line characters `\n` instead of DOS new line characters `\r\n`
46 | new-lines:
47 | type: unix
48 | octal-values: disable
49 | quoted-strings:
50 | quote-type: any
51 | required: false
52 | trailing-spaces: enable
53 | truthy: disable
54 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # terraform-aws-network
2 |
3 | 
4 | 
5 | [](https://github.com/pre-commit/pre-commit)
6 |
7 | Terraform module which creates network related resources on AWS.
8 |
9 | - [nacl](./modules/nacl)
10 | - [nat-gateway](./modules/nat-gateway)
11 | - [route-table](./modules/route-table)
12 | - [security-group](./modules/security-group)
13 | - [subnet-group](./modules/subnet-group)
14 | - [vpc](./modules/vpc)
15 |
16 |
17 | ## Target AWS Services
18 |
19 | Terraform Modules from [this package](https://github.com/tedilabs/terraform-aws-network) were written to manage the following AWS Services with Terraform.
20 |
21 | - **AWS VPC (Virtual Private Cloud)**
22 | - VPC
23 | - Default Network ACL
24 | - Default Security Group
25 | - Subnet
26 | - Route Table
27 | - NACL (Network ACL)
28 | - Security Group
29 | - Gateways
30 | - Internet Gateway
31 | - Egress-only Internet Gateway
32 | - NAT Gateway
33 | - VPN Gateway (Virtual Private Gateway)
34 |
35 |
36 | ## Examples
37 |
38 | ### VPC
39 |
40 | - [vpc-full](./examples/vpc-full)
41 | - [vpc-ipv4-secondary-cidrs](./examples/vpc-ipv4-secondary-cidrs)
42 | - [vpc-ipv6-cidrs](./examples/vpc-ipv6-cidrs)
43 | - [vpc-simple](./examples/vpc-simple)
44 | - [vpc-with-ipam](./examples/vpc-with-ipam)
45 |
46 | ### Security Group
47 |
48 | - [security-group-simple](./examples/security-group-simple)
49 | - [security-group-with-ipv4-cidrs](./examples/security-group-with-ipv4-cidrs)
50 |
51 | ### NAT Gateway
52 |
53 | - [nat-gateway-public](./examples/nat-gateway-public/)
54 | - [nat-gateway-private](./examples/nat-gateway-private/)
55 | - [nat-gateway-private-secondary-ip-addresses](./examples/nat-gateway-private-secondary-ip-addresses)
56 |
57 |
58 | ## Other Terraform Modules from Tedilabs
59 |
60 | Enjoying [terraform-aws-network](https://github.com/tedilabs/terraform-aws-network)? Check out some of our other modules:
61 |
62 | - [AWS Container](https://github.com/tedilabs/terraform-aws-container) - A package of Terraform Modules to manage AWS Container resources.
63 | - [AWS Domain](https://github.com/tedilabs/terraform-aws-domain) - A package of Terraform Modules to manage AWS Domain resources.
64 | - [AWS IPAM](https://github.com/tedilabs/terraform-aws-ipam) - A package of Terraform Modules to manage AWS IPAM related resources (IPAM, Elastic IP, Prefix List).
65 | - [AWS Load Balancer](https://github.com/tedilabs/terraform-aws-load-balancer) - A package of Terraform Modules to manage AWS Load Balancer resources.
66 | - [AWS Security](https://github.com/tedilabs/terraform-aws-security) - A package of Terraform Modules to manage AWS Security resources.
67 | - [AWS VPC Connectivity](https://github.com/tedilabs/terraform-aws-vpc-connectivity) - A package of Terraform Modules to manage AWS VPC Connectivity related resources (VPC Peering, VPC Private Link, VPC Lattice, Client VPN, Site-to-Site VPN, DX).
68 |
69 | Or check out [the full list](https://github.com/search?q=org%3Atedilabs+topic%3Aterraform-module&type=repositories)
70 |
71 |
72 | ## Self Promotion
73 |
74 | Like this project? Follow the repository on [GitHub](https://github.com/tedilabs/terraform-aws-network). And if you're feeling especially charitable, follow **[posquit0](https://github.com/posquit0)** on GitHub.
75 |
76 |
77 | ## License
78 |
79 | Provided under the terms of the [Apache License](LICENSE).
80 |
81 | Copyright © 2021-2023, [Byungjin Park](https://www.posquit0.com).
82 |
--------------------------------------------------------------------------------
/VERSION:
--------------------------------------------------------------------------------
1 | 0.32.2
2 |
--------------------------------------------------------------------------------
/examples/nat-gateway-private-secondary-ip-addresses/main.tf:
--------------------------------------------------------------------------------
1 | provider "aws" {
2 | region = "us-east-1"
3 | }
4 |
5 | data "aws_vpc" "default" {
6 | default = true
7 | }
8 |
9 | data "aws_subnets" "default" {
10 | filter {
11 | name = "vpc-id"
12 | values = [data.aws_vpc.default.id]
13 | }
14 | }
15 |
16 |
17 | ###################################################
18 | # Public NAT Gateway
19 | ###################################################
20 |
21 | module "nat_gateway" {
22 | source = "../../modules/nat-gateway"
23 | # source = "tedilabs/network/aws//modules/nat-gateway"
24 | # version = "~> 0.2.0"
25 |
26 | name = "test-count"
27 | is_private = true
28 | subnet = data.aws_subnets.default.ids[0]
29 |
30 |
31 | ## Primary IP Address
32 | primary_ip_assignment = {
33 | # Automatically assign a public IP address to the NAT Gateway
34 | private_ip = null
35 | }
36 |
37 |
38 | ## Secondary IP Addresses
39 | secondary_ip_count = 7
40 |
41 |
42 | tags = {
43 | "project" = "terraform-aws-network-examples"
44 | }
45 | }
46 |
47 | module "nat_gateway_2" {
48 | source = "../../modules/nat-gateway"
49 | # source = "tedilabs/network/aws//modules/nat-gateway"
50 | # version = "~> 0.2.0"
51 |
52 | name = "test-assingments"
53 | is_private = true
54 | subnet = data.aws_subnets.default.ids[0]
55 |
56 |
57 | ## Primary IP Address
58 | primary_ip_assignment = {
59 | # Automatically assign a public IP address to the NAT Gateway
60 | private_ip = "172.31.51.100"
61 | }
62 |
63 |
64 | ## Secondary IP Addresses
65 | secondary_ip_assignments = [
66 | {
67 | private_ip = "172.31.51.101"
68 | },
69 | {
70 | private_ip = "172.31.51.102"
71 | },
72 | {
73 | private_ip = "172.31.51.103"
74 | },
75 | {
76 | private_ip = "172.31.51.104"
77 | },
78 | ]
79 |
80 |
81 | tags = {
82 | "project" = "terraform-aws-network-examples"
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/examples/nat-gateway-private-secondary-ip-addresses/outputs.tf:
--------------------------------------------------------------------------------
1 | output "nat_gateway" {
2 | description = "The NAT Gateways."
3 | value = {
4 | count = module.nat_gateway
5 | assignments = module.nat_gateway_2
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/examples/nat-gateway-private-secondary-ip-addresses/versions.tf:
--------------------------------------------------------------------------------
1 | terraform {
2 | required_version = "~> 1.5"
3 |
4 | required_providers {
5 | aws = {
6 | source = "hashicorp/aws"
7 | version = "~> 5.0"
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/examples/nat-gateway-private/main.tf:
--------------------------------------------------------------------------------
1 | provider "aws" {
2 | region = "us-east-1"
3 | }
4 |
5 | data "aws_vpc" "default" {
6 | default = true
7 | }
8 |
9 | data "aws_subnets" "default" {
10 | filter {
11 | name = "vpc-id"
12 | values = [data.aws_vpc.default.id]
13 | }
14 | }
15 |
16 |
17 | ###################################################
18 | # Public NAT Gateway
19 | ###################################################
20 |
21 | module "nat_gateway" {
22 | source = "../../modules/nat-gateway"
23 | # source = "tedilabs/network/aws//modules/nat-gateway"
24 | # version = "~> 0.2.0"
25 |
26 | name = "test/az1"
27 | is_private = true
28 | subnet = data.aws_subnets.default.ids[0]
29 |
30 |
31 | ## Primary IP Address
32 | primary_ip_assignment = {
33 | # Automatically assign a public IP address to the NAT Gateway
34 | private_ip = null
35 | }
36 |
37 |
38 | tags = {
39 | "project" = "terraform-aws-network-examples"
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/examples/nat-gateway-private/outputs.tf:
--------------------------------------------------------------------------------
1 | output "nat_gateway" {
2 | description = "The NAT Gateway."
3 | value = module.nat_gateway
4 | }
5 |
--------------------------------------------------------------------------------
/examples/nat-gateway-private/versions.tf:
--------------------------------------------------------------------------------
1 | terraform {
2 | required_version = "~> 1.5"
3 |
4 | required_providers {
5 | aws = {
6 | source = "hashicorp/aws"
7 | version = "~> 5.0"
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/examples/nat-gateway-public/main.tf:
--------------------------------------------------------------------------------
1 | provider "aws" {
2 | region = "us-east-1"
3 | }
4 |
5 | data "aws_vpc" "default" {
6 | default = true
7 | }
8 |
9 | data "aws_subnets" "default" {
10 | filter {
11 | name = "vpc-id"
12 | values = [data.aws_vpc.default.id]
13 | }
14 | }
15 |
16 |
17 | ###################################################
18 | # Elastic IP
19 | ###################################################
20 |
21 | module "elastic_ip" {
22 | source = "tedilabs/ipam/aws//modules/elastic-ip"
23 | version = "~> 0.3.0"
24 |
25 | name = "nat-gw-public"
26 | type = "AMAZON"
27 |
28 | tags = {
29 | "project" = "terraform-aws-network-examples"
30 | }
31 | }
32 |
33 |
34 | ###################################################
35 | # Public NAT Gateway
36 | ###################################################
37 |
38 | module "nat_gateway" {
39 | source = "../../modules/nat-gateway"
40 | # source = "tedilabs/network/aws//modules/nat-gateway"
41 | # version = "~> 0.2.0"
42 |
43 | name = "test/az1"
44 | is_private = false
45 | subnet = data.aws_subnets.default.ids[0]
46 |
47 |
48 | ## Primary IP Address
49 | primary_ip_assignment = {
50 | elastic_ip = module.elastic_ip.id
51 | }
52 |
53 |
54 | tags = {
55 | "project" = "terraform-aws-network-examples"
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/examples/nat-gateway-public/outputs.tf:
--------------------------------------------------------------------------------
1 | output "elastic_ip" {
2 | description = "The Elastic IP."
3 | value = module.elastic_ip
4 | }
5 |
6 | output "nat_gateway" {
7 | description = "The NAT Gateway."
8 | value = module.nat_gateway
9 | }
10 |
--------------------------------------------------------------------------------
/examples/nat-gateway-public/versions.tf:
--------------------------------------------------------------------------------
1 | terraform {
2 | required_version = "~> 1.5"
3 |
4 | required_providers {
5 | aws = {
6 | source = "hashicorp/aws"
7 | version = "~> 5.0"
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/examples/security-group-simple/main.tf:
--------------------------------------------------------------------------------
1 | provider "aws" {
2 | region = "us-east-1"
3 | }
4 |
5 | data "aws_vpc" "default" {
6 | default = true
7 | }
8 |
9 |
10 | ###################################################
11 | # Security Group
12 | ###################################################
13 |
14 | module "security_group" {
15 | source = "../../modules/security-group"
16 | # source = "tedilabs/ipam/aws//modules/security-group"
17 | # version = "~> 0.30.0"
18 |
19 | vpc_id = data.aws_vpc.default.id
20 |
21 | name = "hello-world"
22 |
23 | tags = {
24 | "project" = "terraform-aws-network-examples"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/examples/security-group-simple/outputs.tf:
--------------------------------------------------------------------------------
1 | output "security_group" {
2 | description = "The Security Group."
3 | value = module.security_group
4 | }
5 |
--------------------------------------------------------------------------------
/examples/security-group-simple/versions.tf:
--------------------------------------------------------------------------------
1 | terraform {
2 | required_version = "~> 1.5"
3 |
4 | required_providers {
5 | aws = {
6 | source = "hashicorp/aws"
7 | version = "~> 5.0"
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/examples/security-group-with-ipv4-cidrs/main.tf:
--------------------------------------------------------------------------------
1 | provider "aws" {
2 | region = "us-east-1"
3 | }
4 |
5 | data "aws_vpc" "default" {
6 | default = true
7 | }
8 |
9 |
10 | ###################################################
11 | # Security Group
12 | ###################################################
13 |
14 | module "security_group" {
15 | source = "../../modules/security-group"
16 | # source = "tedilabs/ipam/aws//modules/security-group"
17 | # version = "~> 0.30.0"
18 |
19 | vpc_id = data.aws_vpc.default.id
20 |
21 | name = "hello-world-ipv4-cidrs"
22 | description = "Sample Security Group with IPv4 CIDRs."
23 |
24 | revoke_rules_on_delete = true
25 |
26 | ingress_rules = [
27 | {
28 | id = "tcp/80"
29 | description = "Allow HTTP from VPC"
30 | from_port = 80
31 | to_port = 80
32 | protocol = "tcp"
33 | ipv4_cidrs = ["192.168.0.0/16", "10.0.0.0/8", "172.168.0.0/24"]
34 | },
35 | ]
36 | egress_rules = [
37 | {
38 | id = "all/all"
39 | description = "Allow all traffics to the internet"
40 | from_port = 0
41 | to_port = 0
42 | protocol = "-1"
43 | ipv4_cidrs = ["0.0.0.0/0"]
44 | },
45 | ]
46 |
47 | tags = {
48 | "project" = "terraform-aws-network-examples"
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/examples/security-group-with-ipv4-cidrs/outputs.tf:
--------------------------------------------------------------------------------
1 | output "security_group" {
2 | description = "The Security Group."
3 | value = module.security_group
4 | }
5 |
--------------------------------------------------------------------------------
/examples/security-group-with-ipv4-cidrs/versions.tf:
--------------------------------------------------------------------------------
1 | terraform {
2 | required_version = "~> 1.5"
3 |
4 | required_providers {
5 | aws = {
6 | source = "hashicorp/aws"
7 | version = "~> 5.0"
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/examples/vpc-full/main.tf:
--------------------------------------------------------------------------------
1 | provider "aws" {
2 | region = "us-east-1"
3 | }
4 |
5 |
6 | ###################################################
7 | # VPC
8 | ###################################################
9 |
10 | module "vpc" {
11 | source = "../../modules/vpc"
12 | # source = "tedilabs/network/aws//modules/vpc"
13 | # version = "~> 0.2.0"
14 |
15 | name = "test"
16 | ipv4_cidrs = [
17 | {
18 | cidr = "10.0.0.0/16"
19 | },
20 | ]
21 | ipv6_cidrs = [
22 | {
23 | type = "AMAZON"
24 | },
25 | ]
26 |
27 |
28 | ## DHCP Option Set
29 | dhcp_options = {
30 | enabled = true
31 | domain_name = "example.com"
32 | domain_name_servers = ["4.4.4.4", "8.8.8.8"]
33 | }
34 |
35 |
36 | ## Gateways
37 | internet_gateway = {
38 | enabled = true
39 | }
40 | egress_only_internet_gateway = {
41 | enabled = true
42 | }
43 | vpn_gateway = {
44 | enabled = true
45 | }
46 |
47 |
48 | ## Defaults
49 | default_network_acl = {
50 | name = "test-default"
51 | ingress_rules = [
52 | {
53 | priority = 200
54 | action = "ALLOW"
55 | protocol = "tcp"
56 | from_port = 443
57 | to_port = 443
58 | ipv4_cidr = "0.0.0.0/0"
59 | },
60 | {
61 | priority = 201
62 | action = "ALLOW"
63 | protocol = "tcp"
64 | from_port = 443
65 | to_port = 443
66 | ipv6_cidr = "::/0"
67 | },
68 | ]
69 | }
70 | default_security_group = {
71 | name = "test-default"
72 | ingress_rules = [
73 | {
74 | protocol = "tcp"
75 | from_port = 80
76 | to_port = 80
77 | ipv4_cidrs = ["10.0.0.0/16"]
78 | },
79 | {
80 | protocol = "tcp"
81 | from_port = 443
82 | to_port = 443
83 | self = true
84 | },
85 | ]
86 | egress_rules = [
87 | {
88 | protocol = "all"
89 | from_port = 0
90 | to_port = 0
91 | ipv4_cidrs = ["0.0.0.0/0"]
92 | ipv6_cidrs = ["::/0"]
93 | }
94 | ]
95 | }
96 |
97 |
98 | tags = {
99 | "project" = "terraform-aws-network-examples"
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/examples/vpc-full/nacls.tf:
--------------------------------------------------------------------------------
1 | ###################################################
2 | # Network ACLs
3 | ###################################################
4 |
5 | module "private_network_acl" {
6 | source = "../../modules/nacl"
7 | # source = "tedilabs/network/aws//modules/nacl"
8 | # version = "~> 0.2.0"
9 |
10 | name = "test-private"
11 | vpc_id = module.vpc.id
12 | subnets = module.private_subnet_group.ids
13 |
14 | ingress_rules = {
15 | 900 = {
16 | action = "ALLOW"
17 | protocol = "-1"
18 | ipv4_cidr = "10.0.0.0/16"
19 | }
20 | }
21 | egress_rules = {
22 | 900 = {
23 | action = "ALLOW"
24 | protocol = "-1"
25 | ipv4_cidr = "10.0.0.0/16"
26 | }
27 | }
28 |
29 | tags = {
30 | "project" = "terraform-aws-network-examples"
31 | }
32 | }
33 |
34 | module "public_network_acl" {
35 | source = "../../modules/nacl"
36 | # source = "tedilabs/network/aws//modules/nacl"
37 | # version = "~> 0.2.0"
38 |
39 | name = "test-public"
40 | vpc_id = module.vpc.id
41 | subnets = module.public_subnet_group.ids
42 |
43 | ingress_rules = {
44 | 100 = {
45 | action = "ALLOW"
46 | protocol = "icmp"
47 | ipv4_cidr = "0.0.0.0/0"
48 | icmp_type = -1
49 | icmp_code = -1
50 | }
51 | 200 = {
52 | action = "ALLOW"
53 | protocol = "tcp"
54 | ipv4_cidr = "0.0.0.0/0"
55 | from_port = 22
56 | to_port = 22
57 | }
58 | 300 = {
59 | action = "ALLOW"
60 | protocol = "tcp"
61 | ipv4_cidr = "0.0.0.0/0"
62 | from_port = 80
63 | to_port = 80
64 | }
65 | 310 = {
66 | action = "ALLOW"
67 | protocol = "tcp"
68 | ipv4_cidr = "0.0.0.0/0"
69 | from_port = 443
70 | to_port = 443
71 | }
72 | 800 = {
73 | action = "ALLOW"
74 | protocol = "tcp"
75 | ipv4_cidr = "0.0.0.0/0"
76 | from_port = 1024
77 | to_port = 65535
78 | }
79 | 801 = {
80 | action = "ALLOW"
81 | protocol = "udp"
82 | ipv4_cidr = "0.0.0.0/0"
83 | from_port = 1024
84 | to_port = 65535
85 | }
86 | 900 = {
87 | action = "ALLOW"
88 | protocol = "-1"
89 | ipv4_cidr = "10.0.0.0/16"
90 | }
91 | }
92 | egress_rules = {
93 | 900 = {
94 | action = "ALLOW"
95 | protocol = "-1"
96 | ipv4_cidr = "0.0.0.0/0"
97 | }
98 | }
99 |
100 | tags = {
101 | "project" = "terraform-aws-network-examples"
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/examples/vpc-full/nat-gateways.tf:
--------------------------------------------------------------------------------
1 | ###################################################
2 | # Elastic IP
3 | ###################################################
4 |
5 | module "elastic_ip" {
6 | source = "tedilabs/ipam/aws//modules/elastic-ip"
7 | version = "~> 0.3.0"
8 |
9 | name = "nat-gw-test-public/az2"
10 | type = "AMAZON"
11 |
12 | tags = {
13 | "project" = "terraform-aws-network-examples"
14 | }
15 | }
16 |
17 |
18 | ###################################################
19 | # Public NAT Gateway
20 | ###################################################
21 |
22 | module "public_nat_gateway" {
23 | source = "../../modules/nat-gateway"
24 | # source = "tedilabs/network/aws//modules/nat-gateway"
25 | # version = "~> 0.2.0"
26 |
27 | name = "test-public/az2"
28 | is_private = false
29 | subnet = module.public_subnet_group.subnets_by_az["use1-az2"][0].id
30 |
31 |
32 | ## Primary IP Address
33 | primary_ip_assignment = {
34 | elastic_ip = module.elastic_ip.id
35 | }
36 |
37 |
38 | tags = {
39 | "project" = "terraform-aws-network-examples"
40 | }
41 | }
42 |
43 |
44 | ###################################################
45 | # Private NAT Gateway
46 | ###################################################
47 |
48 | module "private_nat_gateway" {
49 | source = "../../modules/nat-gateway"
50 | # source = "tedilabs/network/aws//modules/nat-gateway"
51 | # version = "~> 0.2.0"
52 |
53 | name = "test-private/az2"
54 | is_private = true
55 | subnet = module.private_subnet_group.subnets_by_az["use1-az2"][0].id
56 |
57 |
58 | ## Primary IP Address
59 | primary_ip_assignment = {
60 | private_ip = "10.0.200.7"
61 | }
62 |
63 |
64 | tags = {
65 | "project" = "terraform-aws-network-examples"
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/examples/vpc-full/outputs.tf:
--------------------------------------------------------------------------------
1 | output "vpc" {
2 | description = "The VPC."
3 | value = module.vpc
4 | }
5 |
6 | output "subnet_groups" {
7 | description = "The Subnet Groups for the VPC."
8 | value = {
9 | private = module.private_subnet_group
10 | public = module.public_subnet_group
11 | }
12 | }
13 |
14 | output "nat_gateways" {
15 | description = "The NAT Gateways."
16 | value = {
17 | public = module.public_nat_gateway
18 | private = module.private_nat_gateway
19 | }
20 | }
21 |
22 | output "nacls" {
23 | description = "The Network ACLs."
24 | value = {
25 | public = module.public_network_acl
26 | private = module.private_network_acl
27 | }
28 | }
29 |
30 | output "route_tables" {
31 | description = "The Route Tables."
32 | value = {
33 | public = module.public_route_table
34 | private = module.private_route_table
35 | }
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/examples/vpc-full/route-tables.tf:
--------------------------------------------------------------------------------
1 | ###################################################
2 | # Route Tables
3 | ###################################################
4 |
5 | module "private_route_table" {
6 | source = "../../modules/route-table"
7 | # source = "tedilabs/network/aws//modules/route-table"
8 | # version = "~> 0.2.0"
9 |
10 | name = "test-private"
11 | vpc_id = module.vpc.id
12 | subnets = module.private_subnet_group.ids
13 | gateways = []
14 |
15 |
16 | ## Route Rules
17 | ipv4_routes = [
18 | {
19 | destination = "0.0.0.0/0"
20 | target = {
21 | type = "NAT_GATEWAY"
22 | id = module.public_nat_gateway.id
23 | }
24 | },
25 | ]
26 | ipv6_routes = []
27 | prefix_list_routes = []
28 |
29 | vpc_gateway_endpoints = []
30 | propagating_vpn_gateways = []
31 |
32 |
33 | tags = {
34 | "project" = "terraform-aws-network-examples"
35 | }
36 | }
37 |
38 | module "public_route_table" {
39 | source = "../../modules/route-table"
40 | # source = "tedilabs/network/aws//modules/route-table"
41 | # version = "~> 0.2.0"
42 |
43 | name = "test-public"
44 | vpc_id = module.vpc.id
45 | subnets = module.public_subnet_group.ids
46 | gateways = []
47 |
48 |
49 | ## Route Rules
50 | ipv4_routes = [
51 | {
52 | destination = "0.0.0.0/0"
53 | target = {
54 | type = "INTERNET_GATEWAY"
55 | id = module.vpc.internet_gateway.id
56 | }
57 | },
58 | ]
59 | ipv6_routes = []
60 | prefix_list_routes = []
61 |
62 | vpc_gateway_endpoints = []
63 | propagating_vpn_gateways = []
64 |
65 |
66 | tags = {
67 | "project" = "terraform-aws-network-examples"
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/examples/vpc-full/subnet-groups.tf:
--------------------------------------------------------------------------------
1 | ###################################################
2 | # Subnet Groups
3 | ###################################################
4 |
5 | module "private_subnet_group" {
6 | source = "../../modules/subnet-group"
7 | # source = "tedilabs/network/aws//modules/subnet-group"
8 | # version = "~> 0.2.0"
9 |
10 | name = "test-private"
11 |
12 | vpc_id = module.vpc.id
13 |
14 | subnets = {
15 | "test-private/az2" = {
16 | availability_zone_id = "use1-az2"
17 | ipv4_cidr = "10.0.200.0/24"
18 | }
19 | "test-private/az4" = {
20 | availability_zone_id = "use1-az4"
21 | ipv4_cidr = "10.0.201.0/24"
22 | }
23 | }
24 |
25 |
26 | ## IP Assignments
27 | public_ipv4_address_assignment = {
28 | enabled = false
29 | }
30 | ipv6_address_assignment = {
31 | enabled = false
32 | }
33 | customer_owned_ipv4_address_assignment = {
34 | enabled = false
35 | }
36 |
37 |
38 | ## DNS Configurations
39 | dns_config = {
40 | hostname_type = "RESOURCE_NAME"
41 | dns_resource_name_ipv4_enabled = true
42 | dns_resource_name_ipv6_enabled = false
43 | dns64_enabled = false
44 | }
45 |
46 | ## Integrations
47 | dax_subnet_group = {
48 | enabled = true
49 | name = "test-dax"
50 | description = "Test DAX Subnet Group"
51 | }
52 | dms_replication_subnet_group = {
53 | enabled = true
54 | name = "test-dms-replication"
55 | description = "Test DMS Replication Subnet Group"
56 | }
57 | docdb_subnet_group = {
58 | enabled = true
59 | name = "test-docdb"
60 | description = "Test DocumentDB Subnet Group"
61 | }
62 | elasticache_subnet_group = {
63 | enabled = true
64 | name = "test-elasticache"
65 | description = "Test ElastiCache Subnet Group"
66 | }
67 | memorydb_subnet_group = {
68 | enabled = true
69 | name = "test-memorydb"
70 | description = "Test MemoryDB Subnet Group"
71 | }
72 | neptune_subnet_group = {
73 | enabled = true
74 | name = "test-neptune"
75 | description = "Test Neptune Subnet Group"
76 | }
77 | rds_subnet_group = {
78 | enabled = true
79 | name = "test-rds"
80 | description = "Test RDS Subnet Group"
81 | }
82 | redshift_subnet_group = {
83 | enabled = true
84 | name = "test-redshift"
85 | description = "Test Redshift Subnet Group"
86 | }
87 |
88 |
89 | ## Sharing
90 | shares = [
91 | # {
92 | # name = "team1"
93 | # principals = ["123456789012"]
94 | # },
95 | ]
96 |
97 | tags = {
98 | "project" = "terraform-aws-network-examples"
99 | }
100 | }
101 |
102 | module "public_subnet_group" {
103 | source = "../../modules/subnet-group"
104 | # source = "tedilabs/network/aws//modules/subnet-group"
105 | # version = "~> 0.2.0"
106 |
107 | name = "test-public"
108 |
109 | vpc_id = module.vpc.id
110 |
111 | subnets = {
112 | "test-public/az2" = {
113 | availability_zone_id = "use1-az2"
114 | ipv4_cidr = "10.0.100.0/24"
115 | }
116 | "test-public/az4" = {
117 | availability_zone_id = "use1-az4"
118 | ipv4_cidr = "10.0.101.0/24"
119 | }
120 | }
121 |
122 |
123 | ## IP Assignments
124 | public_ipv4_address_assignment = {
125 | enabled = true
126 | }
127 | ipv6_address_assignment = {
128 | enabled = false
129 | }
130 | customer_owned_ipv4_address_assignment = {
131 | enabled = false
132 | }
133 |
134 |
135 | ## DNS Configurations
136 | dns_config = {
137 | hostname_type = "RESOURCE_NAME"
138 | dns_resource_name_ipv4_enabled = true
139 | dns_resource_name_ipv6_enabled = false
140 | dns64_enabled = false
141 | }
142 |
143 |
144 | tags = {
145 | "project" = "terraform-aws-network-examples"
146 | }
147 | }
148 |
--------------------------------------------------------------------------------
/examples/vpc-full/versions.tf:
--------------------------------------------------------------------------------
1 | terraform {
2 | required_version = "~> 1.5"
3 |
4 | required_providers {
5 | aws = {
6 | source = "hashicorp/aws"
7 | version = "~> 5.0"
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/examples/vpc-ipv4-secondary-cidrs/main.tf:
--------------------------------------------------------------------------------
1 | provider "aws" {
2 | region = "us-east-1"
3 | }
4 |
5 |
6 | ###################################################
7 | # VPC
8 | ###################################################
9 |
10 | module "vpc" {
11 | source = "../../modules/vpc"
12 | # source = "tedilabs/network/aws//modules/vpc"
13 | # version = "~> 0.2.0"
14 |
15 | name = "test"
16 | ipv4_cidrs = [
17 | {
18 | cidr = "10.0.0.0/16"
19 | },
20 | {
21 | cidr = "10.1.0.0/16"
22 | },
23 | {
24 | cidr = "10.2.0.0/16"
25 | },
26 | ]
27 |
28 | tags = {
29 | "project" = "terraform-aws-network-examples"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/examples/vpc-ipv4-secondary-cidrs/outputs.tf:
--------------------------------------------------------------------------------
1 | output "vpc" {
2 | description = "The VPC."
3 | value = module.vpc
4 | }
5 |
--------------------------------------------------------------------------------
/examples/vpc-ipv4-secondary-cidrs/versions.tf:
--------------------------------------------------------------------------------
1 | terraform {
2 | required_version = "~> 1.5"
3 |
4 | required_providers {
5 | aws = {
6 | source = "hashicorp/aws"
7 | version = "~> 5.0"
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/examples/vpc-ipv6-cidrs/main.tf:
--------------------------------------------------------------------------------
1 | provider "aws" {
2 | region = "us-east-1"
3 | }
4 |
5 |
6 | ###################################################
7 | # VPC
8 | ###################################################
9 |
10 | module "vpc" {
11 | source = "../../modules/vpc"
12 | # source = "tedilabs/network/aws//modules/vpc"
13 | # version = "~> 0.2.0"
14 |
15 | name = "test"
16 | ipv4_cidrs = [
17 | {
18 | cidr = "10.0.0.0/16"
19 | },
20 | ]
21 | ipv6_cidrs = [
22 | {
23 | type = "AMAZON"
24 | },
25 | ]
26 |
27 | tags = {
28 | "project" = "terraform-aws-network-examples"
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/examples/vpc-ipv6-cidrs/outputs.tf:
--------------------------------------------------------------------------------
1 | output "vpc" {
2 | description = "The VPC."
3 | value = module.vpc
4 | }
5 |
--------------------------------------------------------------------------------
/examples/vpc-ipv6-cidrs/versions.tf:
--------------------------------------------------------------------------------
1 | terraform {
2 | required_version = "~> 1.5"
3 |
4 | required_providers {
5 | aws = {
6 | source = "hashicorp/aws"
7 | version = "~> 5.0"
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/examples/vpc-simple/main.tf:
--------------------------------------------------------------------------------
1 | provider "aws" {
2 | region = "us-east-1"
3 | }
4 |
5 |
6 | ###################################################
7 | # VPC
8 | ###################################################
9 |
10 | module "vpc" {
11 | source = "../../modules/vpc"
12 | # source = "tedilabs/network/aws//modules/vpc"
13 | # version = "~> 0.2.0"
14 |
15 | name = "test"
16 | ipv4_cidrs = [
17 | {
18 | cidr = "10.0.0.0/16"
19 | },
20 | ]
21 |
22 | tags = {
23 | "project" = "terraform-aws-network-examples"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/examples/vpc-simple/outputs.tf:
--------------------------------------------------------------------------------
1 | output "vpc" {
2 | description = "The VPC."
3 | value = module.vpc
4 | }
5 |
--------------------------------------------------------------------------------
/examples/vpc-simple/versions.tf:
--------------------------------------------------------------------------------
1 | terraform {
2 | required_version = "~> 1.5"
3 |
4 | required_providers {
5 | aws = {
6 | source = "hashicorp/aws"
7 | version = "~> 5.0"
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/examples/vpc-with-ipam/ipam.tf:
--------------------------------------------------------------------------------
1 | data "aws_region" "this" {}
2 |
3 | locals {
4 | region = data.aws_region.this.name
5 | }
6 |
7 |
8 | ###################################################
9 | # IPAM
10 | ###################################################
11 |
12 | module "ipam" {
13 | source = "tedilabs/ipam/aws//modules/ipam"
14 | version = "~> 0.1.0"
15 |
16 | name = "test"
17 | description = "Managed by Terraform."
18 |
19 | operating_regions = [local.region]
20 |
21 | tags = {
22 | "project" = "terraform-aws-network-examples"
23 | }
24 | }
25 |
26 |
27 | ###################################################
28 | # IPAM Pools
29 | ###################################################
30 |
31 | resource "aws_vpc_ipam_pool" "ipv4" {
32 | address_family = "ipv4"
33 | ipam_scope_id = module.ipam.default_scopes["private"]
34 | locale = local.region
35 | }
36 |
37 | resource "aws_vpc_ipam_pool_cidr" "ipv4" {
38 | ipam_pool_id = aws_vpc_ipam_pool.ipv4.id
39 | cidr = "10.20.0.0/16"
40 |
41 | }
42 |
43 | resource "aws_vpc_ipam_pool" "ipv6" {
44 | address_family = "ipv6"
45 | ipam_scope_id = module.ipam.default_scopes["public"]
46 | locale = local.region
47 | publicly_advertisable = false
48 | public_ip_source = "amazon"
49 | aws_service = "ec2"
50 | }
51 |
52 | resource "aws_vpc_ipam_pool_cidr" "ipv6" {
53 | ipam_pool_id = aws_vpc_ipam_pool.ipv6.id
54 | netmask_length = 52
55 | }
56 |
--------------------------------------------------------------------------------
/examples/vpc-with-ipam/main.tf:
--------------------------------------------------------------------------------
1 | provider "aws" {
2 | region = "us-east-1"
3 | }
4 |
5 |
6 | ###################################################
7 | # VPC
8 | ###################################################
9 |
10 | module "vpc" {
11 | source = "../../modules/vpc"
12 | # source = "tedilabs/network/aws//modules/vpc"
13 | # version = "~> 0.2.0"
14 |
15 | name = "test"
16 | ipv4_cidrs = [
17 | {
18 | type = "IPAM_POOL"
19 | ipam_pool = {
20 | id = aws_vpc_ipam_pool.ipv4.id
21 | netmask_length = 28
22 | }
23 | },
24 | {
25 | cidr = "10.0.0.0/16"
26 | },
27 | {
28 | type = "IPAM_POOL"
29 | ipam_pool = {
30 | id = aws_vpc_ipam_pool.ipv4.id
31 | netmask_length = 28
32 | }
33 | },
34 | ]
35 | ipv6_cidrs = [
36 | {
37 | type = "AMAZON"
38 | },
39 | {
40 | type = "IPAM_POOL"
41 | ipam_pool = {
42 | id = aws_vpc_ipam_pool.ipv6.id
43 | netmask_length = 56
44 | }
45 | },
46 | {
47 | type = "IPAM_POOL"
48 | ipam_pool = {
49 | id = aws_vpc_ipam_pool.ipv6.id
50 | cidr = "2600:1f28:7f:4100::/56"
51 | }
52 | },
53 | ]
54 |
55 | tags = {
56 | "project" = "terraform-aws-network-examples"
57 | }
58 |
59 | depends_on = [
60 | aws_vpc_ipam_pool_cidr.ipv4,
61 | aws_vpc_ipam_pool_cidr.ipv6,
62 | ]
63 | }
64 |
--------------------------------------------------------------------------------
/examples/vpc-with-ipam/outputs.tf:
--------------------------------------------------------------------------------
1 | output "vpc" {
2 | description = "The VPC."
3 | value = module.vpc
4 | }
5 |
--------------------------------------------------------------------------------
/examples/vpc-with-ipam/versions.tf:
--------------------------------------------------------------------------------
1 | terraform {
2 | required_version = "~> 1.5"
3 |
4 | required_providers {
5 | aws = {
6 | source = "hashicorp/aws"
7 | version = "~> 5.0"
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/modules/nacl/README.md:
--------------------------------------------------------------------------------
1 | # nacl
2 |
3 | This module creates following resources.
4 |
5 | - `aws_network_acl`
6 | - `aws_network_acl_association` (optional)
7 | - `aws_network_acl_rule` (optional)
8 |
9 |
10 | ## Requirements
11 |
12 | | Name | Version |
13 | |------|---------|
14 | | [terraform](#requirement\_terraform) | >= 1.6 |
15 | | [aws](#requirement\_aws) | >= 4.59 |
16 |
17 | ## Providers
18 |
19 | | Name | Version |
20 | |------|---------|
21 | | [aws](#provider\_aws) | 5.22.0 |
22 |
23 | ## Modules
24 |
25 | | Name | Source | Version |
26 | |------|--------|---------|
27 | | [resource\_group](#module\_resource\_group) | tedilabs/misc/aws//modules/resource-group | ~> 0.10.0 |
28 |
29 | ## Resources
30 |
31 | | Name | Type |
32 | |------|------|
33 | | [aws_network_acl.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/network_acl) | resource |
34 | | [aws_network_acl_rule.egress](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/network_acl_rule) | resource |
35 | | [aws_network_acl_rule.ingress](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/network_acl_rule) | resource |
36 |
37 | ## Inputs
38 |
39 | | Name | Description | Type | Default | Required |
40 | |------|-------------|------|---------|:--------:|
41 | | [name](#input\_name) | (Required) Desired name for the network ACL resources. | `string` | n/a | yes |
42 | | [vpc\_id](#input\_vpc\_id) | (Required) The ID of the VPC to associate. | `string` | n/a | yes |
43 | | [egress\_rules](#input\_egress\_rules) | (Optional) A set of egress rules in the default Network ACL. Use the key of map as the rule number (priority). If not explicitly defined, the AWS default rules are applied. Each block of `egress_rules` as defined below.
(Required) `priority` - The rule priority. The rule number. Used for ordering.
(Required) `action` - The action to indicate whether to allow or deny the traffic that matches the rule. Valid values are `ALLOW` and `DENY`.
(Required) `protocol` - The protocol to match. If using the `-1` 'all' protocol, you must specify a from and to port of `0`.
(Optional) `from_port` - The from port to match.
(Optional) `to_port` - The to port to match.
(Optional) `ipv4_cidr` - The IPv4 network range to allow or deny, in CIDR notation. Cannot be specified with `ipv6_cidr`.
(Optional) `ipv6_cidr` - The IPv6 network range to allow or deny, in CIDR notation. Cannot be specified with `ipv4_cidr`.
(Optional) `icmp_type` - The ICMP type to be used. Defaults to `0`.
(Optional) `icmp_code` - The ICMP code to be used. Defaults to `0`. |
map(object({| `{}` | no | 44 | | [ingress\_rules](#input\_ingress\_rules) | (Optional) A map of ingress rules in the default Network ACL. Use the key of map as the rule number (priority). If not explicitly defined, the AWS default rules are applied. Each block of `ingress_rules` as defined below.
action = string
protocol = string
from_port = optional(number)
to_port = optional(number)
ipv4_cidr = optional(string)
ipv6_cidr = optional(string)
icmp_type = optional(number, 0)
icmp_code = optional(number, 0)
}))
map(object({| `{}` | no | 45 | | [module\_tags\_enabled](#input\_module\_tags\_enabled) | (Optional) Whether to create AWS Resource Tags for the module informations. | `bool` | `true` | no | 46 | | [resource\_group\_description](#input\_resource\_group\_description) | (Optional) The description of Resource Group. | `string` | `"Managed by Terraform."` | no | 47 | | [resource\_group\_enabled](#input\_resource\_group\_enabled) | (Optional) Whether to create Resource Group to find and group AWS resources which are created by this module. | `bool` | `true` | no | 48 | | [resource\_group\_name](#input\_resource\_group\_name) | (Optional) The name of Resource Group. A Resource Group name can have a maximum of 127 characters, including letters, numbers, hyphens, dots, and underscores. The name cannot start with `AWS` or `aws`. | `string` | `""` | no | 49 | | [subnets](#input\_subnets) | (Optional) A list of subnet IDs to apply the ACL to. | `list(string)` | `[]` | no | 50 | | [tags](#input\_tags) | (Optional) A map of tags to add to all resources. | `map(string)` | `{}` | no | 51 | 52 | ## Outputs 53 | 54 | | Name | Description | 55 | |------|-------------| 56 | | [arn](#output\_arn) | The ARN of the network ACL. | 57 | | [id](#output\_id) | The ID of the network ACL. | 58 | | [name](#output\_name) | The name of the network ACL. | 59 | | [owner\_id](#output\_owner\_id) | The ID of the AWS account that owns the network ACL. | 60 | | [subnets](#output\_subnets) | A list of subnet IDs which is associated with the network ACL. | 61 | | [vpc\_id](#output\_vpc\_id) | The VPC ID of the network ACL. | 62 | 63 | -------------------------------------------------------------------------------- /modules/nacl/main.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | metadata = { 3 | package = "terraform-aws-network" 4 | version = trimspace(file("${path.module}/../../VERSION")) 5 | module = basename(path.module) 6 | name = var.name 7 | } 8 | module_tags = var.module_tags_enabled ? { 9 | "module.terraform.io/package" = local.metadata.package 10 | "module.terraform.io/version" = local.metadata.version 11 | "module.terraform.io/name" = local.metadata.module 12 | "module.terraform.io/full-name" = "${local.metadata.package}/${local.metadata.module}" 13 | "module.terraform.io/instance" = local.metadata.name 14 | } : {} 15 | } 16 | 17 | 18 | ################################################### 19 | # Network ACL 20 | ################################################### 21 | 22 | # INFO: Not supported attributes 23 | # - `ingress` 24 | # - `egress` 25 | resource "aws_network_acl" "this" { 26 | vpc_id = var.vpc_id 27 | subnet_ids = var.subnets 28 | 29 | tags = merge( 30 | { 31 | "Name" = local.metadata.name 32 | }, 33 | local.module_tags, 34 | var.tags, 35 | ) 36 | } 37 | 38 | 39 | ################################################### 40 | # Subnet Associations of Network ACL 41 | ################################################### 42 | 43 | # resource "aws_network_acl_association" "this" { 44 | # for_each = toset(var.subnets) 45 | # 46 | # network_acl_id = aws_network_acl.this.id 47 | # subnet_id = each.value 48 | # } 49 | 50 | 51 | ################################################### 52 | # Network ACL Rules 53 | ################################################### 54 | 55 | resource "aws_network_acl_rule" "ingress" { 56 | for_each = var.ingress_rules 57 | 58 | network_acl_id = aws_network_acl.this.id 59 | 60 | egress = false 61 | rule_number = each.key 62 | 63 | rule_action = lower(each.value.action) 64 | protocol = each.value.protocol 65 | from_port = each.value.from_port 66 | to_port = each.value.to_port 67 | icmp_type = each.value.icmp_type 68 | icmp_code = each.value.icmp_code 69 | cidr_block = each.value.ipv4_cidr 70 | ipv6_cidr_block = each.value.ipv6_cidr 71 | } 72 | 73 | resource "aws_network_acl_rule" "egress" { 74 | for_each = var.egress_rules 75 | 76 | network_acl_id = aws_network_acl.this.id 77 | 78 | egress = true 79 | rule_number = each.key 80 | 81 | rule_action = lower(each.value.action) 82 | protocol = each.value.protocol 83 | from_port = each.value.from_port 84 | to_port = each.value.to_port 85 | icmp_type = each.value.icmp_type 86 | icmp_code = each.value.icmp_code 87 | cidr_block = each.value.ipv4_cidr 88 | ipv6_cidr_block = each.value.ipv6_cidr 89 | } 90 | -------------------------------------------------------------------------------- /modules/nacl/migrations.tf: -------------------------------------------------------------------------------- 1 | # 2023-02-01 2 | moved { 3 | from = aws_resourcegroups_group.this[0] 4 | to = module.resource_group[0].aws_resourcegroups_group.this 5 | } 6 | -------------------------------------------------------------------------------- /modules/nacl/outputs.tf: -------------------------------------------------------------------------------- 1 | output "id" { 2 | description = "The ID of the network ACL." 3 | value = aws_network_acl.this.id 4 | } 5 | 6 | output "arn" { 7 | description = "The ARN of the network ACL." 8 | value = aws_network_acl.this.arn 9 | } 10 | 11 | output "owner_id" { 12 | description = "The ID of the AWS account that owns the network ACL." 13 | value = aws_network_acl.this.owner_id 14 | } 15 | 16 | output "name" { 17 | description = "The name of the network ACL." 18 | value = var.name 19 | } 20 | 21 | output "vpc_id" { 22 | description = "The VPC ID of the network ACL." 23 | value = aws_network_acl.this.vpc_id 24 | } 25 | 26 | output "subnets" { 27 | description = "A list of subnet IDs which is associated with the network ACL." 28 | value = aws_network_acl.this.subnet_ids 29 | } 30 | -------------------------------------------------------------------------------- /modules/nacl/resource-group.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | resource_group_name = (var.resource_group_name != "" 3 | ? var.resource_group_name 4 | : join(".", [ 5 | local.metadata.package, 6 | local.metadata.module, 7 | replace(local.metadata.name, "/[^a-zA-Z0-9_\\.-]/", "-"), 8 | ]) 9 | ) 10 | } 11 | 12 | 13 | module "resource_group" { 14 | source = "tedilabs/misc/aws//modules/resource-group" 15 | version = "~> 0.10.0" 16 | 17 | count = (var.resource_group_enabled && var.module_tags_enabled) ? 1 : 0 18 | 19 | name = local.resource_group_name 20 | description = var.resource_group_description 21 | 22 | query = { 23 | resource_tags = local.module_tags 24 | } 25 | 26 | module_tags_enabled = false 27 | tags = merge( 28 | local.module_tags, 29 | var.tags, 30 | ) 31 | } 32 | -------------------------------------------------------------------------------- /modules/nacl/variables.tf: -------------------------------------------------------------------------------- 1 | variable "name" { 2 | description = "(Required) Desired name for the network ACL resources." 3 | type = string 4 | nullable = false 5 | } 6 | 7 | variable "vpc_id" { 8 | description = "(Required) The ID of the VPC to associate." 9 | type = string 10 | nullable = false 11 | } 12 | 13 | variable "subnets" { 14 | description = "(Optional) A list of subnet IDs to apply the ACL to." 15 | type = list(string) 16 | default = [] 17 | nullable = false 18 | } 19 | 20 | variable "ingress_rules" { 21 | description = <
action = string
protocol = string
from_port = optional(number)
to_port = optional(number)
ipv4_cidr = optional(string)
ipv6_cidr = optional(string)
icmp_type = optional(number, 0)
icmp_code = optional(number, 0)
}))
object({| `{}` | no | 44 | | [resource\_group\_description](#input\_resource\_group\_description) | (Optional) The description of Resource Group. | `string` | `"Managed by Terraform."` | no | 45 | | [resource\_group\_enabled](#input\_resource\_group\_enabled) | (Optional) Whether to create Resource Group to find and group AWS resources which are created by this module. | `bool` | `true` | no | 46 | | [resource\_group\_name](#input\_resource\_group\_name) | (Optional) The name of Resource Group. A Resource Group name can have a maximum of 127 characters, including letters, numbers, hyphens, dots, and underscores. The name cannot start with `AWS` or `aws`. | `string` | `""` | no | 47 | | [secondary\_ip\_assignments](#input\_secondary\_ip\_assignments) | (Optional) A configuration to assign secondary ip addresses with the NAT Gateway. Each block of `secondary_ip_assignments` as defined below.
elastic_ip = optional(string)
private_ip = optional(string)
})
list(object({| `[]` | no | 48 | | [secondary\_ip\_count](#input\_secondary\_ip\_count) | (Optional) The number of secondary private IPv4 addresses to assign to the NAT Gateway. Only used with private NAT Gateway. | `number` | `null` | no | 49 | | [tags](#input\_tags) | (Optional) A map of tags to add to all resources. | `map(string)` | `{}` | no | 50 | | [timeouts](#input\_timeouts) | (Optional) How long to wait for the NAT Gateway to be created/updated/deleted. |
elastic_ip = optional(string)
private_ip = optional(string)
}))
object({| `{}` | no | 51 | 52 | ## Outputs 53 | 54 | | Name | Description | 55 | |------|-------------| 56 | | [availability\_zone](#output\_availability\_zone) | The availability zone of the NAT Gateway.
create = optional(string, "10m")
update = optional(string, "10m")
delete = optional(string, "30m")
})
list(object({| `[]` | no | 54 | | [ipv6\_routes](#input\_ipv6\_routes) | (Optional) A list of route rules for destinations to IPv6 CIDRs. Each block of `ipv6_routes` as defined below.
destination = string
target = object({
type = string
id = string
})
}))
list(object({| `[]` | no | 55 | | [is\_main](#input\_is\_main) | (Optional) Whether to set this route table as the main route table. Defaults to `false`. | `bool` | `false` | no | 56 | | [module\_tags\_enabled](#input\_module\_tags\_enabled) | (Optional) Whether to create AWS Resource Tags for the module informations. | `bool` | `true` | no | 57 | | [prefix\_list\_routes](#input\_prefix\_list\_routes) | (Optional) A list of route rules for destinations to Prefix Lists. Each block of `prefix_list_routes` as defined below.
destination = string
target = object({
type = string
id = string
})
}))
list(object({| `[]` | no | 58 | | [propagating\_vpn\_gateways](#input\_propagating\_vpn\_gateways) | (Optional) A list of Virtual Private Gateway IDs to propagate routes from. | `list(string)` | `[]` | no | 59 | | [resource\_group\_description](#input\_resource\_group\_description) | (Optional) The description of Resource Group. | `string` | `"Managed by Terraform."` | no | 60 | | [resource\_group\_enabled](#input\_resource\_group\_enabled) | (Optional) Whether to create Resource Group to find and group AWS resources which are created by this module. | `bool` | `true` | no | 61 | | [resource\_group\_name](#input\_resource\_group\_name) | (Optional) The name of Resource Group. A Resource Group name can have a maximum of 127 characters, including letters, numbers, hyphens, dots, and underscores. The name cannot start with `AWS` or `aws`. | `string` | `""` | no | 62 | | [subnets](#input\_subnets) | (Optional) A list of subnet IDs to associate with the route table. | `list(string)` | `[]` | no | 63 | | [tags](#input\_tags) | (Optional) A map of tags to add to all resources. | `map(string)` | `{}` | no | 64 | | [timeouts](#input\_timeouts) | (Optional) How long to wait for the route table to be created/updated/deleted. |
name = string
destination = string
target = object({
type = string
id = string
})
}))
object({| `{}` | no | 65 | | [vpc\_gateway\_endpoints](#input\_vpc\_gateway\_endpoints) | (Optional) A list of the VPC Endpoint IDs with which the Route Table will be associated. | `list(string)` | `[]` | no | 66 | 67 | ## Outputs 68 | 69 | | Name | Description | 70 | |------|-------------| 71 | | [arn](#output\_arn) | The ARN of the routing table. | 72 | | [associated\_gateways](#output\_associated\_gateways) | A list of gateway IDs which is associated with the route table. | 73 | | [associated\_subnets](#output\_associated\_subnets) | A list of subnet IDs which is associated with the route table. | 74 | | [associated\_vpc\_gateway\_endpoints](#output\_associated\_vpc\_gateway\_endpoints) | A list of the VPC Gateway Endpoint IDs which is associated with the route table. | 75 | | [id](#output\_id) | The ID of the routing table. | 76 | | [ipv4\_routes](#output\_ipv4\_routes) | A list of route rules for destinations to IPv4 CIDRs. | 77 | | [ipv6\_routes](#output\_ipv6\_routes) | A list of route rules for destinations to IPv6 CIDRs. | 78 | | [is\_main](#output\_is\_main) | Whether to set this route table as the main route table. | 79 | | [owner](#output\_owner) | The ID of the AWS account that owns subnets in the routing table. | 80 | | [prefix\_list\_routes](#output\_prefix\_list\_routes) | A list of route rules for destinations to Prefix Lists. | 81 | | [propagated\_vpn\_gateways](#output\_propagated\_vpn\_gateways) | A list of Virtual Private Gateway IDs which propagate routes from. | 82 | | [vpc\_id](#output\_vpc\_id) | The ID of the VPC which the route table belongs to. | 83 | 84 | -------------------------------------------------------------------------------- /modules/route-table/main.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | metadata = { 3 | package = "terraform-aws-network" 4 | version = trimspace(file("${path.module}/../../VERSION")) 5 | module = basename(path.module) 6 | name = var.name 7 | } 8 | module_tags = var.module_tags_enabled ? { 9 | "module.terraform.io/package" = local.metadata.package 10 | "module.terraform.io/version" = local.metadata.version 11 | "module.terraform.io/name" = local.metadata.module 12 | "module.terraform.io/full-name" = "${local.metadata.package}/${local.metadata.module}" 13 | "module.terraform.io/instance" = local.metadata.name 14 | } : {} 15 | } 16 | 17 | 18 | ################################################### 19 | # Route Table 20 | ################################################### 21 | 22 | resource "aws_route_table" "this" { 23 | vpc_id = var.vpc_id 24 | 25 | timeouts { 26 | create = var.timeouts.create 27 | update = var.timeouts.update 28 | delete = var.timeouts.delete 29 | } 30 | 31 | tags = merge( 32 | { 33 | "Name" = local.metadata.name 34 | }, 35 | local.module_tags, 36 | var.tags, 37 | ) 38 | 39 | lifecycle { 40 | create_before_destroy = true 41 | } 42 | } 43 | 44 | resource "aws_main_route_table_association" "this" { 45 | count = var.is_main ? 1 : 0 46 | 47 | vpc_id = var.vpc_id 48 | route_table_id = aws_route_table.this.id 49 | 50 | timeouts { 51 | create = var.timeouts.create 52 | update = var.timeouts.update 53 | delete = var.timeouts.delete 54 | } 55 | } 56 | 57 | 58 | ################################################### 59 | # Associations 60 | ################################################### 61 | 62 | resource "aws_route_table_association" "subnets" { 63 | count = length(var.subnets) 64 | 65 | route_table_id = aws_route_table.this.id 66 | subnet_id = var.subnets[count.index] 67 | } 68 | 69 | resource "aws_route_table_association" "gateways" { 70 | count = length(var.gateways) 71 | 72 | route_table_id = aws_route_table.this.id 73 | gateway_id = var.gateways[count.index] 74 | } 75 | 76 | 77 | ################################################### 78 | # VPC Gateway Endpoint Association 79 | ################################################### 80 | 81 | resource "aws_vpc_endpoint_route_table_association" "this" { 82 | for_each = toset(var.vpc_gateway_endpoints) 83 | 84 | route_table_id = aws_route_table.this.id 85 | vpc_endpoint_id = each.value 86 | } 87 | 88 | 89 | ################################################### 90 | # Route Propagations 91 | ################################################### 92 | 93 | resource "aws_vpn_gateway_route_propagation" "this" { 94 | for_each = toset(var.propagating_vpn_gateways) 95 | 96 | route_table_id = aws_route_table.this.id 97 | vpn_gateway_id = each.value 98 | } 99 | -------------------------------------------------------------------------------- /modules/route-table/migrations.tf: -------------------------------------------------------------------------------- 1 | # 2023-02-01 2 | moved { 3 | from = aws_resourcegroups_group.this[0] 4 | to = module.resource_group[0].aws_resourcegroups_group.this 5 | } 6 | -------------------------------------------------------------------------------- /modules/route-table/outputs.tf: -------------------------------------------------------------------------------- 1 | output "vpc_id" { 2 | description = "The ID of the VPC which the route table belongs to." 3 | value = var.vpc_id 4 | } 5 | 6 | output "id" { 7 | description = "The ID of the routing table." 8 | value = aws_route_table.this.id 9 | } 10 | 11 | output "arn" { 12 | description = "The ARN of the routing table." 13 | value = aws_route_table.this.arn 14 | } 15 | 16 | output "owner" { 17 | description = "The ID of the AWS account that owns subnets in the routing table." 18 | value = aws_route_table.this.owner_id 19 | } 20 | 21 | output "is_main" { 22 | description = "Whether to set this route table as the main route table." 23 | value = var.is_main 24 | } 25 | 26 | output "ipv4_routes" { 27 | description = "A list of route rules for destinations to IPv4 CIDRs." 28 | value = [ 29 | for route in var.ipv4_routes : { 30 | id = aws_route.ipv4[route.destination].id, 31 | state = aws_route.ipv4[route.destination].state, 32 | destination = route.destination 33 | target = { 34 | type = route.target.type 35 | id = coalesce( 36 | aws_route.ipv4[route.destination].carrier_gateway_id, 37 | aws_route.ipv4[route.destination].core_network_arn, 38 | aws_route.ipv4[route.destination].egress_only_gateway_id, 39 | aws_route.ipv4[route.destination].gateway_id, 40 | aws_route.ipv4[route.destination].local_gateway_id, 41 | aws_route.ipv4[route.destination].nat_gateway_id, 42 | aws_route.ipv4[route.destination].network_interface_id, 43 | aws_route.ipv4[route.destination].transit_gateway_id, 44 | aws_route.ipv4[route.destination].vpc_endpoint_id, 45 | aws_route.ipv4[route.destination].vpc_peering_connection_id, 46 | ) 47 | } 48 | } 49 | ] 50 | } 51 | 52 | output "ipv6_routes" { 53 | description = "A list of route rules for destinations to IPv6 CIDRs." 54 | value = [ 55 | for route in var.ipv6_routes : { 56 | id = aws_route.ipv6[route.destination].id, 57 | state = aws_route.ipv6[route.destination].state, 58 | destination = route.destination 59 | target = { 60 | type = route.target.type 61 | id = coalesce( 62 | aws_route.ipv6[route.destination].carrier_gateway_id, 63 | aws_route.ipv6[route.destination].core_network_arn, 64 | aws_route.ipv6[route.destination].egress_only_gateway_id, 65 | aws_route.ipv6[route.destination].gateway_id, 66 | aws_route.ipv6[route.destination].local_gateway_id, 67 | aws_route.ipv6[route.destination].nat_gateway_id, 68 | aws_route.ipv6[route.destination].network_interface_id, 69 | aws_route.ipv6[route.destination].transit_gateway_id, 70 | aws_route.ipv6[route.destination].vpc_endpoint_id, 71 | aws_route.ipv6[route.destination].vpc_peering_connection_id, 72 | ) 73 | } 74 | } 75 | ] 76 | } 77 | 78 | output "prefix_list_routes" { 79 | description = "A list of route rules for destinations to Prefix Lists." 80 | value = [ 81 | for route in var.prefix_list_routes : { 82 | id = aws_route.prefix_list[route.name].id, 83 | state = aws_route.prefix_list[route.name].state, 84 | destination = route.destination 85 | target = { 86 | type = route.target.type 87 | id = coalesce( 88 | aws_route.prefix_list[route.name].carrier_gateway_id, 89 | aws_route.prefix_list[route.name].core_network_arn, 90 | aws_route.prefix_list[route.name].egress_only_gateway_id, 91 | aws_route.prefix_list[route.name].gateway_id, 92 | aws_route.prefix_list[route.name].local_gateway_id, 93 | aws_route.prefix_list[route.name].nat_gateway_id, 94 | aws_route.prefix_list[route.name].network_interface_id, 95 | aws_route.prefix_list[route.name].transit_gateway_id, 96 | aws_route.prefix_list[route.name].vpc_endpoint_id, 97 | aws_route.prefix_list[route.name].vpc_peering_connection_id, 98 | ) 99 | } 100 | } 101 | ] 102 | } 103 | 104 | output "associated_subnets" { 105 | description = "A list of subnet IDs which is associated with the route table." 106 | value = aws_route_table_association.subnets[*].subnet_id 107 | } 108 | 109 | output "associated_gateways" { 110 | description = "A list of gateway IDs which is associated with the route table." 111 | value = aws_route_table_association.gateways[*].gateway_id 112 | } 113 | 114 | output "associated_vpc_gateway_endpoints" { 115 | description = "A list of the VPC Gateway Endpoint IDs which is associated with the route table." 116 | value = var.vpc_gateway_endpoints 117 | } 118 | 119 | output "propagated_vpn_gateways" { 120 | description = "A list of Virtual Private Gateway IDs which propagate routes from." 121 | value = values(aws_vpn_gateway_route_propagation.this)[*].vpn_gateway_id 122 | } 123 | -------------------------------------------------------------------------------- /modules/route-table/resource-group.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | resource_group_name = (var.resource_group_name != "" 3 | ? var.resource_group_name 4 | : join(".", [ 5 | local.metadata.package, 6 | local.metadata.module, 7 | replace(local.metadata.name, "/[^a-zA-Z0-9_\\.-]/", "-"), 8 | ]) 9 | ) 10 | } 11 | 12 | 13 | module "resource_group" { 14 | source = "tedilabs/misc/aws//modules/resource-group" 15 | version = "~> 0.10.0" 16 | 17 | count = (var.resource_group_enabled && var.module_tags_enabled) ? 1 : 0 18 | 19 | name = local.resource_group_name 20 | description = var.resource_group_description 21 | 22 | query = { 23 | resource_tags = local.module_tags 24 | } 25 | 26 | module_tags_enabled = false 27 | tags = merge( 28 | local.module_tags, 29 | var.tags, 30 | ) 31 | } 32 | -------------------------------------------------------------------------------- /modules/route-table/routes.tf: -------------------------------------------------------------------------------- 1 | ################################################### 2 | # IPv4 Routes 3 | ################################################### 4 | 5 | # INFO: Not supported attributes 6 | # - `instance_id` (Deprecated) 7 | resource "aws_route" "ipv4" { 8 | for_each = { 9 | for route in var.ipv4_routes : 10 | route.destination => route 11 | } 12 | 13 | route_table_id = aws_route_table.this.id 14 | destination_cidr_block = each.key 15 | 16 | 17 | ## Targets 18 | carrier_gateway_id = (each.value.target.type == "CARRIER_GATEWAY" 19 | ? each.value.target.id 20 | : null 21 | ) 22 | core_network_arn = (each.value.target.type == "CORE_NETWORK" 23 | ? each.value.target.id 24 | : null 25 | ) 26 | egress_only_gateway_id = (each.value.target.type == "EGRESS_ONLY_INTERNET_GATEWAY" 27 | ? each.value.target.id 28 | : null 29 | ) 30 | gateway_id = (contains(["INTERNET_GATEWAY", "VPN_GATEWAY"], each.value.target.type) 31 | ? each.value.target.id 32 | : null 33 | ) 34 | local_gateway_id = (each.value.target.type == "LOCAL_GATEWAY" 35 | ? each.value.target.id 36 | : null 37 | ) 38 | nat_gateway_id = (each.value.target.type == "NAT_GATEWAY" 39 | ? each.value.target.id 40 | : null 41 | ) 42 | network_interface_id = (each.value.target.type == "NETWORK_INTERFACE" 43 | ? each.value.target.id 44 | : null 45 | ) 46 | transit_gateway_id = (each.value.target.type == "TRANSIT_GATEWAY" 47 | ? each.value.target.id 48 | : null 49 | ) 50 | vpc_endpoint_id = (each.value.target.type == "VPC_ENDPOINT" 51 | ? each.value.target.id 52 | : null 53 | ) 54 | vpc_peering_connection_id = (each.value.target.type == "VPC_PEERING_CONNECTION" 55 | ? each.value.target.id 56 | : null 57 | ) 58 | } 59 | 60 | 61 | ################################################### 62 | # IPv6 Routes 63 | ################################################### 64 | 65 | resource "aws_route" "ipv6" { 66 | for_each = { 67 | for route in var.ipv6_routes : 68 | route.destination => route 69 | } 70 | 71 | route_table_id = aws_route_table.this.id 72 | destination_ipv6_cidr_block = each.key 73 | 74 | 75 | ## Targets 76 | carrier_gateway_id = (each.value.target.type == "CARRIER_GATEWAY" 77 | ? each.value.target.id 78 | : null 79 | ) 80 | core_network_arn = (each.value.target.type == "CORE_NETWORK" 81 | ? each.value.target.id 82 | : null 83 | ) 84 | egress_only_gateway_id = (each.value.target.type == "EGRESS_ONLY_INTERNET_GATEWAY" 85 | ? each.value.target.id 86 | : null 87 | ) 88 | gateway_id = (contains(["INTERNET_GATEWAY", "VPN_GATEWAY"], each.value.target.type) 89 | ? each.value.target.id 90 | : null 91 | ) 92 | local_gateway_id = (each.value.target.type == "LOCAL_GATEWAY" 93 | ? each.value.target.id 94 | : null 95 | ) 96 | nat_gateway_id = (each.value.target.type == "NAT_GATEWAY" 97 | ? each.value.target.id 98 | : null 99 | ) 100 | network_interface_id = (each.value.target.type == "NETWORK_INTERFACE" 101 | ? each.value.target.id 102 | : null 103 | ) 104 | transit_gateway_id = (each.value.target.type == "TRANSIT_GATEWAY" 105 | ? each.value.target.id 106 | : null 107 | ) 108 | vpc_endpoint_id = (each.value.target.type == "VPC_ENDPOINT" 109 | ? each.value.target.id 110 | : null 111 | ) 112 | vpc_peering_connection_id = (each.value.target.type == "VPC_PEERING_CONNECTION" 113 | ? each.value.target.id 114 | : null 115 | ) 116 | } 117 | 118 | 119 | ################################################### 120 | # Prefix List Routes 121 | ################################################### 122 | 123 | resource "aws_route" "prefix_list" { 124 | for_each = { 125 | for route in var.prefix_list_routes : 126 | route.name => route 127 | } 128 | 129 | route_table_id = aws_route_table.this.id 130 | destination_prefix_list_id = each.value.destination 131 | 132 | 133 | ## Targets 134 | carrier_gateway_id = (each.value.target.type == "CARRIER_GATEWAY" 135 | ? each.value.target.id 136 | : null 137 | ) 138 | core_network_arn = (each.value.target.type == "CORE_NETWORK" 139 | ? each.value.target.id 140 | : null 141 | ) 142 | egress_only_gateway_id = (each.value.target.type == "EGRESS_ONLY_INTERNET_GATEWAY" 143 | ? each.value.target.id 144 | : null 145 | ) 146 | gateway_id = (contains(["INTERNET_GATEWAY", "VPN_GATEWAY"], each.value.target.type) 147 | ? each.value.target.id 148 | : null 149 | ) 150 | local_gateway_id = (each.value.target.type == "LOCAL_GATEWAY" 151 | ? each.value.target.id 152 | : null 153 | ) 154 | nat_gateway_id = (each.value.target.type == "NAT_GATEWAY" 155 | ? each.value.target.id 156 | : null 157 | ) 158 | network_interface_id = (each.value.target.type == "NETWORK_INTERFACE" 159 | ? each.value.target.id 160 | : null 161 | ) 162 | transit_gateway_id = (each.value.target.type == "TRANSIT_GATEWAY" 163 | ? each.value.target.id 164 | : null 165 | ) 166 | vpc_endpoint_id = (each.value.target.type == "VPC_ENDPOINT" 167 | ? each.value.target.id 168 | : null 169 | ) 170 | vpc_peering_connection_id = (each.value.target.type == "VPC_PEERING_CONNECTION" 171 | ? each.value.target.id 172 | : null 173 | ) 174 | } 175 | -------------------------------------------------------------------------------- /modules/route-table/variables.tf: -------------------------------------------------------------------------------- 1 | variable "name" { 2 | description = "(Required) Desired name for the route table resources." 3 | type = string 4 | nullable = false 5 | } 6 | 7 | variable "vpc_id" { 8 | description = "(Required) The ID of the VPC which the route table belongs to." 9 | type = string 10 | nullable = false 11 | } 12 | 13 | variable "is_main" { 14 | description = "(Optional) Whether to set this route table as the main route table. Defaults to `false`." 15 | type = bool 16 | default = false 17 | nullable = false 18 | } 19 | 20 | variable "subnets" { 21 | description = "(Optional) A list of subnet IDs to associate with the route table." 22 | type = list(string) 23 | default = [] 24 | nullable = false 25 | } 26 | 27 | variable "gateways" { 28 | description = "(Optional) A list of gateway IDs to associate with the route table. Only support Internet Gateway and Virtual Private Gateway." 29 | type = list(string) 30 | default = [] 31 | nullable = false 32 | } 33 | 34 | variable "vpc_gateway_endpoints" { 35 | description = "(Optional) A list of the VPC Endpoint IDs with which the Route Table will be associated." 36 | type = list(string) 37 | default = [] 38 | nullable = false 39 | } 40 | 41 | variable "propagating_vpn_gateways" { 42 | description = "(Optional) A list of Virtual Private Gateway IDs to propagate routes from." 43 | type = list(string) 44 | default = [] 45 | nullable = false 46 | } 47 | 48 | variable "ipv4_routes" { 49 | description = <
create = optional(string, "5m")
update = optional(string, "2m")
delete = optional(string, "5m")
})
list(object({| `[]` | no | 45 | | [ingress\_rules](#input\_ingress\_rules) | (Optional) The configuration for ingress rules of the security group. Each block of `ingress_rules` as defined below.
id = string
description = optional(string, "Managed by Terraform.")
protocol = string
from_port = number
to_port = number
ipv4_cidrs = optional(list(string), [])
ipv6_cidrs = optional(list(string), [])
prefix_lists = optional(list(string), [])
security_groups = optional(list(string), [])
self = optional(bool, false)
}))
list(object({| `[]` | no | 46 | | [module\_tags\_enabled](#input\_module\_tags\_enabled) | (Optional) Whether to create AWS Resource Tags for the module informations. | `bool` | `true` | no | 47 | | [resource\_group\_description](#input\_resource\_group\_description) | (Optional) The description of Resource Group. | `string` | `"Managed by Terraform."` | no | 48 | | [resource\_group\_enabled](#input\_resource\_group\_enabled) | (Optional) Whether to create Resource Group to find and group AWS resources which are created by this module. | `bool` | `true` | no | 49 | | [resource\_group\_name](#input\_resource\_group\_name) | (Optional) The name of Resource Group. A Resource Group name can have a maximum of 127 characters, including letters, numbers, hyphens, dots, and underscores. The name cannot start with `AWS` or `aws`. | `string` | `""` | no | 50 | | [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | (Optional) Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. This is normally not needed. | `bool` | `false` | no | 51 | | [tags](#input\_tags) | (Optional) A map of tags to add to all resources. | `map(string)` | `{}` | no | 52 | 53 | ## Outputs 54 | 55 | | Name | Description | 56 | |------|-------------| 57 | | [arn](#output\_arn) | The ARN of the security group. | 58 | | [description](#output\_description) | The description of the security group. | 59 | | [egress\_rules](#output\_egress\_rules) | The configuration of the security group egress rules. | 60 | | [id](#output\_id) | The ID of the security group. | 61 | | [ingress\_rules](#output\_ingress\_rules) | The configuration of the security group ingress rules. | 62 | | [name](#output\_name) | The name of the security group. | 63 | | [owner\_id](#output\_owner\_id) | The ID of the AWS account that owns the security group. | 64 | | [vpc\_id](#output\_vpc\_id) | The ID of the associated VPC. | 65 | 66 | -------------------------------------------------------------------------------- /modules/security-group/main.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | metadata = { 3 | package = "terraform-aws-network" 4 | version = trimspace(file("${path.module}/../../VERSION")) 5 | module = basename(path.module) 6 | name = var.name 7 | } 8 | module_tags = var.module_tags_enabled ? { 9 | "module.terraform.io/package" = local.metadata.package 10 | "module.terraform.io/version" = local.metadata.version 11 | "module.terraform.io/name" = local.metadata.module 12 | "module.terraform.io/full-name" = "${local.metadata.package}/${local.metadata.module}" 13 | "module.terraform.io/instance" = local.metadata.name 14 | } : {} 15 | } 16 | 17 | 18 | ################################################### 19 | # Security Group 20 | ################################################### 21 | 22 | # INFO: Not supported attributes 23 | # - `name_prefix` 24 | # INFO: Use a separate resource 25 | # - `egress` 26 | # - `ingress` 27 | resource "aws_security_group" "this" { 28 | vpc_id = var.vpc_id 29 | 30 | name = var.name 31 | # name_prefix = var.name_prefix 32 | description = var.description 33 | 34 | revoke_rules_on_delete = var.revoke_rules_on_delete 35 | 36 | tags = merge( 37 | { 38 | "Name" = local.metadata.name 39 | }, 40 | local.module_tags, 41 | var.tags, 42 | ) 43 | } 44 | -------------------------------------------------------------------------------- /modules/security-group/migrations.tf: -------------------------------------------------------------------------------- 1 | # 2023-02-01 2 | moved { 3 | from = aws_resourcegroups_group.this[0] 4 | to = module.resource_group[0].aws_resourcegroups_group.this 5 | } 6 | -------------------------------------------------------------------------------- /modules/security-group/outputs.tf: -------------------------------------------------------------------------------- 1 | output "id" { 2 | description = "The ID of the security group." 3 | value = aws_security_group.this.id 4 | } 5 | 6 | output "arn" { 7 | description = "The ARN of the security group." 8 | value = aws_security_group.this.arn 9 | } 10 | 11 | output "name" { 12 | description = "The name of the security group." 13 | value = aws_security_group.this.name 14 | } 15 | 16 | output "description" { 17 | description = "The description of the security group." 18 | value = aws_security_group.this.description 19 | } 20 | 21 | output "owner_id" { 22 | description = "The ID of the AWS account that owns the security group." 23 | value = aws_security_group.this.owner_id 24 | } 25 | 26 | output "vpc_id" { 27 | description = "The ID of the associated VPC." 28 | value = aws_security_group.this.vpc_id 29 | } 30 | 31 | output "ingress_rules" { 32 | description = <
id = string
description = optional(string, "Managed by Terraform.")
protocol = string
from_port = number
to_port = number
ipv4_cidrs = optional(list(string), [])
ipv6_cidrs = optional(list(string), [])
prefix_lists = optional(list(string), [])
security_groups = optional(list(string), [])
self = optional(bool, false)
}))