diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..b11dfab
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,42 @@
+build/
+plan.out
+plan.out.json
+
+# Local .terraform directories
+.terraform/
+
+# .tfstate files
+*.tfstate
+*.tfstate.*
+
+# Crash log files
+crash.log
+
+# Exclude all .tfvars files, which are likely to contain sentitive data, such as
+# password, private keys, and other secrets. These should not be part of version
+# control as they are data points which are potentially sensitive and subject
+# to change depending on the environment.
+#
+*.tfvars
+
+# Ignore override files as they are usually used to override resources locally and so
+# are not checked in
+override.tf
+override.tf.json
+*_override.tf
+*_override.tf.json
+
+# Include override files you do wish to add to version control using negated pattern
+#
+# !example_override.tf
+
+# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan
+# example: *tfplan*
+
+# Ignore CLI configuration files
+.terraformrc
+terraform.rc
+.terraform.lock.hcl
+
+go.mod
+go.sum
diff --git a/.header.md b/.header.md
new file mode 100644
index 0000000..2d740ef
--- /dev/null
+++ b/.header.md
@@ -0,0 +1,57 @@
+# Creating modules for AWS I&A Organization
+
+This repo template is used to seed Terraform Module templates for the [AWS I&A GitHub organization](https://github.com/aws-ia). Usage of this template is allowed per included license. PRs to this template will be considered but are not guaranteed to be included. Consider creating an issue to discuss a feature you want to include before taking the time to create a PR.
+### TL;DR
+
+1. [install pre-commit](https://pre-commit.com/)
+2. configure pre-commit: `pre-commit install`
+3. install required tools
+ - [tflint](https://github.com/terraform-linters/tflint)
+ - [tfsec](https://aquasecurity.github.io/tfsec/v1.0.11/)
+ - [terraform-docs](https://github.com/terraform-docs/terraform-docs)
+ - [golang](https://go.dev/doc/install) (for macos you can use `brew`)
+ - [coreutils](https://www.gnu.org/software/coreutils/)
+
+Write code according to [I&A module standards](https://aws-ia.github.io/standards-terraform/)
+
+## Module Documentation
+
+**Do not manually update README.md**. `terraform-docs` is used to generate README files. For any instructions an content, please update [.header.md](./.header.md) then simply run `terraform-docs ./` or allow the `pre-commit` to do so.
+
+## Terratest
+
+Please include tests to validate your examples/<> root modules, at a minimum. This can be accomplished with usually only slight modifications to the [boilerplate test provided in this template](./test/examples_basic_test.go)
+
+### Configure and run Terratest
+
+1. Install
+
+ [golang](https://go.dev/doc/install) (for macos you can use `brew`)
+2. Change directory into the test folder.
+
+ `cd test`
+3. Initialize your test
+
+ go mod init github.com/[github org]/[repository]
+
+ `go mod init github.com/aws-ia/terraform-aws-vpc`
+4. Run tidy
+
+ `git mod tidy`
+5. Install Terratest
+
+ `go get github.com/gruntwork-io/terratest/modules/terraform`
+6. Run test (You can have multiple test files).
+ - Run all tests
+
+ `go test`
+ - Run a specific test with a timeout
+
+ `go test -run examples_basic_test.go -timeout 45m`
+## Module Standards
+
+For best practices and information on developing with Terraform, see the [I&A Module Standards](https://aws-ia.github.io/standards-terraform/)
+
+## Continuous Integration
+
+The I&A team uses AWS CodeBuild to perform continuous integration (CI) within the organization. Our CI uses the a repo's `.pre-commit-config.yaml` file as well as some other checks. All PRs with other CI will be rejected. See our [FAQ](https://aws-ia.github.io/standards-terraform/faq/#are-modules-protected-by-ci-automation) for more details.
\ No newline at end of file
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 0000000..cbafa4b
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,11 @@
+---
+fail_fast: false
+minimum_pre_commit_version: "2.6.0"
+repos:
+ -
+ repo: https://github.com/aws-ia/pre-commit-configs
+ # To update run:
+ # pre-commit autoupdate --freeze
+ rev: 80ed3f0a164f282afaac0b6aec70e20f7e541932 # frozen: v1.5.0
+ hooks:
+ - id: aws-ia-meta-hook
diff --git a/.terraform-docs.yaml b/.terraform-docs.yaml
new file mode 100644
index 0000000..1e310cc
--- /dev/null
+++ b/.terraform-docs.yaml
@@ -0,0 +1,20 @@
+formatter: markdown
+header-from: .header.md
+settings:
+ anchor: true
+ color: true
+ default: true
+ escape: true
+ html: true
+ indent: 2
+ required: true
+ sensitive: true
+ type: true
+
+sort:
+ enabled: true
+ by: required
+
+output:
+ file: README.md
+ mode: replace
diff --git a/.tflint.hcl b/.tflint.hcl
new file mode 100644
index 0000000..0e31ba5
--- /dev/null
+++ b/.tflint.hcl
@@ -0,0 +1,66 @@
+# https://github.com/terraform-linters/tflint/blob/master/docs/user-guide/module-inspection.md
+# borrowed & modified indefinitely from https://github.com/ksatirli/building-infrastructure-you-can-mostly-trust/blob/main/.tflint.hcl
+
+plugin "aws" {
+ enabled = true
+ version = "0.14.0"
+ source = "github.com/terraform-linters/tflint-ruleset-aws"
+}
+
+config {
+ module = true
+ force = false
+}
+
+rule "terraform_required_providers" {
+ enabled = true
+}
+
+rule "terraform_required_version" {
+ enabled = true
+}
+
+rule "terraform_naming_convention" {
+ enabled = true
+ format = "snake_case"
+}
+
+rule "terraform_typed_variables" {
+ enabled = true
+}
+
+rule "terraform_unused_declarations" {
+ enabled = true
+}
+
+rule "terraform_comment_syntax" {
+ enabled = true
+}
+
+rule "terraform_deprecated_index" {
+ enabled = true
+}
+
+rule "terraform_deprecated_interpolation" {
+ enabled = true
+}
+
+rule "terraform_documented_outputs" {
+ enabled = true
+}
+
+rule "terraform_documented_variables" {
+ enabled = true
+}
+
+rule "terraform_module_pinned_source" {
+ enabled = true
+}
+
+rule "terraform_standard_module_structure" {
+ enabled = true
+}
+
+rule "terraform_workspace_remote" {
+ enabled = true
+}
diff --git a/.tfsec/launch_configuration_imdsv2_tfchecks.json b/.tfsec/launch_configuration_imdsv2_tfchecks.json
new file mode 100644
index 0000000..308ef01
--- /dev/null
+++ b/.tfsec/launch_configuration_imdsv2_tfchecks.json
@@ -0,0 +1,39 @@
+{
+ "checks": [
+ {
+ "code": "CUS002",
+ "description": "Check to IMDSv2 is required on EC2 instances created by this Launch Template",
+ "impact": "Instance metadata service can be interacted with freely",
+ "resolution": "Enable HTTP token requirement for IMDS",
+ "requiredTypes": [
+ "resource"
+ ],
+ "requiredLabels": [
+ "aws_launch_configuration"
+ ],
+ "severity": "CRITICAL",
+ "matchSpec": {
+ "action": "isPresent",
+ "name": "metadata_options",
+ "subMatch": {
+ "action": "and",
+ "predicateMatchSpec": [
+ {
+ "action": "equals",
+ "name": "http_tokens",
+ "value": "required"
+
+ }
+ ]
+ }
+ },
+
+ "errorMessage": "is missing `metadata_options` block - it is required with `http_tokens` set to `required` to make Instance Metadata Service more secure.",
+ "relatedLinks": [
+ "https://tfsec.dev/docs/aws/ec2/enforce-http-token-imds#aws/ec2",
+ "https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/launch_configuration#metadata-options",
+ "https://aws.amazon.com/blogs/security/defense-in-depth-open-firewalls-reverse-proxies-ssrf-vulnerabilities-ec2-instance-metadata-service"
+ ]
+ }
+ ]
+}
diff --git a/.tfsec/launch_template_imdsv2_tfchecks.json b/.tfsec/launch_template_imdsv2_tfchecks.json
new file mode 100644
index 0000000..e1f1aa7
--- /dev/null
+++ b/.tfsec/launch_template_imdsv2_tfchecks.json
@@ -0,0 +1,39 @@
+{
+ "checks": [
+ {
+ "code": "CUS001",
+ "description": "Check to IMDSv2 is required on EC2 instances created by this Launch Template",
+ "impact": "Instance metadata service can be interacted with freely",
+ "resolution": "Enable HTTP token requirement for IMDS",
+ "requiredTypes": [
+ "resource"
+ ],
+ "requiredLabels": [
+ "aws_launch_template"
+ ],
+ "severity": "CRITICAL",
+ "matchSpec": {
+ "action": "isPresent",
+ "name": "metadata_options",
+ "subMatch": {
+ "action": "and",
+ "predicateMatchSpec": [
+ {
+ "action": "equals",
+ "name": "http_tokens",
+ "value": "required"
+
+ }
+ ]
+ }
+ },
+
+ "errorMessage": "is missing `metadata_options` block - it is required with `http_tokens` set to `required` to make Instance Metadata Service more secure.",
+ "relatedLinks": [
+ "https://tfsec.dev/docs/aws/ec2/enforce-http-token-imds#aws/ec2",
+ "https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/launch_template#metadata-options",
+ "https://aws.amazon.com/blogs/security/defense-in-depth-open-firewalls-reverse-proxies-ssrf-vulnerabilities-ec2-instance-metadata-service"
+ ]
+ }
+ ]
+}
diff --git a/.tfsec/no_launch_config_tfchecks.json b/.tfsec/no_launch_config_tfchecks.json
new file mode 100644
index 0000000..89b6328
--- /dev/null
+++ b/.tfsec/no_launch_config_tfchecks.json
@@ -0,0 +1,27 @@
+{
+ "checks": [
+ {
+ "code": "CUS003",
+ "description": "Use `aws_launch_template` over `aws_launch_configuration",
+ "impact": "Launch configurations are not capable of versions",
+ "resolution": "Convert resource type and attributes to `aws_launch_template`",
+ "requiredTypes": [
+ "resource"
+ ],
+ "requiredLabels": [
+ "aws_launch_configuration"
+ ],
+ "severity": "MEDIUM",
+ "matchSpec": {
+ "action": "notPresent",
+ "name": "image_id"
+ },
+
+ "errorMessage": "should be changed to `aws_launch_template` since the functionality is the same but templates can be versioned.",
+ "relatedLinks": [
+ "https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/launch_template",
+ "https://aws.amazon.com/blogs/security/defense-in-depth-open-firewalls-reverse-proxies-ssrf-vulnerabilities-ec2-instance-metadata-service"
+ ]
+ }
+ ]
+}
diff --git a/.tfsec/sg_no_embedded_egress_rules_tfchecks.json b/.tfsec/sg_no_embedded_egress_rules_tfchecks.json
new file mode 100644
index 0000000..ce43e66
--- /dev/null
+++ b/.tfsec/sg_no_embedded_egress_rules_tfchecks.json
@@ -0,0 +1,27 @@
+{
+ "checks": [
+ {
+ "code": "CUS005",
+ "description": "Security group rules should be defined with `aws_security_group_rule` instead of embedded.",
+ "impact": "Embedded security group rules can cause issues during configuration updates.",
+ "resolution": "Move `egress` rules to `aws_security_group_rule` and attach to `aws_security_group`.",
+ "requiredTypes": [
+ "resource"
+ ],
+ "requiredLabels": [
+ "aws_security_group"
+ ],
+ "severity": "MEDIUM",
+ "matchSpec": {
+ "action": "notPresent",
+ "name": "egress"
+ },
+
+ "errorMessage": "`egress` rules should be moved to `aws_security_group_rule` and attached to `aws_security_group` instead of embedded.",
+ "relatedLinks": [
+ "https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule",
+ "https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group"
+ ]
+ }
+ ]
+}
diff --git a/.tfsec/sg_no_embedded_ingress_rules_tfchecks.json b/.tfsec/sg_no_embedded_ingress_rules_tfchecks.json
new file mode 100644
index 0000000..333ebc5
--- /dev/null
+++ b/.tfsec/sg_no_embedded_ingress_rules_tfchecks.json
@@ -0,0 +1,27 @@
+{
+ "checks": [
+ {
+ "code": "CUS004",
+ "description": "Security group rules should be defined with `aws_security_group_rule` instead of embedded.",
+ "impact": "Embedded security group rules can cause issues during configuration updates.",
+ "resolution": "Move `ingress` rules to `aws_security_group_rule` and attach to `aws_security_group`.",
+ "requiredTypes": [
+ "resource"
+ ],
+ "requiredLabels": [
+ "aws_security_group"
+ ],
+ "severity": "MEDIUM",
+ "matchSpec": {
+ "action": "notPresent",
+ "name": "ingress"
+ },
+
+ "errorMessage": "`ingress` rules should be moved to `aws_security_group_rule` and attached to `aws_security_group` instead of embedded.",
+ "relatedLinks": [
+ "https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule",
+ "https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group"
+ ]
+ }
+ ]
+}
diff --git a/CODEOWNERS b/CODEOWNERS
new file mode 100644
index 0000000..1006f66
--- /dev/null
+++ b/CODEOWNERS
@@ -0,0 +1 @@
+* @aws-ia/aws-ia
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
index 67db858..261eeb9 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,3 @@
-
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
@@ -173,3 +172,30 @@
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/NOTICE.txt b/NOTICE.txt
new file mode 100644
index 0000000..919c27c
--- /dev/null
+++ b/NOTICE.txt
@@ -0,0 +1,7 @@
+Copyright 2016-2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at
+
+ http://aws.amazon.com/apache2.0/
+
+or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
diff --git a/README.md b/README.md
index 847260c..9c7e0a0 100644
--- a/README.md
+++ b/README.md
@@ -1,17 +1,88 @@
-## My Project
+
+# Creating modules for AWS I&A Organization
-TODO: Fill this README out!
+This repo template is used to seed Terraform Module templates for the [AWS I&A GitHub organization](https://github.com/aws-ia). Usage of this template is allowed per included license. PRs to this template will be considered but are not guaranteed to be included. Consider creating an issue to discuss a feature you want to include before taking the time to create a PR.
+### TL;DR
-Be sure to:
+1. [install pre-commit](https://pre-commit.com/)
+2. configure pre-commit: `pre-commit install`
+3. install required tools
+ - [tflint](https://github.com/terraform-linters/tflint)
+ - [tfsec](https://aquasecurity.github.io/tfsec/v1.0.11/)
+ - [terraform-docs](https://github.com/terraform-docs/terraform-docs)
+ - [golang](https://go.dev/doc/install) (for macos you can use `brew`)
+ - [coreutils](https://www.gnu.org/software/coreutils/)
-* Change the title in this README
-* Edit your repository description on GitHub
+Write code according to [I&A module standards](https://aws-ia.github.io/standards-terraform/)
-## Security
+## Module Documentation
-See [CONTRIBUTING](CONTRIBUTING.md#security-issue-notifications) for more information.
+**Do not manually update README.md**. `terraform-docs` is used to generate README files. For any instructions an content, please update [.header.md](./.header.md) then simply run `terraform-docs ./` or allow the `pre-commit` to do so.
-## License
+## Terratest
-This project is licensed under the Apache-2.0 License.
+Please include tests to validate your examples/<> root modules, at a minimum. This can be accomplished with usually only slight modifications to the [boilerplate test provided in this template](./test/examples\_basic\_test.go)
+### Configure and run Terratest
+
+1. Install
+
+ [golang](https://go.dev/doc/install) (for macos you can use `brew`)
+2. Change directory into the test folder.
+
+ `cd test`
+3. Initialize your test
+
+ go mod init github.com/[github org]/[repository]
+
+ `go mod init github.com/aws-ia/terraform-aws-vpc`
+4. Run tidy
+
+ `git mod tidy`
+5. Install Terratest
+
+ `go get github.com/gruntwork-io/terratest/modules/terraform`
+6. Run test (You can have multiple test files).
+ - Run all tests
+
+ `go test`
+ - Run a specific test with a timeout
+
+ `go test -run examples_basic_test.go -timeout 45m`
+
+## Module Standards
+
+For best practices and information on developing with Terraform, see the [I&A Module Standards](https://aws-ia.github.io/standards-terraform/)
+
+## Continuous Integration
+
+The I&A team uses AWS CodeBuild to perform continuous integration (CI) within the organization. Our CI uses the a repo's `.pre-commit-config.yaml` file as well as some other checks. All PRs with other CI will be rejected. See our [FAQ](https://aws-ia.github.io/standards-terraform/faq/#are-modules-protected-by-ci-automation) for more details.
+
+## Requirements
+
+| Name | Version |
+|------|---------|
+| [terraform](#requirement\_terraform) | >= 0.14.0 |
+| [aws](#requirement\_aws) | >= 4.0.0, < 5.0.0 |
+| [awscc](#requirement\_awscc) | >= 0.24.0 |
+
+## Providers
+
+No providers.
+
+## Modules
+
+No modules.
+
+## Resources
+
+No resources.
+
+## Inputs
+
+No inputs.
+
+## Outputs
+
+No outputs.
+
diff --git a/examples/basic/.header.md b/examples/basic/.header.md
new file mode 100644
index 0000000..e69de29
diff --git a/examples/basic/README.md b/examples/basic/README.md
new file mode 100644
index 0000000..f53c234
--- /dev/null
+++ b/examples/basic/README.md
@@ -0,0 +1,29 @@
+
+## Requirements
+
+| Name | Version |
+|------|---------|
+| [terraform](#requirement\_terraform) | >= 0.14.0 |
+| [aws](#requirement\_aws) | >= 3.72.0 |
+| [awscc](#requirement\_awscc) | >= 0.11.0 |
+
+## Providers
+
+No providers.
+
+## Modules
+
+No modules.
+
+## Resources
+
+No resources.
+
+## Inputs
+
+No inputs.
+
+## Outputs
+
+No outputs.
+
\ No newline at end of file
diff --git a/examples/basic/main.tf b/examples/basic/main.tf
new file mode 100644
index 0000000..b2619ce
--- /dev/null
+++ b/examples/basic/main.tf
@@ -0,0 +1,5 @@
+#####################################################################################
+# Terraform module examples are meant to show an _example_ on how to use a module
+# per use-case. The code below should not be copied directly but referenced in order
+# to build your own root module that invokes this module
+#####################################################################################
diff --git a/examples/basic/outputs.tf b/examples/basic/outputs.tf
new file mode 100644
index 0000000..e69de29
diff --git a/examples/basic/providers.tf b/examples/basic/providers.tf
new file mode 100644
index 0000000..0f413cb
--- /dev/null
+++ b/examples/basic/providers.tf
@@ -0,0 +1,21 @@
+terraform {
+ required_version = ">= 0.14.0"
+ required_providers {
+ aws = {
+ source = "hashicorp/aws"
+ version = ">= 3.72.0"
+ }
+ awscc = {
+ source = "hashicorp/awscc"
+ version = ">= 0.11.0"
+ }
+ }
+}
+
+provider "awscc" {
+ user_agent = [{
+ product_name = "terraform-awscc-"
+ product_version = "0.0.1"
+ comment = "V1/AWS-D69B4015/"
+ }]
+}
diff --git a/examples/basic/variables.tf b/examples/basic/variables.tf
new file mode 100644
index 0000000..e69de29
diff --git a/main.tf b/main.tf
new file mode 100644
index 0000000..e69de29
diff --git a/outputs.tf b/outputs.tf
new file mode 100644
index 0000000..e69de29
diff --git a/providers.tf b/providers.tf
new file mode 100644
index 0000000..c34e744
--- /dev/null
+++ b/providers.tf
@@ -0,0 +1,13 @@
+terraform {
+ required_version = ">= 0.14.0"
+ required_providers {
+ aws = {
+ source = "hashicorp/aws"
+ version = ">= 4.0.0, < 5.0.0"
+ }
+ awscc = {
+ source = "hashicorp/awscc"
+ version = ">= 0.24.0"
+ }
+ }
+}
diff --git a/test/examples_basic_test.go b/test/examples_basic_test.go
new file mode 100644
index 0000000..ea44232
--- /dev/null
+++ b/test/examples_basic_test.go
@@ -0,0 +1,21 @@
+package test
+
+import (
+ "testing"
+
+ "github.com/gruntwork-io/terratest/modules/terraform"
+)
+
+func TestExamplesBasic(t *testing.T) {
+
+ terraformOptions := &terraform.Options{
+ TerraformDir: "../examples/basic",
+ // Vars: map[string]interface{}{
+ // "myvar": "test",
+ // "mylistvar": []string{"list_item_1"},
+ // },
+ }
+
+ defer terraform.Destroy(t, terraformOptions)
+ terraform.InitAndApply(t, terraformOptions)
+}
diff --git a/variables.tf b/variables.tf
new file mode 100644
index 0000000..e69de29