diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 924f8c5..96a2e14 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -11,8 +11,6 @@ repos:
hooks:
- id: terraform_fmt
- id: terragrunt_fmt
- # per module tflint config
- - id: terraform_tflint
# global tflint config
- id: terraform_tflint
args:
diff --git a/.tflint.hcl b/.tflint.hcl
index 427121c..062eb57 100644
--- a/.tflint.hcl
+++ b/.tflint.hcl
@@ -2,3 +2,11 @@ plugin "terraform" {
enabled = true
preset = "recommended"
}
+
+rule "terraform_required_providers" {
+ enabled = false
+}
+
+rule "terraform_required_version" {
+ enabled = false
+}
diff --git a/modules/aws-acm/.gitignore b/modules/aws-acm/.gitignore
new file mode 100644
index 0000000..397af32
--- /dev/null
+++ b/modules/aws-acm/.gitignore
@@ -0,0 +1,29 @@
+# Local .terraform directories
+**/.terraform/*
+
+# Terraform lockfile
+.terraform.lock.hcl
+
+# .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
+
+# Ignore CLI configuration files
+.terraformrc
+terraform.rc
diff --git a/modules/aws-acm/README.md b/modules/aws-acm/README.md
new file mode 100644
index 0000000..7fcc41d
--- /dev/null
+++ b/modules/aws-acm/README.md
@@ -0,0 +1,220 @@
+# AWS Certificate Manager (ACM) Terraform module
+
+Terraform module which creates ACM certificates and validates them using Route53 DNS (recommended) or e-mail.
+
+## Usage with Route53 DNS validation (recommended)
+
+```hcl
+module "acm" {
+ source = "terraform-modules/acm/aws"
+ version = "~> 4.0"
+
+ domain_name = "my-domain.com"
+ zone_id = "Z2ES7B9AZ6SHAE"
+
+ subject_alternative_names = [
+ "*.my-domain.com",
+ "app.sub.my-domain.com",
+ ]
+
+ wait_for_validation = true
+
+ tags = {
+ Name = "my-domain.com"
+ }
+}
+```
+
+## Usage with external DNS validation (e.g. CloudFlare)
+
+```hcl
+module "acm" {
+ source = "terraform-modules/acm/aws"
+ version = "~> 4.0"
+
+ domain_name = "weekly.tf"
+ zone_id = "b7d259641bf30b89887c943ffc9d2138"
+
+ subject_alternative_names = [
+ "*.weekly.tf",
+ ]
+
+ create_route53_records = false
+ validation_record_fqdns = [
+ "_689571ee9a5f9ec307c512c5d851e25a.weekly.tf",
+ ]
+
+ tags = {
+ Name = "weekly.tf"
+ }
+}
+
+```
+
+## [Usage with CloudFront](https://aws.amazon.com/premiumsupport/knowledge-center/install-ssl-cloudfront/)
+
+```hcl
+# CloudFront supports US East (N. Virginia) Region only.
+provider "aws" {
+ alias = "us-east-1"
+ region = "us-east-1"
+}
+
+module "acm" {
+ source = "terraform-modules/acm/aws"
+
+ providers = {
+ aws = aws.us-east-1
+ }
+
+ domain_name = "my-domain.com"
+ zone_id = "Z266PL4W4W6MSG"
+
+ wait_for_validation = true
+
+ tags = {
+ Name = "my-domain.com"
+ }
+}
+```
+
+## Usage with Route53 DNS validation and separate AWS providers
+
+```hcl
+provider "aws" {
+ alias = "acm"
+}
+
+provider "aws" {
+ alias = "route53"
+}
+
+module "acm" {
+ source = "terraform-modules/acm/aws"
+ version = "~> 4.0"
+
+ providers = {
+ aws = aws.acm
+ }
+
+ domain_name = "my-domain.com"
+
+ subject_alternative_names = [
+ "*.my-domain.com",
+ "app.sub.my-domain.com",
+ ]
+
+ create_route53_records = false
+ validation_record_fqdns = module.route53_records.validation_route53_record_fqdns
+}
+
+module "route53_records" {
+ source = "terraform-modules/acm/aws"
+ version = "~> 4.0"
+
+ providers = {
+ aws = aws.route53
+ }
+
+ create_certificate = false
+ create_route53_records_only = true
+
+ distinct_domain_names = module.acm.distinct_domain_names
+ zone_id = "Z266PL4W4W6MSG"
+
+ acm_certificate_domain_validation_options = module.acm.acm_certificate_domain_validation_options
+}
+```
+
+## Examples
+
+- [Complete example with DNS validation (recommended)](https://github.com/ToggTrumore/terraform-modules/terraform-aws-acm/tree/main/examples/complete-dns-validation)
+- [Complete example with DNS validation via external DNS provider (CloudFlare)](https://github.com/ToggTrumore/terraform-modules/terraform-aws-acm/tree/main/examples/complete-dns-validation-with-cloudflare)
+- [Complete example with EMAIL validation](https://github.com/ToggTrumore/terraform-modules/terraform-aws-acm/tree/main/examples/complete-email-validation)
+- [Complete example with EMAIL validation and validation domain override](https://github.com/ToggTrumore/terraform-modules/terraform-aws-acm/tree/main/examples/complete-email-validation-with-validation-domain)
+
+## Conditional creation and validation
+
+Sometimes you need to have a way to create ACM certificate conditionally but Terraform does not allow to use `count` inside `module` block, so the solution is to specify argument `create_certificate`.
+
+```hcl
+module "acm" {
+ source = "terraform-modules/acm/aws"
+
+ create_certificate = false
+ # ... omitted
+}
+```
+
+Similarly, to disable DNS validation of ACM certificate:
+
+```hcl
+module "acm" {
+ source = "terraform-aws-modules/acm/aws"
+
+ validate_certificate = false
+ # ... omitted
+}
+```
+
+
+
+## Requirements
+
+| Name | Version |
+|------|---------|
+| [terraform](#requirement\_terraform) | >= 1.0 |
+| [aws](#requirement\_aws) | >= 4.12.0 |
+
+## Providers
+
+| Name | Version |
+|------|---------|
+| [aws](#provider\_aws) | >= 4.12.0 |
+
+## Modules
+
+No modules.
+
+## Resources
+
+| Name | Type |
+|------|------|
+| [aws_acm_certificate.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/acm_certificate) | resource |
+| [aws_acm_certificate_validation.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/acm_certificate_validation) | resource |
+| [aws_route53_record.validation](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_record) | resource |
+
+## Inputs
+
+| Name | Description | Type | Default | Required |
+|------|-------------|------|---------|:--------:|
+| [acm\_certificate\_domain\_validation\_options](#input\_acm\_certificate\_domain\_validation\_options) | A list of domain\_validation\_options created by the ACM certificate to create required Route53 records from it (used when create\_route53\_records\_only is set to true) | `any` | `{}` | no |
+| [certificate\_transparency\_logging\_preference](#input\_certificate\_transparency\_logging\_preference) | Specifies whether certificate details should be added to a certificate transparency log | `bool` | `true` | no |
+| [create\_certificate](#input\_create\_certificate) | Whether to create ACM certificate | `bool` | `true` | no |
+| [create\_route53\_records](#input\_create\_route53\_records) | When validation is set to DNS, define whether to create the DNS records internally via Route53 or externally using any DNS provider | `bool` | `true` | no |
+| [create\_route53\_records\_only](#input\_create\_route53\_records\_only) | Whether to create only Route53 records (e.g. using separate AWS provider) | `bool` | `false` | no |
+| [distinct\_domain\_names](#input\_distinct\_domain\_names) | List of distinct domains and SANs (used when create\_route53\_records\_only is set to true) | `list(string)` | `[]` | no |
+| [dns\_ttl](#input\_dns\_ttl) | The TTL of DNS recursive resolvers to cache information about this record. | `number` | `60` | no |
+| [domain\_name](#input\_domain\_name) | A domain name for which the certificate should be issued | `string` | `""` | no |
+| [subject\_alternative\_names](#input\_subject\_alternative\_names) | A list of domains that should be SANs in the issued certificate | `list(string)` | `[]` | no |
+| [tags](#input\_tags) | A mapping of tags to assign to the resource | `map(string)` | `{}` | no |
+| [validate\_certificate](#input\_validate\_certificate) | Whether to validate certificate by creating Route53 record | `bool` | `true` | no |
+| [validation\_allow\_overwrite\_records](#input\_validation\_allow\_overwrite\_records) | Whether to allow overwrite of Route53 records | `bool` | `true` | no |
+| [validation\_method](#input\_validation\_method) | Which method to use for validation. DNS or EMAIL are valid, NONE can be used for certificates that were imported into ACM and then into Terraform. | `string` | `"DNS"` | no |
+| [validation\_option](#input\_validation\_option) | The domain name that you want ACM to use to send you validation emails. This domain name is the suffix of the email addresses that you want ACM to use. | `any` | `{}` | no |
+| [validation\_record\_fqdns](#input\_validation\_record\_fqdns) | When validation is set to DNS and the DNS validation records are set externally, provide the fqdns for the validation | `list(string)` | `[]` | no |
+| [wait\_for\_validation](#input\_wait\_for\_validation) | Whether to wait for the validation to complete | `bool` | `true` | no |
+| [zone\_id](#input\_zone\_id) | The ID of the hosted zone to contain this record. Required when validating via Route53 | `string` | `""` | no |
+
+## Outputs
+
+| Name | Description |
+|------|-------------|
+| [acm\_certificate\_arn](#output\_acm\_certificate\_arn) | The ARN of the certificate |
+| [acm\_certificate\_domain\_validation\_options](#output\_acm\_certificate\_domain\_validation\_options) | A list of attributes to feed into other resources to complete certificate validation. Can have more than one element, e.g. if SANs are defined. Only set if DNS-validation was used. |
+| [acm\_certificate\_status](#output\_acm\_certificate\_status) | Status of the certificate. |
+| [acm\_certificate\_validation\_emails](#output\_acm\_certificate\_validation\_emails) | A list of addresses that received a validation E-Mail. Only set if EMAIL-validation was used. |
+| [distinct\_domain\_names](#output\_distinct\_domain\_names) | List of distinct domains names used for the validation. |
+| [validation\_domains](#output\_validation\_domains) | List of distinct domain validation options. This is useful if subject alternative names contain wildcards. |
+| [validation\_route53\_record\_fqdns](#output\_validation\_route53\_record\_fqdns) | List of FQDNs built using the zone domain and name. |
+
diff --git a/modules/aws-acm/examples/complete-dns-validation-with-cloudflare/README.md b/modules/aws-acm/examples/complete-dns-validation-with-cloudflare/README.md
new file mode 100644
index 0000000..f97af83
--- /dev/null
+++ b/modules/aws-acm/examples/complete-dns-validation-with-cloudflare/README.md
@@ -0,0 +1,64 @@
+# Complete ACM example with external CloudFlare DNS validation
+
+Configuration in this directory creates an ACM certificate (valid for the domain name and wildcard) while the DNS validation is done via an external DNS provider.
+
+For this example CloudFlare DNS is used but any DNS provider could be used instead.
+
+This is a complete example which fits most of scenarios.
+
+## Usage
+
+To run this example you need to execute:
+
+```bash
+$ terraform init
+$ terraform plan
+$ terraform apply
+```
+
+Note that this example may create resources which cost money. Run `terraform destroy` when you don't need these resources.
+
+
+## Requirements
+
+| Name | Version |
+|------|---------|
+| [terraform](#requirement\_terraform) | >= 0.13.1 |
+| [aws](#requirement\_aws) | >= 2.53 |
+| [cloudflare](#requirement\_cloudflare) | >= 3.4.0 |
+
+## Providers
+
+| Name | Version |
+|------|---------|
+| [cloudflare](#provider\_cloudflare) | >= 3.4.0 |
+
+## Modules
+
+| Name | Source | Version |
+|------|--------|---------|
+| [acm](#module\_acm) | ../../ | n/a |
+
+## Resources
+
+| Name | Type |
+|------|------|
+| [cloudflare_record.validation](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/record) | resource |
+| [cloudflare_zone.this](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/data-sources/zone) | data source |
+
+## Inputs
+
+No inputs.
+
+## Outputs
+
+| Name | Description |
+|------|-------------|
+| [acm\_certificate\_arn](#output\_acm\_certificate\_arn) | The ARN of the certificate |
+| [acm\_certificate\_domain\_validation\_options](#output\_acm\_certificate\_domain\_validation\_options) | A list of attributes to feed into other resources to complete certificate validation. Can have more than one element, e.g. if SANs are defined. Only set if DNS-validation was used. |
+| [acm\_certificate\_status](#output\_acm\_certificate\_status) | Status of the certificate. |
+| [acm\_certificate\_validation\_emails](#output\_acm\_certificate\_validation\_emails) | A list of addresses that received a validation E-Mail. Only set if EMAIL-validation was used. |
+| [distinct\_domain\_names](#output\_distinct\_domain\_names) | List of distinct domains names used for the validation. |
+| [validation\_domains](#output\_validation\_domains) | List of distinct domain validation options. This is useful if subject alternative names contain wildcards. |
+| [validation\_route53\_record\_fqdns](#output\_validation\_route53\_record\_fqdns) | List of FQDNs built using the zone domain and name. |
+
diff --git a/modules/aws-acm/examples/complete-dns-validation-with-cloudflare/main.tf b/modules/aws-acm/examples/complete-dns-validation-with-cloudflare/main.tf
new file mode 100644
index 0000000..7e368c4
--- /dev/null
+++ b/modules/aws-acm/examples/complete-dns-validation-with-cloudflare/main.tf
@@ -0,0 +1,49 @@
+locals {
+ domain = "terraform-aws-modules.modules.tf"
+
+ # Removing trailing dot from domain - just to be sure :)
+ domain_name = trimsuffix(local.domain, ".")
+}
+
+module "acm" {
+ source = "../../"
+
+ providers = {
+ aws.acm = aws,
+ aws.dns = aws
+ }
+
+ domain_name = local.domain_name
+ zone_id = data.cloudflare_zone.this.id
+
+ subject_alternative_names = [
+ "*.alerts.${local.domain_name}",
+ "new.sub.${local.domain_name}",
+ "*.${local.domain_name}",
+ "alerts.${local.domain_name}",
+ ]
+
+ create_route53_records = false
+ validation_record_fqdns = cloudflare_record.validation.*.hostname
+
+ tags = {
+ Name = local.domain_name
+ }
+}
+
+resource "cloudflare_record" "validation" {
+ count = length(module.acm.distinct_domain_names)
+
+ zone_id = data.cloudflare_zone.this.id
+ name = element(module.acm.validation_domains, count.index)["resource_record_name"]
+ type = element(module.acm.validation_domains, count.index)["resource_record_type"]
+ value = trimsuffix(element(module.acm.validation_domains, count.index)["resource_record_value"], ".")
+ ttl = 60
+ proxied = false
+
+ allow_overwrite = true
+}
+
+data "cloudflare_zone" "this" {
+ name = local.domain_name
+}
diff --git a/modules/aws-acm/examples/complete-dns-validation-with-cloudflare/outputs.tf b/modules/aws-acm/examples/complete-dns-validation-with-cloudflare/outputs.tf
new file mode 100644
index 0000000..83083be
--- /dev/null
+++ b/modules/aws-acm/examples/complete-dns-validation-with-cloudflare/outputs.tf
@@ -0,0 +1,34 @@
+output "acm_certificate_arn" {
+ description = "The ARN of the certificate"
+ value = module.acm.acm_certificate_arn
+}
+
+output "acm_certificate_domain_validation_options" {
+ description = "A list of attributes to feed into other resources to complete certificate validation. Can have more than one element, e.g. if SANs are defined. Only set if DNS-validation was used."
+ value = module.acm.acm_certificate_domain_validation_options
+}
+
+output "acm_certificate_status" {
+ description = "Status of the certificate."
+ value = module.acm.acm_certificate_status
+}
+
+output "acm_certificate_validation_emails" {
+ description = "A list of addresses that received a validation E-Mail. Only set if EMAIL-validation was used."
+ value = module.acm.acm_certificate_validation_emails
+}
+
+output "validation_route53_record_fqdns" {
+ description = "List of FQDNs built using the zone domain and name."
+ value = module.acm.validation_route53_record_fqdns
+}
+
+output "distinct_domain_names" {
+ description = "List of distinct domains names used for the validation."
+ value = module.acm.distinct_domain_names
+}
+
+output "validation_domains" {
+ description = "List of distinct domain validation options. This is useful if subject alternative names contain wildcards."
+ value = module.acm.validation_domains
+}
diff --git a/modules/aws-acm/examples/complete-dns-validation-with-cloudflare/variables.tf b/modules/aws-acm/examples/complete-dns-validation-with-cloudflare/variables.tf
new file mode 100644
index 0000000..e69de29
diff --git a/modules/aws-acm/examples/complete-dns-validation-with-cloudflare/versions.tf b/modules/aws-acm/examples/complete-dns-validation-with-cloudflare/versions.tf
new file mode 100644
index 0000000..ec2f77a
--- /dev/null
+++ b/modules/aws-acm/examples/complete-dns-validation-with-cloudflare/versions.tf
@@ -0,0 +1,14 @@
+terraform {
+ required_version = ">= 0.13.1"
+
+ required_providers {
+ aws = {
+ source = "hashicorp/aws"
+ version = ">= 2.53"
+ }
+ cloudflare = {
+ source = "cloudflare/cloudflare"
+ version = ">= 3.4.0"
+ }
+ }
+}
diff --git a/modules/aws-acm/examples/complete-dns-validation/README.md b/modules/aws-acm/examples/complete-dns-validation/README.md
new file mode 100644
index 0000000..e7fa8b5
--- /dev/null
+++ b/modules/aws-acm/examples/complete-dns-validation/README.md
@@ -0,0 +1,65 @@
+# Complete ACM example with Route53 DNS validation
+
+Configuration in this directory creates new Route53 zone and ACM certificate (valid for the domain name and wildcard) with one (default) or two instances of AWS providers (one to manage ACM resources, another to manage Route53 records).
+
+Also, ACM certificate is being validate using DNS method.
+
+This is a complete example which fits most of scenarios.
+
+## Usage
+
+To run this example you need to execute:
+
+```bash
+$ terraform init
+$ terraform plan
+$ terraform apply
+```
+
+Note that this example may create resources which cost money. Run `terraform destroy` when you don't need these resources.
+
+
+## Requirements
+
+| Name | Version |
+|------|---------|
+| [terraform](#requirement\_terraform) | >= 0.13.1 |
+| [aws](#requirement\_aws) | >= 2.53 |
+
+## Providers
+
+| Name | Version |
+|------|---------|
+| [aws](#provider\_aws) | >= 2.53 |
+
+## Modules
+
+| Name | Source | Version |
+|------|--------|---------|
+| [acm](#module\_acm) | ../../ | n/a |
+| [acm\_only](#module\_acm\_only) | ../../ | n/a |
+| [route53\_records\_only](#module\_route53\_records\_only) | ../../ | n/a |
+
+## Resources
+
+| Name | Type |
+|------|------|
+| [aws_route53_zone.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_zone) | resource |
+| [aws_route53_zone.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/route53_zone) | data source |
+
+## Inputs
+
+No inputs.
+
+## Outputs
+
+| Name | Description |
+|------|-------------|
+| [acm\_certificate\_arn](#output\_acm\_certificate\_arn) | The ARN of the certificate |
+| [acm\_certificate\_domain\_validation\_options](#output\_acm\_certificate\_domain\_validation\_options) | A list of attributes to feed into other resources to complete certificate validation. Can have more than one element, e.g. if SANs are defined. Only set if DNS-validation was used. |
+| [acm\_certificate\_status](#output\_acm\_certificate\_status) | Status of the certificate. |
+| [acm\_certificate\_validation\_emails](#output\_acm\_certificate\_validation\_emails) | A list of addresses that received a validation E-Mail. Only set if EMAIL-validation was used. |
+| [distinct\_domain\_names](#output\_distinct\_domain\_names) | List of distinct domains names used for the validation. |
+| [validation\_domains](#output\_validation\_domains) | List of distinct domain validation options. This is useful if subject alternative names contain wildcards. |
+| [validation\_route53\_record\_fqdns](#output\_validation\_route53\_record\_fqdns) | List of FQDNs built using the zone domain and name. |
+
diff --git a/modules/aws-acm/examples/complete-dns-validation/main.tf b/modules/aws-acm/examples/complete-dns-validation/main.tf
new file mode 100644
index 0000000..928e9d3
--- /dev/null
+++ b/modules/aws-acm/examples/complete-dns-validation/main.tf
@@ -0,0 +1,101 @@
+locals {
+ # Use existing (via data source) or create new zone (will fail validation, if zone is not reachable)
+ use_existing_route53_zone = true
+
+ domain = "terraform-aws-modules.modules.tf"
+
+ # Removing trailing dot from domain - just to be sure :)
+ domain_name = trimsuffix(local.domain, ".")
+
+ zone_id = coalescelist(data.aws_route53_zone.this.*.zone_id, aws_route53_zone.this.*.zone_id)[0]
+}
+
+##########################################################
+# Example 1 (default case):
+# Using one AWS provider for both ACM and Route53 records
+##########################################################
+
+data "aws_route53_zone" "this" {
+ count = local.use_existing_route53_zone ? 1 : 0
+
+ name = local.domain_name
+ private_zone = false
+}
+
+resource "aws_route53_zone" "this" {
+ count = !local.use_existing_route53_zone ? 1 : 0
+
+ name = local.domain_name
+}
+
+module "acm" {
+ source = "../../"
+
+ providers = {
+ aws.acm = aws,
+ aws.dns = aws
+ }
+
+ domain_name = local.domain_name
+ zone_id = local.zone_id
+
+ subject_alternative_names = [
+ "*.alerts.${local.domain_name}",
+ "new.sub.${local.domain_name}",
+ "*.${local.domain_name}",
+ "alerts.${local.domain_name}",
+ ]
+
+ tags = {
+ Name = local.domain_name
+ }
+}
+
+################################################################
+# Example 2:
+# Using separate AWS providers for ACM and Route53 records.
+# Useful when these resources belong to different AWS accounts.
+################################################################
+
+provider "aws" {
+ alias = "route53"
+}
+
+provider "aws" {
+ alias = "acm"
+}
+
+module "acm_only" {
+ source = "../../"
+
+ providers = {
+ aws = aws.acm
+ }
+
+ domain_name = local.domain_name
+ subject_alternative_names = [
+ "*.alerts.separated.${local.domain_name}",
+ "new.sub.separated.${local.domain_name}",
+ "*.separated.${local.domain_name}",
+ "alerts.separated.${local.domain_name}",
+ ]
+
+ create_route53_records = false
+ validation_record_fqdns = module.route53_records_only.validation_route53_record_fqdns
+}
+
+module "route53_records_only" {
+ source = "../../"
+
+ providers = {
+ aws = aws.route53
+ }
+
+ create_certificate = false
+ create_route53_records_only = true
+
+ zone_id = local.zone_id
+ distinct_domain_names = module.acm_only.distinct_domain_names
+
+ acm_certificate_domain_validation_options = module.acm_only.acm_certificate_domain_validation_options
+}
diff --git a/modules/aws-acm/examples/complete-dns-validation/outputs.tf b/modules/aws-acm/examples/complete-dns-validation/outputs.tf
new file mode 100644
index 0000000..83083be
--- /dev/null
+++ b/modules/aws-acm/examples/complete-dns-validation/outputs.tf
@@ -0,0 +1,34 @@
+output "acm_certificate_arn" {
+ description = "The ARN of the certificate"
+ value = module.acm.acm_certificate_arn
+}
+
+output "acm_certificate_domain_validation_options" {
+ description = "A list of attributes to feed into other resources to complete certificate validation. Can have more than one element, e.g. if SANs are defined. Only set if DNS-validation was used."
+ value = module.acm.acm_certificate_domain_validation_options
+}
+
+output "acm_certificate_status" {
+ description = "Status of the certificate."
+ value = module.acm.acm_certificate_status
+}
+
+output "acm_certificate_validation_emails" {
+ description = "A list of addresses that received a validation E-Mail. Only set if EMAIL-validation was used."
+ value = module.acm.acm_certificate_validation_emails
+}
+
+output "validation_route53_record_fqdns" {
+ description = "List of FQDNs built using the zone domain and name."
+ value = module.acm.validation_route53_record_fqdns
+}
+
+output "distinct_domain_names" {
+ description = "List of distinct domains names used for the validation."
+ value = module.acm.distinct_domain_names
+}
+
+output "validation_domains" {
+ description = "List of distinct domain validation options. This is useful if subject alternative names contain wildcards."
+ value = module.acm.validation_domains
+}
diff --git a/modules/aws-acm/examples/complete-dns-validation/variables.tf b/modules/aws-acm/examples/complete-dns-validation/variables.tf
new file mode 100644
index 0000000..e69de29
diff --git a/modules/aws-acm/examples/complete-dns-validation/versions.tf b/modules/aws-acm/examples/complete-dns-validation/versions.tf
new file mode 100644
index 0000000..25f85e5
--- /dev/null
+++ b/modules/aws-acm/examples/complete-dns-validation/versions.tf
@@ -0,0 +1,10 @@
+terraform {
+ required_version = ">= 0.13.1"
+
+ required_providers {
+ aws = {
+ source = "hashicorp/aws"
+ version = ">= 2.53"
+ }
+ }
+}
diff --git a/modules/aws-acm/examples/complete-email-validation-with-validation-domain/README.md b/modules/aws-acm/examples/complete-email-validation-with-validation-domain/README.md
new file mode 100644
index 0000000..a51588c
--- /dev/null
+++ b/modules/aws-acm/examples/complete-email-validation-with-validation-domain/README.md
@@ -0,0 +1,70 @@
+# Complete ACM example with EMAIL validation with validation_domain configured
+
+Configuration in this directory creates new Route53 zone and ACM certificate (valid for the domain name and wildcard).
+
+ACM certificate will be created with EMAIL validation method, which means that emails will be send to domain owners and it is not possible to automate using Terraform!
+The validation domain option is set, which overrides the domain to which validation emails will be sent.
+
+If you want to use EMAIL validation method make sure that you have access to at least one of these emails in your domain:
+
+```
+hostmaster@VALIDATION_DOMAIN
+postmaster@VALIDATION_DOMAIN
+admin@VALIDATION_DOMAIN
+administrator@VALIDATION_DOMAIN
+webmaster@VALIDATION_DOMAIN
+```
+
+## Usage
+
+To run this example you need to execute:
+
+```bash
+$ terraform init
+$ terraform plan -var 'domain_name=foo.bar.com' -var 'validation_domain=bar.com'
+$ terraform apply -var 'domain_name=foo.bar.com' -var 'validation_domain=bar.com'
+```
+
+Note that this example may create resources which cost money. Run `terraform destroy` when you don't need these resources.
+
+
+## Requirements
+
+| Name | Version |
+|------|---------|
+| [terraform](#requirement\_terraform) | >= 1.0 |
+| [aws](#requirement\_aws) | >= 4.12.0 |
+
+## Providers
+
+| Name | Version |
+|------|---------|
+| [aws](#provider\_aws) | >= 4.12.0 |
+
+## Modules
+
+| Name | Source | Version |
+|------|--------|---------|
+| [acm](#module\_acm) | ../../ | n/a |
+
+## Resources
+
+| Name | Type |
+|------|------|
+| [aws_route53_zone.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_zone) | resource |
+
+## Inputs
+
+| Name | Description | Type | Default | Required |
+|------|-------------|------|---------|:--------:|
+| [domain\_name](#input\_domain\_name) | Domain name to use as Route53 zone and ACM certificate | `string` | n/a | yes |
+| [validation\_domain](#input\_validation\_domain) | Domain name to use for verifying var.domain\_name | `string` | n/a | yes |
+
+## Outputs
+
+| Name | Description |
+|------|-------------|
+| [acm\_certificate\_arn](#output\_acm\_certificate\_arn) | The ARN of the certificate |
+| [acm\_certificate\_domain\_validation\_options](#output\_acm\_certificate\_domain\_validation\_options) | A list of attributes to feed into other resources to complete certificate validation. Can have more than one element, e.g. if SANs are defined. Only set if DNS-validation was used. |
+| [acm\_certificate\_validation\_emails](#output\_acm\_certificate\_validation\_emails) | A list of addresses that received a validation E-Mail. Only set if EMAIL-validation was used. |
+
diff --git a/modules/aws-acm/examples/complete-email-validation-with-validation-domain/main.tf b/modules/aws-acm/examples/complete-email-validation-with-validation-domain/main.tf
new file mode 100644
index 0000000..9a79ac6
--- /dev/null
+++ b/modules/aws-acm/examples/complete-email-validation-with-validation-domain/main.tf
@@ -0,0 +1,27 @@
+resource "aws_route53_zone" "this" {
+ name = var.domain_name
+}
+
+module "acm" {
+ source = "../../"
+
+ domain_name = var.domain_name
+ zone_id = aws_route53_zone.this.zone_id
+
+ # The key is the domain name which you want to change the validation domain for.
+ # Validation emails will be send to a fixed list of recipients:
+ # admin@VALIDATION_DOMAIN, administrator@VALIDATION_DOMAIN, hostmaster@VALIDATION_DOMAIN, postmaster@VALIDATION_DOMAIN, webmaster@VALIDATION_DOMAIN
+ # validation_domain has to be a top-level domain of the actual domain
+ validation_option = {
+ (var.domain_name) = {
+ validation_domain = var.validation_domain
+ }
+ }
+
+ validation_method = "EMAIL"
+ wait_for_validation = false
+
+ tags = {
+ Name = var.domain_name
+ }
+}
diff --git a/modules/aws-acm/examples/complete-email-validation-with-validation-domain/outputs.tf b/modules/aws-acm/examples/complete-email-validation-with-validation-domain/outputs.tf
new file mode 100644
index 0000000..edf4f63
--- /dev/null
+++ b/modules/aws-acm/examples/complete-email-validation-with-validation-domain/outputs.tf
@@ -0,0 +1,14 @@
+output "acm_certificate_arn" {
+ description = "The ARN of the certificate"
+ value = module.acm.acm_certificate_arn
+}
+
+output "acm_certificate_domain_validation_options" {
+ description = "A list of attributes to feed into other resources to complete certificate validation. Can have more than one element, e.g. if SANs are defined. Only set if DNS-validation was used."
+ value = module.acm.acm_certificate_domain_validation_options
+}
+
+output "acm_certificate_validation_emails" {
+ description = "A list of addresses that received a validation E-Mail. Only set if EMAIL-validation was used."
+ value = module.acm.acm_certificate_validation_emails
+}
diff --git a/modules/aws-acm/examples/complete-email-validation-with-validation-domain/variables.tf b/modules/aws-acm/examples/complete-email-validation-with-validation-domain/variables.tf
new file mode 100644
index 0000000..8e22c52
--- /dev/null
+++ b/modules/aws-acm/examples/complete-email-validation-with-validation-domain/variables.tf
@@ -0,0 +1,9 @@
+variable "domain_name" {
+ description = "Domain name to use as Route53 zone and ACM certificate"
+ type = string
+}
+
+variable "validation_domain" {
+ description = "Domain name to use for verifying var.domain_name"
+ type = string
+}
diff --git a/modules/aws-acm/examples/complete-email-validation-with-validation-domain/versions.tf b/modules/aws-acm/examples/complete-email-validation-with-validation-domain/versions.tf
new file mode 100644
index 0000000..e76924e
--- /dev/null
+++ b/modules/aws-acm/examples/complete-email-validation-with-validation-domain/versions.tf
@@ -0,0 +1,10 @@
+terraform {
+ required_version = ">= 1.0"
+
+ required_providers {
+ aws = {
+ source = "hashicorp/aws"
+ version = ">= 4.12.0"
+ }
+ }
+}
diff --git a/modules/aws-acm/examples/complete-email-validation/README.md b/modules/aws-acm/examples/complete-email-validation/README.md
new file mode 100644
index 0000000..c89cd19
--- /dev/null
+++ b/modules/aws-acm/examples/complete-email-validation/README.md
@@ -0,0 +1,74 @@
+# Complete ACM example with EMAIL validation
+
+Configuration in this directory creates new Route53 zone and ACM certificate (valid for the domain name and wildcard).
+
+ACM certificate will be created with EMAIL validation method, which means that emails will be send to domain owners and it is not possible to automate using Terraform!
+
+If you want to use EMAIL validation method make sure that you have access to at least one of these emails in your domain:
+
+```
+hostmaster@...
+postmaster@...
+admin@...
+administrator@...
+webmaster@...
+hostmaster@...
+postmaster@...
+admin@...
+administrator@...
+webmaster@...
+```
+
+## Usage
+
+To run this example you need to execute:
+
+```bash
+$ terraform init
+$ terraform plan
+$ terraform apply
+```
+
+Note that this example may create resources which cost money. Run `terraform destroy` when you don't need these resources.
+
+
+## Requirements
+
+| Name | Version |
+|------|---------|
+| [terraform](#requirement\_terraform) | >= 0.13.1 |
+| [aws](#requirement\_aws) | >= 2.53 |
+
+## Providers
+
+| Name | Version |
+|------|---------|
+| [aws](#provider\_aws) | >= 2.53 |
+
+## Modules
+
+| Name | Source | Version |
+|------|--------|---------|
+| [acm](#module\_acm) | ../../ | n/a |
+
+## Resources
+
+| Name | Type |
+|------|------|
+| [aws_route53_zone.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_zone) | resource |
+
+## Inputs
+
+| Name | Description | Type | Default | Required |
+|------|-------------|------|---------|:--------:|
+| [domain\_name](#input\_domain\_name) | Domain name to use as Route53 zone and ACM certificate | `string` | `"my-domain-name2.com"` | no |
+
+## Outputs
+
+| Name | Description |
+|------|-------------|
+| [acm\_certificate\_arn](#output\_acm\_certificate\_arn) | The ARN of the certificate |
+| [acm\_certificate\_domain\_validation\_options](#output\_acm\_certificate\_domain\_validation\_options) | A list of attributes to feed into other resources to complete certificate validation. Can have more than one element, e.g. if SANs are defined. Only set if DNS-validation was used. |
+| [acm\_certificate\_status](#output\_acm\_certificate\_status) | Status of the certificate. |
+| [acm\_certificate\_validation\_emails](#output\_acm\_certificate\_validation\_emails) | A list of addresses that received a validation E-Mail. Only set if EMAIL-validation was used. |
+
diff --git a/modules/aws-acm/examples/complete-email-validation/main.tf b/modules/aws-acm/examples/complete-email-validation/main.tf
new file mode 100644
index 0000000..ce4b1ec
--- /dev/null
+++ b/modules/aws-acm/examples/complete-email-validation/main.tf
@@ -0,0 +1,20 @@
+resource "aws_route53_zone" "this" {
+ name = var.domain_name
+}
+
+module "acm" {
+ source = "../../"
+
+ domain_name = var.domain_name
+ zone_id = aws_route53_zone.this.zone_id
+
+ subject_alternative_names = [
+ "*.${var.domain_name}",
+ ]
+
+ validation_method = "EMAIL"
+
+ tags = {
+ Name = var.domain_name
+ }
+}
diff --git a/modules/aws-acm/examples/complete-email-validation/outputs.tf b/modules/aws-acm/examples/complete-email-validation/outputs.tf
new file mode 100644
index 0000000..193e5e9
--- /dev/null
+++ b/modules/aws-acm/examples/complete-email-validation/outputs.tf
@@ -0,0 +1,19 @@
+output "acm_certificate_arn" {
+ description = "The ARN of the certificate"
+ value = module.acm.acm_certificate_arn
+}
+
+output "acm_certificate_domain_validation_options" {
+ description = "A list of attributes to feed into other resources to complete certificate validation. Can have more than one element, e.g. if SANs are defined. Only set if DNS-validation was used."
+ value = module.acm.acm_certificate_domain_validation_options
+}
+
+output "acm_certificate_status" {
+ description = "Status of the certificate."
+ value = module.acm.acm_certificate_status
+}
+
+output "acm_certificate_validation_emails" {
+ description = "A list of addresses that received a validation E-Mail. Only set if EMAIL-validation was used."
+ value = module.acm.acm_certificate_validation_emails
+}
diff --git a/modules/aws-acm/examples/complete-email-validation/variables.tf b/modules/aws-acm/examples/complete-email-validation/variables.tf
new file mode 100644
index 0000000..b3a6a45
--- /dev/null
+++ b/modules/aws-acm/examples/complete-email-validation/variables.tf
@@ -0,0 +1,5 @@
+variable "domain_name" {
+ description = "Domain name to use as Route53 zone and ACM certificate"
+ type = string
+ default = "my-domain-name2.com"
+}
diff --git a/modules/aws-acm/examples/complete-email-validation/versions.tf b/modules/aws-acm/examples/complete-email-validation/versions.tf
new file mode 100644
index 0000000..25f85e5
--- /dev/null
+++ b/modules/aws-acm/examples/complete-email-validation/versions.tf
@@ -0,0 +1,10 @@
+terraform {
+ required_version = ">= 0.13.1"
+
+ required_providers {
+ aws = {
+ source = "hashicorp/aws"
+ version = ">= 2.53"
+ }
+ }
+}
diff --git a/modules/aws-acm/main.tf b/modules/aws-acm/main.tf
new file mode 100644
index 0000000..0286cd1
--- /dev/null
+++ b/modules/aws-acm/main.tf
@@ -0,0 +1,79 @@
+locals {
+ create_certificate = var.create_certificate
+ create_route53_records_only = var.create_route53_records_only
+
+ # Get distinct list of domains and SANs
+ distinct_domain_names = coalescelist(var.distinct_domain_names, distinct(
+ [for s in concat([var.domain_name], var.subject_alternative_names) : replace(s, "*.", "")]
+ ))
+
+ # Get the list of distinct domain_validation_options, with wildcard
+ # domain names replaced by the domain name
+ validation_domains = local.create_certificate || local.create_route53_records_only ? distinct(
+ [for k, v in try(aws_acm_certificate.this[0].domain_validation_options, var.acm_certificate_domain_validation_options) : merge(
+ tomap(v), { domain_name = replace(v.domain_name, "*.", "") }
+ )]
+ ) : []
+}
+
+resource "aws_acm_certificate" "this" {
+ count = local.create_certificate ? 1 : 0
+ provider = aws.aws_acm
+
+ domain_name = var.domain_name
+ subject_alternative_names = var.subject_alternative_names
+ validation_method = var.validation_method
+
+ options {
+ certificate_transparency_logging_preference = var.certificate_transparency_logging_preference ? "ENABLED" : "DISABLED"
+ }
+
+ dynamic "validation_option" {
+ for_each = var.validation_option
+
+ content {
+ domain_name = try(validation_option.value["domain_name"], validation_option.key)
+ validation_domain = validation_option.value["validation_domain"]
+ }
+ }
+
+ tags = var.tags
+
+ lifecycle {
+ create_before_destroy = true
+ }
+}
+
+data "aws_route53_zone" "selected" {
+ count = (local.create_certificate || local.create_route53_records_only) && var.validation_method == "DNS" && var.create_route53_records && (var.validate_certificate || local.create_route53_records_only) ? length(local.distinct_domain_names) : 0
+ provider = aws.shared_infra
+ name = var.domain_name
+ private_zone = false
+}
+
+resource "aws_route53_record" "validation" {
+ provider = aws.shared_infra
+ count = (local.create_certificate || local.create_route53_records_only) && var.validation_method == "DNS" && var.create_route53_records && (var.validate_certificate || local.create_route53_records_only) ? length(local.distinct_domain_names) : 0
+
+ zone_id = data.aws_route53_zone.selected[0].zone_id
+ name = element(local.validation_domains, count.index)["resource_record_name"]
+ type = element(local.validation_domains, count.index)["resource_record_type"]
+ ttl = var.dns_ttl
+
+ records = [
+ element(local.validation_domains, count.index)["resource_record_value"]
+ ]
+
+ allow_overwrite = var.validation_allow_overwrite_records
+
+ depends_on = [aws_acm_certificate.this]
+}
+
+resource "aws_acm_certificate_validation" "this" {
+ count = local.create_certificate && var.validation_method != "NONE" && var.validate_certificate && var.wait_for_validation ? 1 : 0
+ provider = aws.aws_acm
+
+ certificate_arn = aws_acm_certificate.this[0].arn
+
+ validation_record_fqdns = flatten([aws_route53_record.validation.*.fqdn, var.validation_record_fqdns])
+}
diff --git a/modules/aws-acm/outputs.tf b/modules/aws-acm/outputs.tf
new file mode 100644
index 0000000..b4b3154
--- /dev/null
+++ b/modules/aws-acm/outputs.tf
@@ -0,0 +1,34 @@
+output "acm_certificate_arn" {
+ description = "The ARN of the certificate"
+ value = element(concat(aws_acm_certificate_validation.this.*.certificate_arn, aws_acm_certificate.this.*.arn, [""]), 0)
+}
+
+output "acm_certificate_domain_validation_options" {
+ description = "A list of attributes to feed into other resources to complete certificate validation. Can have more than one element, e.g. if SANs are defined. Only set if DNS-validation was used."
+ value = flatten(aws_acm_certificate.this.*.domain_validation_options)
+}
+
+output "acm_certificate_status" {
+ description = "Status of the certificate."
+ value = element(concat(aws_acm_certificate.this.*.status, [""]), 0)
+}
+
+output "acm_certificate_validation_emails" {
+ description = "A list of addresses that received a validation E-Mail. Only set if EMAIL-validation was used."
+ value = flatten(aws_acm_certificate.this.*.validation_emails)
+}
+
+output "validation_route53_record_fqdns" {
+ description = "List of FQDNs built using the zone domain and name."
+ value = aws_route53_record.validation.*.fqdn
+}
+
+output "distinct_domain_names" {
+ description = "List of distinct domains names used for the validation."
+ value = local.distinct_domain_names
+}
+
+output "validation_domains" {
+ description = "List of distinct domain validation options. This is useful if subject alternative names contain wildcards."
+ value = local.validation_domains
+}
diff --git a/modules/aws-acm/variables.tf b/modules/aws-acm/variables.tf
new file mode 100644
index 0000000..fb97417
--- /dev/null
+++ b/modules/aws-acm/variables.tf
@@ -0,0 +1,106 @@
+variable "create_certificate" {
+ description = "Whether to create ACM certificate"
+ type = bool
+ default = true
+}
+
+variable "create_route53_records_only" {
+ description = "Whether to create only Route53 records (e.g. using separate AWS provider)"
+ type = bool
+ default = false
+}
+
+variable "validate_certificate" {
+ description = "Whether to validate certificate by creating Route53 record"
+ type = bool
+ default = true
+}
+
+variable "validation_allow_overwrite_records" {
+ description = "Whether to allow overwrite of Route53 records"
+ type = bool
+ default = true
+}
+
+variable "wait_for_validation" {
+ description = "Whether to wait for the validation to complete"
+ type = bool
+ default = true
+}
+
+variable "certificate_transparency_logging_preference" {
+ description = "Specifies whether certificate details should be added to a certificate transparency log"
+ type = bool
+ default = true
+}
+
+variable "domain_name" {
+ description = "A domain name for which the certificate should be issued"
+ type = string
+ default = ""
+}
+
+variable "subject_alternative_names" {
+ description = "A list of domains that should be SANs in the issued certificate"
+ type = list(string)
+ default = []
+}
+
+variable "validation_method" {
+ description = "Which method to use for validation. DNS or EMAIL are valid, NONE can be used for certificates that were imported into ACM and then into Terraform."
+ type = string
+ default = "DNS"
+
+ validation {
+ condition = contains(["DNS", "EMAIL", "NONE"], var.validation_method)
+ error_message = "Valid values are DNS, EMAIL or NONE."
+ }
+}
+
+variable "validation_option" {
+ description = "The domain name that you want ACM to use to send you validation emails. This domain name is the suffix of the email addresses that you want ACM to use."
+ type = any
+ default = {}
+}
+
+variable "create_route53_records" {
+ description = "When validation is set to DNS, define whether to create the DNS records internally via Route53 or externally using any DNS provider"
+ type = bool
+ default = true
+}
+
+variable "validation_record_fqdns" {
+ description = "When validation is set to DNS and the DNS validation records are set externally, provide the fqdns for the validation"
+ type = list(string)
+ default = []
+}
+
+variable "zone_id" {
+ description = "The ID of the hosted zone to contain this record. Required when validating via Route53"
+ type = string
+ default = ""
+}
+
+variable "tags" {
+ description = "A mapping of tags to assign to the resource"
+ type = map(string)
+ default = {}
+}
+
+variable "dns_ttl" {
+ description = "The TTL of DNS recursive resolvers to cache information about this record."
+ type = number
+ default = 60
+}
+
+variable "acm_certificate_domain_validation_options" {
+ description = "A list of domain_validation_options created by the ACM certificate to create required Route53 records from it (used when create_route53_records_only is set to true)"
+ type = any
+ default = {}
+}
+
+variable "distinct_domain_names" {
+ description = "List of distinct domains and SANs (used when create_route53_records_only is set to true)"
+ type = list(string)
+ default = []
+}
diff --git a/modules/aws-acm/versions.tf b/modules/aws-acm/versions.tf
new file mode 100644
index 0000000..e76924e
--- /dev/null
+++ b/modules/aws-acm/versions.tf
@@ -0,0 +1,10 @@
+terraform {
+ required_version = ">= 1.0"
+
+ required_providers {
+ aws = {
+ source = "hashicorp/aws"
+ version = ">= 4.12.0"
+ }
+ }
+}
diff --git a/modules/aws-acm/wrappers/README.md b/modules/aws-acm/wrappers/README.md
new file mode 100644
index 0000000..6d994ce
--- /dev/null
+++ b/modules/aws-acm/wrappers/README.md
@@ -0,0 +1,100 @@
+# Wrapper for the root module
+
+The configuration in this directory contains an implementation of a single module wrapper pattern, which allows managing several copies of a module in places where using the native Terraform 0.13+ `for_each` feature is not feasible (e.g., with Terragrunt).
+
+You may want to use a single Terragrunt configuration file to manage multiple resources without duplicating `terragrunt.hcl` files for each copy of the same module.
+
+This wrapper does not implement any extra functionality.
+
+## Usage with Terragrunt
+
+`terragrunt.hcl`:
+
+```hcl
+terraform {
+ source = "tfr:///terraform-aws-modules/acm/aws//wrappers"
+ # Alternative source:
+ # source = "git::git@github.com:terraform-aws-modules/terraform-aws-acm.git//wrappers?ref=master"
+}
+
+inputs = {
+ defaults = { # Default values
+ create = true
+ tags = {
+ Terraform = "true"
+ Environment = "dev"
+ }
+ }
+
+ items = {
+ my-item = {
+ # omitted... can be any argument supported by the module
+ }
+ my-second-item = {
+ # omitted... can be any argument supported by the module
+ }
+ # omitted...
+ }
+}
+```
+
+## Usage with Terraform
+
+```hcl
+module "wrapper" {
+ source = "terraform-aws-modules/acm/aws//wrappers"
+
+ defaults = { # Default values
+ create = true
+ tags = {
+ Terraform = "true"
+ Environment = "dev"
+ }
+ }
+
+ items = {
+ my-item = {
+ # omitted... can be any argument supported by the module
+ }
+ my-second-item = {
+ # omitted... can be any argument supported by the module
+ }
+ # omitted...
+ }
+}
+```
+
+## Example: Manage multiple S3 buckets in one Terragrunt layer
+
+`eu-west-1/s3-buckets/terragrunt.hcl`:
+
+```hcl
+terraform {
+ source = "tfr:///terraform-aws-modules/s3-bucket/aws//wrappers"
+ # Alternative source:
+ # source = "git::git@github.com:terraform-aws-modules/terraform-aws-s3-bucket.git//wrappers?ref=master"
+}
+
+inputs = {
+ defaults = {
+ force_destroy = true
+
+ attach_elb_log_delivery_policy = true
+ attach_lb_log_delivery_policy = true
+ attach_deny_insecure_transport_policy = true
+ attach_require_latest_tls_policy = true
+ }
+
+ items = {
+ bucket1 = {
+ bucket = "my-random-bucket-1"
+ }
+ bucket2 = {
+ bucket = "my-random-bucket-2"
+ tags = {
+ Secure = "probably"
+ }
+ }
+ }
+}
+```
diff --git a/modules/aws-acm/wrappers/main.tf b/modules/aws-acm/wrappers/main.tf
new file mode 100644
index 0000000..159282f
--- /dev/null
+++ b/modules/aws-acm/wrappers/main.tf
@@ -0,0 +1,23 @@
+module "wrapper" {
+ source = "../"
+
+ for_each = var.items
+
+ create_certificate = try(each.value.create_certificate, var.defaults.create_certificate, true)
+ create_route53_records_only = try(each.value.create_route53_records_only, var.defaults.create_route53_records_only, false)
+ validate_certificate = try(each.value.validate_certificate, var.defaults.validate_certificate, true)
+ validation_allow_overwrite_records = try(each.value.validation_allow_overwrite_records, var.defaults.validation_allow_overwrite_records, true)
+ wait_for_validation = try(each.value.wait_for_validation, var.defaults.wait_for_validation, true)
+ certificate_transparency_logging_preference = try(each.value.certificate_transparency_logging_preference, var.defaults.certificate_transparency_logging_preference, true)
+ domain_name = try(each.value.domain_name, var.defaults.domain_name, "")
+ subject_alternative_names = try(each.value.subject_alternative_names, var.defaults.subject_alternative_names, [])
+ validation_method = try(each.value.validation_method, var.defaults.validation_method, "DNS")
+ validation_option = try(each.value.validation_option, var.defaults.validation_option, {})
+ create_route53_records = try(each.value.create_route53_records, var.defaults.create_route53_records, true)
+ validation_record_fqdns = try(each.value.validation_record_fqdns, var.defaults.validation_record_fqdns, [])
+ zone_id = try(each.value.zone_id, var.defaults.zone_id, "")
+ tags = try(each.value.tags, var.defaults.tags, {})
+ dns_ttl = try(each.value.dns_ttl, var.defaults.dns_ttl, 60)
+ acm_certificate_domain_validation_options = try(each.value.acm_certificate_domain_validation_options, var.defaults.acm_certificate_domain_validation_options, {})
+ distinct_domain_names = try(each.value.distinct_domain_names, var.defaults.distinct_domain_names, [])
+}
diff --git a/modules/aws-acm/wrappers/outputs.tf b/modules/aws-acm/wrappers/outputs.tf
new file mode 100644
index 0000000..5da7c09
--- /dev/null
+++ b/modules/aws-acm/wrappers/outputs.tf
@@ -0,0 +1,5 @@
+output "wrapper" {
+ description = "Map of outputs of a wrapper."
+ value = module.wrapper
+ # sensitive = false # No sensitive module output found
+}
diff --git a/modules/aws-acm/wrappers/variables.tf b/modules/aws-acm/wrappers/variables.tf
new file mode 100644
index 0000000..a6ea096
--- /dev/null
+++ b/modules/aws-acm/wrappers/variables.tf
@@ -0,0 +1,11 @@
+variable "defaults" {
+ description = "Map of default values which will be used for each item."
+ type = any
+ default = {}
+}
+
+variable "items" {
+ description = "Maps of items to create a wrapper from. Values are passed through to the module."
+ type = any
+ default = {}
+}
diff --git a/modules/aws-acm/wrappers/versions.tf b/modules/aws-acm/wrappers/versions.tf
new file mode 100644
index 0000000..51cad10
--- /dev/null
+++ b/modules/aws-acm/wrappers/versions.tf
@@ -0,0 +1,3 @@
+terraform {
+ required_version = ">= 0.13.1"
+}
diff --git a/modules/aws-alb-master/main.tf b/modules/aws-alb-master/main.tf
new file mode 100644
index 0000000..92a64aa
--- /dev/null
+++ b/modules/aws-alb-master/main.tf
@@ -0,0 +1,288 @@
+#------------------------------------------------------------------------------
+# S3 BUCKET - For access logs
+#------------------------------------------------------------------------------
+data "aws_elb_service_account" "default" {}
+
+resource "random_string" "log_s3_name" {
+ count = var.enable_s3_logs ? 1 : 0
+ length = 8
+ numeric = true
+ special = false
+ upper = false
+}
+
+module "lb_logs_s3" {
+ source = "../terraform-aws-s3"
+ count = var.enable_s3_logs ? 1 : 0
+
+
+ bucket = "alb-log-bucket-${random_string.log_s3_name[0].result}"
+ acl = "log-delivery-write"
+
+ # Allow deletion of non-empty bucket
+ force_destroy = true
+
+ attach_elb_log_delivery_policy = true # Required for ALB logs
+ attach_lb_log_delivery_policy = true # Required for ALB/NLB logs
+ attach_cross_account_policy = false
+
+}
+
+#------------------------------------------------------------------------------
+# APPLICATION LOAD BALANCER
+#------------------------------------------------------------------------------
+resource "random_string" "lb_name" {
+ count = var.use_random_name_for_lb ? 1 : 0
+ length = 32
+ numeric = true
+ special = false
+}
+
+resource "aws_lb" "lb" {
+ name = var.use_random_name_for_lb ? random_string.lb_name[0].result : substr("${var.name_prefix}-lb", 0, 31)
+
+ internal = var.internal
+ load_balancer_type = "application"
+ drop_invalid_header_fields = var.drop_invalid_header_fields
+ subnets = var.internal ? var.private_subnets : var.public_subnets
+ idle_timeout = var.idle_timeout
+ enable_deletion_protection = var.enable_deletion_protection
+ enable_cross_zone_load_balancing = var.enable_cross_zone_load_balancing
+ enable_http2 = var.enable_http2
+ ip_address_type = var.ip_address_type
+ security_groups = compact(var.security_groups)
+
+ dynamic "access_logs" {
+ for_each = var.enable_s3_logs ? [1] : []
+ content {
+ bucket = module.lb_logs_s3[0].s3_bucket_id
+ enabled = var.enable_s3_logs
+ }
+ }
+
+ tags = merge(
+ var.tags,
+ {
+ Name = "${var.name_prefix}-lb"
+ },
+ )
+}
+
+resource "aws_wafv2_web_acl_association" "waf_association" {
+ count = var.waf_web_acl_arn != "" ? 1 : 0
+ resource_arn = aws_lb.lb.arn
+ web_acl_arn = var.waf_web_acl_arn
+}
+
+#------------------------------------------------------------------------------
+# AWS LOAD BALANCER - Target Groups
+#------------------------------------------------------------------------------
+resource "aws_lb_target_group" "lb_http_tgs" {
+ for_each = {
+ for name, config in var.http_ports : name => config
+ if lookup(config, "type", "") == "" || lookup(config, "type", "") == "forward"
+ }
+ name = "${var.name_prefix}-http-${each.value.target_group_port}"
+ port = each.value.target_group_port
+ protocol = lookup(each.value, "target_group_protocol", "") == "" ? "HTTP" : each.value.target_group_protocol
+ vpc_id = var.vpc_id
+ deregistration_delay = var.deregistration_delay
+ slow_start = var.slow_start
+ load_balancing_algorithm_type = var.load_balancing_algorithm_type
+ dynamic "stickiness" {
+ for_each = var.stickiness == null ? [] : [var.stickiness]
+ content {
+ type = stickiness.value.type
+ cookie_duration = stickiness.value.cookie_duration
+ enabled = stickiness.value.enabled
+ }
+ }
+ health_check {
+ enabled = var.target_group_health_check_enabled
+ interval = var.target_group_health_check_interval
+ path = var.target_group_health_check_path
+ protocol = lookup(each.value, "target_group_protocol", "") == "" ? "HTTP" : each.value.target_group_protocol
+ timeout = var.target_group_health_check_timeout
+ healthy_threshold = var.target_group_health_check_healthy_threshold
+ unhealthy_threshold = var.target_group_health_check_unhealthy_threshold
+ matcher = var.target_group_health_check_matcher
+ }
+ target_type = "ip"
+ tags = merge(
+ var.tags,
+ {
+ Name = "${var.name_prefix}-http-${each.value.target_group_port}"
+ },
+ )
+ lifecycle {
+ create_before_destroy = true
+ }
+ depends_on = [aws_lb.lb]
+}
+
+resource "aws_lb_target_group" "lb_https_tgs" {
+ for_each = {
+ for name, config in var.https_ports : name => config
+ if lookup(config, "type", "") == "" || lookup(config, "type", "") == "forward"
+ }
+ name = "${var.name_prefix}-https-${each.value.target_group_port}"
+ port = each.value.target_group_port
+ protocol = lookup(each.value, "target_group_protocol", "") == "" ? "HTTPS" : each.value.target_group_protocol
+ vpc_id = var.vpc_id
+ deregistration_delay = var.deregistration_delay
+ slow_start = var.slow_start
+ load_balancing_algorithm_type = var.load_balancing_algorithm_type
+ dynamic "stickiness" {
+ for_each = var.stickiness == null ? [] : [var.stickiness]
+ content {
+ type = stickiness.value.type
+ cookie_duration = stickiness.value.cookie_duration
+ enabled = stickiness.value.enabled
+ }
+ }
+ health_check {
+ enabled = var.target_group_health_check_enabled
+ interval = var.target_group_health_check_interval
+ path = var.target_group_health_check_path
+ protocol = lookup(each.value, "target_group_protocol", "") == "" ? "HTTPS" : each.value.target_group_protocol
+ timeout = var.target_group_health_check_timeout
+ healthy_threshold = var.target_group_health_check_healthy_threshold
+ unhealthy_threshold = var.target_group_health_check_unhealthy_threshold
+ matcher = var.target_group_health_check_matcher
+ }
+ target_type = "ip"
+ tags = merge(
+ var.tags,
+ {
+ Name = "${var.name_prefix}-https-${each.value.target_group_port}"
+ },
+ )
+ lifecycle {
+ create_before_destroy = true
+ }
+ depends_on = [aws_lb.lb]
+}
+
+#------------------------------------------------------------------------------
+# AWS LOAD BALANCER - Listeners
+#------------------------------------------------------------------------------
+resource "aws_lb_listener" "lb_http_listeners" {
+ for_each = var.http_ports
+ load_balancer_arn = aws_lb.lb.arn
+ port = each.value.listener_port
+ protocol = "HTTP"
+
+ dynamic "default_action" {
+ for_each = lookup(each.value, "type", "") == "redirect" ? [1] : []
+ content {
+ type = "redirect"
+
+ redirect {
+ host = lookup(each.value, "host", "#{host}")
+ path = lookup(each.value, "path", "/#{path}")
+ port = lookup(each.value, "port", "#{port}")
+ protocol = lookup(each.value, "protocol", "#{protocol}")
+ query = lookup(each.value, "query", "#{query}")
+ status_code = lookup(each.value, "status_code", "HTTP_301")
+ }
+ }
+ }
+
+ dynamic "default_action" {
+ for_each = lookup(each.value, "type", "") == "fixed-response" ? [1] : []
+ content {
+ type = "fixed-response"
+
+ fixed_response {
+ content_type = lookup(each.value, "content_type", "text/plain")
+ message_body = lookup(each.value, "message_body", "Fixed response content")
+ status_code = lookup(each.value, "status_code", "200")
+ }
+ }
+ }
+
+ # We fallback to using forward type action if type is not defined
+ dynamic "default_action" {
+ for_each = (lookup(each.value, "type", "") == "" || lookup(each.value, "type", "") == "forward") ? [1] : []
+ content {
+ target_group_arn = aws_lb_target_group.lb_http_tgs[each.key].arn
+ type = "forward"
+ }
+ }
+
+ tags = var.tags
+}
+
+resource "aws_lb_listener" "lb_https_listeners" {
+ for_each = var.https_ports
+ load_balancer_arn = aws_lb.lb.arn
+ port = each.value.listener_port
+ protocol = "HTTPS"
+ ssl_policy = var.ssl_policy
+ certificate_arn = var.default_certificate_arn
+
+ dynamic "default_action" {
+ for_each = lookup(each.value, "type", "") == "redirect" ? [1] : []
+ content {
+ type = "redirect"
+
+ redirect {
+ host = lookup(each.value, "host", "#{host}")
+ path = lookup(each.value, "path", "/#{path}")
+ port = lookup(each.value, "port", "#{port}")
+ protocol = lookup(each.value, "protocol", "#{protocol}")
+ query = lookup(each.value, "query", "#{query}")
+ status_code = lookup(each.value, "status_code", "HTTP_301")
+ }
+ }
+ }
+
+ dynamic "default_action" {
+ for_each = lookup(each.value, "type", "") == "fixed-response" ? [1] : []
+ content {
+ type = "fixed-response"
+
+ fixed_response {
+ content_type = lookup(each.value, "content_type", "text/plain")
+ message_body = lookup(each.value, "message_body", "Fixed response content")
+ status_code = lookup(each.value, "status_code", "200")
+ }
+ }
+ }
+
+ # We fallback to using forward type action if type is not defined
+ dynamic "default_action" {
+ for_each = (lookup(each.value, "type", "") == "" || lookup(each.value, "type", "") == "forward") ? [1] : []
+ content {
+ target_group_arn = aws_lb_target_group.lb_https_tgs[each.key].arn
+ type = "forward"
+ }
+ }
+
+ tags = var.tags
+}
+
+locals {
+ list_maps_listener_certificate_arns = flatten([
+ for cert_arn in var.additional_certificates_arn_for_https_listeners : [
+ for listener in aws_lb_listener.lb_https_listeners : {
+ name = "${listener}-${cert_arn}"
+ listener_arn = listener.arn
+ certificate_arn = cert_arn
+ }
+ ]
+ ])
+
+ map_listener_certificate_arns = {
+ for obj in local.list_maps_listener_certificate_arns : obj.name => {
+ listener_arn = obj.listener_arn,
+ certificate_arn = obj.certificate_arn
+ }
+ }
+}
+
+resource "aws_lb_listener_certificate" "additional_certificates_for_https_listeners" {
+ for_each = local.map_listener_certificate_arns
+ listener_arn = each.value.listener_arn
+ certificate_arn = each.value.certificate_arn
+}
diff --git a/modules/aws-alb-master/outputs.tf b/modules/aws-alb-master/outputs.tf
new file mode 100644
index 0000000..f933d96
--- /dev/null
+++ b/modules/aws-alb-master/outputs.tf
@@ -0,0 +1,120 @@
+#------------------------------------------------------------------------------
+# APPLICATION LOAD BALANCER
+#------------------------------------------------------------------------------
+output "aws_lb_lb_id" {
+ description = "The ARN of the load balancer (matches arn)."
+ value = aws_lb.lb.id
+}
+
+output "aws_lb_lb_arn" {
+ description = "The ARN of the load balancer (matches id)."
+ value = aws_lb.lb.arn
+}
+
+output "aws_lb_lb_arn_suffix" {
+ description = "The ARN suffix for use with CloudWatch Metrics."
+ value = aws_lb.lb.arn_suffix
+}
+
+output "aws_lb_lb_dns_name" {
+ description = "The DNS name of the load balancer."
+ value = aws_lb.lb.dns_name
+}
+
+output "aws_lb_lb_zone_id" {
+ description = "The canonical hosted zone ID of the load balancer (to be used in a Route 53 Alias record)."
+ value = aws_lb.lb.zone_id
+}
+
+#------------------------------------------------------------------------------
+# AWS LOAD BALANCER - Target Groups
+#------------------------------------------------------------------------------
+output "lb_http_tgs_ids" {
+ description = "List of HTTP Target Groups IDs"
+ value = [for tg in aws_lb_target_group.lb_http_tgs : tg.id]
+}
+
+output "lb_http_tgs_arns" {
+ description = "List of HTTP Target Groups ARNs"
+ value = [for tg in aws_lb_target_group.lb_http_tgs : tg.arn]
+}
+
+output "lb_http_tgs_names" {
+ description = "List of HTTP Target Groups Names"
+ value = [for tg in aws_lb_target_group.lb_http_tgs : tg.name]
+}
+
+output "lb_http_tgs_ports" {
+ description = "List of HTTP Target Groups ports"
+ value = [for tg in aws_lb_target_group.lb_http_tgs : tostring(tg.port)]
+}
+
+output "lb_http_tgs_map_arn_port" {
+ value = zipmap(
+ [for tg in aws_lb_target_group.lb_http_tgs : tg.arn],
+ [for tg in aws_lb_target_group.lb_http_tgs : tostring(tg.port)]
+ )
+}
+
+output "lb_https_tgs_ids" {
+ description = "List of HTTPS Target Groups IDs"
+ value = [for tg in aws_lb_target_group.lb_https_tgs : tg.id]
+}
+
+output "lb_https_tgs_arns" {
+ description = "List of HTTPS Target Groups ARNs"
+ value = [for tg in aws_lb_target_group.lb_https_tgs : tg.arn]
+}
+
+output "lb_https_tgs_names" {
+ description = "List of HTTPS Target Groups Names"
+ value = [for tg in aws_lb_target_group.lb_https_tgs : tg.name]
+}
+
+output "lb_https_tgs_ports" {
+ description = "List of HTTPS Target Groups ports"
+ value = [for tg in aws_lb_target_group.lb_https_tgs : tostring(tg.port)]
+}
+
+output "lb_https_tgs_map_arn_port" {
+ value = zipmap(
+ [for tg in aws_lb_target_group.lb_https_tgs : tg.arn],
+ [for tg in aws_lb_target_group.lb_https_tgs : tostring(tg.port)]
+ )
+}
+
+#------------------------------------------------------------------------------
+# AWS LOAD BALANCER - Listeners
+#------------------------------------------------------------------------------
+output "lb_http_listeners_ids" {
+ description = "List of HTTP Listeners IDs"
+ value = [for listener in aws_lb_listener.lb_http_listeners : listener.id]
+}
+
+output "lb_http_listeners_arns" {
+ description = "List of HTTP Listeners ARNs"
+ value = [for listener in aws_lb_listener.lb_http_listeners : listener.arn]
+}
+
+output "lb_https_listeners_ids" {
+ description = "List of HTTPS Listeners IDs"
+ value = [for listener in aws_lb_listener.lb_https_listeners : listener.id]
+}
+
+output "lb_https_listeners_arns" {
+ description = "List of HTTPS Listeners ARNs"
+ value = [for listener in aws_lb_listener.lb_https_listeners : listener.arn]
+}
+
+#------------------------------------------------------------------------------
+# S3 LB Logging Bucket
+#------------------------------------------------------------------------------
+output "lb_logs_s3_bucket_id" {
+ description = "LB Logging S3 Bucket ID"
+ value = var.enable_s3_logs ? module.lb_logs_s3[0].s3_bucket_id : null
+}
+
+output "lb_logs_s3_bucket_arn" {
+ description = "LB Logging S3 Bucket ARN"
+ value = var.enable_s3_logs ? module.lb_logs_s3[0].s3_bucket_arn : null
+}
\ No newline at end of file
diff --git a/modules/aws-alb-master/variables.tf b/modules/aws-alb-master/variables.tf
new file mode 100644
index 0000000..f1499f7
--- /dev/null
+++ b/modules/aws-alb-master/variables.tf
@@ -0,0 +1,249 @@
+#------------------------------------------------------------------------------
+# Misc
+#------------------------------------------------------------------------------
+variable "name_prefix" {
+ description = "Name prefix for resources on AWS"
+}
+
+variable "use_random_name_for_lb" {
+ description = "If true the LB name will be a random string"
+ type = bool
+ default = false
+}
+
+variable "tags" {
+ type = map(string)
+ default = {}
+ description = "Resource tags"
+}
+
+#------------------------------------------------------------------------------
+# AWS Networking
+#------------------------------------------------------------------------------
+variable "vpc_id" {
+ description = "ID of the VPC"
+}
+
+#------------------------------------------------------------------------------
+# S3 logs bucket
+#------------------------------------------------------------------------------
+variable "enable_s3_logs" {
+ description = "(Optional) If true, all resources to send LB logs to S3 will be created"
+ type = bool
+ default = true
+}
+
+
+#------------------------------------------------------------------------------
+# APPLICATION LOAD BALANCER
+#------------------------------------------------------------------------------
+variable "internal" {
+ description = "(Optional) If true, the LB will be internal."
+ type = bool
+ default = false
+}
+
+variable "security_groups" {
+ description = "(Optional) A list of security group IDs to assign to the LB."
+ type = list(string)
+ default = []
+}
+
+variable "drop_invalid_header_fields" {
+ description = "(Optional) Indicates whether HTTP headers with header fields that are not valid are removed by the load balancer (true) or routed to targets (false). The default is false. Elastic Load Balancing requires that message header names contain only alphanumeric characters and hyphens."
+ type = bool
+ default = false
+}
+
+variable "private_subnets" {
+ description = "A list of private subnet IDs to attach to the LB if it is INTERNAL."
+ type = list(string)
+}
+
+variable "public_subnets" {
+ description = "A list of public subnet IDs to attach to the LB if it is NOT internal."
+ type = list(string)
+}
+
+variable "idle_timeout" {
+ description = "(Optional) The time in seconds that the connection is allowed to be idle. Default: 60."
+ type = number
+ default = 60
+}
+
+variable "enable_deletion_protection" {
+ description = "(Optional) If true, deletion of the load balancer will be disabled via the AWS API. This will prevent Terraform from deleting the load balancer. Defaults to false."
+ type = bool
+ default = false
+}
+
+variable "enable_cross_zone_load_balancing" {
+ description = "(Optional) If true, cross-zone load balancing of the load balancer will be enabled. Defaults to false."
+ type = bool
+ default = false
+}
+
+variable "enable_http2" {
+ description = "(Optional) Indicates whether HTTP/2 is enabled in the load balancer. Defaults to true."
+ type = bool
+ default = true
+}
+
+variable "ip_address_type" {
+ description = "(Optional) The type of IP addresses used by the subnets for your load balancer. The possible values are ipv4 and dualstack. Defaults to ipv4"
+ type = string
+ default = "ipv4"
+}
+
+variable "waf_web_acl_arn" {
+ description = "ARN of a WAFV2 to associate with the ALB"
+ type = string
+ default = ""
+}
+
+#------------------------------------------------------------------------------
+# ACCESS CONTROL TO APPLICATION LOAD BALANCER
+#------------------------------------------------------------------------------
+variable "http_ports" {
+ description = "Map containing objects to define listeners behaviour based on type field. If type field is `forward`, include listener_port and the target_group_port. For `redirect` type, include listener port, host, path, port, protocol, query and status_code. For `fixed-response`, include listener_port, content_type, message_body and status_code"
+ type = map(any)
+ default = {
+ default_http = {
+ type = "forward"
+ listener_port = 80
+ target_group_port = 80
+ }
+ }
+}
+
+variable "https_ports" {
+ description = "Map containing objects to define listeners behaviour based on type field. If type field is `forward`, include listener_port and the target_group_port. For `redirect` type, include listener port, host, path, port, protocol, query and status_code. For `fixed-response`, include listener_port, content_type, message_body and status_code"
+ type = map(any)
+ default = {
+ default_http = {
+ type = "forward"
+ listener_port = 443
+ target_group_port = 443
+ }
+ }
+}
+
+
+variable "http_ingress_cidr_blocks" {
+ description = "List of CIDR blocks to allowed to access the Load Balancer through HTTP"
+ type = list(string)
+ default = ["0.0.0.0/0"]
+}
+
+variable "http_ingress_prefix_list_ids" {
+ description = "List of prefix list IDs blocks to allowed to access the Load Balancer through HTTP"
+ type = list(string)
+ default = []
+}
+
+variable "https_ingress_cidr_blocks" {
+ description = "List of CIDR blocks to allowed to access the Load Balancer through HTTPS"
+ type = list(string)
+ default = ["0.0.0.0/0"]
+}
+
+variable "https_ingress_prefix_list_ids" {
+ description = "List of prefix list IDs blocks to allowed to access the Load Balancer through HTTPS"
+ type = list(string)
+ default = []
+}
+
+#------------------------------------------------------------------------------
+# AWS LOAD BALANCER - Target Groups
+#------------------------------------------------------------------------------
+variable "deregistration_delay" {
+ description = "(Optional) The amount time for Elastic Load Balancing to wait before changing the state of a deregistering target from draining to unused. The range is 0-3600 seconds. The default value is 300 seconds."
+ type = number
+ default = 300
+}
+
+variable "slow_start" {
+ description = "(Optional) The amount time for targets to warm up before the load balancer sends them a full share of requests. The range is 30-900 seconds or 0 to disable. The default value is 0 seconds."
+ type = number
+ default = 0
+}
+
+variable "load_balancing_algorithm_type" {
+ description = "(Optional) Determines how the load balancer selects targets when routing requests. The value is round_robin or least_outstanding_requests. The default is round_robin."
+ type = string
+ default = "round_robin"
+}
+
+variable "stickiness" {
+ description = "(Optional) A Stickiness block. Provide three fields. type, the type of sticky sessions. The only current possible value is lb_cookie. cookie_duration, the time period, in seconds, during which requests from a client should be routed to the same target. After this time period expires, the load balancer-generated cookie is considered stale. The range is 1 second to 1 week (604800 seconds). The default value is 1 day (86400 seconds). enabled, boolean to enable / disable stickiness. Default is true."
+ type = object({
+ type = string
+ cookie_duration = string
+ enabled = bool
+ })
+ default = {
+ type = "lb_cookie"
+ cookie_duration = 86400
+ enabled = true
+ }
+}
+
+variable "target_group_health_check_enabled" {
+ description = "(Optional) Indicates whether health checks are enabled. Defaults to true."
+ type = bool
+ default = true
+}
+
+variable "target_group_health_check_interval" {
+ description = "(Optional) The approximate amount of time, in seconds, between health checks of an individual target. Minimum value 5 seconds, Maximum value 300 seconds. Default 30 seconds."
+ type = number
+ default = 30
+}
+
+variable "target_group_health_check_path" {
+ description = "The destination for the health check request."
+ type = string
+ default = "/"
+}
+
+variable "target_group_health_check_timeout" {
+ description = "(Optional) The amount of time, in seconds, during which no response means a failed health check. The range is 2 to 120 seconds, and the default is 5 seconds."
+ type = number
+ default = 5
+}
+
+variable "target_group_health_check_healthy_threshold" {
+ description = "(Optional) The number of consecutive health checks successes required before considering an unhealthy target healthy. Defaults to 3."
+ type = number
+ default = 3
+}
+
+variable "target_group_health_check_unhealthy_threshold" {
+ description = "(Optional) The number of consecutive health check failures required before considering the target unhealthy. Defaults to 3."
+ type = number
+ default = 3
+}
+
+variable "target_group_health_check_matcher" {
+ description = "The HTTP codes to use when checking for a successful response from a target. You can specify multiple values (for example, \"200,202\") or a range of values (for example, \"200-299\"). Default is 200."
+ type = string
+ default = "200"
+}
+
+variable "ssl_policy" {
+ description = "(Optional) The name of the SSL Policy for the listener. . Required if var.https_ports is set."
+ type = string
+ default = null
+}
+
+variable "default_certificate_arn" {
+ description = "(Optional) The ARN of the default SSL server certificate. Required if var.https_ports is set."
+ type = string
+ default = null
+}
+
+variable "additional_certificates_arn_for_https_listeners" {
+ description = "(Optional) List of SSL server certificate ARNs for HTTPS listener. Use it if you need to set additional certificates besides default_certificate_arn"
+ type = list(any)
+ default = []
+}
\ No newline at end of file
diff --git a/modules/aws-alb-master/versions.tf b/modules/aws-alb-master/versions.tf
new file mode 100644
index 0000000..35402be
--- /dev/null
+++ b/modules/aws-alb-master/versions.tf
@@ -0,0 +1,10 @@
+terraform {
+ required_version = ">= 1.0"
+
+ required_providers {
+ aws = {
+ source = "hashicorp/aws"
+ version = ">= 4.6"
+ }
+ }
+}
diff --git a/modules/aws-amplify/main.tf b/modules/aws-amplify/main.tf
new file mode 100644
index 0000000..75185ef
--- /dev/null
+++ b/modules/aws-amplify/main.tf
@@ -0,0 +1,62 @@
+resource "aws_amplify_app" "this" {
+ name = var.name
+ repository = var.repository
+
+ build_spec = var.build_spec
+
+ environment_variables = var.environment_variables
+
+ auto_branch_creation_patterns = var.auto_branch_creation_patterns
+
+ enable_auto_branch_creation = try(var.enable_auto_branch_creation, false)
+ enable_basic_auth = try(var.enable_basic_auth, false)
+ enable_branch_auto_build = try(var.enable_branch_auto_build, false)
+ enable_branch_auto_deletion = try(var.enable_branch_auto_deletion, false)
+
+ iam_service_role_arn = var.iam_service_role_arn
+
+ platform = var.platform
+
+ dynamic "custom_rule" {
+ for_each = var.custom_rules
+
+ content {
+ source = custom_rule.value["source"]
+ status = custom_rule.value["status"]
+ target = custom_rule.value["target"]
+ }
+ }
+
+ tags = var.tags
+}
+
+resource "aws_amplify_branch" "this" {
+ app_id = aws_amplify_app.this.id
+ branch_name = var.branch_name
+
+ framework = var.framework
+ stage = var.stage
+
+ enable_auto_build = var.enable_auto_build
+ enable_performance_mode = var.enable_performance_mode
+ enable_pull_request_preview = var.enable_pull_request_preview
+
+ tags = var.tags
+}
+
+resource "aws_amplify_domain_association" "this" {
+ app_id = aws_amplify_app.this.id
+ domain_name = var.domain_name
+
+ enable_auto_sub_domain = var.enable_auto_sub_domain
+
+ dynamic "sub_domain" {
+ for_each = var.sub_domains
+
+ content {
+ branch_name = aws_amplify_branch.this.branch_name
+ prefix = try(sub_domain.value["prefix"], "")
+ dns_record = try(sub_domain.value["dns_record"], null)
+ }
+ }
+}
diff --git a/modules/aws-amplify/variables.tf b/modules/aws-amplify/variables.tf
new file mode 100644
index 0000000..a0b914a
--- /dev/null
+++ b/modules/aws-amplify/variables.tf
@@ -0,0 +1,111 @@
+variable "name" {
+ description = "Application repository address connect to"
+ type = string
+}
+
+variable "repository" {
+ description = "Application repository address connect to"
+ type = string
+}
+
+variable "build_spec" {
+ description = "Application repository address connect to"
+ type = string
+}
+
+variable "environment_variables" {
+ type = any
+ default = {}
+}
+
+variable "enable_auto_branch_creation" {
+ description = "Application repository address connect to"
+ type = bool
+ default = false
+}
+
+variable "enable_basic_auth" {
+ description = "Application repository address connect to"
+ type = bool
+ default = false
+}
+
+variable "enable_branch_auto_build" {
+ description = "Application repository address connect to"
+ type = bool
+ default = false
+}
+
+variable "enable_branch_auto_deletion" {
+ description = "Application repository address connect to"
+ type = bool
+ default = false
+}
+
+variable "enable_auto_build" {
+ description = "Application repository address connect to"
+ type = bool
+ default = true
+}
+
+variable "enable_performance_mode" {
+ description = "Application repository address connect to"
+ type = bool
+ default = false
+}
+
+variable "platform" {
+ description = "Application repository address connect to"
+ type = string
+ default = "WEB_COMPUTE"
+}
+
+variable "auto_branch_creation_patterns" {
+ description = "Application repository address connect to"
+ type = list(any)
+ default = []
+}
+
+variable "iam_service_role_arn" {
+ description = "Application repository address connect to"
+ type = string
+}
+
+variable "custom_rules" {
+ type = list(any)
+ default = []
+}
+
+variable "tags" {
+ type = any
+ default = []
+}
+
+variable "branch_name" {
+ type = string
+ default = "main"
+}
+
+variable "framework" {
+ type = string
+}
+variable "domain_name" {
+ type = string
+}
+variable "sub_domains" {
+ type = list(any)
+}
+
+variable "stage" {
+ type = string
+}
+
+variable "enable_pull_request_preview" {
+ type = bool
+ default = false
+}
+
+variable "enable_auto_sub_domain" {
+ type = bool
+ default = false
+}
diff --git a/modules/aws-api-gateway/README.md b/modules/aws-api-gateway/README.md
new file mode 100644
index 0000000..da0ed8c
--- /dev/null
+++ b/modules/aws-api-gateway/README.md
@@ -0,0 +1,279 @@
+ ** DO NOT EDIT THIS FILE
+ **
+ ** This file was automatically generated by the `build-harness`.
+ ** 1) Make all changes to `README.yaml`
+ ** 2) Run `make init` (you only need to do this once)
+ ** 3) Run`make readme` to rebuild this file.
+ **
+ ** (We maintain HUNDREDS of open source projects. This is how we maintain our sanity.)
+ **
+
+
+
+
+
+-->
+
+Terraform module to provision API Gatway resources.
+
+The root module creates an API Gateway [REST API](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-rest-api.html)
+along with configuring tracing, logging, and metrics.
+
+We literally have [*hundreds of terraform modules*][terraform_modules] that are Open Source and well-maintained. Check them out!
+
+
+
+
+
+## Introduction
+
+A set of modules for configuring an API Gateway
+
+
+## Security & Compliance
+
+
+## Usage
+
+
+**IMPORTANT:** We do not pin modules to versions in our examples because of the
+difficulty of keeping the versions in the documentation in sync with the latest released versions.
+We highly recommend that in your code you pin the version to the exact version you are
+using so that your infrastructure remains stable, and update versions in a
+systematic way so that they do not catch you by surprise.
+
+Also, because of a bug in the Terraform registry ([hashicorp/terraform#21417](https://github.com/hashicorp/terraform/issues/21417)),
+the registry shows many of our inputs as required when in fact they are optional.
+The table below correctly indicates which inputs are required.
+
+
+
+Setup the account-level settings for logging and metrics for API Gateway:
+
+```hcl
+module "api_gateway_account_settgings" {
+ source = "cloudposse/api-gateway/aws//modules/account-settings"
+ # version = "x.x.x"
+
+ context = module.this.context
+}
+```
+
+
+
+
+## Examples
+
+Review the [examples](examples) folder to see how to use the API Gateway modules.
+
+
+
+
+## Makefile Targets
+```text
+Available targets:
+
+ help Help screen
+ help/all Display help for all targets
+ help/short This help short screen
+ lint Lint terraform code
+
+```
+
+
+## Requirements
+
+| Name | Version |
+|------|---------|
+| [terraform](#requirement\_terraform) | >= 0.13 |
+| [aws](#requirement\_aws) | >= 3.0 |
+
+## Providers
+
+| Name | Version |
+|------|---------|
+| [aws](#provider\_aws) | >= 3.0 |
+
+## Modules
+
+| Name | Source | Version |
+|------|--------|---------|
+| [cloudwatch\_log\_group](#module\_cloudwatch\_log\_group) | cloudposse/cloudwatch-logs/aws | 0.6.5 |
+| [this](#module\_this) | cloudposse/label/null | 0.25.0 |
+
+## Resources
+
+| Name | Type |
+|------|------|
+| [aws_api_gateway_deployment.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/api_gateway_deployment) | resource |
+| [aws_api_gateway_method_settings.all](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/api_gateway_method_settings) | resource |
+| [aws_api_gateway_rest_api.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/api_gateway_rest_api) | resource |
+| [aws_api_gateway_rest_api_policy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/api_gateway_rest_api_policy) | resource |
+| [aws_api_gateway_stage.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/api_gateway_stage) | resource |
+| [aws_api_gateway_vpc_link.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/api_gateway_vpc_link) | resource |
+
+## Inputs
+
+| Name | Description | Type | Default | Required |
+|------|-------------|------|---------|:--------:|
+| [access\_log\_format](#input\_access\_log\_format) | The format of the access log file. | `string` | `" {\n\t\"requestTime\": \"$context.requestTime\",\n\t\"requestId\": \"$context.requestId\",\n\t\"httpMethod\": \"$context.httpMethod\",\n\t\"path\": \"$context.path\",\n\t\"resourcePath\": \"$context.resourcePath\",\n\t\"status\": $context.status,\n\t\"responseLatency\": $context.responseLatency,\n \"xrayTraceId\": \"$context.xrayTraceId\",\n \"integrationRequestId\": \"$context.integration.requestId\",\n\t\"functionResponseStatus\": \"$context.integration.status\",\n \"integrationLatency\": \"$context.integration.latency\",\n\t\"integrationServiceStatus\": \"$context.integration.integrationStatus\",\n \"authorizeResultStatus\": \"$context.authorize.status\",\n\t\"authorizerServiceStatus\": \"$context.authorizer.status\",\n\t\"authorizerLatency\": \"$context.authorizer.latency\",\n\t\"authorizerRequestId\": \"$context.authorizer.requestId\",\n \"ip\": \"$context.identity.sourceIp\",\n\t\"userAgent\": \"$context.identity.userAgent\",\n\t\"principalId\": \"$context.authorizer.principalId\",\n\t\"cognitoUser\": \"$context.identity.cognitoIdentityId\",\n \"user\": \"$context.identity.user\"\n}\n"` | no |
+| [additional\_tag\_map](#input\_additional\_tag\_map) | Additional key-value pairs to add to each map in `tags_as_list_of_maps`. Not added to `tags` or `id`.
This is for some rare cases where resources want additional configuration of tags
and therefore take a list of maps with tag key, value, and additional configuration. | `map(string)` | `{}` | no |
+| [attributes](#input\_attributes) | ID element. Additional attributes (e.g. `workers` or `cluster`) to add to `id`,
in the order they appear in the list. New attributes are appended to the
end of the list. The elements of the list are joined by the `delimiter`
and treated as a single ID element. | `list(string)` | `[]` | no |
+| [context](#input\_context) | Single object for setting entire context at once.
See description of individual variables for details.
Leave string and numeric variables as `null` to use default value.
Individual variable settings (non-null) override settings in context object,
except for attributes, tags, and additional\_tag\_map, which are merged. | `any` |
{| no | +| [delimiter](#input\_delimiter) | Delimiter to be used between ID elements.
"additional_tag_map": {},
"attributes": [],
"delimiter": null,
"descriptor_formats": {},
"enabled": true,
"environment": null,
"id_length_limit": null,
"label_key_case": null,
"label_order": [],
"label_value_case": null,
"labels_as_tags": [
"unset"
],
"name": null,
"namespace": null,
"regex_replace_chars": null,
"stage": null,
"tags": {},
"tenant": null
}
[| no | +| [logging\_level](#input\_logging\_level) | The logging level of the API. One of - OFF, INFO, ERROR | `string` | `"INFO"` | no | +| [metrics\_enabled](#input\_metrics\_enabled) | A flag to indicate whether to enable metrics collection. | `bool` | `false` | no | +| [name](#input\_name) | ID element. Usually the component or solution name, e.g. 'app' or 'jenkins'.
"default"
]
{| no | +| [delimiter](#input\_delimiter) | Delimiter to be used between ID elements.
"additional_tag_map": {},
"attributes": [],
"delimiter": null,
"descriptor_formats": {},
"enabled": true,
"environment": null,
"id_length_limit": null,
"label_key_case": null,
"label_order": [],
"label_value_case": null,
"labels_as_tags": [
"unset"
],
"name": null,
"namespace": null,
"regex_replace_chars": null,
"stage": null,
"tags": {},
"tenant": null
}
[| no | +| [logging\_level](#input\_logging\_level) | The logging level of the API. One of - OFF, INFO, ERROR | `string` | `"INFO"` | no | +| [metrics\_enabled](#input\_metrics\_enabled) | A flag to indicate whether to enable metrics collection. | `bool` | `false` | no | +| [name](#input\_name) | ID element. Usually the component or solution name, e.g. 'app' or 'jenkins'.
"default"
]
[| no | +| [cognito\_authentication\_enabled](#input\_cognito\_authentication\_enabled) | Whether to enable Amazon Cognito authentication with Kibana | `bool` | `false` | no | +| [cognito\_iam\_role\_arn](#input\_cognito\_iam\_role\_arn) | ARN of the IAM role that has the AmazonESCognitoAccess policy attached | `string` | `""` | no | +| [cognito\_identity\_pool\_id](#input\_cognito\_identity\_pool\_id) | The ID of the Cognito Identity Pool to use | `string` | `""` | no | +| [cognito\_user\_pool\_id](#input\_cognito\_user\_pool\_id) | The ID of the Cognito User Pool to use | `string` | `""` | no | +| [create\_iam\_service\_linked\_role](#input\_create\_iam\_service\_linked\_role) | Whether to create `AWSServiceRoleForAmazonElasticsearchService` service-linked role. Set it to `false` if you already have an ElasticSearch cluster created in the AWS account and AWSServiceRoleForAmazonElasticsearchService already exists. See https://github.com/terraform-providers/terraform-provider-aws/issues/5218 for more info | `bool` | `true` | no | +| [custom\_endpoint](#input\_custom\_endpoint) | Fully qualified domain for custom endpoint. | `string` | `""` | no | +| [custom\_endpoint\_certificate\_arn](#input\_custom\_endpoint\_certificate\_arn) | ACM certificate ARN for custom endpoint. | `string` | `""` | no | +| [custom\_endpoint\_enabled](#input\_custom\_endpoint\_enabled) | Whether to enable custom endpoint for the Elasticsearch domain. | `bool` | `false` | no | +| [dedicated\_master\_count](#input\_dedicated\_master\_count) | Number of dedicated master nodes in the cluster | `number` | `0` | no | +| [dedicated\_master\_enabled](#input\_dedicated\_master\_enabled) | Indicates whether dedicated master nodes are enabled for the cluster | `bool` | `false` | no | +| [dedicated\_master\_type](#input\_dedicated\_master\_type) | Instance type of the dedicated master nodes in the cluster | `string` | `"t2.small.elasticsearch"` | no | +| [dns\_zone\_id](#input\_dns\_zone\_id) | Route53 DNS Zone ID to add hostname records for Elasticsearch domain and Kibana | `string` | `""` | no | +| [domain\_endpoint\_options\_enforce\_https](#input\_domain\_endpoint\_options\_enforce\_https) | Whether or not to require HTTPS | `bool` | `true` | no | +| [domain\_endpoint\_options\_tls\_security\_policy](#input\_domain\_endpoint\_options\_tls\_security\_policy) | The name of the TLS security policy that needs to be applied to the HTTPS endpoint | `string` | `"Policy-Min-TLS-1-0-2019-07"` | no | +| [domain\_hostname\_enabled](#input\_domain\_hostname\_enabled) | Explicit flag to enable creating a DNS hostname for ES. If `true`, then `var.dns_zone_id` is required. | `bool` | `false` | no | +| [ebs\_iops](#input\_ebs\_iops) | The baseline input/output (I/O) performance of EBS volumes attached to data nodes. Applicable only for the Provisioned IOPS EBS volume type | `number` | `0` | no | +| [ebs\_volume\_size](#input\_ebs\_volume\_size) | EBS volumes for data storage in GB | `number` | `0` | no | +| [ebs\_volume\_type](#input\_ebs\_volume\_type) | Storage type of EBS volumes | `string` | `"gp2"` | no | +| [elasticsearch\_subdomain\_name](#input\_elasticsearch\_subdomain\_name) | The name of the subdomain for Elasticsearch in the DNS zone (\_e.g.\_ `elasticsearch`, `ui`, `ui-es`, `search-ui`) | `string` | `""` | no | +| [elasticsearch\_version](#input\_elasticsearch\_version) | Version of Elasticsearch to deploy (\_e.g.\_ `7.4`, `7.1`, `6.8`, `6.7`, `6.5`, `6.4`, `6.3`, `6.2`, `6.0`, `5.6`, `5.5`, `5.3`, `5.1`, `2.3`, `1.5` | `string` | `"7.4"` | no | +| [enabled](#input\_enabled) | Set to false to prevent the module from creating any resources | `bool` | `null` | no | +| [encrypt\_at\_rest\_enabled](#input\_encrypt\_at\_rest\_enabled) | Whether to enable encryption at rest | `bool` | `true` | no | +| [encrypt\_at\_rest\_kms\_key\_id](#input\_encrypt\_at\_rest\_kms\_key\_id) | The KMS key ID to encrypt the Elasticsearch domain with. If not specified, then it defaults to using the AWS/Elasticsearch service KMS key | `string` | `""` | no | +| [iam\_actions](#input\_iam\_actions) | List of actions to allow for the IAM roles, _e.g._ `es:ESHttpGet`, `es:ESHttpPut`, `es:ESHttpPost` | `list(string)` | `[]` | no | +| [iam\_authorizing\_role\_arns](#input\_iam\_authorizing\_role\_arns) | List of IAM role ARNs to permit to assume the Elasticsearch user role | `list(string)` | `[]` | no | +| [iam\_role\_arns](#input\_iam\_role\_arns) | List of IAM role ARNs to permit access to the Elasticsearch domain | `list(string)` | `[]` | no | +| [iam\_role\_max\_session\_duration](#input\_iam\_role\_max\_session\_duration) | The maximum session duration (in seconds) for the user role. Can have a value from 1 hour to 12 hours | `number` | `3600` | no | +| [iam\_role\_permissions\_boundary](#input\_iam\_role\_permissions\_boundary) | The ARN of the permissions boundary policy which will be attached to the Elasticsearch user role | `string` | `null` | no | +| [ingress\_port\_range\_end](#input\_ingress\_port\_range\_end) | End number for allowed port range. (e.g. `443`) | `number` | `65535` | no | +| [ingress\_port\_range\_start](#input\_ingress\_port\_range\_start) | Start number for allowed port range. (e.g. `443`) | `number` | `0` | no | +| [instance\_count](#input\_instance\_count) | Number of data nodes in the cluster | `number` | `4` | no | +| [instance\_type](#input\_instance\_type) | Elasticsearch instance type for data nodes in the cluster | `string` | `"t2.small.elasticsearch"` | no | +| [kibana\_hostname\_enabled](#input\_kibana\_hostname\_enabled) | Explicit flag to enable creating a DNS hostname for Kibana. If `true`, then `var.dns_zone_id` is required. | `bool` | `false` | no | +| [kibana\_subdomain\_name](#input\_kibana\_subdomain\_name) | The name of the subdomain for Kibana in the DNS zone (\_e.g.\_ `kibana`, `ui`, `ui-es`, `search-ui`, `kibana.elasticsearch`) | `string` | `""` | no | +| [log\_publishing\_application\_cloudwatch\_log\_group\_arn](#input\_log\_publishing\_application\_cloudwatch\_log\_group\_arn) | ARN of the CloudWatch log group to which log for ES\_APPLICATION\_LOGS needs to be published | `string` | `""` | no | +| [log\_publishing\_application\_enabled](#input\_log\_publishing\_application\_enabled) | Specifies whether log publishing option for ES\_APPLICATION\_LOGS is enabled or not | `bool` | `false` | no | +| [log\_publishing\_audit\_cloudwatch\_log\_group\_arn](#input\_log\_publishing\_audit\_cloudwatch\_log\_group\_arn) | ARN of the CloudWatch log group to which log for AUDIT\_LOGS needs to be published | `string` | `""` | no | +| [log\_publishing\_audit\_enabled](#input\_log\_publishing\_audit\_enabled) | Specifies whether log publishing option for AUDIT\_LOGS is enabled or not | `bool` | `false` | no | +| [log\_publishing\_index\_cloudwatch\_log\_group\_arn](#input\_log\_publishing\_index\_cloudwatch\_log\_group\_arn) | ARN of the CloudWatch log group to which log for INDEX\_SLOW\_LOGS needs to be published | `string` | `""` | no | +| [log\_publishing\_index\_enabled](#input\_log\_publishing\_index\_enabled) | Specifies whether log publishing option for INDEX\_SLOW\_LOGS is enabled or not | `bool` | `false` | no | +| [log\_publishing\_search\_cloudwatch\_log\_group\_arn](#input\_log\_publishing\_search\_cloudwatch\_log\_group\_arn) | ARN of the CloudWatch log group to which log for SEARCH\_SLOW\_LOGS needs to be published | `string` | `""` | no | +| [log\_publishing\_search\_enabled](#input\_log\_publishing\_search\_enabled) | Specifies whether log publishing option for SEARCH\_SLOW\_LOGS is enabled or not | `bool` | `false` | no | +| [node\_to\_node\_encryption\_enabled](#input\_node\_to\_node\_encryption\_enabled) | Whether to enable node-to-node encryption | `bool` | `false` | no | +| [security\_groups](#input\_security\_groups) | List of security group IDs to be allowed to connect to the cluster | `list(string)` | `[]` | no | +| [subnet\_ids](#input\_subnet\_ids) | VPC Subnet IDs | `list(string)` | `[]` | no | +| [tags](#input\_tags) | Additional tags (e.g. `{'BusinessUnit': 'XYZ'}`).
"ec2.amazonaws.com"
]
{| no | +| [wait\_for\_deployment](#input\_wait\_for\_deployment) | If enabled, the resource will wait for the distribution status to change from InProgress to Deployed. Setting this tofalse will skip the process. | `bool` | `true` | no | +| [web\_acl\_id](#input\_web\_acl\_id) | If you're using AWS WAF to filter CloudFront requests, the Id of the AWS WAF web ACL that is associated with the distribution. The WAF Web ACL must exist in the WAF Global (CloudFront) region and the credentials configuring this argument must have waf:GetWebACL permissions assigned. If using WAFv2, provide the ARN of the web ACL. | `string` | `null` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [cloudfront\_distribution\_arn](#output\_cloudfront\_distribution\_arn) | The ARN (Amazon Resource Name) for the distribution. | +| [cloudfront\_distribution\_caller\_reference](#output\_cloudfront\_distribution\_caller\_reference) | Internal value used by CloudFront to allow future updates to the distribution configuration. | +| [cloudfront\_distribution\_domain\_name](#output\_cloudfront\_distribution\_domain\_name) | The domain name corresponding to the distribution. | +| [cloudfront\_distribution\_etag](#output\_cloudfront\_distribution\_etag) | The current version of the distribution's information. | +| [cloudfront\_distribution\_hosted\_zone\_id](#output\_cloudfront\_distribution\_hosted\_zone\_id) | The CloudFront Route 53 zone ID that can be used to route an Alias Resource Record Set to. | +| [cloudfront\_distribution\_id](#output\_cloudfront\_distribution\_id) | The identifier for the distribution. | +| [cloudfront\_distribution\_in\_progress\_validation\_batches](#output\_cloudfront\_distribution\_in\_progress\_validation\_batches) | The number of invalidation batches currently in progress. | +| [cloudfront\_distribution\_last\_modified\_time](#output\_cloudfront\_distribution\_last\_modified\_time) | The date and time the distribution was last modified. | +| [cloudfront\_distribution\_status](#output\_cloudfront\_distribution\_status) | The current status of the distribution. Deployed if the distribution's information is fully propagated throughout the Amazon CloudFront system. | +| [cloudfront\_distribution\_tags](#output\_cloudfront\_distribution\_tags) | Tags of the distribution's | +| [cloudfront\_distribution\_trusted\_signers](#output\_cloudfront\_distribution\_trusted\_signers) | List of nested attributes for active trusted signers, if the distribution is set up to serve private content with signed URLs | +| [cloudfront\_monitoring\_subscription\_id](#output\_cloudfront\_monitoring\_subscription\_id) | The ID of the CloudFront monitoring subscription, which corresponds to the `distribution_id`. | +| [cloudfront\_origin\_access\_identities](#output\_cloudfront\_origin\_access\_identities) | The origin access identities created | +| [cloudfront\_origin\_access\_identity\_iam\_arns](#output\_cloudfront\_origin\_access\_identity\_iam\_arns) | The IAM arns of the origin access identities created | +| [cloudfront\_origin\_access\_identity\_ids](#output\_cloudfront\_origin\_access\_identity\_ids) | The IDS of the origin access identities created | +| [s3\_bucket\_name](#s3\_bucket\_name) | S3 origin bucket name for Cloudfront | +| [zone\_id](#zone\_id) | Zone id of the route53 record| + \ No newline at end of file diff --git a/modules/aws-cloudfront/examples/complete/.gitignore b/modules/aws-cloudfront/examples/complete/.gitignore new file mode 100644 index 0000000..c4c4ffc --- /dev/null +++ b/modules/aws-cloudfront/examples/complete/.gitignore @@ -0,0 +1 @@ +*.zip diff --git a/modules/aws-cloudfront/examples/complete/README.md b/modules/aws-cloudfront/examples/complete/README.md new file mode 100644 index 0000000..6572fc1 --- /dev/null +++ b/modules/aws-cloudfront/examples/complete/README.md @@ -0,0 +1,88 @@ +# Complete CloudFront distribution with most of supported features enabled + +Configuration in this directory creates CloudFront distribution which demos such capabilities: +- access logging +- origins and origin groups +- caching behaviours +- Origin Access Identities (with S3 bucket policy) +- Lambda@Edge +- ACM certificate +- Route53 record + +## Usage + +To run this example you need to execute: + +```bash +$ terraform init +$ terraform plan +$ terraform apply +``` + +Note that this example may create resources which cost money. Run `terraform destroy` when you don't need these resources. + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 4.29 | +| [external](#requirement\_external) | >= 1.0 | +| [local](#requirement\_local) | >= 1.0 | +| [null](#requirement\_null) | >= 2.0 | +| [random](#requirement\_random) | >= 2.0 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 4.29 | +| [null](#provider\_null) | >= 2.0 | +| [random](#provider\_random) | >= 2.0 | + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [acm](#module\_acm) | terraform-aws-modules/acm/aws | ~> 4.0 | +| [cloudfront](#module\_cloudfront) | ../../ | n/a | +| [lambda\_function](#module\_lambda\_function) | terraform-aws-modules/lambda/aws | ~> 4.0 | +| [log\_bucket](#module\_log\_bucket) | terraform-aws-modules/s3-bucket/aws | ~> 3.0 | +| [records](#module\_records) | terraform-aws-modules/route53/aws//modules/records | ~> 2.0 | +| [s3\_one](#module\_s3\_one) | terraform-aws-modules/s3-bucket/aws | ~> 3.0 | + +## Resources + +| Name | Type | +|------|------| +| [aws_cloudfront_function.example](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudfront_function) | resource | +| [aws_s3_bucket_policy.bucket_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_policy) | resource | +| [null_resource.download_package](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource | +| [random_pet.this](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/pet) | resource | +| [aws_canonical_user_id.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/canonical_user_id) | data source | +| [aws_iam_policy_document.s3_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_route53_zone.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/route53_zone) | data source | + +## Inputs + +No inputs. + +## Outputs + +| Name | Description | +|------|-------------| +| [cloudfront\_distribution\_arn](#output\_cloudfront\_distribution\_arn) | The ARN (Amazon Resource Name) for the distribution. | +| [cloudfront\_distribution\_caller\_reference](#output\_cloudfront\_distribution\_caller\_reference) | Internal value used by CloudFront to allow future updates to the distribution configuration. | +| [cloudfront\_distribution\_domain\_name](#output\_cloudfront\_distribution\_domain\_name) | The domain name corresponding to the distribution. | +| [cloudfront\_distribution\_etag](#output\_cloudfront\_distribution\_etag) | The current version of the distribution's information. | +| [cloudfront\_distribution\_hosted\_zone\_id](#output\_cloudfront\_distribution\_hosted\_zone\_id) | The CloudFront Route 53 zone ID that can be used to route an Alias Resource Record Set to. | +| [cloudfront\_distribution\_id](#output\_cloudfront\_distribution\_id) | The identifier for the distribution. | +| [cloudfront\_distribution\_in\_progress\_validation\_batches](#output\_cloudfront\_distribution\_in\_progress\_validation\_batches) | The number of invalidation batches currently in progress. | +| [cloudfront\_distribution\_last\_modified\_time](#output\_cloudfront\_distribution\_last\_modified\_time) | The date and time the distribution was last modified. | +| [cloudfront\_distribution\_status](#output\_cloudfront\_distribution\_status) | The current status of the distribution. Deployed if the distribution's information is fully propagated throughout the Amazon CloudFront system. | +| [cloudfront\_distribution\_trusted\_signers](#output\_cloudfront\_distribution\_trusted\_signers) | List of nested attributes for active trusted signers, if the distribution is set up to serve private content with signed URLs | +| [cloudfront\_origin\_access\_identities](#output\_cloudfront\_origin\_access\_identities) | The origin access identities created | +| [cloudfront\_origin\_access\_identity\_iam\_arns](#output\_cloudfront\_origin\_access\_identity\_iam\_arns) | The IAM arns of the origin access identities created | +| [cloudfront\_origin\_access\_identity\_ids](#output\_cloudfront\_origin\_access\_identity\_ids) | The IDS of the origin access identities created | + diff --git a/modules/aws-cloudfront/examples/complete/example-function.js b/modules/aws-cloudfront/examples/complete/example-function.js new file mode 100644 index 0000000..8983e5f --- /dev/null +++ b/modules/aws-cloudfront/examples/complete/example-function.js @@ -0,0 +1,13 @@ +function handler(event) { + // NOTE: This example function is for a viewer request event trigger. + // Choose viewer request for event trigger when you associate this function with a distribution. + var response = { + statusCode: 302, + statusDescription: 'Found', + headers: { + 'cloudfront-functions': { value: 'generated-by-CloudFront-Functions' }, + 'location': { value: 'https://aws.amazon.com/cloudfront/' } + } + }; + return response; +} diff --git a/modules/aws-cloudfront/examples/complete/main.tf b/modules/aws-cloudfront/examples/complete/main.tf new file mode 100644 index 0000000..ddbec93 --- /dev/null +++ b/modules/aws-cloudfront/examples/complete/main.tf @@ -0,0 +1,299 @@ +provider "aws" { + region = "us-east-1" # CloudFront expects ACM resources in us-east-1 region only + + # Make it faster by skipping something + skip_get_ec2_platforms = true + skip_metadata_api_check = true + skip_region_validation = true + skip_credentials_validation = true + + # skip_requesting_account_id should be disabled to generate valid ARN in apigatewayv2_api_execution_arn + skip_requesting_account_id = false +} + +locals { + domain_name = "terraform-aws-modules.modules.tf" # trimsuffix(data.aws_route53_zone.this.name, ".") + subdomain = "cdn" +} + +module "cloudfront" { + source = "../../" + + aliases = ["${local.subdomain}.${local.domain_name}"] + + comment = "My awesome CloudFront" + enabled = true + is_ipv6_enabled = true + price_class = "PriceClass_All" + retain_on_delete = false + wait_for_deployment = false + + # When you enable additional metrics for a distribution, CloudFront sends up to 8 metrics to CloudWatch in the US East (N. Virginia) Region. + # This rate is charged only once per month, per metric (up to 8 metrics per distribution). + create_monitoring_subscription = true + + create_origin_access_identity = true + origin_access_identities = { + s3_bucket_one = "My awesome CloudFront can access" + } + + logging_config = { + bucket = module.log_bucket.s3_bucket_bucket_domain_name + prefix = "cloudfront" + } + + origin = { + appsync = { + domain_name = "appsync.${local.domain_name}" + custom_origin_config = { + http_port = 80 + https_port = 443 + origin_protocol_policy = "match-viewer" + origin_ssl_protocols = ["TLSv1", "TLSv1.1", "TLSv1.2"] + } + + custom_header = [ + { + name = "X-Forwarded-Scheme" + value = "https" + }, + { + name = "X-Frame-Options" + value = "SAMEORIGIN" + } + ] + + origin_shield = { + enabled = true + origin_shield_region = "us-east-1" + } + } + + s3_one = { + domain_name = module.s3_one.s3_bucket_bucket_regional_domain_name + s3_origin_config = { + origin_access_identity = "s3_bucket_one" # key in `origin_access_identities` + # cloudfront_access_identity_path = "origin-access-identity/cloudfront/E5IGQAA1QO48Z" # external OAI resource + } + } + } + + origin_group = { + group_one = { + failover_status_codes = [403, 404, 500, 502] + primary_member_origin_id = "appsync" + secondary_member_origin_id = "s3_one" + } + } + + default_cache_behavior = { + target_origin_id = "appsync" + viewer_protocol_policy = "allow-all" + allowed_methods = ["GET", "HEAD", "OPTIONS"] + cached_methods = ["GET", "HEAD"] + compress = true + query_string = true + + # This is id for SecurityHeadersPolicy copied from https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/using-managed-response-headers-policies.html + response_headers_policy_id = "67f7725c-6f97-4210-82d7-5512b31e9d03" + + lambda_function_association = { + + # Valid keys: viewer-request, origin-request, viewer-response, origin-response + viewer-request = { + lambda_arn = module.lambda_function.lambda_function_qualified_arn + include_body = true + } + + origin-request = { + lambda_arn = module.lambda_function.lambda_function_qualified_arn + } + } + } + + ordered_cache_behavior = [ + { + path_pattern = "/static/*" + target_origin_id = "s3_one" + viewer_protocol_policy = "redirect-to-https" + + allowed_methods = ["GET", "HEAD", "OPTIONS"] + cached_methods = ["GET", "HEAD"] + compress = true + query_string = true + + function_association = { + # Valid keys: viewer-request, viewer-response + viewer-request = { + function_arn = aws_cloudfront_function.example.arn + } + + viewer-response = { + function_arn = aws_cloudfront_function.example.arn + } + } + } + ] + + viewer_certificate = { + acm_certificate_arn = module.acm.acm_certificate_arn + ssl_support_method = "sni-only" + } + + geo_restriction = { + restriction_type = "whitelist" + locations = ["NO", "UA", "US", "GB"] + } + +} + +###### +# ACM +###### + +data "aws_route53_zone" "this" { + name = local.domain_name +} + +module "acm" { + source = "terraform-aws-modules/acm/aws" + version = "~> 4.0" + + domain_name = local.domain_name + zone_id = data.aws_route53_zone.this.id + subject_alternative_names = ["${local.subdomain}.${local.domain_name}"] +} + +############# +# S3 buckets +############# + +data "aws_canonical_user_id" "current" {} + +module "s3_one" { + source = "terraform-aws-modules/s3-bucket/aws" + version = "~> 3.0" + + bucket = "s3-one-${random_pet.this.id}" + force_destroy = true +} + +module "log_bucket" { + source = "terraform-aws-modules/s3-bucket/aws" + version = "~> 3.0" + + bucket = "logs-${random_pet.this.id}" + acl = null + grant = [{ + type = "CanonicalUser" + permission = "FULL_CONTROL" + id = data.aws_canonical_user_id.current.id + }, { + type = "CanonicalUser" + permission = "FULL_CONTROL" + id = "c4c1ede66af53448b93c283ce9448c4ba468c9432aa01d700d3878632f77d2d0" + # Ref. https://github.com/terraform-providers/terraform-provider-aws/issues/12512 + # Ref. https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/AccessLogs.html + }] + force_destroy = true +} + +############################################# +# Using packaged function from Lambda module +############################################# + +locals { + package_url = "https://raw.githubusercontent.com/terraform-aws-modules/terraform-aws-lambda/master/examples/fixtures/python3.8-zip/existing_package.zip" + downloaded = "downloaded_package_${md5(local.package_url)}.zip" +} + +resource "null_resource" "download_package" { + triggers = { + downloaded = local.downloaded + } + + provisioner "local-exec" { + command = "curl -L -o ${local.downloaded} ${local.package_url}" + } +} + +module "lambda_function" { + source = "terraform-aws-modules/lambda/aws" + version = "~> 4.0" + + function_name = "${random_pet.this.id}-lambda" + description = "My awesome lambda function" + handler = "index.lambda_handler" + runtime = "python3.8" + + publish = true + lambda_at_edge = true + + create_package = false + local_existing_package = local.downloaded + + # @todo: Missing CloudFront as allowed_triggers? + + # allowed_triggers = { + # AllowExecutionFromAPIGateway = { + # service = "apigateway" + # arn = module.api_gateway.apigatewayv2_api_execution_arn + # } + # } +} + +########## +# Route53 +########## + +module "records" { + source = "terraform-aws-modules/route53/aws//modules/records" + version = "~> 2.0" + + zone_id = data.aws_route53_zone.this.zone_id + + records = [ + { + name = local.subdomain + type = "A" + alias = { + name = module.cloudfront.cloudfront_distribution_domain_name + zone_id = module.cloudfront.cloudfront_distribution_hosted_zone_id + } + }, + ] +} + +########################### +# Origin Access Identities +########################### +data "aws_iam_policy_document" "s3_policy" { + statement { + actions = ["s3:GetObject"] + resources = ["${module.s3_one.s3_bucket_arn}/static/*"] + + principals { + type = "AWS" + identifiers = module.cloudfront.cloudfront_origin_access_identity_iam_arns + } + } +} + +resource "aws_s3_bucket_policy" "bucket_policy" { + bucket = module.s3_one.s3_bucket_id + policy = data.aws_iam_policy_document.s3_policy.json +} + +######## +# Extra +######## + +resource "random_pet" "this" { + length = 2 +} + +resource "aws_cloudfront_function" "example" { + name = "example-${random_pet.this.id}" + runtime = "cloudfront-js-1.0" + code = file("example-function.js") +} diff --git a/modules/aws-cloudfront/examples/complete/outputs.tf b/modules/aws-cloudfront/examples/complete/outputs.tf new file mode 100644 index 0000000..3b775e2 --- /dev/null +++ b/modules/aws-cloudfront/examples/complete/outputs.tf @@ -0,0 +1,64 @@ +output "cloudfront_distribution_id" { + description = "The identifier for the distribution." + value = module.cloudfront.cloudfront_distribution_id +} + +output "cloudfront_distribution_arn" { + description = "The ARN (Amazon Resource Name) for the distribution." + value = module.cloudfront.cloudfront_distribution_arn +} + +output "cloudfront_distribution_caller_reference" { + description = "Internal value used by CloudFront to allow future updates to the distribution configuration." + value = module.cloudfront.cloudfront_distribution_caller_reference +} + +output "cloudfront_distribution_status" { + description = "The current status of the distribution. Deployed if the distribution's information is fully propagated throughout the Amazon CloudFront system." + value = module.cloudfront.cloudfront_distribution_status +} + +output "cloudfront_distribution_trusted_signers" { + description = "List of nested attributes for active trusted signers, if the distribution is set up to serve private content with signed URLs" + value = module.cloudfront.cloudfront_distribution_trusted_signers +} + +output "cloudfront_distribution_domain_name" { + description = "The domain name corresponding to the distribution." + value = module.cloudfront.cloudfront_distribution_domain_name +} + +output "cloudfront_distribution_last_modified_time" { + description = "The date and time the distribution was last modified." + value = module.cloudfront.cloudfront_distribution_last_modified_time +} + +output "cloudfront_distribution_in_progress_validation_batches" { + description = "The number of invalidation batches currently in progress." + value = module.cloudfront.cloudfront_distribution_in_progress_validation_batches +} + +output "cloudfront_distribution_etag" { + description = "The current version of the distribution's information." + value = module.cloudfront.cloudfront_distribution_etag +} + +output "cloudfront_distribution_hosted_zone_id" { + description = "The CloudFront Route 53 zone ID that can be used to route an Alias Resource Record Set to." + value = module.cloudfront.cloudfront_distribution_hosted_zone_id +} + +output "cloudfront_origin_access_identities" { + description = "The origin access identities created" + value = module.cloudfront.cloudfront_origin_access_identities +} + +output "cloudfront_origin_access_identity_ids" { + description = "The IDS of the origin access identities created" + value = module.cloudfront.cloudfront_origin_access_identity_ids +} + +output "cloudfront_origin_access_identity_iam_arns" { + description = "The IAM arns of the origin access identities created" + value = module.cloudfront.cloudfront_origin_access_identity_iam_arns +} diff --git a/modules/aws-cloudfront/examples/complete/variables.tf b/modules/aws-cloudfront/examples/complete/variables.tf new file mode 100644 index 0000000..e69de29 diff --git a/modules/aws-cloudfront/examples/complete/versions.tf b/modules/aws-cloudfront/examples/complete/versions.tf new file mode 100644 index 0000000..55001ba --- /dev/null +++ b/modules/aws-cloudfront/examples/complete/versions.tf @@ -0,0 +1,26 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.29" + } + random = { + source = "hashicorp/random" + version = ">= 2.0" + } + null = { + source = "hashicorp/null" + version = ">= 2.0" + } + external = { + source = "hashicorp/external" + version = ">= 1.0" + } + local = { + source = "hashicorp/local" + version = ">= 1.0" + } + } +} diff --git a/modules/aws-cloudfront/main.tf b/modules/aws-cloudfront/main.tf new file mode 100644 index 0000000..e5a54c6 --- /dev/null +++ b/modules/aws-cloudfront/main.tf @@ -0,0 +1,461 @@ +locals { + create_origin_access_identity = var.create_origin_access_identity && length(keys(var.origin_access_identities)) > 0 + # create_s3_bucket = var.create_s3_bucket && length(var.s3_bucket_name) > 0 +} + + + +resource "aws_cloudfront_origin_access_identity" "this" { + for_each = local.create_origin_access_identity ? var.origin_access_identities : {} + + comment = each.value + + lifecycle { + create_before_destroy = true + } +} + +data "aws_route53_zone" "selected" { + provider = aws.shared_infra + count = length(var.aliases) > 0 ? 1 : 0 + name = var.zone_name + private_zone = false +} + +data "aws_s3_bucket" "existing_bucket" { + count = var.s3_bucket_name != "" && var.create_s3_bucket == false ? 1 : 0 + bucket = var.s3_bucket_name +} + +resource "aws_route53_record" "this" { + provider = aws.shared_infra + count = length(var.aliases) + zone_id = data.aws_route53_zone.selected[0].id + name = var.aliases[count.index] + type = "A" + alias { + name = aws_cloudfront_distribution.this[0].domain_name + zone_id = aws_cloudfront_distribution.this[0].hosted_zone_id + evaluate_target_health = true + } +} + +resource "aws_s3_bucket" "this" { + count = var.create_origin_access_identity && var.create_s3_bucket ? 1 : 0 + bucket = var.s3_bucket_name + # object_ownership = var.object_ownership +} + +resource "aws_s3_bucket_cors_configuration" "this" { + count = ((length(var.cors_rule) > 0 ? true : false) && var.create_origin_access_identity) ? 1 : 0 + bucket = aws_s3_bucket.this[0].id + #expected_bucket_owner = var.expected_bucket_owner + + dynamic "cors_rule" { + for_each = var.cors_rule + + content { + id = try(cors_rule.value.id, null) + allowed_methods = cors_rule.value.AllowedMethods + allowed_origins = cors_rule.value.AllowedOrigins + allowed_headers = try(cors_rule.value.AllowedHeaders, null) + expose_headers = try(cors_rule.value.ExposeHeaders, null) + max_age_seconds = try(cors_rule.value.MaxAgeSeconds, null) + } + } +} + +resource "aws_s3_bucket_policy" "s3_policy" { + for_each = local.create_origin_access_identity && var.create_s3_bucket ? var.origin_access_identities : {} + bucket = aws_s3_bucket.this[0].id + policy = jsonencode( + { + Version = "2008-10-17", + Id = "PolicyForCloudFrontPrivateContent", + Statement = [ + { + Sid = "1", + Effect = "Allow", + Principal = { + "AWS" : "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity ${aws_cloudfront_origin_access_identity.this[each.key].id}" + }, + Action = "s3:GetObject", + Resource = var.bucket_policy_resources == null ? ["arn:aws:s3:::${aws_s3_bucket.this[0].id}/*"] : var.bucket_policy_resources # split(",",var.bucket_policy_resources) + + }, + ] + } + ) +} + +resource "aws_s3_bucket_ownership_controls" "this" { + count = var.control_object_ownership ? 1 : 0 + bucket = aws_s3_bucket.this[0].id # local.create_origin_access_identity ? aws_s3_bucket_policy.s3_policy[0].id : aws_s3_bucket.this[0].id + + rule { + object_ownership = var.object_ownership + } + + # This `depends_on` is to prevent "A conflicting conditional operation is currently in progress against this resource." + depends_on = [ + aws_s3_bucket_policy.s3_policy, + aws_s3_bucket.this + ] +} + +resource "aws_s3_bucket_website_configuration" "this" { + count = length(keys(var.website)) > 0 ? 1 : 0 + bucket = aws_s3_bucket.this[0].id + + dynamic "index_document" { + for_each = try([var.website["index_document"]], []) + + content { + suffix = index_document.value + } + } + + dynamic "error_document" { + for_each = try([var.website["error_document"]], []) + + content { + key = error_document.value + } + } + + dynamic "redirect_all_requests_to" { + for_each = try([var.website["redirect_all_requests_to"]], []) + + content { + host_name = redirect_all_requests_to.value.host_name + protocol = try(redirect_all_requests_to.value.protocol, null) + } + } + + dynamic "routing_rule" { + for_each = try(flatten([var.website["routing_rules"]]), []) + + content { + dynamic "condition" { + for_each = [try([routing_rule.value.condition], [])] + + content { + http_error_code_returned_equals = try(routing_rule.value.condition["http_error_code_returned_equals"], null) + key_prefix_equals = try(routing_rule.value.condition["key_prefix_equals"], null) + } + } + + redirect { + host_name = try(routing_rule.value.redirect["host_name"], null) + http_redirect_code = try(routing_rule.value.redirect["http_redirect_code"], null) + protocol = try(routing_rule.value.redirect["protocol"], null) + replace_key_prefix_with = try(routing_rule.value.redirect["replace_key_prefix_with"], null) + replace_key_with = try(routing_rule.value.redirect["replace_key_with"], null) + } + } + } +} + + +resource "aws_cloudfront_distribution" "this" { + depends_on = [ + aws_cloudfront_origin_request_policy.this[0] + ] + count = var.create_distribution ? 1 : 0 + + aliases = var.aliases + comment = var.comment + default_root_object = var.default_root_object + enabled = var.enabled + http_version = var.http_version + is_ipv6_enabled = var.is_ipv6_enabled + price_class = var.price_class + retain_on_delete = var.retain_on_delete + wait_for_deployment = var.wait_for_deployment + web_acl_id = var.web_acl_id + tags = var.tags + + dynamic "logging_config" { + for_each = length(keys(var.logging_config)) == 0 ? [] : [var.logging_config] + + content { + bucket = logging_config.value["bucket"] + prefix = lookup(logging_config.value, "prefix", null) + include_cookies = lookup(logging_config.value, "include_cookies", null) + } + } + + dynamic "origin" { + for_each = var.origin + + content { + domain_name = var.cloudfront_elb ? lookup(origin.value, "domain_name", origin.key) : lookup(origin.value, "domain_name", + var.s3_bucket_name != "" && var.create_s3_bucket == false ? data.aws_s3_bucket.existing_bucket[0].bucket_domain_name : aws_s3_bucket.this[0].bucket_domain_name) + origin_id = lookup(origin.value, "origin_id", origin.key) + origin_path = lookup(origin.value, "origin_path", "") + connection_attempts = lookup(origin.value, "connection_attempts", null) + connection_timeout = lookup(origin.value, "connection_timeout", null) + origin_access_control_id = lookup(origin.value, "origin_access_control_id", null) + + dynamic "s3_origin_config" { + for_each = length(keys(lookup(origin.value, "s3_origin_config", {}))) == 0 ? [] : [lookup(origin.value, "s3_origin_config", {})] + + content { + origin_access_identity = lookup(s3_origin_config.value, "cloudfront_access_identity_path", lookup(lookup(aws_cloudfront_origin_access_identity.this, lookup(s3_origin_config.value, "origin_access_identity", ""), {}), "cloudfront_access_identity_path", null)) + } + } + + dynamic "custom_origin_config" { + for_each = length(lookup(origin.value, "custom_origin_config", "")) == 0 ? [] : [lookup(origin.value, "custom_origin_config", "")] + + content { + http_port = custom_origin_config.value.http_port + https_port = custom_origin_config.value.https_port + origin_protocol_policy = custom_origin_config.value.origin_protocol_policy + origin_ssl_protocols = custom_origin_config.value.origin_ssl_protocols + origin_keepalive_timeout = lookup(custom_origin_config.value, "origin_keepalive_timeout", null) + origin_read_timeout = lookup(custom_origin_config.value, "origin_read_timeout", null) + } + } + + dynamic "custom_header" { + for_each = lookup(origin.value, "custom_header", []) + + content { + name = custom_header.value.name + value = custom_header.value.value + } + } + + dynamic "origin_shield" { + for_each = length(keys(lookup(origin.value, "origin_shield", {}))) == 0 ? [] : [lookup(origin.value, "origin_shield", {})] + + content { + enabled = origin_shield.value.enabled + origin_shield_region = origin_shield.value.origin_shield_region + } + } + } + } + + dynamic "origin_group" { + for_each = var.origin_group + + content { + origin_id = lookup(origin_group.value, "origin_id", origin_group.key) + + failover_criteria { + status_codes = origin_group.value["failover_status_codes"] + } + + member { + origin_id = origin_group.value["primary_member_origin_id"] + } + + member { + origin_id = origin_group.value["secondary_member_origin_id"] + } + } + } + + dynamic "default_cache_behavior" { + for_each = [var.default_cache_behavior] + iterator = i + + content { + target_origin_id = var.cloudfront_elb ? lookup(i.value, "domain_name", "") : (var.s3_bucket_name != "" && var.create_s3_bucket == false ? data.aws_s3_bucket.existing_bucket[0].id : aws_s3_bucket.this[0].id) + viewer_protocol_policy = i.value["viewer_protocol_policy"] + + allowed_methods = lookup(i.value, "allowed_methods", ["GET", "HEAD", "OPTIONS"]) + cached_methods = lookup(i.value, "cached_methods", ["GET", "HEAD"]) + compress = lookup(i.value, "compress", null) + field_level_encryption_id = lookup(i.value, "field_level_encryption_id", null) + smooth_streaming = lookup(i.value, "smooth_streaming", null) + trusted_signers = lookup(i.value, "trusted_signers", null) + trusted_key_groups = lookup(i.value, "trusted_key_groups", null) + + cache_policy_id = var.create_and_attach_origin_request_policy || lookup(i.value, "managed_cache_disabled_policy", false) ? data.aws_cloudfront_cache_policy.managed_cache_disabled.id : lookup(i.value, "cache_policy_id", null) + origin_request_policy_id = var.create_and_attach_origin_request_policy ? aws_cloudfront_origin_request_policy.this[0].id : ( + lookup(i.value, "origin_request_policy_id", null) == "managed_origin_request_policy" ? data.aws_cloudfront_origin_request_policy.managed_origin_request_policy.id : lookup(i.value, "origin_request_policy_id", null) + ) + response_headers_policy_id = lookup(i.value, "response_headers_policy_id", null) + realtime_log_config_arn = lookup(i.value, "realtime_log_config_arn", null) + + min_ttl = lookup(i.value, "min_ttl", null) + default_ttl = lookup(i.value, "default_ttl", null) + max_ttl = lookup(i.value, "max_ttl", null) + + dynamic "forwarded_values" { + for_each = lookup(i.value, "use_forwarded_values", true) ? [true] : [] + + content { + query_string = lookup(i.value, "query_string", false) + query_string_cache_keys = lookup(i.value, "query_string_cache_keys", []) + headers = lookup(i.value, "headers", []) + + cookies { + forward = lookup(i.value, "cookies_forward", "none") + whitelisted_names = lookup(i.value, "cookies_whitelisted_names", null) + } + } + } + + dynamic "lambda_function_association" { + for_each = lookup(i.value, "lambda_function_association", []) + iterator = l + + content { + event_type = l.key + lambda_arn = l.value.lambda_arn + include_body = lookup(l.value, "include_body", null) + } + } + + dynamic "function_association" { + for_each = lookup(i.value, "function_association", []) + iterator = f + + content { + event_type = f.key + function_arn = f.value.function_arn + } + } + } + } + + dynamic "ordered_cache_behavior" { + for_each = var.ordered_cache_behavior + iterator = i + + content { + path_pattern = i.value["path_pattern"] + target_origin_id = var.cloudfront_elb ? lookup(i.value, "domain_name", "") : aws_s3_bucket.this[0].id + viewer_protocol_policy = i.value["viewer_protocol_policy"] + + allowed_methods = lookup(i.value, "allowed_methods", ["GET", "HEAD", "OPTIONS"]) + cached_methods = lookup(i.value, "cached_methods", ["GET", "HEAD"]) + compress = lookup(i.value, "compress", null) + field_level_encryption_id = lookup(i.value, "field_level_encryption_id", null) + smooth_streaming = lookup(i.value, "smooth_streaming", null) + trusted_signers = lookup(i.value, "trusted_signers", null) + trusted_key_groups = lookup(i.value, "trusted_key_groups", null) + + cache_policy_id = lookup(i.value, "cache_policy_id", null) + origin_request_policy_id = lookup(i.value, "origin_request_policy_id", null) + response_headers_policy_id = lookup(i.value, "response_headers_policy_id", null) + realtime_log_config_arn = lookup(i.value, "realtime_log_config_arn", null) + + min_ttl = lookup(i.value, "min_ttl", null) + default_ttl = lookup(i.value, "default_ttl", null) + max_ttl = lookup(i.value, "max_ttl", null) + + dynamic "forwarded_values" { + for_each = lookup(i.value, "use_forwarded_values", true) ? [true] : [] + + content { + query_string = lookup(i.value, "query_string", false) + query_string_cache_keys = lookup(i.value, "query_string_cache_keys", []) + headers = lookup(i.value, "headers", []) + + cookies { + forward = lookup(i.value, "cookies_forward", "none") + whitelisted_names = lookup(i.value, "cookies_whitelisted_names", null) + } + } + } + + dynamic "lambda_function_association" { + for_each = lookup(i.value, "lambda_function_association", []) + iterator = l + + content { + event_type = l.key + lambda_arn = l.value.lambda_arn + include_body = lookup(l.value, "include_body", null) + } + } + + dynamic "function_association" { + for_each = lookup(i.value, "function_association", []) + iterator = f + + content { + event_type = f.key + function_arn = f.value.function_arn + } + } + } + } + + viewer_certificate { + acm_certificate_arn = lookup(var.viewer_certificate, "acm_certificate_arn", null) + cloudfront_default_certificate = lookup(var.viewer_certificate, "cloudfront_default_certificate", null) + iam_certificate_id = lookup(var.viewer_certificate, "iam_certificate_id", null) + + minimum_protocol_version = lookup(var.viewer_certificate, "minimum_protocol_version", "TLSv1") + ssl_support_method = lookup(var.viewer_certificate, "ssl_support_method", null) + } + + dynamic "custom_error_response" { + for_each = var.custom_error_response + + content { + error_code = custom_error_response.value["error_code"] + + response_code = lookup(custom_error_response.value, "response_code", null) + response_page_path = lookup(custom_error_response.value, "response_page_path", null) + error_caching_min_ttl = lookup(custom_error_response.value, "error_caching_min_ttl", null) + } + } + + restrictions { + dynamic "geo_restriction" { + for_each = [var.geo_restriction] + + content { + restriction_type = lookup(geo_restriction.value, "restriction_type", "none") + locations = lookup(geo_restriction.value, "locations", []) + } + } + } +} + +resource "aws_cloudfront_monitoring_subscription" "this" { + count = var.create_distribution && var.create_monitoring_subscription ? 1 : 0 + + distribution_id = aws_cloudfront_distribution.this[0].id + + monitoring_subscription { + realtime_metrics_subscription_config { + realtime_metrics_subscription_status = var.realtime_metrics_subscription_status + } + } +} + +resource "aws_cloudfront_origin_request_policy" "this" { + count = var.create_distribution && var.create_and_attach_origin_request_policy ? 1 : 0 + name = var.origin_request_policy_name + comment = "origin request policy includes the following headers" + cookies_config { + cookie_behavior = "all" + } + headers_config { + header_behavior = "whitelist" + headers { + items = var.origin_request_policy_headers + } + } + query_strings_config { + query_string_behavior = "all" + } + +} + + +data "aws_cloudfront_cache_policy" "managed_cache_disabled" { + name = "Managed-CachingDisabled" +} + +data "aws_cloudfront_origin_request_policy" "managed_origin_request_policy" { + name = "Managed-AllViewerAndCloudFrontHeaders-2022-06" +} diff --git a/modules/aws-cloudfront/outputs.tf b/modules/aws-cloudfront/outputs.tf new file mode 100644 index 0000000..e1fac95 --- /dev/null +++ b/modules/aws-cloudfront/outputs.tf @@ -0,0 +1,88 @@ +output "cloudfront_distribution_id" { + description = "The identifier for the distribution." + value = element(concat(aws_cloudfront_distribution.this.*.id, [""]), 0) +} + +output "cloudfront_distribution_arn" { + description = "The ARN (Amazon Resource Name) for the distribution." + value = element(concat(aws_cloudfront_distribution.this.*.arn, [""]), 0) +} + +output "cloudfront_distribution_caller_reference" { + description = "Internal value used by CloudFront to allow future updates to the distribution configuration." + value = element(concat(aws_cloudfront_distribution.this.*.caller_reference, [""]), 0) +} + +output "cloudfront_distribution_status" { + description = "The current status of the distribution. Deployed if the distribution's information is fully propagated throughout the Amazon CloudFront system." + value = element(concat(aws_cloudfront_distribution.this.*.status, [""]), 0) +} + +output "cloudfront_distribution_trusted_signers" { + description = "List of nested attributes for active trusted signers, if the distribution is set up to serve private content with signed URLs" + value = element(concat(aws_cloudfront_distribution.this.*.trusted_signers, [""]), 0) +} + +output "cloudfront_distribution_domain_name" { + description = "The domain name corresponding to the distribution." + value = element(concat(aws_cloudfront_distribution.this.*.domain_name, [""]), 0) +} + +output "cloudfront_distribution_last_modified_time" { + description = "The date and time the distribution was last modified." + value = element(concat(aws_cloudfront_distribution.this.*.last_modified_time, [""]), 0) +} + +output "cloudfront_distribution_in_progress_validation_batches" { + description = "The number of invalidation batches currently in progress." + value = element(concat(aws_cloudfront_distribution.this.*.in_progress_validation_batches, [""]), 0) +} + +output "cloudfront_distribution_etag" { + description = "The current version of the distribution's information." + value = element(concat(aws_cloudfront_distribution.this.*.etag, [""]), 0) +} + +output "cloudfront_distribution_hosted_zone_id" { + description = "The CloudFront Route 53 zone ID that can be used to route an Alias Resource Record Set to." + value = element(concat(aws_cloudfront_distribution.this.*.hosted_zone_id, [""]), 0) +} + +output "cloudfront_origin_access_identities" { + description = "The origin access identities created" + value = local.create_origin_access_identity ? { for k, v in aws_cloudfront_origin_access_identity.this : k => v } : {} +} + +output "cloudfront_origin_access_identity_ids" { + description = "The IDS of the origin access identities created" + value = local.create_origin_access_identity ? [for v in aws_cloudfront_origin_access_identity.this : v.id] : [] +} + +output "cloudfront_origin_access_identity_iam_arns" { + description = "The IAM arns of the origin access identities created" + value = local.create_origin_access_identity ? [for v in aws_cloudfront_origin_access_identity.this : v.iam_arn] : [] +} + +output "cloudfront_monitoring_subscription_id" { + description = " The ID of the CloudFront monitoring subscription, which corresponds to the `distribution_id`." + value = element(concat(aws_cloudfront_monitoring_subscription.this.*.id, [""]), 0) +} + +output "cloudfront_distribution_tags" { + description = "Tags of the distribution's" + value = element(concat(aws_cloudfront_distribution.this.*.tags_all, [""]), 0) +} + +output "s3_bucket_website_endpoint" { + description = "The website endpoint, if the bucket is configured with a website. If not, this will be an empty string." + value = try(aws_s3_bucket_website_configuration.this[0].website_endpoint, "") +} + +output "s3_bucket_website_domain" { + description = "The domain of the website endpoint, if the bucket is configured with a website. If not, this will be an empty string. This is used to create Route 53 alias records." + value = try(aws_s3_bucket_website_configuration.this[0].website_domain, "") +} + +output "bucket_name" { + value = var.s3_bucket_name +} \ No newline at end of file diff --git a/modules/aws-cloudfront/variables.tf b/modules/aws-cloudfront/variables.tf new file mode 100644 index 0000000..5817168 --- /dev/null +++ b/modules/aws-cloudfront/variables.tf @@ -0,0 +1,250 @@ +variable "create_distribution" { + description = "Controls if CloudFront distribution should be created" + type = bool + default = true +} + +variable "create_origin_access_identity" { + description = "Controls if CloudFront origin access identity should be created" + type = bool + default = false +} + +variable "origin_access_identities" { + description = "Map of CloudFront origin access identities (value as a comment)" + type = map(string) + default = {} +} + +variable "aliases" { + description = "Extra CNAMEs (alternate domain names), if any, for this distribution." + type = list(string) + default = null +} + +variable "comment" { + description = "Any comments you want to include about the distribution." + type = string + default = null +} + +variable "default_root_object" { + description = "The object that you want CloudFront to return (for example, index.html) when an end user requests the root URL." + type = string + default = null +} + +variable "enabled" { + description = "Whether the distribution is enabled to accept end user requests for content." + type = bool + default = true +} + +variable "http_version" { + description = "The maximum HTTP version to support on the distribution. Allowed values are http1.1 and http2. The default is http2." + type = string + default = "http2" +} + +variable "is_ipv6_enabled" { + description = "Whether the IPv6 is enabled for the distribution." + type = bool + default = null +} + +variable "price_class" { + description = "The price class for this distribution. One of PriceClass_All, PriceClass_200, PriceClass_100" + type = string + default = null +} + +variable "retain_on_delete" { + description = "Disables the distribution instead of deleting it when destroying the resource through Terraform. If this is set, the distribution needs to be deleted manually afterwards." + type = bool + default = false +} + +variable "wait_for_deployment" { + description = "If enabled, the resource will wait for the distribution status to change from InProgress to Deployed. Setting this tofalse will skip the process." + type = bool + default = true +} + +variable "web_acl_id" { + description = "If you're using AWS WAF to filter CloudFront requests, the Id of the AWS WAF web ACL that is associated with the distribution. The WAF Web ACL must exist in the WAF Global (CloudFront) region and the credentials configuring this argument must have waf:GetWebACL permissions assigned. If using WAFv2, provide the ARN of the web ACL." + type = string + default = null +} + +variable "tags" { + description = "A map of tags to assign to the resource." + type = map(string) + default = null +} + +variable "origin" { + description = "One or more origins for this distribution (multiples allowed)." + type = any + default = null +} + +variable "origin_group" { + description = "One or more origin_group for this distribution (multiples allowed)." + type = any + default = {} +} + +variable "viewer_certificate" { + description = "The SSL configuration for this distribution" + type = any + default = { + cloudfront_default_certificate = true + minimum_protocol_version = "TLSv1" + } +} + +variable "geo_restriction" { + description = "The restriction configuration for this distribution (geo_restrictions)" + type = any + default = {} +} + +variable "logging_config" { + description = "The logging configuration that controls how logs are written to your distribution (maximum one)." + type = any + default = {} +} + +variable "custom_error_response" { + description = "One or more custom error response elements" + type = any + default = {} +} + +variable "default_cache_behavior" { + description = "The default cache behavior for this distribution" + type = any + default = null +} + +variable "ordered_cache_behavior" { + description = "An ordered list of cache behaviors resource for this distribution. List from top to bottom in order of precedence. The topmost cache behavior will have precedence 0." + type = any + default = [] +} + +variable "create_monitoring_subscription" { + description = "If enabled, the resource for monitoring subscription will created." + type = bool + default = false +} + +variable "realtime_metrics_subscription_status" { + description = "A flag that indicates whether additional CloudWatch metrics are enabled for a given CloudFront distribution. Valid values are `Enabled` and `Disabled`." + type = string + default = "Enabled" +} + +variable "s3_bucket_name" { + description = "Name of the bucket" + default = "" +} + +variable "zone_name" { + description = "Zone Name of the record that will be created for alias" + default = "" +} + +variable "create_and_attach_origin_request_policy" { + description = "Controls if CloudFront cache policy should be created" + type = bool + default = true +} + +variable "cloudfront_elb" { + description = "Controls if CloudFront origin will be a Load Balancer" + type = bool + default = false +} + +variable "origin_request_policy_name" { + description = "Policy name of the origin request to make it regional" + type = string + default = "" +} + +variable "cache_policy_name" { + description = "Policy name of the origin request to make it regional" + type = string + default = "" +} + +variable "origin_request_policy_headers" { + description = "List of headers" + type = list(string) + default = [] +} + + +variable "cache_default_ttl" { + description = "Default TTL seconds" + type = number + default = 50 +} +variable "cache_max_ttl" { + description = "Max TTL seconds" + type = number + default = 100 +} +variable "cache_min_ttl" { + description = "Min TTL seconds" + type = number + default = 1 +} + +variable "accept_encoding_brotli" { + description = "Accept encoding Brotli" + type = bool + default = false +} + +variable "accept_encoding_gzip" { + description = "Accept encoding gzip" + type = bool + default = false +} + +variable "bucket_policy_resources" { + description = "This is optional. List of arns. Default is 'all items in bucket'. Usage ex: ['arn:aws:s3:::
"cloudfront_default_certificate": true,
"minimum_protocol_version": "TLSv1"
}
{| no | +| [create\_access\_log\_bucket](#input\_create\_access\_log\_bucket) | A flag to indicate if a bucket for s3 access logs should be created | `bool` | `false` | no | +| [delimiter](#input\_delimiter) | Delimiter to be used between ID elements.
"additional_tag_map": {},
"attributes": [],
"delimiter": null,
"descriptor_formats": {},
"enabled": true,
"environment": null,
"id_length_limit": null,
"label_key_case": null,
"label_order": [],
"label_value_case": null,
"labels_as_tags": [
"unset"
],
"name": null,
"namespace": null,
"regex_replace_chars": null,
"stage": null,
"tags": {},
"tenant": null
}
[| no | +| [lifecycle\_prefix](#input\_lifecycle\_prefix) | Prefix filter. Used to manage object lifecycle events | `string` | `""` | no | +| [lifecycle\_rule\_enabled](#input\_lifecycle\_rule\_enabled) | Enable lifecycle events on this bucket | `bool` | `true` | no | +| [lifecycle\_tags](#input\_lifecycle\_tags) | Tags filter. Used to manage object lifecycle events | `map(string)` | `{}` | no | +| [name](#input\_name) | ID element. Usually the component or solution name, e.g. 'app' or 'jenkins'.
"default"
]
{| no | +| [create\_access\_log\_bucket](#input\_create\_access\_log\_bucket) | A flag to indicate if a bucket for s3 access logs should be created | `bool` | `false` | no | +| [delimiter](#input\_delimiter) | Delimiter to be used between ID elements.
"additional_tag_map": {},
"attributes": [],
"delimiter": null,
"descriptor_formats": {},
"enabled": true,
"environment": null,
"id_length_limit": null,
"label_key_case": null,
"label_order": [],
"label_value_case": null,
"labels_as_tags": [
"unset"
],
"name": null,
"namespace": null,
"regex_replace_chars": null,
"stage": null,
"tags": {},
"tenant": null
}
[| no | +| [lifecycle\_prefix](#input\_lifecycle\_prefix) | Prefix filter. Used to manage object lifecycle events | `string` | `""` | no | +| [lifecycle\_rule\_enabled](#input\_lifecycle\_rule\_enabled) | Enable lifecycle events on this bucket | `bool` | `true` | no | +| [lifecycle\_tags](#input\_lifecycle\_tags) | Tags filter. Used to manage object lifecycle events | `map(string)` | `{}` | no | +| [name](#input\_name) | ID element. Usually the component or solution name, e.g. 'app' or 'jenkins'.
"default"
]
{| no | +| [delimiter](#input\_delimiter) | Delimiter to be used between ID elements.
"additional_tag_map": {},
"attributes": [],
"delimiter": null,
"descriptor_formats": {},
"enabled": true,
"environment": null,
"id_length_limit": null,
"label_key_case": null,
"label_order": [],
"label_value_case": null,
"labels_as_tags": [
"unset"
],
"name": null,
"namespace": null,
"regex_replace_chars": null,
"stage": null,
"tags": {},
"tenant": null
}
list(object({| `[]` | no | +| [id\_length\_limit](#input\_id\_length\_limit) | Limit `id` to this many characters (minimum 6).
include_management_events = bool
read_write_type = string
data_resource = list(object({
type = string
values = list(string)
}))
}))
list(object({| `[]` | no | +| [is\_multi\_region\_trail](#input\_is\_multi\_region\_trail) | Specifies whether the trail is created in the current region or in all regions | `bool` | `true` | no | +| [is\_organization\_trail](#input\_is\_organization\_trail) | The trail is an AWS Organizations trail | `bool` | `false` | no | +| [kms\_key\_arn](#input\_kms\_key\_arn) | Specifies the KMS key ARN to use to encrypt the logs delivered by CloudTrail | `string` | `""` | no | +| [label\_key\_case](#input\_label\_key\_case) | Controls the letter case of the `tags` keys (label names) for tags generated by this module.
insight_type = string
}))
[| no | +| [name](#input\_name) | ID element. Usually the component or solution name, e.g. 'app' or 'jenkins'.
"default"
]
{| no | +| [delimiter](#input\_delimiter) | Delimiter to be used between ID elements.
"additional_tag_map": {},
"attributes": [],
"delimiter": null,
"descriptor_formats": {},
"enabled": true,
"environment": null,
"id_length_limit": null,
"label_key_case": null,
"label_order": [],
"label_value_case": null,
"labels_as_tags": [
"unset"
],
"name": null,
"namespace": null,
"regex_replace_chars": null,
"stage": null,
"tags": {},
"tenant": null
}
list(object({| `[]` | no | +| [id\_length\_limit](#input\_id\_length\_limit) | Limit `id` to this many characters (minimum 6).
include_management_events = bool
read_write_type = string
data_resource = list(object({
type = string
values = list(string)
}))
}))
list(object({| `[]` | no | +| [is\_multi\_region\_trail](#input\_is\_multi\_region\_trail) | Specifies whether the trail is created in the current region or in all regions | `bool` | `true` | no | +| [is\_organization\_trail](#input\_is\_organization\_trail) | The trail is an AWS Organizations trail | `bool` | `false` | no | +| [kms\_key\_arn](#input\_kms\_key\_arn) | Specifies the KMS key ARN to use to encrypt the logs delivered by CloudTrail | `string` | `""` | no | +| [label\_key\_case](#input\_label\_key\_case) | Controls the letter case of the `tags` keys (label names) for tags generated by this module.
insight_type = string
}))
[| no | +| [name](#input\_name) | ID element. Usually the component or solution name, e.g. 'app' or 'jenkins'.
"default"
]
+ + +
+ Terraform module to create cloudwatch event rule on AWS. +
+ ++ + + + + + + + + + + + + + + +
+ +We are The Cloud Experts!
+We ❤️ Open Source and you can check out our other modules to get help with your new Cloud ideas.
+ + [website]: https://clouddrove.com + [github]: https://github.com/clouddrove + [linkedin]: https://cpco.io/linkedin + [twitter]: https://twitter.com/clouddrove/ + [email]: https://clouddrove.com/contact-us.html + [terraform_modules]: https://github.com/clouddrove?utf8=%E2%9C%93&q=terraform-&type=&language= diff --git a/modules/aws-cloudwatch-event-rule-master/_example/example.tf b/modules/aws-cloudwatch-event-rule-master/_example/example.tf new file mode 100644 index 0000000..33e5fe7 --- /dev/null +++ b/modules/aws-cloudwatch-event-rule-master/_example/example.tf @@ -0,0 +1,25 @@ +provider "aws" { + region = "eu-west-1" +} + +data "aws_caller_identity" "current" {} + +module "event-rule" { + source = "./../" + + name = "event-rule" + environment = "test" + label_order = ["environment", "name"] + + description = "Event Rule." + schedule_expression = "cron(0/5 * * * ? *)" + + target_id = "test" + arn = "arn:aws:lambda:eu-west-1:${data.aws_caller_identity.current.account_id}:function:hello_world_lambda" + input_template = "\"{| no | +| [client\_write\_attributes](#input\_client\_write\_attributes) | List of user pool attributes the application client can write to | `list(string)` | `[]` | no | +| [clients](#input\_clients) | A container with the clients definitions | `any` | `[]` | no | +| [deletion\_protection](#input\_deletion\_protection) | When active, DeletionProtection prevents accidental deletion of your user pool. Before you can delete a user pool that you have protected against deletion, you must deactivate this feature. Valid values are `ACTIVE` and `INACTIVE`. | `string` | `"INACTIVE"` | no | +| [device\_configuration](#input\_device\_configuration) | The configuration for the user pool's device tracking | `map(any)` | `{}` | no | +| [device\_configuration\_challenge\_required\_on\_new\_device](#input\_device\_configuration\_challenge\_required\_on\_new\_device) | Indicates whether a challenge is required on a new device. Only applicable to a new device | `bool` | `false` | no | +| [device\_configuration\_device\_only\_remembered\_on\_user\_prompt](#input\_device\_configuration\_device\_only\_remembered\_on\_user\_prompt) | If true, a device is only remembered on user prompt | `bool` | `false` | no | +| [domain](#input\_domain) | Cognito User Pool domain | `string` | `null` | no | +| [domain\_certificate\_arn](#input\_domain\_certificate\_arn) | The ARN of an ISSUED ACM certificate in us-east-1 for a custom domain | `string` | `null` | no | +| [email\_configuration](#input\_email\_configuration) | The Email Configuration | `map(any)` | `{}` | no | +| [email\_configuration\_configuration\_set](#input\_email\_configuration\_configuration\_set) | The name of the configuration set | `string` | `null` | no | +| [email\_configuration\_email\_sending\_account](#input\_email\_configuration\_email\_sending\_account) | Instruct Cognito to either use its built-in functional or Amazon SES to send out emails. Allowed values: `COGNITO_DEFAULT` or `DEVELOPER` | `string` | `"COGNITO_DEFAULT"` | no | +| [email\_configuration\_from\_email\_address](#input\_email\_configuration\_from\_email\_address) | Sender’s email address or sender’s display name with their email address (e.g. `john@example.com`, `John Smith
"access_token": "minutes",
"id_token": "minutes",
"refresh_token": "days"
}
object({| `null` | no | +| [password\_policy\_minimum\_length](#input\_password\_policy\_minimum\_length) | The minimum length of the password policy that you have set | `number` | `8` | no | +| [password\_policy\_require\_lowercase](#input\_password\_policy\_require\_lowercase) | Whether you have required users to use at least one lowercase letter in their password | `bool` | `true` | no | +| [password\_policy\_require\_numbers](#input\_password\_policy\_require\_numbers) | Whether you have required users to use at least one number in their password | `bool` | `true` | no | +| [password\_policy\_require\_symbols](#input\_password\_policy\_require\_symbols) | Whether you have required users to use at least one symbol in their password | `bool` | `true` | no | +| [password\_policy\_require\_uppercase](#input\_password\_policy\_require\_uppercase) | Whether you have required users to use at least one uppercase letter in their password | `bool` | `true` | no | +| [password\_policy\_temporary\_password\_validity\_days](#input\_password\_policy\_temporary\_password\_validity\_days) | The minimum length of the password policy that you have set | `number` | `7` | no | +| [recovery\_mechanisms](#input\_recovery\_mechanisms) | The list of Account Recovery Options | `list(any)` | `[]` | no | +| [resource\_server\_identifier](#input\_resource\_server\_identifier) | An identifier for the resource server | `string` | `null` | no | +| [resource\_server\_name](#input\_resource\_server\_name) | A name for the resource server | `string` | `null` | no | +| [resource\_server\_scope\_description](#input\_resource\_server\_scope\_description) | The scope description | `string` | `null` | no | +| [resource\_server\_scope\_name](#input\_resource\_server\_scope\_name) | The scope name | `string` | `null` | no | +| [resource\_servers](#input\_resource\_servers) | A container with the user\_groups definitions | `list(any)` | `[]` | no | +| [schemas](#input\_schemas) | A container with the schema attributes of a user pool. Maximum of 50 attributes | `list(any)` | `[]` | no | +| [sms\_authentication\_message](#input\_sms\_authentication\_message) | A string representing the SMS authentication message | `string` | `null` | no | +| [sms\_configuration](#input\_sms\_configuration) | The SMS Configuration | `map(any)` | `{}` | no | +| [sms\_configuration\_external\_id](#input\_sms\_configuration\_external\_id) | The external ID used in IAM role trust relationships | `string` | `""` | no | +| [sms\_configuration\_sns\_caller\_arn](#input\_sms\_configuration\_sns\_caller\_arn) | The ARN of the Amazon SNS caller. This is usually the IAM role that you've given Cognito permission to assume | `string` | `""` | no | +| [sms\_verification\_message](#input\_sms\_verification\_message) | A string representing the SMS verification message | `string` | `null` | no | +| [software\_token\_mfa\_configuration](#input\_software\_token\_mfa\_configuration) | Configuration block for software token MFA (multifactor-auth). mfa\_configuration must also be enabled for this to work | `map(any)` | `{}` | no | +| [software\_token\_mfa\_configuration\_enabled](#input\_software\_token\_mfa\_configuration\_enabled) | If true, and if mfa\_configuration is also enabled, multi-factor authentication by software TOTP generator will be enabled | `bool` | `false` | no | +| [string\_schemas](#input\_string\_schemas) | A container with the string schema attributes of a user pool. Maximum of 50 attributes | `list(any)` | `[]` | no | +| [tags](#input\_tags) | A mapping of tags to assign to the User Pool | `map(string)` | `{}` | no | +| [temporary\_password\_validity\_days](#input\_temporary\_password\_validity\_days) | The user account expiration limit, in days, after which the account is no longer usable | `number` | `7` | no | +| [user\_attribute\_update\_settings](#input\_user\_attribute\_update\_settings) | Configuration block for user attribute update settings. Must contain key `attributes_require_verification_before_update` with list with only valid values of `email` and `phone_number` | `map(list(string))` | `null` | no | +| [user\_group\_description](#input\_user\_group\_description) | The description of the user group | `string` | `null` | no | +| [user\_group\_name](#input\_user\_group\_name) | The name of the user group | `string` | `null` | no | +| [user\_group\_precedence](#input\_user\_group\_precedence) | The precedence of the user group | `number` | `null` | no | +| [user\_group\_role\_arn](#input\_user\_group\_role\_arn) | The ARN of the IAM role to be associated with the user group | `string` | `null` | no | +| [user\_groups](#input\_user\_groups) | A container with the user\_groups definitions | `list(any)` | `[]` | no | +| [user\_pool\_add\_ons](#input\_user\_pool\_add\_ons) | Configuration block for user pool add-ons to enable user pool advanced security mode features | `map(any)` | `{}` | no | +| [user\_pool\_add\_ons\_advanced\_security\_mode](#input\_user\_pool\_add\_ons\_advanced\_security\_mode) | The mode for advanced security, must be one of `OFF`, `AUDIT` or `ENFORCED` | `string` | `null` | no | +| [user\_pool\_name](#input\_user\_pool\_name) | The name of the user pool | `string` | n/a | yes | +| [username\_attributes](#input\_username\_attributes) | Specifies whether email addresses or phone numbers can be specified as usernames when a user signs up. Conflicts with `alias_attributes` | `list(string)` | `null` | no | +| [username\_configuration](#input\_username\_configuration) | The Username Configuration. Setting `case_sensitive` specifies whether username case sensitivity will be applied for all users in the user pool through Cognito APIs | `map(any)` | `{}` | no | +| [verification\_message\_template](#input\_verification\_message\_template) | The verification message templates configuration | `map(any)` | `{}` | no | +| [verification\_message\_template\_default\_email\_option](#input\_verification\_message\_template\_default\_email\_option) | The default email option. Must be either `CONFIRM_WITH_CODE` or `CONFIRM_WITH_LINK`. Defaults to `CONFIRM_WITH_CODE` | `string` | `null` | no | +| [verification\_message\_template\_email\_message\_by\_link](#input\_verification\_message\_template\_email\_message\_by\_link) | The email message template for sending a confirmation link to the user, it must contain the `{##Click Here##}` placeholder | `string` | `null` | no | +| [verification\_message\_template\_email\_subject\_by\_link](#input\_verification\_message\_template\_email\_subject\_by\_link) | The subject line for the email message template for sending a confirmation link to the user | `string` | `null` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [arn](#output\_arn) | The ARN of the user pool | +| [client\_ids](#output\_client\_ids) | The ids of the user pool clients | +| [client\_ids\_map](#output\_client\_ids\_map) | The ids map of the user pool clients | +| [client\_secrets](#output\_client\_secrets) | The client secrets of the user pool clients | +| [client\_secrets\_map](#output\_client\_secrets\_map) | The client secrets map of the user pool clients | +| [creation\_date](#output\_creation\_date) | The date the user pool was created | +| [domain\_app\_version](#output\_domain\_app\_version) | The app version | +| [domain\_aws\_account\_id](#output\_domain\_aws\_account\_id) | The AWS account ID for the user pool owner | +| [domain\_cloudfront\_distribution\_arn](#output\_domain\_cloudfront\_distribution\_arn) | The ARN of the CloudFront distribution | +| [domain\_s3\_bucket](#output\_domain\_s3\_bucket) | The S3 bucket where the static files for this domain are stored | +| [endpoint](#output\_endpoint) | The endpoint name of the user pool. Example format: cognito-idp.REGION.amazonaws.com/xxxx\_yyyyy | +| [id](#output\_id) | The id of the user pool | +| [last\_modified\_date](#output\_last\_modified\_date) | The date the user pool was last modified | +| [name](#output\_name) | The name of the user pool | +| [resource\_servers\_scope\_identifiers](#output\_resource\_servers\_scope\_identifiers) | A list of all scopes configured in the format identifier/scope\_name | + + +## Know issues +### Removing all lambda triggers +If you define lambda triggers using the `lambda_config` block or any `lambda_config_*` variable and you want to remove all triggers, define the lambda_config block with an empty map `{}` and apply the plan. Then comment the `lambda_config` block or define it as `null` and apply the plan again. + +This is needed because all parameters for the `lambda_config` block are optional and keeping all block attributes empty or null forces to create a `lambda_config {}` block very time a plan/apply is run. diff --git a/modules/aws-cognito-user-pool/client.tf b/modules/aws-cognito-user-pool/client.tf new file mode 100644 index 0000000..303867c --- /dev/null +++ b/modules/aws-cognito-user-pool/client.tf @@ -0,0 +1,90 @@ +resource "aws_cognito_user_pool_client" "client" { + count = var.enabled ? length(local.clients) : 0 + allowed_oauth_flows = lookup(element(local.clients, count.index), "allowed_oauth_flows", null) + allowed_oauth_flows_user_pool_client = lookup(element(local.clients, count.index), "allowed_oauth_flows_user_pool_client", null) + allowed_oauth_scopes = lookup(element(local.clients, count.index), "allowed_oauth_scopes", null) + auth_session_validity = lookup(element(local.clients, count.index), "auth_session_validity", null) + callback_urls = lookup(element(local.clients, count.index), "callback_urls", null) + default_redirect_uri = lookup(element(local.clients, count.index), "default_redirect_uri", null) + explicit_auth_flows = lookup(element(local.clients, count.index), "explicit_auth_flows", null) + generate_secret = lookup(element(local.clients, count.index), "generate_secret", null) + logout_urls = lookup(element(local.clients, count.index), "logout_urls", null) + name = lookup(element(local.clients, count.index), "name", null) + read_attributes = lookup(element(local.clients, count.index), "read_attributes", null) + access_token_validity = lookup(element(local.clients, count.index), "access_token_validity", null) + id_token_validity = lookup(element(local.clients, count.index), "id_token_validity", null) + refresh_token_validity = lookup(element(local.clients, count.index), "refresh_token_validity", null) + supported_identity_providers = lookup(element(local.clients, count.index), "supported_identity_providers", null) + prevent_user_existence_errors = lookup(element(local.clients, count.index), "prevent_user_existence_errors", null) + write_attributes = lookup(element(local.clients, count.index), "write_attributes", null) + enable_token_revocation = lookup(element(local.clients, count.index), "enable_token_revocation", null) + user_pool_id = aws_cognito_user_pool.pool[0].id + + # token_validity_units + dynamic "token_validity_units" { + for_each = length(lookup(element(local.clients, count.index), "token_validity_units", {})) == 0 ? [] : [lookup(element(local.clients, count.index), "token_validity_units")] + content { + access_token = lookup(token_validity_units.value, "access_token", null) + id_token = lookup(token_validity_units.value, "id_token", null) + refresh_token = lookup(token_validity_units.value, "refresh_token", null) + } + } + + depends_on = [ + aws_cognito_resource_server.resource, + aws_cognito_identity_provider.identity_provider + ] +} + +locals { + clients_default = [ + { + allowed_oauth_flows = var.client_allowed_oauth_flows + allowed_oauth_flows_user_pool_client = var.client_allowed_oauth_flows_user_pool_client + allowed_oauth_scopes = var.client_allowed_oauth_scopes + auth_session_validity = var.client_auth_session_validity + callback_urls = var.client_callback_urls + default_redirect_uri = var.client_default_redirect_uri + explicit_auth_flows = var.client_explicit_auth_flows + generate_secret = var.client_generate_secret + logout_urls = var.client_logout_urls + name = var.client_name + read_attributes = var.client_read_attributes + access_token_validity = var.client_access_token_validity + id_token_validity = var.client_id_token_validity + token_validity_units = var.client_token_validity_units + refresh_token_validity = var.client_refresh_token_validity + supported_identity_providers = var.client_supported_identity_providers + prevent_user_existence_errors = var.client_prevent_user_existence_errors + write_attributes = var.client_write_attributes + enable_token_revocation = var.client_enable_token_revocation + } + ] + + # This parses vars.clients which is a list of objects (map), and transforms it to a tuple of elements to avoid conflict with the ternary and local.clients_default + clients_parsed = [for e in var.clients : { + allowed_oauth_flows = lookup(e, "allowed_oauth_flows", null) + allowed_oauth_flows_user_pool_client = lookup(e, "allowed_oauth_flows_user_pool_client", null) + allowed_oauth_scopes = lookup(e, "allowed_oauth_scopes", null) + auth_session_validity = lookup(e, "auth_session_validity", null) + callback_urls = lookup(e, "callback_urls", null) + default_redirect_uri = lookup(e, "default_redirect_uri", null) + explicit_auth_flows = lookup(e, "explicit_auth_flows", null) + generate_secret = lookup(e, "generate_secret", null) + logout_urls = lookup(e, "logout_urls", null) + name = lookup(e, "name", null) + read_attributes = lookup(e, "read_attributes", null) + access_token_validity = lookup(e, "access_token_validity", null) + id_token_validity = lookup(e, "id_token_validity", null) + refresh_token_validity = lookup(e, "refresh_token_validity", null) + token_validity_units = lookup(e, "token_validity_units", {}) + supported_identity_providers = lookup(e, "supported_identity_providers", null) + prevent_user_existence_errors = lookup(e, "prevent_user_existence_errors", null) + write_attributes = lookup(e, "write_attributes", null) + enable_token_revocation = lookup(e, "enable_token_revocation", null) + } + ] + + clients = length(var.clients) == 0 && (var.client_name == null || var.client_name == "") ? [] : (length(var.clients) > 0 ? local.clients_parsed : local.clients_default) + +} diff --git a/modules/aws-cognito-user-pool/domain.tf b/modules/aws-cognito-user-pool/domain.tf new file mode 100644 index 0000000..7872cf5 --- /dev/null +++ b/modules/aws-cognito-user-pool/domain.tf @@ -0,0 +1,6 @@ +resource "aws_cognito_user_pool_domain" "domain" { + count = !var.enabled || var.domain == null || var.domain == "" ? 0 : 1 + domain = var.domain + certificate_arn = var.domain_certificate_arn + user_pool_id = aws_cognito_user_pool.pool[0].id +} diff --git a/modules/aws-cognito-user-pool/examples/complete/README.md b/modules/aws-cognito-user-pool/examples/complete/README.md new file mode 100644 index 0000000..c025085 --- /dev/null +++ b/modules/aws-cognito-user-pool/examples/complete/README.md @@ -0,0 +1,264 @@ +# This is a complete example + +``` +module "aws_cognito_user_pool_complete_example" { + + source = "lgallard/cognito-user-pool/aws" + + user_pool_name = "mypool_complete" + alias_attributes = ["email", "phone_number"] + auto_verified_attributes = ["email"] + sms_authentication_message = "Your username is {username} and temporary password is {####}." + sms_verification_message = "This is the verification message {####}." + + deletion_protection = "ACTIVE" + + mfa_configuration = "OPTIONAL" + software_token_mfa_configuration = { + enabled = true + } + + admin_create_user_config = { + email_message = "Dear {username}, your verification code is {####}." + email_subject = "Here, your verification code baby" + sms_message = "Your username is {username} and temporary password is {####}." + } + + device_configuration = { + challenge_required_on_new_device = true + device_only_remembered_on_user_prompt = true + } + + email_configuration = { + email_sending_account = "DEVELOPER" + reply_to_email_address = "email@mydomain.com" + source_arn = "arn:aws:ses:us-east-1:123456789012:identity/myemail@mydomain.com" + } + + lambda_config = { + create_auth_challenge = "arn:aws:lambda:us-east-1:123456789012:function:create_auth_challenge" + custom_message = "arn:aws:lambda:us-east-1:123456789012:function:custom_message" + define_auth_challenge = "arn:aws:lambda:us-east-1:123456789012:function:define_auth_challenge" + post_authentication = "arn:aws:lambda:us-east-1:123456789012:function:post_authentication" + post_confirmation = "arn:aws:lambda:us-east-1:123456789012:function:post_confirmation" + pre_authentication = "arn:aws:lambda:us-east-1:123456789012:function:pre_authentication" + pre_sign_up = "arn:aws:lambda:us-east-1:123456789012:function:pre_sign_up" + pre_token_generation = "arn:aws:lambda:us-east-1:123456789012:function:pre_token_generation" + user_migration = "arn:aws:lambda:us-east-1:123456789012:function:user_migration" + verify_auth_challenge_response = "arn:aws:lambda:us-east-1:123456789012:function:verify_auth_challenge_response" + } + + password_policy = { + minimum_length = 10 + require_lowercase = false + require_numbers = true + require_symbols = true + require_uppercase = true + temporary_password_validity_days = 120 + + } + + user_pool_add_ons = { + advanced_security_mode = "ENFORCED" + } + + verification_message_template = { + default_email_option = "CONFIRM_WITH_CODE" + } + + schemas = [ + { + attribute_data_type = "Boolean" + developer_only_attribute = false + mutable = true + name = "available" + required = false + }, + { + attribute_data_type = "Boolean" + developer_only_attribute = true + mutable = true + name = "registered" + required = false + } + ] + + string_schemas = [ + { + attribute_data_type = "String" + developer_only_attribute = false + mutable = false + name = "email" + required = true + + string_attribute_constraints = { + min_length = 7 + max_length = 15 + } + }, + { + attribute_data_type = "String" + developer_only_attribute = false + mutable = false + name = "gender" + required = true + + string_attribute_constraints = { + min_length = 7 + max_length = 15 + } + }, + ] + + number_schemas = [ + { + attribute_data_type = "Number" + developer_only_attribute = true + mutable = true + name = "mynumber1" + required = false + + number_attribute_constraints = { + min_value = 2 + max_value = 6 + } + }, + { + attribute_data_type = "Number" + developer_only_attribute = true + mutable = true + name = "mynumber2" + required = false + + number_attribute_constraints = { + min_value = 2 + max_value = 6 + } + }, + ] + + # user_pool_domain + domain = "mydomain-com" + + # clients + clients = [ + { + allowed_oauth_flows = [] + allowed_oauth_flows_user_pool_client = false + allowed_oauth_scopes = [] + callback_urls = ["https://mydomain.com/callback"] + default_redirect_uri = "https://mydomain.com/callback" + explicit_auth_flows = [] + generate_secret = true + logout_urls = [] + name = "test1" + read_attributes = ["email"] + supported_identity_providers = [] + write_attributes = [] + access_token_validity = 1 + id_token_validity = 1 + refresh_token_validity = 60 + token_validity_units = { + access_token = "hours" + id_token = "hours" + refresh_token = "days" + } + }, + { + allowed_oauth_flows = [] + allowed_oauth_flows_user_pool_client = false + allowed_oauth_scopes = [] + callback_urls = ["https://mydomain.com/callback"] + default_redirect_uri = "https://mydomain.com/callback" + explicit_auth_flows = [] + generate_secret = false + logout_urls = [] + name = "test2" + read_attributes = [] + supported_identity_providers = [] + write_attributes = [] + refresh_token_validity = 30 + }, + { + allowed_oauth_flows = ["code", "implicit"] + allowed_oauth_flows_user_pool_client = true + allowed_oauth_scopes = ["email", "openid"] + callback_urls = ["https://mydomain.com/callback"] + default_redirect_uri = "https://mydomain.com/callback" + explicit_auth_flows = ["CUSTOM_AUTH_FLOW_ONLY", "ADMIN_NO_SRP_AUTH"] + generate_secret = false + logout_urls = ["https://mydomain.com/logout"] + name = "test3" + read_attributes = ["email", "phone_number"] + supported_identity_providers = [] + write_attributes = ["email", "gender", "locale", ] + refresh_token_validity = 30 + } + ] + + # user_group + user_groups = [ + { name = "mygroup1" + description = "My group 1" + }, + { name = "mygroup2" + description = "My group 2" + }, + ] + + # resource_servers + resource_servers = [ + { + identifier = "https://mydomain.com" + name = "mydomain" + scope = [ + { + scope_name = "sample-scope-1" + scope_description = "A sample Scope Description for mydomain.com" + }, + { + scope_name = "sample-scope-2" + scope_description = "Another sample Scope Description for mydomain.com" + }, + ] + }, + { + identifier = "https://weather-read-app.com" + name = "weather-read" + scope = [ + { + scope_name = "weather.read" + scope_description = "Read weather forecasts" + } + ] + } + ] + + # identity_providers + identity_providers = [ + { + provider_name = "Google" + provider_type = "Google" + + provider_details = { + authorize_scopes = "email" + client_id = "your client_id" + client_secret = "your client_secret" + } + + attribute_mapping = { + email = "email" + username = "sub" + gender = "gender" + } + } + ] + + # tags + tags = { + Owner = "infra" + Environment = "production" + Terraform = true + } +} +``` diff --git a/modules/aws-cognito-user-pool/examples/complete/main.tf b/modules/aws-cognito-user-pool/examples/complete/main.tf new file mode 100644 index 0000000..f4e4270 --- /dev/null +++ b/modules/aws-cognito-user-pool/examples/complete/main.tf @@ -0,0 +1,280 @@ +module "aws_cognito_user_pool_complete_example" { + + source = "lgallard/cognito-user-pool/aws" + + user_pool_name = "mypool_complete" + alias_attributes = ["email", "phone_number"] + auto_verified_attributes = ["email"] + sms_authentication_message = "Your username is {username} and temporary password is {####}." + sms_verification_message = "This is the verification message {####}." + + deletion_protection = "ACTIVE" + + mfa_configuration = "OPTIONAL" + software_token_mfa_configuration = { + enabled = true + } + + admin_create_user_config = { + email_message = "Dear {username}, your verification code is {####}." + email_subject = "Here, your verification code baby" + sms_message = "Your username is {username} and temporary password is {####}." + } + + device_configuration = { + challenge_required_on_new_device = true + device_only_remembered_on_user_prompt = true + } + + email_configuration = { + email_sending_account = "DEVELOPER" + reply_to_email_address = "email@mydomain.com" + source_arn = "arn:aws:ses:us-east-1:123456789012:identity/myemail@mydomain.com" + } + + lambda_config = { + create_auth_challenge = "arn:aws:lambda:us-east-1:123456789012:function:create_auth_challenge" + custom_message = "arn:aws:lambda:us-east-1:123456789012:function:custom_message" + define_auth_challenge = "arn:aws:lambda:us-east-1:123456789012:function:define_auth_challenge" + post_authentication = "arn:aws:lambda:us-east-1:123456789012:function:post_authentication" + post_confirmation = "arn:aws:lambda:us-east-1:123456789012:function:post_confirmation" + pre_authentication = "arn:aws:lambda:us-east-1:123456789012:function:pre_authentication" + pre_sign_up = "arn:aws:lambda:us-east-1:123456789012:function:pre_sign_up" + pre_token_generation = "arn:aws:lambda:us-east-1:123456789012:function:pre_token_generation" + user_migration = "arn:aws:lambda:us-east-1:123456789012:function:user_migration" + verify_auth_challenge_response = "arn:aws:lambda:us-east-1:123456789012:function:verify_auth_challenge_response" + kms_key_id = aws_kms_key.lambda-custom-sender.arn + custom_email_sender = { + lambda_arn = "arn:aws:lambda:us-east-1:123456789012:function:custom_email_sender" + lambda_version = "V1_0" + } + custom_sms_sender = { + lambda_arn = "arn:aws:lambda:us-east-1:123456789012:function:custom_sms_sender" + lambda_version = "V1_0" + } + } + + password_policy = { + minimum_length = 10 + require_lowercase = false + require_numbers = true + require_symbols = true + require_uppercase = true + temporary_password_validity_days = 120 + + } + + user_pool_add_ons = { + advanced_security_mode = "ENFORCED" + } + + verification_message_template = { + default_email_option = "CONFIRM_WITH_CODE" + } + + schemas = [ + { + attribute_data_type = "Boolean" + developer_only_attribute = false + mutable = true + name = "available" + required = false + }, + { + attribute_data_type = "Boolean" + developer_only_attribute = true + mutable = true + name = "registered" + required = false + } + ] + + string_schemas = [ + { + attribute_data_type = "String" + developer_only_attribute = false + mutable = false + name = "email" + required = true + + string_attribute_constraints = { + min_length = 7 + max_length = 15 + } + }, + { + attribute_data_type = "String" + developer_only_attribute = false + mutable = false + name = "gender" + required = true + + string_attribute_constraints = { + min_length = 7 + max_length = 15 + } + }, + ] + + number_schemas = [ + { + attribute_data_type = "Number" + developer_only_attribute = true + mutable = true + name = "mynumber1" + required = false + + number_attribute_constraints = { + min_value = 2 + max_value = 6 + } + }, + { + attribute_data_type = "Number" + developer_only_attribute = true + mutable = true + name = "mynumber2" + required = false + + number_attribute_constraints = { + min_value = 2 + max_value = 6 + } + }, + ] + + # user_pool_domain + domain = "mydomain-com" + + # clients + clients = [ + { + allowed_oauth_flows = [] + allowed_oauth_flows_user_pool_client = false + allowed_oauth_scopes = [] + callback_urls = ["https://mydomain.com/callback"] + default_redirect_uri = "https://mydomain.com/callback" + explicit_auth_flows = [] + generate_secret = true + logout_urls = [] + name = "test1" + read_attributes = ["email"] + supported_identity_providers = [] + write_attributes = [] + access_token_validity = 1 + id_token_validity = 1 + refresh_token_validity = 60 + token_validity_units = { + access_token = "hours" + id_token = "hours" + refresh_token = "days" + } + }, + { + allowed_oauth_flows = [] + allowed_oauth_flows_user_pool_client = false + allowed_oauth_scopes = [] + callback_urls = ["https://mydomain.com/callback"] + default_redirect_uri = "https://mydomain.com/callback" + explicit_auth_flows = [] + generate_secret = false + logout_urls = [] + name = "test2" + read_attributes = [] + supported_identity_providers = [] + write_attributes = [] + refresh_token_validity = 30 + }, + { + allowed_oauth_flows = ["code", "implicit"] + allowed_oauth_flows_user_pool_client = true + allowed_oauth_scopes = ["email", "openid"] + callback_urls = ["https://mydomain.com/callback"] + default_redirect_uri = "https://mydomain.com/callback" + explicit_auth_flows = ["CUSTOM_AUTH_FLOW_ONLY", "ADMIN_NO_SRP_AUTH"] + generate_secret = false + logout_urls = ["https://mydomain.com/logout"] + name = "test3" + read_attributes = ["email", "phone_number"] + supported_identity_providers = [] + write_attributes = ["email", "gender", "locale", ] + refresh_token_validity = 30 + } + ] + + # user_group + user_groups = [ + { name = "mygroup1" + description = "My group 1" + }, + { name = "mygroup2" + description = "My group 2" + }, + ] + + # resource_servers + resource_servers = [ + { + identifier = "https://mydomain.com" + name = "mydomain" + scope = [ + { + scope_name = "sample-scope-1" + scope_description = "A sample Scope Description for mydomain.com" + }, + { + scope_name = "sample-scope-2" + scope_description = "Another sample Scope Description for mydomain.com" + }, + ] + }, + { + identifier = "https://weather-read-app.com" + name = "weather-read" + scope = [ + { + scope_name = "weather.read" + scope_description = "Read weather forecasts" + } + ] + } + ] + + # identity_providers + identity_providers = [ + { + provider_name = "Google" + provider_type = "Google" + + provider_details = { + authorize_scopes = "email" + client_id = "your client_id" + client_secret = "your client_secret" + attributes_url_add_attributes = "true" + authorize_url = "https://accounts.google.com/o/oauth2/v2/auth" + oidc_issuer = "https://accounts.google.com" + token_request_method = "POST" + token_url = "https://www.googleapis.com/oauth2/v4/token" + } + + attribute_mapping = { + email = "email" + username = "sub" + gender = "gender" + } + } + ] + + # tags + tags = { + Owner = "infra" + Environment = "production" + Terraform = true + } +} + + +# KMS key for lambda custom sender config" +resource "aws_kms_key" "lambda-custom-sender" { + description = "KMS key for lambda custom sender config" +} diff --git a/modules/aws-cognito-user-pool/examples/complete/provider.tf b/modules/aws-cognito-user-pool/examples/complete/provider.tf new file mode 100644 index 0000000..634c762 --- /dev/null +++ b/modules/aws-cognito-user-pool/examples/complete/provider.tf @@ -0,0 +1,4 @@ +provider "aws" { + region = var.env["region"] + profile = var.env["profile"] +} diff --git a/modules/aws-cognito-user-pool/examples/complete/variables.tf b/modules/aws-cognito-user-pool/examples/complete/variables.tf new file mode 100644 index 0000000..c7b7aed --- /dev/null +++ b/modules/aws-cognito-user-pool/examples/complete/variables.tf @@ -0,0 +1,4 @@ +variable "env" { + type = map(any) + default = {} +} diff --git a/modules/aws-cognito-user-pool/examples/simple/README.md b/modules/aws-cognito-user-pool/examples/simple/README.md new file mode 100644 index 0000000..b70971f --- /dev/null +++ b/modules/aws-cognito-user-pool/examples/simple/README.md @@ -0,0 +1,17 @@ +# The simple example + +``` +module "aws_cognito_user_pool_simple_example" { + + source = "../modules/terraform-aws-cognito-user-pool" + + user_pool_name = "simple_pool" + + # tags + tags = { + Owner = "infra" + Environment = "production" + Terraform = true + } +} +``` diff --git a/modules/aws-cognito-user-pool/examples/simple/main.tf b/modules/aws-cognito-user-pool/examples/simple/main.tf new file mode 100644 index 0000000..1600e81 --- /dev/null +++ b/modules/aws-cognito-user-pool/examples/simple/main.tf @@ -0,0 +1,13 @@ +module "aws_cognito_user_pool_simple_example" { + + source = "lgallard/cognito-user-pool/aws" + + user_pool_name = "simple_pool" + + # tags + tags = { + Owner = "infra" + Environment = "production" + Terraform = true + } +} diff --git a/modules/aws-cognito-user-pool/examples/simple/provider.tf b/modules/aws-cognito-user-pool/examples/simple/provider.tf new file mode 100644 index 0000000..634c762 --- /dev/null +++ b/modules/aws-cognito-user-pool/examples/simple/provider.tf @@ -0,0 +1,4 @@ +provider "aws" { + region = var.env["region"] + profile = var.env["profile"] +} diff --git a/modules/aws-cognito-user-pool/examples/simple/variables.tf b/modules/aws-cognito-user-pool/examples/simple/variables.tf new file mode 100644 index 0000000..c7b7aed --- /dev/null +++ b/modules/aws-cognito-user-pool/examples/simple/variables.tf @@ -0,0 +1,4 @@ +variable "env" { + type = map(any) + default = {} +} diff --git a/modules/aws-cognito-user-pool/examples/simple_extended/README.md b/modules/aws-cognito-user-pool/examples/simple_extended/README.md new file mode 100644 index 0000000..34e2987 --- /dev/null +++ b/modules/aws-cognito-user-pool/examples/simple_extended/README.md @@ -0,0 +1,73 @@ +# This is the simple example, but extended +``` +module "aws_cognito_user_pool_simple_extended_example" { + + source = "../modules/terraform-aws-cognito-user-pool" + + user_pool_name = "simple_extended_pool" + alias_attributes = ["email", "phone_number"] + auto_verified_attributes = ["email"] + sms_authentication_message = "Your username is {username} and temporary password is {####}." + sms_verification_message = "This is the verification message {####}." + lambda_config_verify_auth_challenge_response = "arn:aws:lambda:us-east-1:123456789012:function:my_lambda_function" + password_policy_require_lowercase = false + password_policy_minimum_length = 11 + user_pool_add_ons_advanced_security_mode = "OFF" + verification_message_template_default_email_option = "CONFIRM_WITH_CODE" + + # schemas + schemas = [ + { + attribute_data_type = "Boolean" + developer_only_attribute = false + mutable = true + name = "available" + required = false + }, + ] + + string_schemas = [ + { + attribute_data_type = "String" + developer_only_attribute = false + mutable = false + name = "email" + required = true + + string_attribute_constraints = { + min_length = 7 + max_length = 15 + } + }, + ] + + # user_pool_domain + domain = "mydomain-com" + + # client + client_name = "client0" + client_allowed_oauth_flows_user_pool_client = false + client_callback_urls = ["https://mydomain.com/callback"] + client_default_redirect_uri = "https://mydomain.com/callback" + client_read_attributes = ["email"] + client_refresh_token_validity = 30 + + + # user_group + user_group_name = "mygroup" + user_group_description = "My group" + + # ressource server + resource_server_identifier = "https://mydomain.com" + resource_server_name = "mydomain" + resource_server_scope_name = "scope" + resource_server_scope_description = "a Sample Scope Description for mydomain" + + # tags + tags = { + Owner = "infra" + Environment = "production" + Terraform = true + } +} +``` diff --git a/modules/aws-cognito-user-pool/examples/simple_extended/main.tf b/modules/aws-cognito-user-pool/examples/simple_extended/main.tf new file mode 100644 index 0000000..c0ce344 --- /dev/null +++ b/modules/aws-cognito-user-pool/examples/simple_extended/main.tf @@ -0,0 +1,70 @@ +module "aws_cognito_user_pool_simple_extended_example" { + + source = "lgallard/cognito-user-pool/aws" + + user_pool_name = "simple_extended_pool" + alias_attributes = ["email", "phone_number"] + auto_verified_attributes = ["email"] + sms_authentication_message = "Your username is {username} and temporary password is {####}." + sms_verification_message = "This is the verification message {####}." + lambda_config_verify_auth_challenge_response = "arn:aws:lambda:us-east-1:123456789012:function:my_lambda_function" + password_policy_require_lowercase = false + password_policy_minimum_length = 11 + user_pool_add_ons_advanced_security_mode = "OFF" + verification_message_template_default_email_option = "CONFIRM_WITH_CODE" + + # schemas + schemas = [ + { + attribute_data_type = "Boolean" + developer_only_attribute = false + mutable = true + name = "available" + required = false + }, + ] + + string_schemas = [ + { + attribute_data_type = "String" + developer_only_attribute = false + mutable = false + name = "email" + required = true + + string_attribute_constraints = { + min_length = 7 + max_length = 15 + } + }, + ] + + # user_pool_domain + domain = "mydomain-com" + + # client + client_name = "client0" + client_allowed_oauth_flows_user_pool_client = false + client_callback_urls = ["https://mydomain.com/callback"] + client_default_redirect_uri = "https://mydomain.com/callback" + client_read_attributes = ["email"] + client_refresh_token_validity = 30 + + + # user_group + user_group_name = "mygroup" + user_group_description = "My group" + + # ressource server + resource_server_identifier = "https://mydomain.com" + resource_server_name = "mydomain" + resource_server_scope_name = "scope" + resource_server_scope_description = "a Sample Scope Description for mydomain" + + # tags + tags = { + Owner = "infra" + Environment = "production" + Terraform = true + } +} diff --git a/modules/aws-cognito-user-pool/examples/simple_extended/provider.tf b/modules/aws-cognito-user-pool/examples/simple_extended/provider.tf new file mode 100644 index 0000000..634c762 --- /dev/null +++ b/modules/aws-cognito-user-pool/examples/simple_extended/provider.tf @@ -0,0 +1,4 @@ +provider "aws" { + region = var.env["region"] + profile = var.env["profile"] +} diff --git a/modules/aws-cognito-user-pool/examples/simple_extended/variables.tf b/modules/aws-cognito-user-pool/examples/simple_extended/variables.tf new file mode 100644 index 0000000..c7b7aed --- /dev/null +++ b/modules/aws-cognito-user-pool/examples/simple_extended/variables.tf @@ -0,0 +1,4 @@ +variable "env" { + type = map(any) + default = {} +} diff --git a/modules/aws-cognito-user-pool/identity-provider.tf b/modules/aws-cognito-user-pool/identity-provider.tf new file mode 100644 index 0000000..5c00861 --- /dev/null +++ b/modules/aws-cognito-user-pool/identity-provider.tf @@ -0,0 +1,11 @@ +resource "aws_cognito_identity_provider" "identity_provider" { + count = var.enabled ? length(var.identity_providers) : 0 + user_pool_id = aws_cognito_user_pool.pool[0].id + provider_name = lookup(element(var.identity_providers, count.index), "provider_name") + provider_type = lookup(element(var.identity_providers, count.index), "provider_type") + + # Optional arguments + attribute_mapping = lookup(element(var.identity_providers, count.index), "attribute_mapping", {}) + idp_identifiers = lookup(element(var.identity_providers, count.index), "idp_identifiers", []) + provider_details = lookup(element(var.identity_providers, count.index), "provider_details", {}) +} diff --git a/modules/aws-cognito-user-pool/main.tf b/modules/aws-cognito-user-pool/main.tf new file mode 100644 index 0000000..a7466db --- /dev/null +++ b/modules/aws-cognito-user-pool/main.tf @@ -0,0 +1,325 @@ +resource "aws_cognito_user_pool" "pool" { + count = var.enabled ? 1 : 0 + + alias_attributes = var.alias_attributes + auto_verified_attributes = var.auto_verified_attributes + name = var.user_pool_name + email_verification_subject = var.email_verification_subject == "" || var.email_verification_subject == null ? var.admin_create_user_config_email_subject : var.email_verification_subject + email_verification_message = var.email_verification_message == "" || var.email_verification_message == null ? var.admin_create_user_config_email_message : var.email_verification_message + mfa_configuration = var.mfa_configuration + sms_authentication_message = var.sms_authentication_message + sms_verification_message = var.sms_verification_message + username_attributes = var.username_attributes + deletion_protection = var.deletion_protection + + # username_configuration + dynamic "username_configuration" { + for_each = local.username_configuration + content { + case_sensitive = lookup(username_configuration.value, "case_sensitive") + } + } + + # admin_create_user_config + dynamic "admin_create_user_config" { + for_each = local.admin_create_user_config + content { + allow_admin_create_user_only = lookup(admin_create_user_config.value, "allow_admin_create_user_only") + + dynamic "invite_message_template" { + for_each = lookup(admin_create_user_config.value, "email_message", null) == null && lookup(admin_create_user_config.value, "email_subject", null) == null && lookup(admin_create_user_config.value, "sms_message", null) == null ? [] : [1] + content { + email_message = lookup(admin_create_user_config.value, "email_message") + email_subject = lookup(admin_create_user_config.value, "email_subject") + sms_message = lookup(admin_create_user_config.value, "sms_message") + } + } + } + } + + # device_configuration + dynamic "device_configuration" { + for_each = local.device_configuration + content { + challenge_required_on_new_device = lookup(device_configuration.value, "challenge_required_on_new_device") + device_only_remembered_on_user_prompt = lookup(device_configuration.value, "device_only_remembered_on_user_prompt") + } + } + + # email_configuration + dynamic "email_configuration" { + for_each = local.email_configuration + content { + configuration_set = lookup(email_configuration.value, "configuration_set") + reply_to_email_address = lookup(email_configuration.value, "reply_to_email_address") + source_arn = lookup(email_configuration.value, "source_arn") + email_sending_account = lookup(email_configuration.value, "email_sending_account") + from_email_address = lookup(email_configuration.value, "from_email_address") + } + } + + # lambda_config + dynamic "lambda_config" { + for_each = var.lambda_config == null || length(var.lambda_config) == 0 ? [] : [1] + content { + create_auth_challenge = lookup(var.lambda_config, "create_auth_challenge", var.lambda_config_create_auth_challenge) + custom_message = lookup(var.lambda_config, "custom_message", var.lambda_config_custom_message) + define_auth_challenge = lookup(var.lambda_config, "define_auth_challenge", var.lambda_config_define_auth_challenge) + post_authentication = lookup(var.lambda_config, "post_authentication", var.lambda_config_post_authentication) + post_confirmation = lookup(var.lambda_config, "post_confirmation", var.lambda_config_post_confirmation) + pre_authentication = lookup(var.lambda_config, "pre_authentication", var.lambda_config_pre_authentication) + pre_sign_up = lookup(var.lambda_config, "pre_sign_up", var.lambda_config_pre_sign_up) + pre_token_generation = lookup(var.lambda_config, "pre_token_generation", var.lambda_config_pre_token_generation) + user_migration = lookup(var.lambda_config, "user_migration", var.lambda_config_user_migration) + verify_auth_challenge_response = lookup(var.lambda_config, "verify_auth_challenge_response", var.lambda_config_verify_auth_challenge_response) + kms_key_id = lookup(var.lambda_config, "kms_key_id", var.lambda_config_kms_key_id) + dynamic "custom_email_sender" { + for_each = lookup(var.lambda_config, "custom_email_sender", var.lambda_config_custom_email_sender) == {} ? [] : [1] + content { + lambda_arn = lookup(lookup(var.lambda_config, "custom_email_sender", var.lambda_config_custom_email_sender), "lambda_arn", null) + lambda_version = lookup(lookup(var.lambda_config, "custom_email_sender", var.lambda_config_custom_email_sender), "lambda_version", null) + } + } + dynamic "custom_sms_sender" { + for_each = lookup(var.lambda_config, "custom_sms_sender", var.lambda_config_custom_sms_sender) == {} ? [] : [1] + content { + lambda_arn = lookup(lookup(var.lambda_config, "custom_sms_sender", var.lambda_config_custom_sms_sender), "lambda_arn", null) + lambda_version = lookup(lookup(var.lambda_config, "custom_sms_sender", var.lambda_config_custom_sms_sender), "lambda_version", null) + } + } + } + } + + # sms_configuration + dynamic "sms_configuration" { + for_each = local.sms_configuration + content { + external_id = lookup(sms_configuration.value, "external_id") + sns_caller_arn = lookup(sms_configuration.value, "sns_caller_arn") + } + } + + # software_token_mfa_configuration + dynamic "software_token_mfa_configuration" { + for_each = local.software_token_mfa_configuration + content { + enabled = lookup(software_token_mfa_configuration.value, "enabled") + } + } + + # password_policy + dynamic "password_policy" { + for_each = local.password_policy + content { + minimum_length = lookup(password_policy.value, "minimum_length") + require_lowercase = lookup(password_policy.value, "require_lowercase") + require_numbers = lookup(password_policy.value, "require_numbers") + require_symbols = lookup(password_policy.value, "require_symbols") + require_uppercase = lookup(password_policy.value, "require_uppercase") + temporary_password_validity_days = lookup(password_policy.value, "temporary_password_validity_days") + } + } + + # schema + dynamic "schema" { + for_each = var.schemas == null ? [] : var.schemas + content { + attribute_data_type = lookup(schema.value, "attribute_data_type") + developer_only_attribute = lookup(schema.value, "developer_only_attribute") + mutable = lookup(schema.value, "mutable") + name = lookup(schema.value, "name") + required = lookup(schema.value, "required") + } + } + + # schema (String) + dynamic "schema" { + for_each = var.string_schemas == null ? [] : var.string_schemas + content { + attribute_data_type = lookup(schema.value, "attribute_data_type") + developer_only_attribute = lookup(schema.value, "developer_only_attribute") + mutable = lookup(schema.value, "mutable") + name = lookup(schema.value, "name") + required = lookup(schema.value, "required") + + # string_attribute_constraints + dynamic "string_attribute_constraints" { + for_each = length(keys(lookup(schema.value, "string_attribute_constraints", {}))) == 0 ? [{}] : [lookup(schema.value, "string_attribute_constraints", {})] + content { + min_length = lookup(string_attribute_constraints.value, "min_length", null) + max_length = lookup(string_attribute_constraints.value, "max_length", null) + } + } + } + } + + # schema (Number) + dynamic "schema" { + for_each = var.number_schemas == null ? [] : var.number_schemas + content { + attribute_data_type = lookup(schema.value, "attribute_data_type") + developer_only_attribute = lookup(schema.value, "developer_only_attribute") + mutable = lookup(schema.value, "mutable") + name = lookup(schema.value, "name") + required = lookup(schema.value, "required") + + # number_attribute_constraints + dynamic "number_attribute_constraints" { + for_each = length(keys(lookup(schema.value, "number_attribute_constraints", {}))) == 0 ? [{}] : [lookup(schema.value, "number_attribute_constraints", {})] + content { + min_value = lookup(number_attribute_constraints.value, "min_value", null) + max_value = lookup(number_attribute_constraints.value, "max_value", null) + } + } + } + } + + # user_pool_add_ons + dynamic "user_pool_add_ons" { + for_each = local.user_pool_add_ons + content { + advanced_security_mode = lookup(user_pool_add_ons.value, "advanced_security_mode") + } + } + + # verification_message_template + dynamic "verification_message_template" { + for_each = local.verification_message_template + content { + default_email_option = lookup(verification_message_template.value, "default_email_option") + email_message_by_link = lookup(verification_message_template.value, "email_message_by_link") + email_subject_by_link = lookup(verification_message_template.value, "email_subject_by_link") + } + } + + dynamic "user_attribute_update_settings" { + for_each = local.user_attribute_update_settings + content { + attributes_require_verification_before_update = lookup(user_attribute_update_settings.value, "attributes_require_verification_before_update") + } + } + + # account_recovery_setting + dynamic "account_recovery_setting" { + for_each = length(var.recovery_mechanisms) == 0 ? [] : [1] + content { + # recovery_mechanism + dynamic "recovery_mechanism" { + for_each = var.recovery_mechanisms + content { + name = lookup(recovery_mechanism.value, "name") + priority = lookup(recovery_mechanism.value, "priority") + } + } + } + } + + # tags + tags = var.tags +} + +locals { + # username_configuration + # If no username_configuration is provided return a empty list + username_configuration_default = length(var.username_configuration) == 0 ? {} : { + case_sensitive = lookup(var.username_configuration, "case_sensitive", true) + } + username_configuration = length(local.username_configuration_default) == 0 ? [] : [local.username_configuration_default] + + # admin_create_user_config + # If no admin_create_user_config list is provided, build a admin_create_user_config using the default values + admin_create_user_config_default = { + allow_admin_create_user_only = lookup(var.admin_create_user_config, "allow_admin_create_user_only", null) == null ? var.admin_create_user_config_allow_admin_create_user_only : lookup(var.admin_create_user_config, "allow_admin_create_user_only") + email_message = lookup(var.admin_create_user_config, "email_message", null) == null ? (var.email_verification_message == "" || var.email_verification_message == null ? var.admin_create_user_config_email_message : var.email_verification_message) : lookup(var.admin_create_user_config, "email_message") + email_subject = lookup(var.admin_create_user_config, "email_subject", null) == null ? (var.email_verification_subject == "" || var.email_verification_subject == null ? var.admin_create_user_config_email_subject : var.email_verification_subject) : lookup(var.admin_create_user_config, "email_subject") + sms_message = lookup(var.admin_create_user_config, "sms_message", null) == null ? var.admin_create_user_config_sms_message : lookup(var.admin_create_user_config, "sms_message") + + } + + admin_create_user_config = [local.admin_create_user_config_default] + + # sms_configuration + # If no sms_configuration list is provided, build a sms_configuration using the default values + sms_configuration_default = { + external_id = lookup(var.sms_configuration, "external_id", null) == null ? var.sms_configuration_external_id : lookup(var.sms_configuration, "external_id") + sns_caller_arn = lookup(var.sms_configuration, "sns_caller_arn", null) == null ? var.sms_configuration_sns_caller_arn : lookup(var.sms_configuration, "sns_caller_arn") + } + + sms_configuration = lookup(local.sms_configuration_default, "external_id") == "" || lookup(local.sms_configuration_default, "sns_caller_arn") == "" ? [] : [local.sms_configuration_default] + + # device_configuration + # If no device_configuration list is provided, build a device_configuration using the default values + device_configuration_default = { + challenge_required_on_new_device = lookup(var.device_configuration, "challenge_required_on_new_device", null) == null ? var.device_configuration_challenge_required_on_new_device : lookup(var.device_configuration, "challenge_required_on_new_device") + device_only_remembered_on_user_prompt = lookup(var.device_configuration, "device_only_remembered_on_user_prompt", null) == null ? var.device_configuration_device_only_remembered_on_user_prompt : lookup(var.device_configuration, "device_only_remembered_on_user_prompt") + } + + device_configuration = lookup(local.device_configuration_default, "challenge_required_on_new_device") == false && lookup(local.device_configuration_default, "device_only_remembered_on_user_prompt") == false ? [] : [local.device_configuration_default] + + # email_configuration + # If no email_configuration is provided, build a email_configuration using the default values + email_configuration_default = { + configuration_set = lookup(var.email_configuration, "configuration_set", null) == null ? var.email_configuration_configuration_set : lookup(var.email_configuration, "configuration_set") + reply_to_email_address = lookup(var.email_configuration, "reply_to_email_address", null) == null ? var.email_configuration_reply_to_email_address : lookup(var.email_configuration, "reply_to_email_address") + source_arn = lookup(var.email_configuration, "source_arn", null) == null ? var.email_configuration_source_arn : lookup(var.email_configuration, "source_arn") + email_sending_account = lookup(var.email_configuration, "email_sending_account", null) == null ? var.email_configuration_email_sending_account : lookup(var.email_configuration, "email_sending_account") + from_email_address = lookup(var.email_configuration, "from_email_address", null) == null ? var.email_configuration_from_email_address : lookup(var.email_configuration, "from_email_address") + } + + email_configuration = [local.email_configuration_default] + + # password_policy + # If no password_policy is provided, build a password_policy using the default values + # If lambda_config is null + password_policy_is_null = { + minimum_length = var.password_policy_minimum_length + require_lowercase = var.password_policy_require_lowercase + require_numbers = var.password_policy_require_numbers + require_symbols = var.password_policy_require_symbols + require_uppercase = var.password_policy_require_uppercase + temporary_password_validity_days = var.password_policy_temporary_password_validity_days + } + + password_policy_not_null = var.password_policy == null ? local.password_policy_is_null : { + minimum_length = lookup(var.password_policy, "minimum_length", null) == null ? var.password_policy_minimum_length : lookup(var.password_policy, "minimum_length") + require_lowercase = lookup(var.password_policy, "require_lowercase", null) == null ? var.password_policy_require_lowercase : lookup(var.password_policy, "require_lowercase") + require_numbers = lookup(var.password_policy, "require_numbers", null) == null ? var.password_policy_require_numbers : lookup(var.password_policy, "require_numbers") + require_symbols = lookup(var.password_policy, "require_symbols", null) == null ? var.password_policy_require_symbols : lookup(var.password_policy, "require_symbols") + require_uppercase = lookup(var.password_policy, "require_uppercase", null) == null ? var.password_policy_require_uppercase : lookup(var.password_policy, "require_uppercase") + temporary_password_validity_days = lookup(var.password_policy, "temporary_password_validity_days", null) == null ? var.password_policy_temporary_password_validity_days : lookup(var.password_policy, "temporary_password_validity_days") + + } + + # Return the default values + password_policy = var.password_policy == null ? [local.password_policy_is_null] : [local.password_policy_not_null] + + # user_pool_add_ons + # If no user_pool_add_ons is provided, build a configuration using the default values + user_pool_add_ons_default = { + advanced_security_mode = lookup(var.user_pool_add_ons, "advanced_security_mode", null) == null ? var.user_pool_add_ons_advanced_security_mode : lookup(var.user_pool_add_ons, "advanced_security_mode") + } + + user_pool_add_ons = var.user_pool_add_ons_advanced_security_mode == null && length(var.user_pool_add_ons) == 0 ? [] : [local.user_pool_add_ons_default] + + # verification_message_template + # If no verification_message_template is provided, build a verification_message_template using the default values + verification_message_template_default = { + default_email_option = lookup(var.verification_message_template, "default_email_option", null) == null ? var.verification_message_template_default_email_option : lookup(var.verification_message_template, "default_email_option") + email_message_by_link = lookup(var.verification_message_template, "email_message_by_link", null) == null ? var.verification_message_template_email_message_by_link : lookup(var.verification_message_template, "email_message_by_link") + email_subject_by_link = lookup(var.verification_message_template, "email_subject_by_link", null) == null ? var.verification_message_template_email_subject_by_link : lookup(var.verification_message_template, "email_subject_by_link") + } + + verification_message_template = [local.verification_message_template_default] + + # software_token_mfa_configuration + # If no software_token_mfa_configuration is provided, build a software_token_mfa_configuration using the default values + software_token_mfa_configuration_default = { + enabled = lookup(var.software_token_mfa_configuration, "enabled", null) == null ? var.software_token_mfa_configuration_enabled : lookup(var.software_token_mfa_configuration, "enabled") + } + + software_token_mfa_configuration = (length(var.sms_configuration) == 0 || local.sms_configuration == null) && var.mfa_configuration == "OFF" ? [] : [local.software_token_mfa_configuration_default] + + # user_attribute_update_settings + # As default, all auto_verified_attributes will become attributes_require_verification_before_update + user_attribute_update_settings = var.user_attribute_update_settings == null ? (length(var.auto_verified_attributes) > 0 ? [{ attributes_require_verification_before_update = var.auto_verified_attributes }] : []) : [var.user_attribute_update_settings] +} diff --git a/modules/aws-cognito-user-pool/outputs.tf b/modules/aws-cognito-user-pool/outputs.tf new file mode 100644 index 0000000..ff94fbe --- /dev/null +++ b/modules/aws-cognito-user-pool/outputs.tf @@ -0,0 +1,85 @@ +output "id" { + description = "The id of the user pool" + value = var.enabled ? aws_cognito_user_pool.pool[0].id : null +} + +output "arn" { + description = "The ARN of the user pool" + value = var.enabled ? aws_cognito_user_pool.pool[0].arn : null +} + +output "endpoint" { + description = "The endpoint name of the user pool. Example format: cognito-idp.REGION.amazonaws.com/xxxx_yyyyy" + value = var.enabled ? aws_cognito_user_pool.pool[0].endpoint : null +} + +output "creation_date" { + description = "The date the user pool was created" + value = var.enabled ? aws_cognito_user_pool.pool[0].creation_date : null +} + +output "last_modified_date" { + description = "The date the user pool was last modified" + value = var.enabled ? aws_cognito_user_pool.pool[0].last_modified_date : null +} + +output "name" { + description = "The name of the user pool" + value = var.enabled ? aws_cognito_user_pool.pool[0].name : null +} + +# +# aws_cognito_user_pool_domain +# +output "domain_aws_account_id" { + description = "The AWS account ID for the user pool owner" + value = var.enabled ? join("", aws_cognito_user_pool_domain.domain.*.aws_account_id) : null +} + +output "domain_cloudfront_distribution_arn" { + description = "The ARN of the CloudFront distribution" + value = var.enabled ? join("", aws_cognito_user_pool_domain.domain.*.cloudfront_distribution_arn) : null +} + +output "domain_s3_bucket" { + description = "The S3 bucket where the static files for this domain are stored" + value = var.enabled ? join("", aws_cognito_user_pool_domain.domain.*.s3_bucket) : null +} + +output "domain_app_version" { + description = "The app version" + value = var.enabled ? join("", aws_cognito_user_pool_domain.domain.*.version) : null +} + +# +# aws_cognito_user_pool_client +# +output "client_ids" { + description = "The ids of the user pool clients" + value = var.enabled ? aws_cognito_user_pool_client.client.*.id : null +} + +output "client_secrets" { + description = " The client secrets of the user pool clients" + value = var.enabled ? aws_cognito_user_pool_client.client.*.client_secret : null + sensitive = true +} + +output "client_ids_map" { + description = "The ids map of the user pool clients" + value = var.enabled ? { for k, v in aws_cognito_user_pool_client.client : v.name => v.id } : null +} + +output "client_secrets_map" { + description = "The client secrets map of the user pool clients" + value = var.enabled ? { for k, v in aws_cognito_user_pool_client.client : v.name => v.client_secret } : null + sensitive = true +} + +# +# aws_cognito_resource_servers +# +output "resource_servers_scope_identifiers" { + description = " A list of all scopes configured in the format identifier/scope_name" + value = var.enabled ? aws_cognito_resource_server.resource.*.scope_identifiers : null +} diff --git a/modules/aws-cognito-user-pool/resource-server.tf b/modules/aws-cognito-user-pool/resource-server.tf new file mode 100644 index 0000000..ec1f1e7 --- /dev/null +++ b/modules/aws-cognito-user-pool/resource-server.tf @@ -0,0 +1,41 @@ +resource "aws_cognito_resource_server" "resource" { + count = var.enabled ? length(local.resource_servers) : 0 + name = lookup(element(local.resource_servers, count.index), "name") + identifier = lookup(element(local.resource_servers, count.index), "identifier") + + #scope + dynamic "scope" { + for_each = lookup(element(local.resource_servers, count.index), "scope") + content { + scope_name = lookup(scope.value, "scope_name") + scope_description = lookup(scope.value, "scope_description") + } + } + + user_pool_id = aws_cognito_user_pool.pool[0].id +} + +locals { + resource_server_default = [ + { + name = var.resource_server_name + identifier = var.resource_server_identifier + scope = [ + { + scope_name = var.resource_server_scope_name + scope_description = var.resource_server_scope_description + }] + } + ] + + # This parses var.user_groups which is a list of objects (map), and transforms it to a tuple of elements to avoid conflict with the ternary and local.groups_default + resource_servers_parsed = [for e in var.resource_servers : { + name = lookup(e, "name", null) + identifier = lookup(e, "identifier", null) + scope = lookup(e, "scope", []) + } + ] + + resource_servers = length(var.resource_servers) == 0 && (var.resource_server_name == null || var.resource_server_name == "") ? [] : (length(var.resource_servers) > 0 ? local.resource_servers_parsed : local.resource_server_default) + +} diff --git a/modules/aws-cognito-user-pool/user-group.tf b/modules/aws-cognito-user-pool/user-group.tf new file mode 100644 index 0000000..c21cdf9 --- /dev/null +++ b/modules/aws-cognito-user-pool/user-group.tf @@ -0,0 +1,32 @@ +resource "aws_cognito_user_group" "main" { + count = var.enabled ? length(local.groups) : 0 + name = lookup(element(local.groups, count.index), "name") + description = lookup(element(local.groups, count.index), "description") + precedence = lookup(element(local.groups, count.index), "precedence") + role_arn = lookup(element(local.groups, count.index), "role_arn") + user_pool_id = aws_cognito_user_pool.pool[0].id +} + +locals { + groups_default = [ + { + name = var.user_group_name + description = var.user_group_description + precedence = var.user_group_precedence + role_arn = var.user_group_role_arn + + } + ] + + # This parses var.user_groups which is a list of objects (map), and transforms it to a tuple of elements to avoid conflict with the ternary and local.groups_default + groups_parsed = [for e in var.user_groups : { + name = lookup(e, "name", null) + description = lookup(e, "description", null) + precedence = lookup(e, "precedence", null) + role_arn = lookup(e, "role_arn", null) + } + ] + + groups = length(var.user_groups) == 0 && (var.user_group_name == null || var.user_group_name == "") ? [] : (length(var.user_groups) > 0 ? local.groups_parsed : local.groups_default) + +} diff --git a/modules/aws-cognito-user-pool/variables.tf b/modules/aws-cognito-user-pool/variables.tf new file mode 100644 index 0000000..1dcd888 --- /dev/null +++ b/modules/aws-cognito-user-pool/variables.tf @@ -0,0 +1,634 @@ +# +# aws_cognito_user_pool +# +variable "enabled" { + description = "Change to false to avoid deploying any resources" + type = bool + default = true +} + +variable "user_pool_name" { + description = "The name of the user pool" + type = string +} + +variable "email_verification_message" { + description = "A string representing the email verification message" + type = string + default = null +} + +variable "email_verification_subject" { + description = "A string representing the email verification subject" + type = string + default = null +} + +# username_configuration +variable "username_configuration" { + description = "The Username Configuration. Setting `case_sensitive` specifies whether username case sensitivity will be applied for all users in the user pool through Cognito APIs" + type = map(any) + default = {} +} + +# admin_create_user_config +variable "admin_create_user_config" { + description = "The configuration for AdminCreateUser requests" + type = map(any) + default = {} +} + +variable "admin_create_user_config_allow_admin_create_user_only" { + description = "Set to True if only the administrator is allowed to create user profiles. Set to False if users can sign themselves up via an app" + type = bool + default = true +} + +variable "temporary_password_validity_days" { + description = "The user account expiration limit, in days, after which the account is no longer usable" + type = number + default = 7 +} + +variable "admin_create_user_config_email_message" { + description = "The message template for email messages. Must contain `{username}` and `{####}` placeholders, for username and temporary password, respectively" + type = string + default = "{username}, your verification code is `{####}`" +} + + +variable "admin_create_user_config_email_subject" { + description = "The subject line for email messages" + type = string + default = "Your verification code" +} + +variable "admin_create_user_config_sms_message" { + description = "- The message template for SMS messages. Must contain `{username}` and `{####}` placeholders, for username and temporary password, respectively" + type = string + default = "Your username is {username} and temporary password is `{####}`" +} + +variable "alias_attributes" { + description = "Attributes supported as an alias for this user pool. Possible values: phone_number, email, or preferred_username. Conflicts with `username_attributes`" + type = list(string) + default = null +} + +variable "username_attributes" { + description = "Specifies whether email addresses or phone numbers can be specified as usernames when a user signs up. Conflicts with `alias_attributes`" + type = list(string) + default = null +} + +variable "deletion_protection" { + description = "When active, DeletionProtection prevents accidental deletion of your user pool. Before you can delete a user pool that you have protected against deletion, you must deactivate this feature. Valid values are `ACTIVE` and `INACTIVE`." + type = string + default = "INACTIVE" +} + +variable "auto_verified_attributes" { + description = "The attributes to be auto-verified. Possible values: email, phone_number" + type = list(string) + default = [] +} + +# sms_configuration +variable "sms_configuration" { + description = "The SMS Configuration" + type = map(any) + default = {} +} + +variable "sms_configuration_external_id" { + description = "The external ID used in IAM role trust relationships" + type = string + default = "" +} + +variable "sms_configuration_sns_caller_arn" { + description = "The ARN of the Amazon SNS caller. This is usually the IAM role that you've given Cognito permission to assume" + type = string + default = "" +} + +# device_configuration +variable "device_configuration" { + description = "The configuration for the user pool's device tracking" + type = map(any) + default = {} +} + +variable "device_configuration_challenge_required_on_new_device" { + description = "Indicates whether a challenge is required on a new device. Only applicable to a new device" + type = bool + default = false +} + +variable "device_configuration_device_only_remembered_on_user_prompt" { + description = "If true, a device is only remembered on user prompt" + type = bool + default = false +} + +# email_configuration +variable "email_configuration" { + description = "The Email Configuration" + type = map(any) + default = {} +} + +variable "email_configuration_configuration_set" { + description = "The name of the configuration set" + type = string + default = null +} + +variable "email_configuration_reply_to_email_address" { + description = "The REPLY-TO email address" + type = string + default = "" +} + +variable "email_configuration_source_arn" { + description = "The ARN of the email source" + type = string + default = "" +} + +variable "email_configuration_email_sending_account" { + description = "Instruct Cognito to either use its built-in functional or Amazon SES to send out emails. Allowed values: `COGNITO_DEFAULT` or `DEVELOPER`" + type = string + default = "COGNITO_DEFAULT" +} + +variable "email_configuration_from_email_address" { + description = "Sender’s email address or sender’s display name with their email address (e.g. `john@example.com`, `John Smith
minimum_length = number,
require_lowercase = bool,
require_numbers = bool,
require_symbols = bool,
require_uppercase = bool,
temporary_password_validity_days = number
})
{| no | +| [autoscaling\_enabled](#input\_autoscaling\_enabled) | Whether or not to enable autoscaling. See note in README about this setting | `bool` | `false` | no | +| [autoscaling\_indexes](#input\_autoscaling\_indexes) | A map of index autoscaling configurations. See example in examples/autoscaling | `map(map(string))` | `{}` | no | +| [autoscaling\_read](#input\_autoscaling\_read) | A map of read autoscaling settings. `max_capacity` is the only required key. See example in examples/autoscaling | `map(string)` | `{}` | no | +| [autoscaling\_write](#input\_autoscaling\_write) | A map of write autoscaling settings. `max_capacity` is the only required key. See example in examples/autoscaling | `map(string)` | `{}` | no | +| [billing\_mode](#input\_billing\_mode) | Controls how you are billed for read/write throughput and how you manage capacity. The valid values are PROVISIONED or PAY\_PER\_REQUEST | `string` | `"PAY_PER_REQUEST"` | no | +| [create\_table](#input\_create\_table) | Controls if DynamoDB table and associated resources are created | `bool` | `true` | no | +| [global\_secondary\_indexes](#input\_global\_secondary\_indexes) | Describe a GSI for the table; subject to the normal limits on the number of GSIs, projected attributes, etc. | `any` | `[]` | no | +| [hash\_key](#input\_hash\_key) | The attribute to use as the hash (partition) key. Must also be defined as an attribute | `string` | `null` | no | +| [local\_secondary\_indexes](#input\_local\_secondary\_indexes) | Describe an LSI on the table; these can only be allocated at creation so you cannot change this definition after you have created the resource. | `any` | `[]` | no | +| [name](#input\_name) | Name of the DynamoDB table | `string` | `null` | no | +| [point\_in\_time\_recovery\_enabled](#input\_point\_in\_time\_recovery\_enabled) | Whether to enable point-in-time recovery | `bool` | `false` | no | +| [range\_key](#input\_range\_key) | The attribute to use as the range (sort) key. Must also be defined as an attribute | `string` | `null` | no | +| [read\_capacity](#input\_read\_capacity) | The number of read units for this table. If the billing\_mode is PROVISIONED, this field should be greater than 0 | `number` | `null` | no | +| [replica\_regions](#input\_replica\_regions) | Region names for creating replicas for a global DynamoDB table. | `any` | `[]` | no | +| [server\_side\_encryption\_enabled](#input\_server\_side\_encryption\_enabled) | Whether or not to enable encryption at rest using an AWS managed KMS customer master key (CMK) | `bool` | `false` | no | +| [server\_side\_encryption\_kms\_key\_arn](#input\_server\_side\_encryption\_kms\_key\_arn) | The ARN of the CMK that should be used for the AWS KMS encryption. This attribute should only be specified if the key is different from the default DynamoDB CMK, alias/aws/dynamodb. | `string` | `null` | no | +| [stream\_enabled](#input\_stream\_enabled) | Indicates whether Streams are to be enabled (true) or disabled (false). | `bool` | `false` | no | +| [stream\_view\_type](#input\_stream\_view\_type) | When an item in the table is modified, StreamViewType determines what information is written to the table's stream. Valid values are KEYS\_ONLY, NEW\_IMAGE, OLD\_IMAGE, NEW\_AND\_OLD\_IMAGES. | `string` | `null` | no | +| [table\_class](#input\_table\_class) | The storage class of the table. Valid values are STANDARD and STANDARD\_INFREQUENT\_ACCESS | `string` | `null` | no | +| [tags](#input\_tags) | A map of tags to add to all resources | `map(string)` | `{}` | no | +| [timeouts](#input\_timeouts) | Updated Terraform resource management timeouts | `map(string)` |
"scale_in_cooldown": 0,
"scale_out_cooldown": 0,
"target_value": 70
}
{| no | +| [ttl\_attribute\_name](#input\_ttl\_attribute\_name) | The name of the table attribute to store the TTL timestamp in | `string` | `""` | no | +| [ttl\_enabled](#input\_ttl\_enabled) | Indicates whether ttl is enabled | `bool` | `false` | no | +| [write\_capacity](#input\_write\_capacity) | The number of write units for this table. If the billing\_mode is PROVISIONED, this field should be greater than 0 | `number` | `null` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [dynamodb\_table\_arn](#output\_dynamodb\_table\_arn) | ARN of the DynamoDB table | +| [dynamodb\_table\_id](#output\_dynamodb\_table\_id) | ID of the DynamoDB table | +| [dynamodb\_table\_stream\_arn](#output\_dynamodb\_table\_stream\_arn) | The ARN of the Table Stream. Only available when var.stream\_enabled is true | +| [dynamodb\_table\_stream\_label](#output\_dynamodb\_table\_stream\_label) | A timestamp, in ISO 8601 format of the Table Stream. Only available when var.stream\_enabled is true | + diff --git a/modules/aws-dynamodb-table/autoscaling.tf b/modules/aws-dynamodb-table/autoscaling.tf new file mode 100644 index 0000000..50e765e --- /dev/null +++ b/modules/aws-dynamodb-table/autoscaling.tf @@ -0,0 +1,119 @@ +resource "aws_appautoscaling_target" "table_read" { + count = var.create_table && var.autoscaling_enabled && length(var.autoscaling_read) > 0 ? 1 : 0 + + max_capacity = var.autoscaling_read["max_capacity"] + min_capacity = var.read_capacity + resource_id = "table/${aws_dynamodb_table.autoscaled[0].name}" + scalable_dimension = "dynamodb:table:ReadCapacityUnits" + service_namespace = "dynamodb" +} + +resource "aws_appautoscaling_policy" "table_read_policy" { + count = var.create_table && var.autoscaling_enabled && length(var.autoscaling_read) > 0 ? 1 : 0 + + name = "DynamoDBReadCapacityUtilization:${aws_appautoscaling_target.table_read[0].resource_id}" + policy_type = "TargetTrackingScaling" + resource_id = aws_appautoscaling_target.table_read[0].resource_id + scalable_dimension = aws_appautoscaling_target.table_read[0].scalable_dimension + service_namespace = aws_appautoscaling_target.table_read[0].service_namespace + + target_tracking_scaling_policy_configuration { + predefined_metric_specification { + predefined_metric_type = "DynamoDBReadCapacityUtilization" + } + + scale_in_cooldown = lookup(var.autoscaling_read, "scale_in_cooldown", var.autoscaling_defaults["scale_in_cooldown"]) + scale_out_cooldown = lookup(var.autoscaling_read, "scale_out_cooldown", var.autoscaling_defaults["scale_out_cooldown"]) + target_value = lookup(var.autoscaling_read, "target_value", var.autoscaling_defaults["target_value"]) + } +} + +resource "aws_appautoscaling_target" "table_write" { + count = var.create_table && var.autoscaling_enabled && length(var.autoscaling_write) > 0 ? 1 : 0 + + max_capacity = var.autoscaling_write["max_capacity"] + min_capacity = var.write_capacity + resource_id = "table/${aws_dynamodb_table.autoscaled[0].name}" + scalable_dimension = "dynamodb:table:WriteCapacityUnits" + service_namespace = "dynamodb" +} + +resource "aws_appautoscaling_policy" "table_write_policy" { + count = var.create_table && var.autoscaling_enabled && length(var.autoscaling_write) > 0 ? 1 : 0 + + name = "DynamoDBWriteCapacityUtilization:${aws_appautoscaling_target.table_write[0].resource_id}" + policy_type = "TargetTrackingScaling" + resource_id = aws_appautoscaling_target.table_write[0].resource_id + scalable_dimension = aws_appautoscaling_target.table_write[0].scalable_dimension + service_namespace = aws_appautoscaling_target.table_write[0].service_namespace + + target_tracking_scaling_policy_configuration { + predefined_metric_specification { + predefined_metric_type = "DynamoDBWriteCapacityUtilization" + } + + scale_in_cooldown = lookup(var.autoscaling_write, "scale_in_cooldown", var.autoscaling_defaults["scale_in_cooldown"]) + scale_out_cooldown = lookup(var.autoscaling_write, "scale_out_cooldown", var.autoscaling_defaults["scale_out_cooldown"]) + target_value = lookup(var.autoscaling_write, "target_value", var.autoscaling_defaults["target_value"]) + } +} + +resource "aws_appautoscaling_target" "index_read" { + for_each = var.create_table && var.autoscaling_enabled ? var.autoscaling_indexes : {} + + max_capacity = each.value["read_max_capacity"] + min_capacity = each.value["read_min_capacity"] + resource_id = "table/${aws_dynamodb_table.autoscaled[0].name}/index/${each.key}" + scalable_dimension = "dynamodb:index:ReadCapacityUnits" + service_namespace = "dynamodb" +} + +resource "aws_appautoscaling_policy" "index_read_policy" { + for_each = var.create_table && var.autoscaling_enabled ? var.autoscaling_indexes : {} + + name = "DynamoDBReadCapacityUtilization:${aws_appautoscaling_target.index_read[each.key].resource_id}" + policy_type = "TargetTrackingScaling" + resource_id = aws_appautoscaling_target.index_read[each.key].resource_id + scalable_dimension = aws_appautoscaling_target.index_read[each.key].scalable_dimension + service_namespace = aws_appautoscaling_target.index_read[each.key].service_namespace + + target_tracking_scaling_policy_configuration { + predefined_metric_specification { + predefined_metric_type = "DynamoDBReadCapacityUtilization" + } + + scale_in_cooldown = merge(var.autoscaling_defaults, each.value)["scale_in_cooldown"] + scale_out_cooldown = merge(var.autoscaling_defaults, each.value)["scale_out_cooldown"] + target_value = merge(var.autoscaling_defaults, each.value)["target_value"] + } +} + +resource "aws_appautoscaling_target" "index_write" { + for_each = var.create_table && var.autoscaling_enabled ? var.autoscaling_indexes : {} + + max_capacity = each.value["write_max_capacity"] + min_capacity = each.value["write_min_capacity"] + resource_id = "table/${aws_dynamodb_table.autoscaled[0].name}/index/${each.key}" + scalable_dimension = "dynamodb:index:WriteCapacityUnits" + service_namespace = "dynamodb" +} + +resource "aws_appautoscaling_policy" "index_write_policy" { + for_each = var.create_table && var.autoscaling_enabled ? var.autoscaling_indexes : {} + + name = "DynamoDBWriteCapacityUtilization:${aws_appautoscaling_target.index_write[each.key].resource_id}" + policy_type = "TargetTrackingScaling" + resource_id = aws_appautoscaling_target.index_write[each.key].resource_id + scalable_dimension = aws_appautoscaling_target.index_write[each.key].scalable_dimension + service_namespace = aws_appautoscaling_target.index_write[each.key].service_namespace + + target_tracking_scaling_policy_configuration { + predefined_metric_specification { + predefined_metric_type = "DynamoDBWriteCapacityUtilization" + } + + scale_in_cooldown = merge(var.autoscaling_defaults, each.value)["scale_in_cooldown"] + scale_out_cooldown = merge(var.autoscaling_defaults, each.value)["scale_out_cooldown"] + target_value = merge(var.autoscaling_defaults, each.value)["target_value"] + } +} diff --git a/modules/aws-dynamodb-table/examples/autoscaling/README.md b/modules/aws-dynamodb-table/examples/autoscaling/README.md new file mode 100644 index 0000000..38b33bf --- /dev/null +++ b/modules/aws-dynamodb-table/examples/autoscaling/README.md @@ -0,0 +1,57 @@ +# DynamoDB Table autoscaling example + +Configuration in this directory creates AWS DynamoDB table with autoscaling. Be sure to read [the note](../../README.md#Notes) about autoscaling settings causing the table to be recreated. + +## Usage + +To run this example you need to execute: + +```bash +$ terraform init +$ terraform plan +$ terraform apply +``` + +Note that this example may create resources which can cost money (AWS Elastic IP, for example). Run `terraform destroy` when you don't need these resources. + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.0 | +| [aws](#requirement\_aws) | >= 3.69 | +| [random](#requirement\_random) | >= 2.0 | + +## Providers + +| Name | Version | +|------|---------| +| [random](#provider\_random) | >= 2.0 | + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [disabled\_dynamodb\_table](#module\_disabled\_dynamodb\_table) | ../../ | n/a | +| [dynamodb\_table](#module\_dynamodb\_table) | ../../ | n/a | + +## Resources + +| Name | Type | +|------|------| +| [random_pet.this](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/pet) | resource | + +## Inputs + +No inputs. + +## Outputs + +| Name | Description | +|------|-------------| +| [dynamodb\_table\_arn](#output\_dynamodb\_table\_arn) | ARN of the DynamoDB table | +| [dynamodb\_table\_id](#output\_dynamodb\_table\_id) | ID of the DynamoDB table | +| [dynamodb\_table\_stream\_arn](#output\_dynamodb\_table\_stream\_arn) | The ARN of the Table Stream. Only available when var.stream\_enabled is true | +| [dynamodb\_table\_stream\_label](#output\_dynamodb\_table\_stream\_label) | A timestamp, in ISO 8601 format of the Table Stream. Only available when var.stream\_enabled is true | + diff --git a/modules/aws-dynamodb-table/examples/autoscaling/main.tf b/modules/aws-dynamodb-table/examples/autoscaling/main.tf new file mode 100644 index 0000000..7a57c01 --- /dev/null +++ b/modules/aws-dynamodb-table/examples/autoscaling/main.tf @@ -0,0 +1,80 @@ +provider "aws" { + region = "eu-west-1" +} + +resource "random_pet" "this" { + length = 2 +} + +module "dynamodb_table" { + source = "../../" + + name = "my-table-${random_pet.this.id}" + hash_key = "id" + range_key = "title" + billing_mode = "PROVISIONED" + read_capacity = 5 + write_capacity = 5 + autoscaling_enabled = true + + autoscaling_read = { + scale_in_cooldown = 50 + scale_out_cooldown = 40 + target_value = 45 + max_capacity = 10 + } + + autoscaling_write = { + scale_in_cooldown = 50 + scale_out_cooldown = 40 + target_value = 45 + max_capacity = 10 + } + + autoscaling_indexes = { + TitleIndex = { + read_max_capacity = 30 + read_min_capacity = 10 + write_max_capacity = 30 + write_min_capacity = 10 + } + } + + attributes = [ + { + name = "id" + type = "N" + }, + { + name = "title" + type = "S" + }, + { + name = "age" + type = "N" + } + ] + + global_secondary_indexes = [ + { + name = "TitleIndex" + hash_key = "title" + range_key = "age" + projection_type = "INCLUDE" + non_key_attributes = ["id"] + write_capacity = 10 + read_capacity = 10 + } + ] + + tags = { + Terraform = "true" + Environment = "staging" + } +} + +module "disabled_dynamodb_table" { + source = "../../" + + create_table = false +} diff --git a/modules/aws-dynamodb-table/examples/autoscaling/outputs.tf b/modules/aws-dynamodb-table/examples/autoscaling/outputs.tf new file mode 100644 index 0000000..e21f490 --- /dev/null +++ b/modules/aws-dynamodb-table/examples/autoscaling/outputs.tf @@ -0,0 +1,19 @@ +output "dynamodb_table_arn" { + description = "ARN of the DynamoDB table" + value = module.dynamodb_table.dynamodb_table_arn +} + +output "dynamodb_table_id" { + description = "ID of the DynamoDB table" + value = module.dynamodb_table.dynamodb_table_id +} + +output "dynamodb_table_stream_arn" { + description = "The ARN of the Table Stream. Only available when var.stream_enabled is true" + value = module.dynamodb_table.dynamodb_table_stream_arn +} + +output "dynamodb_table_stream_label" { + description = "A timestamp, in ISO 8601 format of the Table Stream. Only available when var.stream_enabled is true" + value = module.dynamodb_table.dynamodb_table_stream_label +} diff --git a/modules/aws-dynamodb-table/examples/autoscaling/variables.tf b/modules/aws-dynamodb-table/examples/autoscaling/variables.tf new file mode 100644 index 0000000..e69de29 diff --git a/modules/aws-dynamodb-table/examples/autoscaling/versions.tf b/modules/aws-dynamodb-table/examples/autoscaling/versions.tf new file mode 100644 index 0000000..8d7f35e --- /dev/null +++ b/modules/aws-dynamodb-table/examples/autoscaling/versions.tf @@ -0,0 +1,14 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.69" + } + random = { + source = "hashicorp/random" + version = ">= 2.0" + } + } +} diff --git a/modules/aws-dynamodb-table/examples/basic/README.md b/modules/aws-dynamodb-table/examples/basic/README.md new file mode 100644 index 0000000..caf8131 --- /dev/null +++ b/modules/aws-dynamodb-table/examples/basic/README.md @@ -0,0 +1,57 @@ +# DynamoDB Table example + +Configuration in this directory creates AWS DynamoDB table. + +## Usage + +To run this example you need to execute: + +```bash +$ terraform init +$ terraform plan +$ terraform apply +``` + +Note that this example may create resources which can cost money (AWS Elastic IP, for example). Run `terraform destroy` when you don't need these resources. + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.0 | +| [aws](#requirement\_aws) | >= 3.69 | +| [random](#requirement\_random) | >= 2.0 | + +## Providers + +| Name | Version | +|------|---------| +| [random](#provider\_random) | >= 2.0 | + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [disabled\_dynamodb\_table](#module\_disabled\_dynamodb\_table) | ../../ | n/a | +| [dynamodb\_table](#module\_dynamodb\_table) | ../../ | n/a | + +## Resources + +| Name | Type | +|------|------| +| [random_pet.this](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/pet) | resource | + +## Inputs + +No inputs. + +## Outputs + +| Name | Description | +|------|-------------| +| [dynamodb\_table\_arn](#output\_dynamodb\_table\_arn) | ARN of the DynamoDB table | +| [dynamodb\_table\_id](#output\_dynamodb\_table\_id) | ID of the DynamoDB table | +| [dynamodb\_table\_stream\_arn](#output\_dynamodb\_table\_stream\_arn) | The ARN of the Table Stream. Only available when var.stream\_enabled is true | +| [dynamodb\_table\_stream\_label](#output\_dynamodb\_table\_stream\_label) | A timestamp, in ISO 8601 format of the Table Stream. Only available when var.stream\_enabled is true | + diff --git a/modules/aws-dynamodb-table/examples/basic/main.tf b/modules/aws-dynamodb-table/examples/basic/main.tf new file mode 100644 index 0000000..74a103c --- /dev/null +++ b/modules/aws-dynamodb-table/examples/basic/main.tf @@ -0,0 +1,53 @@ +provider "aws" { + region = "eu-west-1" +} + +resource "random_pet" "this" { + length = 2 +} + +module "dynamodb_table" { + source = "../../" + + name = "my-table-${random_pet.this.id}" + hash_key = "id" + range_key = "title" + table_class = "STANDARD" + + attributes = [ + { + name = "id" + type = "N" + }, + { + name = "title" + type = "S" + }, + { + name = "age" + type = "N" + } + ] + + global_secondary_indexes = [ + { + name = "TitleIndex" + hash_key = "title" + range_key = "age" + projection_type = "INCLUDE" + non_key_attributes = ["id"] + } + ] + + tags = { + Terraform = "true" + Environment = "staging" + } +} + + +module "disabled_dynamodb_table" { + source = "../../" + + create_table = false +} diff --git a/modules/aws-dynamodb-table/examples/basic/outputs.tf b/modules/aws-dynamodb-table/examples/basic/outputs.tf new file mode 100644 index 0000000..e21f490 --- /dev/null +++ b/modules/aws-dynamodb-table/examples/basic/outputs.tf @@ -0,0 +1,19 @@ +output "dynamodb_table_arn" { + description = "ARN of the DynamoDB table" + value = module.dynamodb_table.dynamodb_table_arn +} + +output "dynamodb_table_id" { + description = "ID of the DynamoDB table" + value = module.dynamodb_table.dynamodb_table_id +} + +output "dynamodb_table_stream_arn" { + description = "The ARN of the Table Stream. Only available when var.stream_enabled is true" + value = module.dynamodb_table.dynamodb_table_stream_arn +} + +output "dynamodb_table_stream_label" { + description = "A timestamp, in ISO 8601 format of the Table Stream. Only available when var.stream_enabled is true" + value = module.dynamodb_table.dynamodb_table_stream_label +} diff --git a/modules/aws-dynamodb-table/examples/basic/variables.tf b/modules/aws-dynamodb-table/examples/basic/variables.tf new file mode 100644 index 0000000..e69de29 diff --git a/modules/aws-dynamodb-table/examples/basic/versions.tf b/modules/aws-dynamodb-table/examples/basic/versions.tf new file mode 100644 index 0000000..8d7f35e --- /dev/null +++ b/modules/aws-dynamodb-table/examples/basic/versions.tf @@ -0,0 +1,14 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.69" + } + random = { + source = "hashicorp/random" + version = ">= 2.0" + } + } +} diff --git a/modules/aws-dynamodb-table/examples/global-tables/README.md b/modules/aws-dynamodb-table/examples/global-tables/README.md new file mode 100644 index 0000000..94d7af6 --- /dev/null +++ b/modules/aws-dynamodb-table/examples/global-tables/README.md @@ -0,0 +1,60 @@ +# DynamoDB Table example + +Configuration in this directory creates a Global AWS DynamoDB table with replicas in eu-west-1 and eu-west-2 regions. + +## Usage + +To run this example you need to execute: + +```bash +$ terraform init +$ terraform plan +$ terraform apply +``` + +Note that this example may create resources which can cost money (AWS Elastic IP, for example). Run `terraform destroy` when you don't need these resources. + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.0 | +| [aws](#requirement\_aws) | >= 4.23 | +| [random](#requirement\_random) | >= 2.0 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 4.23 | +| [aws.euwest2](#provider\_aws.euwest2) | >= 4.23 | +| [random](#provider\_random) | >= 2.0 | + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [dynamodb\_table](#module\_dynamodb\_table) | ../../ | n/a | + +## Resources + +| Name | Type | +|------|------| +| [aws_kms_key.primary](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | resource | +| [aws_kms_key.secondary](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | resource | +| [random_pet.this](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/pet) | resource | + +## Inputs + +No inputs. + +## Outputs + +| Name | Description | +|------|-------------| +| [dynamodb\_table\_arn](#output\_dynamodb\_table\_arn) | ARN of the DynamoDB table | +| [dynamodb\_table\_id](#output\_dynamodb\_table\_id) | ID of the DynamoDB table | +| [dynamodb\_table\_stream\_arn](#output\_dynamodb\_table\_stream\_arn) | The ARN of the Table Stream. Only available when var.stream\_enabled is true | +| [dynamodb\_table\_stream\_label](#output\_dynamodb\_table\_stream\_label) | A timestamp, in ISO 8601 format of the Table Stream. Only available when var.stream\_enabled is true | + diff --git a/modules/aws-dynamodb-table/examples/global-tables/main.tf b/modules/aws-dynamodb-table/examples/global-tables/main.tf new file mode 100644 index 0000000..b996557 --- /dev/null +++ b/modules/aws-dynamodb-table/examples/global-tables/main.tf @@ -0,0 +1,86 @@ +provider "aws" { + region = "eu-west-1" +} + +provider "aws" { + alias = "euwest2" + region = "eu-west-2" +} + +locals { + tags = { + Terraform = "true" + Environment = "staging" + } +} + +################################################################################ +# Supporting Resources +################################################################################ + +resource "random_pet" "this" { + length = 2 +} + +resource "aws_kms_key" "primary" { + description = "CMK for primary region" + tags = local.tags +} + +resource "aws_kms_key" "secondary" { + provider = aws.euwest2 + + description = "CMK for secondary region" + tags = local.tags +} + +################################################################################ +# DynamoDB Global Table +################################################################################ + +module "dynamodb_table" { + source = "../../" + + name = "my-table-${random_pet.this.id}" + hash_key = "id" + range_key = "title" + stream_enabled = true + stream_view_type = "NEW_AND_OLD_IMAGES" + + server_side_encryption_enabled = true + server_side_encryption_kms_key_arn = aws_kms_key.primary.arn + + attributes = [ + { + name = "id" + type = "N" + }, + { + name = "title" + type = "S" + }, + { + name = "age" + type = "N" + } + ] + + global_secondary_indexes = [ + { + name = "TitleIndex" + hash_key = "title" + range_key = "age" + projection_type = "INCLUDE" + non_key_attributes = ["id"] + } + ] + + replica_regions = [{ + region_name = "eu-west-2" + kms_key_arn = aws_kms_key.secondary.arn + propagate_tags = true + point_in_time_recovery = true + }] + + tags = local.tags +} diff --git a/modules/aws-dynamodb-table/examples/global-tables/outputs.tf b/modules/aws-dynamodb-table/examples/global-tables/outputs.tf new file mode 100644 index 0000000..e21f490 --- /dev/null +++ b/modules/aws-dynamodb-table/examples/global-tables/outputs.tf @@ -0,0 +1,19 @@ +output "dynamodb_table_arn" { + description = "ARN of the DynamoDB table" + value = module.dynamodb_table.dynamodb_table_arn +} + +output "dynamodb_table_id" { + description = "ID of the DynamoDB table" + value = module.dynamodb_table.dynamodb_table_id +} + +output "dynamodb_table_stream_arn" { + description = "The ARN of the Table Stream. Only available when var.stream_enabled is true" + value = module.dynamodb_table.dynamodb_table_stream_arn +} + +output "dynamodb_table_stream_label" { + description = "A timestamp, in ISO 8601 format of the Table Stream. Only available when var.stream_enabled is true" + value = module.dynamodb_table.dynamodb_table_stream_label +} diff --git a/modules/aws-dynamodb-table/examples/global-tables/variables.tf b/modules/aws-dynamodb-table/examples/global-tables/variables.tf new file mode 100644 index 0000000..e69de29 diff --git a/modules/aws-dynamodb-table/examples/global-tables/versions.tf b/modules/aws-dynamodb-table/examples/global-tables/versions.tf new file mode 100644 index 0000000..d2bf143 --- /dev/null +++ b/modules/aws-dynamodb-table/examples/global-tables/versions.tf @@ -0,0 +1,14 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.23" + } + random = { + source = "hashicorp/random" + version = ">= 2.0" + } + } +} diff --git a/modules/aws-dynamodb-table/main.tf b/modules/aws-dynamodb-table/main.tf new file mode 100644 index 0000000..a553f24 --- /dev/null +++ b/modules/aws-dynamodb-table/main.tf @@ -0,0 +1,175 @@ +resource "aws_dynamodb_table" "this" { + count = var.create_table && !var.autoscaling_enabled ? 1 : 0 + + name = var.name + billing_mode = var.billing_mode + hash_key = var.hash_key + range_key = var.range_key + read_capacity = var.read_capacity + write_capacity = var.write_capacity + stream_enabled = var.stream_enabled + stream_view_type = var.stream_view_type + table_class = var.table_class + + ttl { + enabled = var.ttl_enabled + attribute_name = var.ttl_attribute_name + } + + point_in_time_recovery { + enabled = var.point_in_time_recovery_enabled + } + + dynamic "attribute" { + for_each = var.attributes + + content { + name = attribute.value.name + type = attribute.value.type + } + } + + dynamic "local_secondary_index" { + for_each = var.local_secondary_indexes + + content { + name = local_secondary_index.value.name + range_key = local_secondary_index.value.range_key + projection_type = local_secondary_index.value.projection_type + non_key_attributes = lookup(local_secondary_index.value, "non_key_attributes", null) + } + } + + dynamic "global_secondary_index" { + for_each = var.global_secondary_indexes + + content { + name = global_secondary_index.value.name + hash_key = global_secondary_index.value.hash_key + projection_type = global_secondary_index.value.projection_type + range_key = lookup(global_secondary_index.value, "range_key", null) + read_capacity = lookup(global_secondary_index.value, "read_capacity", null) + write_capacity = lookup(global_secondary_index.value, "write_capacity", null) + non_key_attributes = lookup(global_secondary_index.value, "non_key_attributes", null) + } + } + + dynamic "replica" { + for_each = var.replica_regions + + content { + region_name = replica.value.region_name + kms_key_arn = lookup(replica.value, "kms_key_arn", null) + propagate_tags = lookup(replica.value, "propagate_tags", null) + point_in_time_recovery = lookup(replica.value, "point_in_time_recovery", null) + } + } + + server_side_encryption { + enabled = var.server_side_encryption_enabled + kms_key_arn = var.server_side_encryption_kms_key_arn + } + + tags = merge( + var.tags, + { + "Name" = format("%s", var.name) + }, + ) + + timeouts { + create = lookup(var.timeouts, "create", null) + delete = lookup(var.timeouts, "delete", null) + update = lookup(var.timeouts, "update", null) + } +} + +resource "aws_dynamodb_table" "autoscaled" { + count = var.create_table && var.autoscaling_enabled ? 1 : 0 + + name = var.name + billing_mode = var.billing_mode + hash_key = var.hash_key + range_key = var.range_key + read_capacity = var.read_capacity + write_capacity = var.write_capacity + stream_enabled = var.stream_enabled + stream_view_type = var.stream_view_type + table_class = var.table_class + + ttl { + enabled = var.ttl_enabled + attribute_name = var.ttl_attribute_name + } + + point_in_time_recovery { + enabled = var.point_in_time_recovery_enabled + } + + dynamic "attribute" { + for_each = var.attributes + + content { + name = attribute.value.name + type = attribute.value.type + } + } + + dynamic "local_secondary_index" { + for_each = var.local_secondary_indexes + + content { + name = local_secondary_index.value.name + range_key = local_secondary_index.value.range_key + projection_type = local_secondary_index.value.projection_type + non_key_attributes = lookup(local_secondary_index.value, "non_key_attributes", null) + } + } + + dynamic "global_secondary_index" { + for_each = var.global_secondary_indexes + + content { + name = global_secondary_index.value.name + hash_key = global_secondary_index.value.hash_key + projection_type = global_secondary_index.value.projection_type + range_key = lookup(global_secondary_index.value, "range_key", null) + read_capacity = lookup(global_secondary_index.value, "read_capacity", null) + write_capacity = lookup(global_secondary_index.value, "write_capacity", null) + non_key_attributes = lookup(global_secondary_index.value, "non_key_attributes", null) + } + } + + dynamic "replica" { + for_each = var.replica_regions + + content { + region_name = replica.value.region_name + kms_key_arn = lookup(replica.value, "kms_key_arn", null) + propagate_tags = lookup(replica.value, "propagate_tags", null) + point_in_time_recovery = lookup(replica.value, "point_in_time_recovery", null) + } + } + + server_side_encryption { + enabled = var.server_side_encryption_enabled + kms_key_arn = var.server_side_encryption_kms_key_arn + } + + tags = merge( + var.tags, + { + "Name" = format("%s", var.name) + }, + ) + + timeouts { + create = lookup(var.timeouts, "create", null) + delete = lookup(var.timeouts, "delete", null) + update = lookup(var.timeouts, "update", null) + } + + lifecycle { + ignore_changes = [read_capacity, write_capacity] + } +} diff --git a/modules/aws-dynamodb-table/outputs.tf b/modules/aws-dynamodb-table/outputs.tf new file mode 100644 index 0000000..310cfc5 --- /dev/null +++ b/modules/aws-dynamodb-table/outputs.tf @@ -0,0 +1,19 @@ +output "dynamodb_table_arn" { + description = "ARN of the DynamoDB table" + value = try(aws_dynamodb_table.this[0].arn, aws_dynamodb_table.autoscaled[0].arn, "") +} + +output "dynamodb_table_id" { + description = "ID of the DynamoDB table" + value = try(aws_dynamodb_table.this[0].id, aws_dynamodb_table.autoscaled[0].id, "") +} + +output "dynamodb_table_stream_arn" { + description = "The ARN of the Table Stream. Only available when var.stream_enabled is true" + value = var.stream_enabled ? try(aws_dynamodb_table.this[0].stream_arn, aws_dynamodb_table.autoscaled[0].stream_arn, "") : null +} + +output "dynamodb_table_stream_label" { + description = "A timestamp, in ISO 8601 format of the Table Stream. Only available when var.stream_enabled is true" + value = var.stream_enabled ? try(aws_dynamodb_table.this[0].stream_label, aws_dynamodb_table.autoscaled[0].stream_label, "") : null +} diff --git a/modules/aws-dynamodb-table/variables.tf b/modules/aws-dynamodb-table/variables.tf new file mode 100644 index 0000000..0df33ac --- /dev/null +++ b/modules/aws-dynamodb-table/variables.tf @@ -0,0 +1,163 @@ +variable "create_table" { + description = "Controls if DynamoDB table and associated resources are created" + type = bool + default = true +} + +variable "name" { + description = "Name of the DynamoDB table" + type = string + default = null +} + +variable "attributes" { + description = "List of nested attribute definitions. Only required for hash_key and range_key attributes. Each attribute has two properties: name - (Required) The name of the attribute, type - (Required) Attribute type, which must be a scalar type: S, N, or B for (S)tring, (N)umber or (B)inary data" + type = list(map(string)) + default = [] +} + +variable "hash_key" { + description = "The attribute to use as the hash (partition) key. Must also be defined as an attribute" + type = string + default = null +} + +variable "range_key" { + description = "The attribute to use as the range (sort) key. Must also be defined as an attribute" + type = string + default = null +} + +variable "billing_mode" { + description = "Controls how you are billed for read/write throughput and how you manage capacity. The valid values are PROVISIONED or PAY_PER_REQUEST" + type = string + default = "PAY_PER_REQUEST" +} + +variable "write_capacity" { + description = "The number of write units for this table. If the billing_mode is PROVISIONED, this field should be greater than 0" + type = number + default = null +} + +variable "read_capacity" { + description = "The number of read units for this table. If the billing_mode is PROVISIONED, this field should be greater than 0" + type = number + default = null +} + +variable "point_in_time_recovery_enabled" { + description = "Whether to enable point-in-time recovery" + type = bool + default = false +} + +variable "ttl_enabled" { + description = "Indicates whether ttl is enabled" + type = bool + default = false +} + +variable "ttl_attribute_name" { + description = "The name of the table attribute to store the TTL timestamp in" + type = string + default = "" +} + +variable "global_secondary_indexes" { + description = "Describe a GSI for the table; subject to the normal limits on the number of GSIs, projected attributes, etc." + type = any + default = [] +} + +variable "local_secondary_indexes" { + description = "Describe an LSI on the table; these can only be allocated at creation so you cannot change this definition after you have created the resource." + type = any + default = [] +} + +variable "replica_regions" { + description = "Region names for creating replicas for a global DynamoDB table." + type = any + default = [] +} + +variable "stream_enabled" { + description = "Indicates whether Streams are to be enabled (true) or disabled (false)." + type = bool + default = false +} + +variable "stream_view_type" { + description = "When an item in the table is modified, StreamViewType determines what information is written to the table's stream. Valid values are KEYS_ONLY, NEW_IMAGE, OLD_IMAGE, NEW_AND_OLD_IMAGES." + type = string + default = null +} + +variable "server_side_encryption_enabled" { + description = "Whether or not to enable encryption at rest using an AWS managed KMS customer master key (CMK)" + type = bool + default = false +} + +variable "server_side_encryption_kms_key_arn" { + description = "The ARN of the CMK that should be used for the AWS KMS encryption. This attribute should only be specified if the key is different from the default DynamoDB CMK, alias/aws/dynamodb." + type = string + default = null +} + +variable "tags" { + description = "A map of tags to add to all resources" + type = map(string) + default = {} +} + +variable "timeouts" { + description = "Updated Terraform resource management timeouts" + type = map(string) + default = { + create = "10m" + update = "60m" + delete = "10m" + } +} + +variable "autoscaling_enabled" { + description = "Whether or not to enable autoscaling. See note in README about this setting" + type = bool + default = false +} + +variable "autoscaling_defaults" { + description = "A map of default autoscaling settings" + type = map(string) + default = { + scale_in_cooldown = 0 + scale_out_cooldown = 0 + target_value = 70 + } +} + +variable "autoscaling_read" { + description = "A map of read autoscaling settings. `max_capacity` is the only required key. See example in examples/autoscaling" + type = map(string) + default = {} +} + +variable "autoscaling_write" { + description = "A map of write autoscaling settings. `max_capacity` is the only required key. See example in examples/autoscaling" + type = map(string) + default = {} +} + +variable "autoscaling_indexes" { + description = "A map of index autoscaling configurations. See example in examples/autoscaling" + type = map(map(string)) + default = {} +} + +variable "table_class" { + description = "The storage class of the table. Valid values are STANDARD and STANDARD_INFREQUENT_ACCESS" + type = string + default = null +} diff --git a/modules/aws-dynamodb-table/versions.tf b/modules/aws-dynamodb-table/versions.tf new file mode 100644 index 0000000..00dcc2d --- /dev/null +++ b/modules/aws-dynamodb-table/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.23" + } + } +} diff --git a/modules/aws-dynamodb-table/wrappers/README.md b/modules/aws-dynamodb-table/wrappers/README.md new file mode 100644 index 0000000..940634f --- /dev/null +++ b/modules/aws-dynamodb-table/wrappers/README.md @@ -0,0 +1,100 @@ +# Wrapper for the root module + +The configuration in this directory contains an implementation of a single module wrapper pattern, which allows managing several copies of a module in places where using the native Terraform 0.13+ `for_each` feature is not feasible (e.g., with Terragrunt). + +You may want to use a single Terragrunt configuration file to manage multiple resources without duplicating `terragrunt.hcl` files for each copy of the same module. + +This wrapper does not implement any extra functionality. + +## Usage with Terragrunt + +`terragrunt.hcl`: + +```hcl +terraform { + source = "tfr:///terraform-aws-modules/dynamodb-table/aws//wrappers" + # Alternative source: + # source = "git::git@github.com:terraform-aws-modules/terraform-aws-dynamodb-table.git?ref=master//wrappers" +} + +inputs = { + defaults = { # Default values + create = true + tags = { + Terraform = "true" + Environment = "dev" + } + } + + items = { + my-item = { + # omitted... can be any argument supported by the module + } + my-second-item = { + # omitted... can be any argument supported by the module + } + # omitted... + } +} +``` + +## Usage with Terraform + +```hcl +module "wrapper" { + source = "terraform-aws-modules/dynamodb-table/aws//wrappers" + + defaults = { # Default values + create = true + tags = { + Terraform = "true" + Environment = "dev" + } + } + + items = { + my-item = { + # omitted... can be any argument supported by the module + } + my-second-item = { + # omitted... can be any argument supported by the module + } + # omitted... + } +} +``` + +## Example: Manage multiple S3 buckets in one Terragrunt layer + +`eu-west-1/s3-buckets/terragrunt.hcl`: + +```hcl +terraform { + source = "tfr:///terraform-aws-modules/s3-bucket/aws//wrappers" + # Alternative source: + # source = "git::git@github.com:terraform-aws-modules/terraform-aws-s3-bucket.git?ref=master//wrappers" +} + +inputs = { + defaults = { + force_destroy = true + + attach_elb_log_delivery_policy = true + attach_lb_log_delivery_policy = true + attach_deny_insecure_transport_policy = true + attach_require_latest_tls_policy = true + } + + items = { + bucket1 = { + bucket = "my-random-bucket-1" + } + bucket2 = { + bucket = "my-random-bucket-2" + tags = { + Secure = "probably" + } + } + } +} +``` diff --git a/modules/aws-dynamodb-table/wrappers/main.tf b/modules/aws-dynamodb-table/wrappers/main.tf new file mode 100644 index 0000000..407f4fa --- /dev/null +++ b/modules/aws-dynamodb-table/wrappers/main.tf @@ -0,0 +1,40 @@ +module "wrapper" { + source = "../" + + for_each = var.items + + create_table = try(each.value.create_table, var.defaults.create_table, true) + name = try(each.value.name, var.defaults.name, null) + attributes = try(each.value.attributes, var.defaults.attributes, []) + hash_key = try(each.value.hash_key, var.defaults.hash_key, null) + range_key = try(each.value.range_key, var.defaults.range_key, null) + billing_mode = try(each.value.billing_mode, var.defaults.billing_mode, "PAY_PER_REQUEST") + write_capacity = try(each.value.write_capacity, var.defaults.write_capacity, null) + read_capacity = try(each.value.read_capacity, var.defaults.read_capacity, null) + point_in_time_recovery_enabled = try(each.value.point_in_time_recovery_enabled, var.defaults.point_in_time_recovery_enabled, false) + ttl_enabled = try(each.value.ttl_enabled, var.defaults.ttl_enabled, false) + ttl_attribute_name = try(each.value.ttl_attribute_name, var.defaults.ttl_attribute_name, "") + global_secondary_indexes = try(each.value.global_secondary_indexes, var.defaults.global_secondary_indexes, []) + local_secondary_indexes = try(each.value.local_secondary_indexes, var.defaults.local_secondary_indexes, []) + replica_regions = try(each.value.replica_regions, var.defaults.replica_regions, []) + stream_enabled = try(each.value.stream_enabled, var.defaults.stream_enabled, false) + stream_view_type = try(each.value.stream_view_type, var.defaults.stream_view_type, null) + server_side_encryption_enabled = try(each.value.server_side_encryption_enabled, var.defaults.server_side_encryption_enabled, false) + server_side_encryption_kms_key_arn = try(each.value.server_side_encryption_kms_key_arn, var.defaults.server_side_encryption_kms_key_arn, null) + tags = try(each.value.tags, var.defaults.tags, {}) + timeouts = try(each.value.timeouts, var.defaults.timeouts, { + create = "10m" + update = "60m" + delete = "10m" + }) + autoscaling_enabled = try(each.value.autoscaling_enabled, var.defaults.autoscaling_enabled, false) + autoscaling_defaults = try(each.value.autoscaling_defaults, var.defaults.autoscaling_defaults, { + scale_in_cooldown = 0 + scale_out_cooldown = 0 + target_value = 70 + }) + autoscaling_read = try(each.value.autoscaling_read, var.defaults.autoscaling_read, {}) + autoscaling_write = try(each.value.autoscaling_write, var.defaults.autoscaling_write, {}) + autoscaling_indexes = try(each.value.autoscaling_indexes, var.defaults.autoscaling_indexes, {}) + table_class = try(each.value.table_class, var.defaults.table_class, null) +} diff --git a/modules/aws-dynamodb-table/wrappers/outputs.tf b/modules/aws-dynamodb-table/wrappers/outputs.tf new file mode 100644 index 0000000..5da7c09 --- /dev/null +++ b/modules/aws-dynamodb-table/wrappers/outputs.tf @@ -0,0 +1,5 @@ +output "wrapper" { + description = "Map of outputs of a wrapper." + value = module.wrapper + # sensitive = false # No sensitive module output found +} diff --git a/modules/aws-dynamodb-table/wrappers/variables.tf b/modules/aws-dynamodb-table/wrappers/variables.tf new file mode 100644 index 0000000..a6ea096 --- /dev/null +++ b/modules/aws-dynamodb-table/wrappers/variables.tf @@ -0,0 +1,11 @@ +variable "defaults" { + description = "Map of default values which will be used for each item." + type = any + default = {} +} + +variable "items" { + description = "Maps of items to create a wrapper from. Values are passed through to the module." + type = any + default = {} +} diff --git a/modules/aws-dynamodb-table/wrappers/versions.tf b/modules/aws-dynamodb-table/wrappers/versions.tf new file mode 100644 index 0000000..51cad10 --- /dev/null +++ b/modules/aws-dynamodb-table/wrappers/versions.tf @@ -0,0 +1,3 @@ +terraform { + required_version = ">= 0.13.1" +} diff --git a/modules/aws-ec2-instance/README.md b/modules/aws-ec2-instance/README.md new file mode 100644 index 0000000..4c01414 --- /dev/null +++ b/modules/aws-ec2-instance/README.md @@ -0,0 +1,297 @@ +# AWS EC2 Instance Terraform module + +Terraform module which creates an EC2 instance on AWS. + +## Usage + +### Single EC2 Instance + +```hcl +module "ec2_instance" { + source = "terraform-aws-modules/ec2-instance/aws" + + name = "single-instance" + + instance_type = "t2.micro" + key_name = "user1" + monitoring = true + vpc_security_group_ids = ["sg-12345678"] + subnet_id = "subnet-eddcdzz4" + + tags = { + Terraform = "true" + Environment = "dev" + } +} +``` + +### Multiple EC2 Instance + +```hcl +module "ec2_instance" { + source = "terraform-aws-modules/ec2-instance/aws" + + for_each = toset(["one", "two", "three"]) + + name = "instance-${each.key}" + + instance_type = "t2.micro" + key_name = "user1" + monitoring = true + vpc_security_group_ids = ["sg-12345678"] + subnet_id = "subnet-eddcdzz4" + + tags = { + Terraform = "true" + Environment = "dev" + } +} +``` + +### Spot EC2 Instance + +```hcl +module "ec2_instance" { + source = "terraform-aws-modules/ec2-instance/aws" + + name = "spot-instance" + + create_spot_instance = true + spot_price = "0.60" + spot_type = "persistent" + + instance_type = "t2.micro" + key_name = "user1" + monitoring = true + vpc_security_group_ids = ["sg-12345678"] + subnet_id = "subnet-eddcdzz4" + + tags = { + Terraform = "true" + Environment = "dev" + } +} +``` + +## Module wrappers + +Users of this Terraform module can create multiple similar resources by using [`for_each` meta-argument within `module` block](https://www.terraform.io/language/meta-arguments/for_each) which became available in Terraform 0.13. + +Users of Terragrunt can achieve similar results by using modules provided in the [wrappers](https://github.com/terraform-aws-modules/terraform-aws-ec2-instance/tree/master/wrappers) directory, if they prefer to reduce amount of configuration files. + +## Examples + +- [Complete EC2 instance](https://github.com/terraform-aws-modules/terraform-aws-ec2-instance/tree/master/examples/complete) +- [EC2 instance with EBS volume attachment](https://github.com/terraform-aws-modules/terraform-aws-ec2-instance/tree/master/examples/volume-attachment) + +## Make an encrypted AMI for use + +This module does not support encrypted AMI's out of the box however it is easy enough for you to generate one for use + +This example creates an encrypted image from the latest ubuntu 16.04 base image. + +```hcl +provider "aws" { + region = "us-west-2" +} + +data "aws_ami" "ubuntu" { + most_recent = true + owners = ["679593333241"] + + filter { + name = "name" + values = ["ubuntu-minimal/images/hvm-ssd/ubuntu-focal-20.04-*"] + } + + filter { + name = "virtualization-type" + values = ["hvm"] + } +} + +resource "aws_ami_copy" "ubuntu_encrypted_ami" { + name = "ubuntu-encrypted-ami" + description = "An encrypted root ami based off ${data.aws_ami.ubuntu.id}" + source_ami_id = data.aws_ami.ubuntu.id + source_ami_region = "eu-west-2" + encrypted = true + + tags = { Name = "ubuntu-encrypted-ami" } +} + +data "aws_ami" "encrypted-ami" { + most_recent = true + + filter { + name = "name" + values = [aws_ami_copy.ubuntu_encrypted_ami.id] + } + + owners = ["self"] +} +``` + +## Conditional creation + +The following combinations are supported to conditionally create resources: + +- Disable resource creation (no resources created): + +```hcl + create = false +``` + +- Create spot instance: + +```hcl + create_spot_instance = true +``` + +## Notes + +- `network_interface` can't be specified together with `vpc_security_group_ids`, `associate_public_ip_address`, `subnet_id`. See [complete example](https://github.com/terraform-aws-modules/terraform-aws-ec2-instance/tree/master/examples/complete) for details. +- Changes in `ebs_block_device` argument will be ignored. Use [aws_volume_attachment](https://www.terraform.io/docs/providers/aws/r/volume_attachment.html) resource to attach and detach volumes from AWS EC2 instances. See [this example](https://github.com/terraform-aws-modules/terraform-aws-ec2-instance/tree/master/examples/volume-attachment). +- In regards to spot instances, you must grant the `AWSServiceRoleForEC2Spot` service-linked role access to any custom KMS keys, otherwise your spot request and instances will fail with `bad parameters`. You can see more details about why the request failed by using the awscli and `aws ec2 describe-spot-instance-requests` + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.0 | +| [aws](#requirement\_aws) | >= 4.66 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 4.66 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_iam_instance_profile.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_instance_profile) | resource | +| [aws_iam_role.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | +| [aws_iam_role_policy_attachment.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_instance.ignore_ami](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance) | resource | +| [aws_instance.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance) | resource | +| [aws_spot_instance_request.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/spot_instance_request) | resource | +| [aws_iam_policy_document.assume_role_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_partition.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/partition) | data source | +| [aws_ssm_parameter.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ssm_parameter) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [ami](#input\_ami) | ID of AMI to use for the instance | `string` | `null` | no | +| [ami\_ssm\_parameter](#input\_ami\_ssm\_parameter) | SSM parameter name for the AMI ID. For Amazon Linux AMI SSM parameters see [reference](https://docs.aws.amazon.com/systems-manager/latest/userguide/parameter-store-public-parameters-ami.html) | `string` | `"/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2"` | no | +| [associate\_public\_ip\_address](#input\_associate\_public\_ip\_address) | Whether to associate a public IP address with an instance in a VPC | `bool` | `null` | no | +| [availability\_zone](#input\_availability\_zone) | AZ to start the instance in | `string` | `null` | no | +| [capacity\_reservation\_specification](#input\_capacity\_reservation\_specification) | Describes an instance's Capacity Reservation targeting option | `any` | `{}` | no | +| [cpu\_core\_count](#input\_cpu\_core\_count) | Sets the number of CPU cores for an instance | `number` | `null` | no | +| [cpu\_credits](#input\_cpu\_credits) | The credit option for CPU usage (unlimited or standard) | `string` | `null` | no | +| [cpu\_options](#input\_cpu\_options) | Defines CPU options to apply to the instance at launch time. | `any` | `{}` | no | +| [cpu\_threads\_per\_core](#input\_cpu\_threads\_per\_core) | Sets the number of CPU threads per core for an instance (has no effect unless cpu\_core\_count is also set) | `number` | `null` | no | +| [create](#input\_create) | Whether to create an instance | `bool` | `true` | no | +| [create\_iam\_instance\_profile](#input\_create\_iam\_instance\_profile) | Determines whether an IAM instance profile is created or to use an existing IAM instance profile | `bool` | `false` | no | +| [create\_spot\_instance](#input\_create\_spot\_instance) | Depicts if the instance is a spot instance | `bool` | `false` | no | +| [disable\_api\_stop](#input\_disable\_api\_stop) | If true, enables EC2 Instance Stop Protection | `bool` | `null` | no | +| [disable\_api\_termination](#input\_disable\_api\_termination) | If true, enables EC2 Instance Termination Protection | `bool` | `null` | no | +| [ebs\_block\_device](#input\_ebs\_block\_device) | Additional EBS block devices to attach to the instance | `list(any)` | `[]` | no | +| [ebs\_optimized](#input\_ebs\_optimized) | If true, the launched EC2 instance will be EBS-optimized | `bool` | `null` | no | +| [enable\_volume\_tags](#input\_enable\_volume\_tags) | Whether to enable volume tags (if enabled it conflicts with root\_block\_device tags) | `bool` | `true` | no | +| [enclave\_options\_enabled](#input\_enclave\_options\_enabled) | Whether Nitro Enclaves will be enabled on the instance. Defaults to `false` | `bool` | `null` | no | +| [ephemeral\_block\_device](#input\_ephemeral\_block\_device) | Customize Ephemeral (also known as Instance Store) volumes on the instance | `list(map(string))` | `[]` | no | +| [get\_password\_data](#input\_get\_password\_data) | If true, wait for password data to become available and retrieve it | `bool` | `null` | no | +| [hibernation](#input\_hibernation) | If true, the launched EC2 instance will support hibernation | `bool` | `null` | no | +| [host\_id](#input\_host\_id) | ID of a dedicated host that the instance will be assigned to. Use when an instance is to be launched on a specific dedicated host | `string` | `null` | no | +| [iam\_instance\_profile](#input\_iam\_instance\_profile) | IAM Instance Profile to launch the instance with. Specified as the name of the Instance Profile | `string` | `null` | no | +| [iam\_role\_description](#input\_iam\_role\_description) | Description of the role | `string` | `null` | no | +| [iam\_role\_name](#input\_iam\_role\_name) | Name to use on IAM role created | `string` | `null` | no | +| [iam\_role\_path](#input\_iam\_role\_path) | IAM role path | `string` | `null` | no | +| [iam\_role\_permissions\_boundary](#input\_iam\_role\_permissions\_boundary) | ARN of the policy that is used to set the permissions boundary for the IAM role | `string` | `null` | no | +| [iam\_role\_policies](#input\_iam\_role\_policies) | Policies attached to the IAM role | `map(string)` | `{}` | no | +| [iam\_role\_tags](#input\_iam\_role\_tags) | A map of additional tags to add to the IAM role/profile created | `map(string)` | `{}` | no | +| [iam\_role\_use\_name\_prefix](#input\_iam\_role\_use\_name\_prefix) | Determines whether the IAM role name (`iam_role_name` or `name`) is used as a prefix | `bool` | `true` | no | +| [ignore\_ami\_changes](#input\_ignore\_ami\_changes) | Whether changes to the AMI ID changes should be ignored by Terraform. Note - changing this value will result in the replacement of the instance | `bool` | `false` | no | +| [instance\_initiated\_shutdown\_behavior](#input\_instance\_initiated\_shutdown\_behavior) | Shutdown behavior for the instance. Amazon defaults this to stop for EBS-backed instances and terminate for instance-store instances. Cannot be set on instance-store instance | `string` | `null` | no | +| [instance\_tags](#input\_instance\_tags) | Additional tags for the instance | `map(string)` | `{}` | no | +| [instance\_type](#input\_instance\_type) | The type of instance to start | `string` | `"t3.micro"` | no | +| [ipv6\_address\_count](#input\_ipv6\_address\_count) | A number of IPv6 addresses to associate with the primary network interface. Amazon EC2 chooses the IPv6 addresses from the range of your subnet | `number` | `null` | no | +| [ipv6\_addresses](#input\_ipv6\_addresses) | Specify one or more IPv6 addresses from the range of the subnet to associate with the primary network interface | `list(string)` | `null` | no | +| [key\_name](#input\_key\_name) | Key name of the Key Pair to use for the instance; which can be managed using the `aws_key_pair` resource | `string` | `null` | no | +| [launch\_template](#input\_launch\_template) | Specifies a Launch Template to configure the instance. Parameters configured on this resource will override the corresponding parameters in the Launch Template | `map(string)` | `{}` | no | +| [maintenance\_options](#input\_maintenance\_options) | The maintenance options for the instance | `any` | `{}` | no | +| [metadata\_options](#input\_metadata\_options) | Customize the metadata options of the instance | `map(string)` |
"create": "10m",
"delete": "10m",
"update": "60m"
}
{| no | +| [monitoring](#input\_monitoring) | If true, the launched EC2 instance will have detailed monitoring enabled | `bool` | `null` | no | +| [name](#input\_name) | Name to be used on EC2 instance created | `string` | `""` | no | +| [network\_interface](#input\_network\_interface) | Customize network interfaces to be attached at instance boot time | `list(map(string))` | `[]` | no | +| [placement\_group](#input\_placement\_group) | The Placement Group to start the instance in | `string` | `null` | no | +| [private\_ip](#input\_private\_ip) | Private IP address to associate with the instance in a VPC | `string` | `null` | no | +| [root\_block\_device](#input\_root\_block\_device) | Customize details about the root block device of the instance. See Block Devices below for details | `list(any)` | `[]` | no | +| [secondary\_private\_ips](#input\_secondary\_private\_ips) | A list of secondary private IPv4 addresses to assign to the instance's primary network interface (eth0) in a VPC. Can only be assigned to the primary network interface (eth0) attached at instance creation, not a pre-existing network interface i.e. referenced in a `network_interface block` | `list(string)` | `null` | no | +| [source\_dest\_check](#input\_source\_dest\_check) | Controls if traffic is routed to the instance when the destination address does not match the instance. Used for NAT or VPNs | `bool` | `null` | no | +| [spot\_block\_duration\_minutes](#input\_spot\_block\_duration\_minutes) | The required duration for the Spot instances, in minutes. This value must be a multiple of 60 (60, 120, 180, 240, 300, or 360) | `number` | `null` | no | +| [spot\_instance\_interruption\_behavior](#input\_spot\_instance\_interruption\_behavior) | Indicates Spot instance behavior when it is interrupted. Valid values are `terminate`, `stop`, or `hibernate` | `string` | `null` | no | +| [spot\_launch\_group](#input\_spot\_launch\_group) | A launch group is a group of spot instances that launch together and terminate together. If left empty instances are launched and terminated individually | `string` | `null` | no | +| [spot\_price](#input\_spot\_price) | The maximum price to request on the spot market. Defaults to on-demand price | `string` | `null` | no | +| [spot\_type](#input\_spot\_type) | If set to one-time, after the instance is terminated, the spot request will be closed. Default `persistent` | `string` | `null` | no | +| [spot\_valid\_from](#input\_spot\_valid\_from) | The start date and time of the request, in UTC RFC3339 format(for example, YYYY-MM-DDTHH:MM:SSZ) | `string` | `null` | no | +| [spot\_valid\_until](#input\_spot\_valid\_until) | The end date and time of the request, in UTC RFC3339 format(for example, YYYY-MM-DDTHH:MM:SSZ) | `string` | `null` | no | +| [spot\_wait\_for\_fulfillment](#input\_spot\_wait\_for\_fulfillment) | If set, Terraform will wait for the Spot Request to be fulfilled, and will throw an error if the timeout of 10m is reached | `bool` | `null` | no | +| [subnet\_id](#input\_subnet\_id) | The VPC Subnet ID to launch in | `string` | `null` | no | +| [tags](#input\_tags) | A mapping of tags to assign to the resource | `map(string)` | `{}` | no | +| [tenancy](#input\_tenancy) | The tenancy of the instance (if the instance is running in a VPC). Available values: default, dedicated, host | `string` | `null` | no | +| [timeouts](#input\_timeouts) | Define maximum timeout for creating, updating, and deleting EC2 instance resources | `map(string)` | `{}` | no | +| [user\_data](#input\_user\_data) | The user data to provide when launching the instance. Do not pass gzip-compressed data via this argument; see user\_data\_base64 instead | `string` | `null` | no | +| [user\_data\_base64](#input\_user\_data\_base64) | Can be used instead of user\_data to pass base64-encoded binary data directly. Use this instead of user\_data whenever the value is not a valid UTF-8 string. For example, gzip-encoded user data must be base64-encoded and passed via this argument to avoid corruption | `string` | `null` | no | +| [user\_data\_replace\_on\_change](#input\_user\_data\_replace\_on\_change) | When used in combination with user\_data or user\_data\_base64 will trigger a destroy and recreate when set to true. Defaults to false if not set | `bool` | `null` | no | +| [volume\_tags](#input\_volume\_tags) | A mapping of tags to assign to the devices created by the instance at launch time | `map(string)` | `{}` | no | +| [vpc\_security\_group\_ids](#input\_vpc\_security\_group\_ids) | A list of security group IDs to associate with | `list(string)` | `null` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [ami](#output\_ami) | AMI ID that was used to create the instance | +| [arn](#output\_arn) | The ARN of the instance | +| [capacity\_reservation\_specification](#output\_capacity\_reservation\_specification) | Capacity reservation specification of the instance | +| [ebs\_block\_device](#output\_ebs\_block\_device) | EBS block device information | +| [ephemeral\_block\_device](#output\_ephemeral\_block\_device) | Ephemeral block device information | +| [iam\_instance\_profile\_arn](#output\_iam\_instance\_profile\_arn) | ARN assigned by AWS to the instance profile | +| [iam\_instance\_profile\_id](#output\_iam\_instance\_profile\_id) | Instance profile's ID | +| [iam\_instance\_profile\_unique](#output\_iam\_instance\_profile\_unique) | Stable and unique string identifying the IAM instance profile | +| [iam\_role\_arn](#output\_iam\_role\_arn) | The Amazon Resource Name (ARN) specifying the IAM role | +| [iam\_role\_name](#output\_iam\_role\_name) | The name of the IAM role | +| [iam\_role\_unique\_id](#output\_iam\_role\_unique\_id) | Stable and unique string identifying the IAM role | +| [id](#output\_id) | The ID of the instance | +| [instance\_state](#output\_instance\_state) | The state of the instance | +| [ipv6\_addresses](#output\_ipv6\_addresses) | The IPv6 address assigned to the instance, if applicable | +| [outpost\_arn](#output\_outpost\_arn) | The ARN of the Outpost the instance is assigned to | +| [password\_data](#output\_password\_data) | Base-64 encoded encrypted password data for the instance. Useful for getting the administrator password for instances running Microsoft Windows. This attribute is only exported if `get_password_data` is true | +| [primary\_network\_interface\_id](#output\_primary\_network\_interface\_id) | The ID of the instance's primary network interface | +| [private\_dns](#output\_private\_dns) | The private DNS name assigned to the instance. Can only be used inside the Amazon EC2, and only available if you've enabled DNS hostnames for your VPC | +| [private\_ip](#output\_private\_ip) | The private IP address assigned to the instance | +| [public\_dns](#output\_public\_dns) | The public DNS name assigned to the instance. For EC2-VPC, this is only available if you've enabled DNS hostnames for your VPC | +| [public\_ip](#output\_public\_ip) | The public IP address assigned to the instance, if applicable. NOTE: If you are using an aws\_eip with your instance, you should refer to the EIP's address directly and not use `public_ip` as this field will change after the EIP is attached | +| [root\_block\_device](#output\_root\_block\_device) | Root block device information | +| [spot\_bid\_status](#output\_spot\_bid\_status) | The current bid status of the Spot Instance Request | +| [spot\_instance\_id](#output\_spot\_instance\_id) | The Instance ID (if any) that is currently fulfilling the Spot Instance request | +| [spot\_request\_state](#output\_spot\_request\_state) | The current request state of the Spot Instance Request | +| [tags\_all](#output\_tags\_all) | A map of tags assigned to the resource, including those inherited from the provider default\_tags configuration block | + + +## Authors + +Module is maintained by [Anton Babenko](https://github.com/antonbabenko) with help from [these awesome contributors](https://github.com/terraform-aws-modules/terraform-aws-ec2-instance/graphs/contributors). + +## License + +Apache 2 Licensed. See [LICENSE](https://github.com/terraform-aws-modules/terraform-aws-ec2-instance/tree/master/LICENSE) for full details. diff --git a/modules/aws-ec2-instance/examples/README.md b/modules/aws-ec2-instance/examples/README.md new file mode 100644 index 0000000..f417c0a --- /dev/null +++ b/modules/aws-ec2-instance/examples/README.md @@ -0,0 +1,8 @@ +# Examples + +Please note - the examples provided serve two primary means: + +1. Show users working examples of the various ways in which the module can be configured and features supported +2. A means of testing/validating module changes + +Please do not mistake the examples provided as "best practices". It is up to users to consult the AWS service documentation for best practices, usage recommendations, etc. diff --git a/modules/aws-ec2-instance/examples/complete/README.md b/modules/aws-ec2-instance/examples/complete/README.md new file mode 100644 index 0000000..9fa60b3 --- /dev/null +++ b/modules/aws-ec2-instance/examples/complete/README.md @@ -0,0 +1,121 @@ +# Complete EC2 instance + +Configuration in this directory creates EC2 instances with different sets of arguments (with Elastic IP, with network interface attached, with credit specifications). + +## Usage + +To run this example you need to execute: + +```bash +$ terraform init +$ terraform plan +$ terraform apply +``` + +Note that this example may create resources which can cost money. Run `terraform destroy` when you don't need these resources. + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.0 | +| [aws](#requirement\_aws) | >= 4.66 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 4.66 | + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [ec2\_complete](#module\_ec2\_complete) | ../../ | n/a | +| [ec2\_cpu\_options](#module\_ec2\_cpu\_options) | ../../ | n/a | +| [ec2\_disabled](#module\_ec2\_disabled) | ../../ | n/a | +| [ec2\_ignore\_ami\_changes](#module\_ec2\_ignore\_ami\_changes) | ../../ | n/a | +| [ec2\_metadata\_options](#module\_ec2\_metadata\_options) | ../../ | n/a | +| [ec2\_multiple](#module\_ec2\_multiple) | ../../ | n/a | +| [ec2\_network\_interface](#module\_ec2\_network\_interface) | ../../ | n/a | +| [ec2\_open\_capacity\_reservation](#module\_ec2\_open\_capacity\_reservation) | ../../ | n/a | +| [ec2\_spot\_instance](#module\_ec2\_spot\_instance) | ../../ | n/a | +| [ec2\_t2\_unlimited](#module\_ec2\_t2\_unlimited) | ../../ | n/a | +| [ec2\_t3\_unlimited](#module\_ec2\_t3\_unlimited) | ../../ | n/a | +| [ec2\_targeted\_capacity\_reservation](#module\_ec2\_targeted\_capacity\_reservation) | ../../ | n/a | +| [security\_group](#module\_security\_group) | terraform-aws-modules/security-group/aws | ~> 4.0 | +| [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 5.0 | + +## Resources + +| Name | Type | +|------|------| +| [aws_ec2_capacity_reservation.open](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ec2_capacity_reservation) | resource | +| [aws_ec2_capacity_reservation.targeted](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ec2_capacity_reservation) | resource | +| [aws_kms_key.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | resource | +| [aws_network_interface.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/network_interface) | resource | +| [aws_placement_group.web](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/placement_group) | resource | +| [aws_ami.amazon_linux](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ami) | data source | +| [aws_ami.amazon_linux_23](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ami) | data source | +| [aws_availability_zones.available](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/availability_zones) | data source | + +## Inputs + +No inputs. + +## Outputs + +| Name | Description | +|------|-------------| +| [ec2\_complete\_arn](#output\_ec2\_complete\_arn) | The ARN of the instance | +| [ec2\_complete\_capacity\_reservation\_specification](#output\_ec2\_complete\_capacity\_reservation\_specification) | Capacity reservation specification of the instance | +| [ec2\_complete\_ebs\_block\_device](#output\_ec2\_complete\_ebs\_block\_device) | EBS block device information | +| [ec2\_complete\_ephemeral\_block\_device](#output\_ec2\_complete\_ephemeral\_block\_device) | Ephemeral block device information | +| [ec2\_complete\_iam\_instance\_profile\_arn](#output\_ec2\_complete\_iam\_instance\_profile\_arn) | ARN assigned by AWS to the instance profile | +| [ec2\_complete\_iam\_instance\_profile\_id](#output\_ec2\_complete\_iam\_instance\_profile\_id) | Instance profile's ID | +| [ec2\_complete\_iam\_instance\_profile\_unique](#output\_ec2\_complete\_iam\_instance\_profile\_unique) | Stable and unique string identifying the IAM instance profile | +| [ec2\_complete\_iam\_role\_arn](#output\_ec2\_complete\_iam\_role\_arn) | The Amazon Resource Name (ARN) specifying the IAM role | +| [ec2\_complete\_iam\_role\_name](#output\_ec2\_complete\_iam\_role\_name) | The name of the IAM role | +| [ec2\_complete\_iam\_role\_unique\_id](#output\_ec2\_complete\_iam\_role\_unique\_id) | Stable and unique string identifying the IAM role | +| [ec2\_complete\_id](#output\_ec2\_complete\_id) | The ID of the instance | +| [ec2\_complete\_instance\_state](#output\_ec2\_complete\_instance\_state) | The state of the instance. One of: `pending`, `running`, `shutting-down`, `terminated`, `stopping`, `stopped` | +| [ec2\_complete\_primary\_network\_interface\_id](#output\_ec2\_complete\_primary\_network\_interface\_id) | The ID of the instance's primary network interface | +| [ec2\_complete\_private\_dns](#output\_ec2\_complete\_private\_dns) | The private DNS name assigned to the instance. Can only be used inside the Amazon EC2, and only available if you've enabled DNS hostnames for your VPC | +| [ec2\_complete\_public\_dns](#output\_ec2\_complete\_public\_dns) | The public DNS name assigned to the instance. For EC2-VPC, this is only available if you've enabled DNS hostnames for your VPC | +| [ec2\_complete\_public\_ip](#output\_ec2\_complete\_public\_ip) | The public IP address assigned to the instance, if applicable. NOTE: If you are using an aws\_eip with your instance, you should refer to the EIP's address directly and not use `public_ip` as this field will change after the EIP is attached | +| [ec2\_complete\_root\_block\_device](#output\_ec2\_complete\_root\_block\_device) | Root block device information | +| [ec2\_complete\_tags\_all](#output\_ec2\_complete\_tags\_all) | A map of tags assigned to the resource, including those inherited from the provider default\_tags configuration block | +| [ec2\_ignore\_ami\_changes\_ami](#output\_ec2\_ignore\_ami\_changes\_ami) | The AMI of the instance (ignore\_ami\_changes = true) | +| [ec2\_multiple](#output\_ec2\_multiple) | The full output of the `ec2_module` module | +| [ec2\_spot\_instance\_arn](#output\_ec2\_spot\_instance\_arn) | The ARN of the instance | +| [ec2\_spot\_instance\_capacity\_reservation\_specification](#output\_ec2\_spot\_instance\_capacity\_reservation\_specification) | Capacity reservation specification of the instance | +| [ec2\_spot\_instance\_id](#output\_ec2\_spot\_instance\_id) | The ID of the instance | +| [ec2\_spot\_instance\_instance\_state](#output\_ec2\_spot\_instance\_instance\_state) | The state of the instance. One of: `pending`, `running`, `shutting-down`, `terminated`, `stopping`, `stopped` | +| [ec2\_spot\_instance\_primary\_network\_interface\_id](#output\_ec2\_spot\_instance\_primary\_network\_interface\_id) | The ID of the instance's primary network interface | +| [ec2\_spot\_instance\_private\_dns](#output\_ec2\_spot\_instance\_private\_dns) | The private DNS name assigned to the instance. Can only be used inside the Amazon EC2, and only available if you've enabled DNS hostnames for your VPC | +| [ec2\_spot\_instance\_public\_dns](#output\_ec2\_spot\_instance\_public\_dns) | The public DNS name assigned to the instance. For EC2-VPC, this is only available if you've enabled DNS hostnames for your VPC | +| [ec2\_spot\_instance\_public\_ip](#output\_ec2\_spot\_instance\_public\_ip) | The public IP address assigned to the instance, if applicable. NOTE: If you are using an aws\_eip with your instance, you should refer to the EIP's address directly and not use `public_ip` as this field will change after the EIP is attached | +| [ec2\_spot\_instance\_tags\_all](#output\_ec2\_spot\_instance\_tags\_all) | A map of tags assigned to the resource, including those inherited from the provider default\_tags configuration block | +| [ec2\_t2\_unlimited\_arn](#output\_ec2\_t2\_unlimited\_arn) | The ARN of the instance | +| [ec2\_t2\_unlimited\_capacity\_reservation\_specification](#output\_ec2\_t2\_unlimited\_capacity\_reservation\_specification) | Capacity reservation specification of the instance | +| [ec2\_t2\_unlimited\_id](#output\_ec2\_t2\_unlimited\_id) | The ID of the instance | +| [ec2\_t2\_unlimited\_instance\_state](#output\_ec2\_t2\_unlimited\_instance\_state) | The state of the instance. One of: `pending`, `running`, `shutting-down`, `terminated`, `stopping`, `stopped` | +| [ec2\_t2\_unlimited\_primary\_network\_interface\_id](#output\_ec2\_t2\_unlimited\_primary\_network\_interface\_id) | The ID of the instance's primary network interface | +| [ec2\_t2\_unlimited\_private\_dns](#output\_ec2\_t2\_unlimited\_private\_dns) | The private DNS name assigned to the instance. Can only be used inside the Amazon EC2, and only available if you've enabled DNS hostnames for your VPC | +| [ec2\_t2\_unlimited\_public\_dns](#output\_ec2\_t2\_unlimited\_public\_dns) | The public DNS name assigned to the instance. For EC2-VPC, this is only available if you've enabled DNS hostnames for your VPC | +| [ec2\_t2\_unlimited\_public\_ip](#output\_ec2\_t2\_unlimited\_public\_ip) | The public IP address assigned to the instance, if applicable. NOTE: If you are using an aws\_eip with your instance, you should refer to the EIP's address directly and not use `public_ip` as this field will change after the EIP is attached | +| [ec2\_t2\_unlimited\_tags\_all](#output\_ec2\_t2\_unlimited\_tags\_all) | A map of tags assigned to the resource, including those inherited from the provider default\_tags configuration block | +| [ec2\_t3\_unlimited\_arn](#output\_ec2\_t3\_unlimited\_arn) | The ARN of the instance | +| [ec2\_t3\_unlimited\_capacity\_reservation\_specification](#output\_ec2\_t3\_unlimited\_capacity\_reservation\_specification) | Capacity reservation specification of the instance | +| [ec2\_t3\_unlimited\_id](#output\_ec2\_t3\_unlimited\_id) | The ID of the instance | +| [ec2\_t3\_unlimited\_instance\_state](#output\_ec2\_t3\_unlimited\_instance\_state) | The state of the instance. One of: `pending`, `running`, `shutting-down`, `terminated`, `stopping`, `stopped` | +| [ec2\_t3\_unlimited\_primary\_network\_interface\_id](#output\_ec2\_t3\_unlimited\_primary\_network\_interface\_id) | The ID of the instance's primary network interface | +| [ec2\_t3\_unlimited\_private\_dns](#output\_ec2\_t3\_unlimited\_private\_dns) | The private DNS name assigned to the instance. Can only be used inside the Amazon EC2, and only available if you've enabled DNS hostnames for your VPC | +| [ec2\_t3\_unlimited\_public\_dns](#output\_ec2\_t3\_unlimited\_public\_dns) | The public DNS name assigned to the instance. For EC2-VPC, this is only available if you've enabled DNS hostnames for your VPC | +| [ec2\_t3\_unlimited\_public\_ip](#output\_ec2\_t3\_unlimited\_public\_ip) | The public IP address assigned to the instance, if applicable. NOTE: If you are using an aws\_eip with your instance, you should refer to the EIP's address directly and not use `public_ip` as this field will change after the EIP is attached | +| [ec2\_t3\_unlimited\_tags\_all](#output\_ec2\_t3\_unlimited\_tags\_all) | A map of tags assigned to the resource, including those inherited from the provider default\_tags configuration block | +| [spot\_bid\_status](#output\_spot\_bid\_status) | The current bid status of the Spot Instance Request | +| [spot\_instance\_id](#output\_spot\_instance\_id) | The Instance ID (if any) that is currently fulfilling the Spot Instance request | +| [spot\_request\_state](#output\_spot\_request\_state) | The current request state of the Spot Instance Request | + diff --git a/modules/aws-ec2-instance/examples/complete/main.tf b/modules/aws-ec2-instance/examples/complete/main.tf new file mode 100644 index 0000000..25baae5 --- /dev/null +++ b/modules/aws-ec2-instance/examples/complete/main.tf @@ -0,0 +1,485 @@ +provider "aws" { + region = local.region +} + +data "aws_availability_zones" "available" {} + +locals { + name = "ex-${basename(path.cwd)}" + region = "eu-west-1" + + vpc_cidr = "10.0.0.0/16" + azs = slice(data.aws_availability_zones.available.names, 0, 3) + + user_data = <<-EOT + #!/bin/bash + echo "Hello Terraform!" + EOT + + tags = { + Name = local.name + Example = local.name + Repository = "https://github.com/terraform-aws-modules/terraform-aws-ec2-instance" + } +} + +################################################################################ +# EC2 Module +################################################################################ + +module "ec2_complete" { + source = "../../" + + name = local.name + + ami = data.aws_ami.amazon_linux.id + instance_type = "c5.xlarge" # used to set core count below + availability_zone = element(module.vpc.azs, 0) + subnet_id = element(module.vpc.private_subnets, 0) + vpc_security_group_ids = [module.security_group.security_group_id] + placement_group = aws_placement_group.web.id + associate_public_ip_address = true + disable_api_stop = false + + create_iam_instance_profile = true + iam_role_description = "IAM role for EC2 instance" + iam_role_policies = { + AdministratorAccess = "arn:aws:iam::aws:policy/AdministratorAccess" + } + + # only one of these can be enabled at a time + hibernation = true + # enclave_options_enabled = true + + user_data_base64 = base64encode(local.user_data) + user_data_replace_on_change = true + + cpu_options = { + core_count = 2 + threads_per_core = 1 + } + enable_volume_tags = false + root_block_device = [ + { + encrypted = true + volume_type = "gp3" + throughput = 200 + volume_size = 50 + tags = { + Name = "my-root-block" + } + }, + ] + + ebs_block_device = [ + { + device_name = "/dev/sdf" + volume_type = "gp3" + volume_size = 5 + throughput = 200 + encrypted = true + kms_key_id = aws_kms_key.this.arn + tags = { + MountPoint = "/mnt/data" + } + } + ] + + tags = local.tags +} + +module "ec2_network_interface" { + source = "../../" + + name = "${local.name}-network-interface" + + network_interface = [ + { + device_index = 0 + network_interface_id = aws_network_interface.this.id + delete_on_termination = false + } + ] + + tags = local.tags +} + +module "ec2_metadata_options" { + source = "../../" + + name = "${local.name}-metadata-options" + + subnet_id = element(module.vpc.private_subnets, 0) + vpc_security_group_ids = [module.security_group.security_group_id] + + metadata_options = { + http_endpoint = "enabled" + http_tokens = "required" + http_put_response_hop_limit = 8 + instance_metadata_tags = "enabled" + } + + tags = local.tags +} + +module "ec2_t2_unlimited" { + source = "../../" + + name = "${local.name}-t2-unlimited" + + instance_type = "t2.micro" + cpu_credits = "unlimited" + subnet_id = element(module.vpc.private_subnets, 0) + vpc_security_group_ids = [module.security_group.security_group_id] + associate_public_ip_address = true + + maintenance_options = { + auto_recovery = "default" + } + + tags = local.tags +} + +module "ec2_t3_unlimited" { + source = "../../" + + name = "${local.name}-t3-unlimited" + + instance_type = "t3.micro" + cpu_credits = "unlimited" + subnet_id = element(module.vpc.private_subnets, 0) + vpc_security_group_ids = [module.security_group.security_group_id] + associate_public_ip_address = true + + tags = local.tags +} + +module "ec2_disabled" { + source = "../../" + + create = false +} + +################################################################################ +# EC2 Module - with ignore AMI changes +################################################################################ + +module "ec2_ignore_ami_changes" { + source = "../../" + + name = local.name + + ignore_ami_changes = true + + ami = data.aws_ami.amazon_linux.id + instance_type = "t2.micro" + availability_zone = element(module.vpc.azs, 0) + subnet_id = element(module.vpc.private_subnets, 0) + vpc_security_group_ids = [module.security_group.security_group_id] + + tags = local.tags +} + +################################################################################ +# EC2 Module - multiple instances with `for_each` +################################################################################ + +locals { + multiple_instances = { + one = { + instance_type = "t3.micro" + availability_zone = element(module.vpc.azs, 0) + subnet_id = element(module.vpc.private_subnets, 0) + root_block_device = [ + { + encrypted = true + volume_type = "gp3" + throughput = 200 + volume_size = 50 + tags = { + Name = "my-root-block" + } + } + ] + } + two = { + instance_type = "t3.small" + availability_zone = element(module.vpc.azs, 1) + subnet_id = element(module.vpc.private_subnets, 1) + root_block_device = [ + { + encrypted = true + volume_type = "gp2" + volume_size = 50 + } + ] + } + three = { + instance_type = "t3.medium" + availability_zone = element(module.vpc.azs, 2) + subnet_id = element(module.vpc.private_subnets, 2) + } + } +} + +module "ec2_multiple" { + source = "../../" + + for_each = local.multiple_instances + + name = "${local.name}-multi-${each.key}" + + instance_type = each.value.instance_type + availability_zone = each.value.availability_zone + subnet_id = each.value.subnet_id + vpc_security_group_ids = [module.security_group.security_group_id] + + enable_volume_tags = false + root_block_device = lookup(each.value, "root_block_device", []) + + tags = local.tags +} + +################################################################################ +# EC2 Module - spot instance request +################################################################################ + +module "ec2_spot_instance" { + source = "../../" + + name = "${local.name}-spot-instance" + create_spot_instance = true + + availability_zone = element(module.vpc.azs, 0) + subnet_id = element(module.vpc.private_subnets, 0) + vpc_security_group_ids = [module.security_group.security_group_id] + associate_public_ip_address = true + + # Spot request specific attributes + spot_price = "0.1" + spot_wait_for_fulfillment = true + spot_type = "persistent" + spot_instance_interruption_behavior = "terminate" + # End spot request specific attributes + + user_data_base64 = base64encode(local.user_data) + + cpu_options = { + core_count = 2 + threads_per_core = 1 + } + + enable_volume_tags = false + root_block_device = [ + { + encrypted = true + volume_type = "gp3" + throughput = 200 + volume_size = 50 + tags = { + Name = "my-root-block" + } + }, + ] + + ebs_block_device = [ + { + device_name = "/dev/sdf" + volume_type = "gp3" + volume_size = 5 + throughput = 200 + encrypted = true + # kms_key_id = aws_kms_key.this.arn # you must grant the AWSServiceRoleForEC2Spot service-linked role access to any custom KMS keys + } + ] + + tags = local.tags +} + +################################################################################ +# EC2 Module - Capacity Reservation +################################################################################ + +module "ec2_open_capacity_reservation" { + source = "../../" + + name = "${local.name}-open-capacity-reservation" + + ami = data.aws_ami.amazon_linux.id + instance_type = "t3.micro" + subnet_id = element(module.vpc.private_subnets, 0) + vpc_security_group_ids = [module.security_group.security_group_id] + associate_public_ip_address = false + + capacity_reservation_specification = { + capacity_reservation_target = { + capacity_reservation_id = aws_ec2_capacity_reservation.open.id + } + } + + tags = local.tags +} + +module "ec2_targeted_capacity_reservation" { + source = "../../" + + name = "${local.name}-targeted-capacity-reservation" + + ami = data.aws_ami.amazon_linux.id + instance_type = "t3.micro" + subnet_id = element(module.vpc.private_subnets, 0) + vpc_security_group_ids = [module.security_group.security_group_id] + associate_public_ip_address = false + + capacity_reservation_specification = { + capacity_reservation_target = { + capacity_reservation_id = aws_ec2_capacity_reservation.targeted.id + } + } + + tags = local.tags +} + +resource "aws_ec2_capacity_reservation" "open" { + instance_type = "t3.micro" + instance_platform = "Linux/UNIX" + availability_zone = "${local.region}a" + instance_count = 1 + instance_match_criteria = "open" +} + +resource "aws_ec2_capacity_reservation" "targeted" { + instance_type = "t3.micro" + instance_platform = "Linux/UNIX" + availability_zone = "${local.region}a" + instance_count = 1 + instance_match_criteria = "targeted" +} + +################################################################################ +# EC2 Module - CPU Options +################################################################################ +module "ec2_cpu_options" { + source = "../../" + + name = "${local.name}-cpu-options" + + ami = data.aws_ami.amazon_linux_23.id + instance_type = "c6a.xlarge" # used to set core count below and test amd_sev_snp attribute + availability_zone = element(module.vpc.azs, 0) + subnet_id = element(module.vpc.private_subnets, 0) + vpc_security_group_ids = [module.security_group.security_group_id] + placement_group = aws_placement_group.web.id + associate_public_ip_address = true + disable_api_stop = false + + create_iam_instance_profile = true + iam_role_description = "IAM role for EC2 instance" + iam_role_policies = { + AdministratorAccess = "arn:aws:iam::aws:policy/AdministratorAccess" + } + + user_data_base64 = base64encode(local.user_data) + user_data_replace_on_change = true + + cpu_options = { + core_count = 2 + threads_per_core = 1 + amd_sev_snp = "enabled" + } + enable_volume_tags = false + root_block_device = [ + { + encrypted = true + volume_type = "gp3" + throughput = 200 + volume_size = 50 + tags = { + Name = "my-root-block" + } + }, + ] + + ebs_block_device = [ + { + device_name = "/dev/sdf" + volume_type = "gp3" + volume_size = 5 + throughput = 200 + encrypted = true + kms_key_id = aws_kms_key.this.arn + tags = { + MountPoint = "/mnt/data" + } + } + ] + + instance_tags = { Persistence = "09:00-18:00" } + + tags = local.tags +} + +################################################################################ +# Supporting Resources +################################################################################ + +module "vpc" { + source = "terraform-aws-modules/vpc/aws" + version = "~> 5.0" + + name = local.name + cidr = local.vpc_cidr + + azs = local.azs + private_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 4, k)] + public_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 48)] + + tags = local.tags +} + +data "aws_ami" "amazon_linux" { + most_recent = true + owners = ["amazon"] + + filter { + name = "name" + values = ["amzn-ami-hvm-*-x86_64-gp2"] + } +} + +data "aws_ami" "amazon_linux_23" { + most_recent = true + owners = ["amazon"] + + filter { + name = "name" + values = ["al2023-ami-2023*-x86_64"] + } +} + +module "security_group" { + source = "terraform-aws-modules/security-group/aws" + version = "~> 4.0" + + name = local.name + description = "Security group for example usage with EC2 instance" + vpc_id = module.vpc.vpc_id + + ingress_cidr_blocks = ["0.0.0.0/0"] + ingress_rules = ["http-80-tcp", "all-icmp"] + egress_rules = ["all-all"] + + tags = local.tags +} + +resource "aws_placement_group" "web" { + name = local.name + strategy = "cluster" +} + +resource "aws_kms_key" "this" { +} + +resource "aws_network_interface" "this" { + subnet_id = element(module.vpc.private_subnets, 0) +} diff --git a/modules/aws-ec2-instance/examples/complete/outputs.tf b/modules/aws-ec2-instance/examples/complete/outputs.tf new file mode 100644 index 0000000..1ce36b8 --- /dev/null +++ b/modules/aws-ec2-instance/examples/complete/outputs.tf @@ -0,0 +1,255 @@ +# EC2 Complete +output "ec2_complete_id" { + description = "The ID of the instance" + value = module.ec2_complete.id +} + +output "ec2_complete_arn" { + description = "The ARN of the instance" + value = module.ec2_complete.arn +} + +output "ec2_complete_capacity_reservation_specification" { + description = "Capacity reservation specification of the instance" + value = module.ec2_complete.capacity_reservation_specification +} + +output "ec2_complete_instance_state" { + description = "The state of the instance. One of: `pending`, `running`, `shutting-down`, `terminated`, `stopping`, `stopped`" + value = module.ec2_complete.instance_state +} + +output "ec2_complete_primary_network_interface_id" { + description = "The ID of the instance's primary network interface" + value = module.ec2_complete.primary_network_interface_id +} + +output "ec2_complete_private_dns" { + description = "The private DNS name assigned to the instance. Can only be used inside the Amazon EC2, and only available if you've enabled DNS hostnames for your VPC" + value = module.ec2_complete.private_dns +} + +output "ec2_complete_public_dns" { + description = "The public DNS name assigned to the instance. For EC2-VPC, this is only available if you've enabled DNS hostnames for your VPC" + value = module.ec2_complete.public_dns +} + +output "ec2_complete_public_ip" { + description = "The public IP address assigned to the instance, if applicable. NOTE: If you are using an aws_eip with your instance, you should refer to the EIP's address directly and not use `public_ip` as this field will change after the EIP is attached" + value = module.ec2_complete.public_ip +} + +output "ec2_complete_tags_all" { + description = "A map of tags assigned to the resource, including those inherited from the provider default_tags configuration block" + value = module.ec2_complete.tags_all +} + +output "ec2_complete_iam_role_name" { + description = "The name of the IAM role" + value = module.ec2_complete.iam_role_name +} + +output "ec2_complete_iam_role_arn" { + description = "The Amazon Resource Name (ARN) specifying the IAM role" + value = module.ec2_complete.iam_role_arn +} + +output "ec2_complete_iam_role_unique_id" { + description = "Stable and unique string identifying the IAM role" + value = module.ec2_complete.iam_role_unique_id +} + +output "ec2_complete_iam_instance_profile_arn" { + description = "ARN assigned by AWS to the instance profile" + value = module.ec2_complete.iam_instance_profile_arn +} + +output "ec2_complete_iam_instance_profile_id" { + description = "Instance profile's ID" + value = module.ec2_complete.iam_instance_profile_id +} + +output "ec2_complete_iam_instance_profile_unique" { + description = "Stable and unique string identifying the IAM instance profile" + value = module.ec2_complete.iam_instance_profile_unique +} + +output "ec2_complete_root_block_device" { + description = "Root block device information" + value = module.ec2_complete.root_block_device +} + +output "ec2_complete_ebs_block_device" { + description = "EBS block device information" + value = module.ec2_complete.ebs_block_device +} + +output "ec2_complete_ephemeral_block_device" { + description = "Ephemeral block device information" + value = module.ec2_complete.ephemeral_block_device +} + +# EC2 T2 Unlimited +output "ec2_t2_unlimited_id" { + description = "The ID of the instance" + value = module.ec2_t2_unlimited.id +} + +output "ec2_t2_unlimited_arn" { + description = "The ARN of the instance" + value = module.ec2_t2_unlimited.arn +} + +output "ec2_t2_unlimited_capacity_reservation_specification" { + description = "Capacity reservation specification of the instance" + value = module.ec2_t2_unlimited.capacity_reservation_specification +} + +output "ec2_t2_unlimited_instance_state" { + description = "The state of the instance. One of: `pending`, `running`, `shutting-down`, `terminated`, `stopping`, `stopped`" + value = module.ec2_t2_unlimited.instance_state +} + +output "ec2_t2_unlimited_primary_network_interface_id" { + description = "The ID of the instance's primary network interface" + value = module.ec2_t2_unlimited.primary_network_interface_id +} + +output "ec2_t2_unlimited_private_dns" { + description = "The private DNS name assigned to the instance. Can only be used inside the Amazon EC2, and only available if you've enabled DNS hostnames for your VPC" + value = module.ec2_t2_unlimited.private_dns +} + +output "ec2_t2_unlimited_public_dns" { + description = "The public DNS name assigned to the instance. For EC2-VPC, this is only available if you've enabled DNS hostnames for your VPC" + value = module.ec2_t2_unlimited.public_dns +} + +output "ec2_t2_unlimited_public_ip" { + description = "The public IP address assigned to the instance, if applicable. NOTE: If you are using an aws_eip with your instance, you should refer to the EIP's address directly and not use `public_ip` as this field will change after the EIP is attached" + value = module.ec2_t2_unlimited.public_ip +} + +output "ec2_t2_unlimited_tags_all" { + description = "A map of tags assigned to the resource, including those inherited from the provider default_tags configuration block" + value = module.ec2_t2_unlimited.tags_all +} + +# EC2 T3 Unlimited +output "ec2_t3_unlimited_id" { + description = "The ID of the instance" + value = module.ec2_t3_unlimited.id +} + +output "ec2_t3_unlimited_arn" { + description = "The ARN of the instance" + value = module.ec2_t3_unlimited.arn +} + +output "ec2_t3_unlimited_capacity_reservation_specification" { + description = "Capacity reservation specification of the instance" + value = module.ec2_t3_unlimited.capacity_reservation_specification +} + +output "ec2_t3_unlimited_instance_state" { + description = "The state of the instance. One of: `pending`, `running`, `shutting-down`, `terminated`, `stopping`, `stopped`" + value = module.ec2_t3_unlimited.instance_state +} + +output "ec2_t3_unlimited_primary_network_interface_id" { + description = "The ID of the instance's primary network interface" + value = module.ec2_t3_unlimited.primary_network_interface_id +} + +output "ec2_t3_unlimited_private_dns" { + description = "The private DNS name assigned to the instance. Can only be used inside the Amazon EC2, and only available if you've enabled DNS hostnames for your VPC" + value = module.ec2_t3_unlimited.private_dns +} + +output "ec2_t3_unlimited_public_dns" { + description = "The public DNS name assigned to the instance. For EC2-VPC, this is only available if you've enabled DNS hostnames for your VPC" + value = module.ec2_t3_unlimited.public_dns +} + +output "ec2_t3_unlimited_public_ip" { + description = "The public IP address assigned to the instance, if applicable. NOTE: If you are using an aws_eip with your instance, you should refer to the EIP's address directly and not use `public_ip` as this field will change after the EIP is attached" + value = module.ec2_t3_unlimited.public_ip +} + +output "ec2_t3_unlimited_tags_all" { + description = "A map of tags assigned to the resource, including those inherited from the provider default_tags configuration block" + value = module.ec2_t3_unlimited.tags_all +} + +# EC2 with ignore AMI changes +output "ec2_ignore_ami_changes_ami" { + description = "The AMI of the instance (ignore_ami_changes = true)" + value = module.ec2_ignore_ami_changes.ami +} + +# EC2 Multiple +output "ec2_multiple" { + description = "The full output of the `ec2_module` module" + value = module.ec2_multiple +} + +# EC2 Spot Instance +output "ec2_spot_instance_id" { + description = "The ID of the instance" + value = module.ec2_spot_instance.id +} + +output "ec2_spot_instance_arn" { + description = "The ARN of the instance" + value = module.ec2_spot_instance.arn +} + +output "ec2_spot_instance_capacity_reservation_specification" { + description = "Capacity reservation specification of the instance" + value = module.ec2_spot_instance.capacity_reservation_specification +} + +output "ec2_spot_instance_instance_state" { + description = "The state of the instance. One of: `pending`, `running`, `shutting-down`, `terminated`, `stopping`, `stopped`" + value = module.ec2_spot_instance.instance_state +} + +output "ec2_spot_instance_primary_network_interface_id" { + description = "The ID of the instance's primary network interface" + value = module.ec2_spot_instance.primary_network_interface_id +} + +output "ec2_spot_instance_private_dns" { + description = "The private DNS name assigned to the instance. Can only be used inside the Amazon EC2, and only available if you've enabled DNS hostnames for your VPC" + value = module.ec2_spot_instance.private_dns +} + +output "ec2_spot_instance_public_dns" { + description = "The public DNS name assigned to the instance. For EC2-VPC, this is only available if you've enabled DNS hostnames for your VPC" + value = module.ec2_spot_instance.public_dns +} + +output "ec2_spot_instance_public_ip" { + description = "The public IP address assigned to the instance, if applicable. NOTE: If you are using an aws_eip with your instance, you should refer to the EIP's address directly and not use `public_ip` as this field will change after the EIP is attached" + value = module.ec2_spot_instance.public_ip +} + +output "ec2_spot_instance_tags_all" { + description = "A map of tags assigned to the resource, including those inherited from the provider default_tags configuration block" + value = module.ec2_spot_instance.tags_all +} + +output "spot_bid_status" { + description = "The current bid status of the Spot Instance Request" + value = module.ec2_spot_instance.spot_bid_status +} + +output "spot_request_state" { + description = "The current request state of the Spot Instance Request" + value = module.ec2_spot_instance.spot_request_state +} + +output "spot_instance_id" { + description = "The Instance ID (if any) that is currently fulfilling the Spot Instance request" + value = module.ec2_spot_instance.spot_instance_id +} diff --git a/modules/aws-ec2-instance/examples/complete/variables.tf b/modules/aws-ec2-instance/examples/complete/variables.tf new file mode 100644 index 0000000..e69de29 diff --git a/modules/aws-ec2-instance/examples/complete/versions.tf b/modules/aws-ec2-instance/examples/complete/versions.tf new file mode 100644 index 0000000..fd4d116 --- /dev/null +++ b/modules/aws-ec2-instance/examples/complete/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.66" + } + } +} diff --git a/modules/aws-ec2-instance/examples/volume-attachment/README.md b/modules/aws-ec2-instance/examples/volume-attachment/README.md new file mode 100644 index 0000000..adede89 --- /dev/null +++ b/modules/aws-ec2-instance/examples/volume-attachment/README.md @@ -0,0 +1,67 @@ +# EC2 instance with EBS volume attachment + +Configuration in this directory creates EC2 instances, EBS volume and attach it together. + +This example outputs instance id and EBS volume id. + +## Usage + +To run this example you need to execute: + +```bash +$ terraform init +$ terraform plan +$ terraform apply +``` + +Note that this example may create resources which can cost money. Run `terraform destroy` when you don't need these resources. + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.0 | +| [aws](#requirement\_aws) | >= 4.20 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 4.20 | + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [ec2](#module\_ec2) | ../../ | n/a | +| [security\_group](#module\_security\_group) | terraform-aws-modules/security-group/aws | ~> 4.0 | +| [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 4.0 | + +## Resources + +| Name | Type | +|------|------| +| [aws_ebs_volume.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ebs_volume) | resource | +| [aws_volume_attachment.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/volume_attachment) | resource | +| [aws_ami.amazon_linux](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ami) | data source | +| [aws_availability_zones.available](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/availability_zones) | data source | + +## Inputs + +No inputs. + +## Outputs + +| Name | Description | +|------|-------------| +| [ec2\_arn](#output\_ec2\_arn) | The ARN of the instance | +| [ec2\_capacity\_reservation\_specification](#output\_ec2\_capacity\_reservation\_specification) | Capacity reservation specification of the instance | +| [ec2\_id](#output\_ec2\_id) | The ID of the instance | +| [ec2\_instance\_state](#output\_ec2\_instance\_state) | The state of the instance. One of: `pending`, `running`, `shutting-down`, `terminated`, `stopping`, `stopped` | +| [ec2\_primary\_network\_interface\_id](#output\_ec2\_primary\_network\_interface\_id) | The ID of the instance's primary network interface | +| [ec2\_private\_dns](#output\_ec2\_private\_dns) | The private DNS name assigned to the instance. Can only be used inside the Amazon EC2, and only available if you've enabled DNS hostnames for your VPC | +| [ec2\_public\_dns](#output\_ec2\_public\_dns) | The public DNS name assigned to the instance. For EC2-VPC, this is only available if you've enabled DNS hostnames for your VPC | +| [ec2\_public\_ip](#output\_ec2\_public\_ip) | The public IP address assigned to the instance, if applicable. NOTE: If you are using an aws\_eip with your instance, you should refer to the EIP's address directly and not use `public_ip` as this field will change after the EIP is attached | +| [ec2\_tags\_all](#output\_ec2\_tags\_all) | A map of tags assigned to the resource, including those inherited from the provider default\_tags configuration block | + diff --git a/modules/aws-ec2-instance/examples/volume-attachment/main.tf b/modules/aws-ec2-instance/examples/volume-attachment/main.tf new file mode 100644 index 0000000..f201cad --- /dev/null +++ b/modules/aws-ec2-instance/examples/volume-attachment/main.tf @@ -0,0 +1,94 @@ +provider "aws" { + region = local.region +} + +data "aws_availability_zones" "available" {} + +locals { + name = "ex-${basename(path.cwd)}" + region = "eu-west-1" + + vpc_cidr = "10.0.0.0/16" + azs = slice(data.aws_availability_zones.available.names, 0, 3) + + tags = { + Name = local.name + Example = local.name + Repository = "https://github.com/terraform-aws-modules/terraform-aws-ec2-instance" + } +} + +################################################################################ +# EC2 Module +################################################################################ + +module "ec2" { + source = "../../" + + name = local.name + + ami = data.aws_ami.amazon_linux.id + instance_type = "c5.large" + availability_zone = element(local.azs, 0) + subnet_id = element(module.vpc.private_subnets, 0) + vpc_security_group_ids = [module.security_group.security_group_id] + associate_public_ip_address = true + + tags = local.tags +} + +resource "aws_volume_attachment" "this" { + device_name = "/dev/sdh" + volume_id = aws_ebs_volume.this.id + instance_id = module.ec2.id +} + +resource "aws_ebs_volume" "this" { + availability_zone = element(local.azs, 0) + size = 1 + + tags = local.tags +} + +################################################################################ +# Supporting Resources +################################################################################ + +module "vpc" { + source = "terraform-aws-modules/vpc/aws" + version = "~> 4.0" + + name = local.name + cidr = local.vpc_cidr + + azs = local.azs + private_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 4, k)] + public_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 48)] + + tags = local.tags +} + +data "aws_ami" "amazon_linux" { + most_recent = true + owners = ["amazon"] + + filter { + name = "name" + values = ["amzn-ami-hvm-*-x86_64-gp2"] + } +} + +module "security_group" { + source = "terraform-aws-modules/security-group/aws" + version = "~> 4.0" + + name = local.name + description = "Security group for example usage with EC2 instance" + vpc_id = module.vpc.vpc_id + + ingress_cidr_blocks = ["0.0.0.0/0"] + ingress_rules = ["http-80-tcp", "all-icmp"] + egress_rules = ["all-all"] + + tags = local.tags +} diff --git a/modules/aws-ec2-instance/examples/volume-attachment/outputs.tf b/modules/aws-ec2-instance/examples/volume-attachment/outputs.tf new file mode 100644 index 0000000..d9304a3 --- /dev/null +++ b/modules/aws-ec2-instance/examples/volume-attachment/outputs.tf @@ -0,0 +1,45 @@ +# EC2 +output "ec2_id" { + description = "The ID of the instance" + value = module.ec2.id +} + +output "ec2_arn" { + description = "The ARN of the instance" + value = module.ec2.arn +} + +output "ec2_capacity_reservation_specification" { + description = "Capacity reservation specification of the instance" + value = module.ec2.capacity_reservation_specification +} + +output "ec2_instance_state" { + description = "The state of the instance. One of: `pending`, `running`, `shutting-down`, `terminated`, `stopping`, `stopped`" + value = module.ec2.instance_state +} + +output "ec2_primary_network_interface_id" { + description = "The ID of the instance's primary network interface" + value = module.ec2.primary_network_interface_id +} + +output "ec2_private_dns" { + description = "The private DNS name assigned to the instance. Can only be used inside the Amazon EC2, and only available if you've enabled DNS hostnames for your VPC" + value = module.ec2.private_dns +} + +output "ec2_public_dns" { + description = "The public DNS name assigned to the instance. For EC2-VPC, this is only available if you've enabled DNS hostnames for your VPC" + value = module.ec2.public_dns +} + +output "ec2_public_ip" { + description = "The public IP address assigned to the instance, if applicable. NOTE: If you are using an aws_eip with your instance, you should refer to the EIP's address directly and not use `public_ip` as this field will change after the EIP is attached" + value = module.ec2.public_ip +} + +output "ec2_tags_all" { + description = "A map of tags assigned to the resource, including those inherited from the provider default_tags configuration block" + value = module.ec2.tags_all +} diff --git a/modules/aws-ec2-instance/examples/volume-attachment/variables.tf b/modules/aws-ec2-instance/examples/volume-attachment/variables.tf new file mode 100644 index 0000000..e69de29 diff --git a/modules/aws-ec2-instance/examples/volume-attachment/versions.tf b/modules/aws-ec2-instance/examples/volume-attachment/versions.tf new file mode 100644 index 0000000..eddf9d5 --- /dev/null +++ b/modules/aws-ec2-instance/examples/volume-attachment/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.20" + } + } +} diff --git a/modules/aws-ec2-instance/main.tf b/modules/aws-ec2-instance/main.tf new file mode 100644 index 0000000..b7548c3 --- /dev/null +++ b/modules/aws-ec2-instance/main.tf @@ -0,0 +1,583 @@ +data "aws_partition" "current" {} + +locals { + create = var.create && var.putin_khuylo + + is_t_instance_type = replace(var.instance_type, "/^t(2|3|3a|4g){1}\\..*$/", "1") == "1" ? true : false +} + +data "aws_ssm_parameter" "this" { + count = local.create ? 1 : 0 + + name = var.ami_ssm_parameter +} + +################################################################################ +# Instance +################################################################################ + +resource "aws_instance" "this" { + count = local.create && !var.ignore_ami_changes && !var.create_spot_instance ? 1 : 0 + + ami = try(coalesce(var.ami, nonsensitive(data.aws_ssm_parameter.this[0].value)), null) + instance_type = var.instance_type + cpu_core_count = var.cpu_core_count + cpu_threads_per_core = var.cpu_threads_per_core + hibernation = var.hibernation + + user_data = var.user_data + user_data_base64 = var.user_data_base64 + user_data_replace_on_change = var.user_data_replace_on_change + + availability_zone = var.availability_zone + subnet_id = var.subnet_id + vpc_security_group_ids = var.vpc_security_group_ids + + key_name = var.key_name + monitoring = var.monitoring + get_password_data = var.get_password_data + iam_instance_profile = var.create_iam_instance_profile ? aws_iam_instance_profile.this[0].name : var.iam_instance_profile + + associate_public_ip_address = var.associate_public_ip_address + private_ip = var.private_ip + secondary_private_ips = var.secondary_private_ips + ipv6_address_count = var.ipv6_address_count + ipv6_addresses = var.ipv6_addresses + + ebs_optimized = var.ebs_optimized + + dynamic "cpu_options" { + for_each = length(var.cpu_options) > 0 ? [var.cpu_options] : [] + + content { + core_count = try(cpu_options.value.core_count, null) + threads_per_core = try(cpu_options.value.threads_per_core, null) + amd_sev_snp = try(cpu_options.value.amd_sev_snp, null) + } + } + + dynamic "capacity_reservation_specification" { + for_each = length(var.capacity_reservation_specification) > 0 ? [var.capacity_reservation_specification] : [] + + content { + capacity_reservation_preference = try(capacity_reservation_specification.value.capacity_reservation_preference, null) + + dynamic "capacity_reservation_target" { + for_each = try([capacity_reservation_specification.value.capacity_reservation_target], []) + + content { + capacity_reservation_id = try(capacity_reservation_target.value.capacity_reservation_id, null) + capacity_reservation_resource_group_arn = try(capacity_reservation_target.value.capacity_reservation_resource_group_arn, null) + } + } + } + } + + dynamic "root_block_device" { + for_each = var.root_block_device + + content { + delete_on_termination = try(root_block_device.value.delete_on_termination, null) + encrypted = try(root_block_device.value.encrypted, null) + iops = try(root_block_device.value.iops, null) + kms_key_id = lookup(root_block_device.value, "kms_key_id", null) + volume_size = try(root_block_device.value.volume_size, null) + volume_type = try(root_block_device.value.volume_type, null) + throughput = try(root_block_device.value.throughput, null) + tags = try(root_block_device.value.tags, null) + } + } + + dynamic "ebs_block_device" { + for_each = var.ebs_block_device + + content { + delete_on_termination = try(ebs_block_device.value.delete_on_termination, null) + device_name = ebs_block_device.value.device_name + encrypted = try(ebs_block_device.value.encrypted, null) + iops = try(ebs_block_device.value.iops, null) + kms_key_id = lookup(ebs_block_device.value, "kms_key_id", null) + snapshot_id = lookup(ebs_block_device.value, "snapshot_id", null) + volume_size = try(ebs_block_device.value.volume_size, null) + volume_type = try(ebs_block_device.value.volume_type, null) + throughput = try(ebs_block_device.value.throughput, null) + tags = try(ebs_block_device.value.tags, null) + } + } + + dynamic "ephemeral_block_device" { + for_each = var.ephemeral_block_device + + content { + device_name = ephemeral_block_device.value.device_name + no_device = try(ephemeral_block_device.value.no_device, null) + virtual_name = try(ephemeral_block_device.value.virtual_name, null) + } + } + + dynamic "metadata_options" { + for_each = length(var.metadata_options) > 0 ? [var.metadata_options] : [] + + content { + http_endpoint = try(metadata_options.value.http_endpoint, "enabled") + http_tokens = try(metadata_options.value.http_tokens, "optional") + http_put_response_hop_limit = try(metadata_options.value.http_put_response_hop_limit, 1) + instance_metadata_tags = try(metadata_options.value.instance_metadata_tags, null) + } + } + + dynamic "network_interface" { + for_each = var.network_interface + + content { + device_index = network_interface.value.device_index + network_interface_id = lookup(network_interface.value, "network_interface_id", null) + delete_on_termination = try(network_interface.value.delete_on_termination, false) + } + } + + dynamic "launch_template" { + for_each = length(var.launch_template) > 0 ? [var.launch_template] : [] + + content { + id = lookup(var.launch_template, "id", null) + name = lookup(var.launch_template, "name", null) + version = lookup(var.launch_template, "version", null) + } + } + + dynamic "maintenance_options" { + for_each = length(var.maintenance_options) > 0 ? [var.maintenance_options] : [] + + content { + auto_recovery = try(maintenance_options.value.auto_recovery, null) + } + } + + enclave_options { + enabled = var.enclave_options_enabled + } + + source_dest_check = length(var.network_interface) > 0 ? null : var.source_dest_check + disable_api_termination = var.disable_api_termination + disable_api_stop = var.disable_api_stop + instance_initiated_shutdown_behavior = var.instance_initiated_shutdown_behavior + placement_group = var.placement_group + tenancy = var.tenancy + host_id = var.host_id + + credit_specification { + cpu_credits = local.is_t_instance_type ? var.cpu_credits : null + } + + timeouts { + create = try(var.timeouts.create, null) + update = try(var.timeouts.update, null) + delete = try(var.timeouts.delete, null) + } + + tags = merge({ "Name" = var.name }, var.instance_tags, var.tags) + volume_tags = var.enable_volume_tags ? merge({ "Name" = var.name }, var.volume_tags) : null +} + +################################################################################ +# Instance - Ignore AMI Changes +################################################################################ + +resource "aws_instance" "ignore_ami" { + count = local.create && var.ignore_ami_changes && !var.create_spot_instance ? 1 : 0 + + ami = try(coalesce(var.ami, nonsensitive(data.aws_ssm_parameter.this[0].value)), null) + instance_type = var.instance_type + cpu_core_count = var.cpu_core_count + cpu_threads_per_core = var.cpu_threads_per_core + hibernation = var.hibernation + + user_data = var.user_data + user_data_base64 = var.user_data_base64 + user_data_replace_on_change = var.user_data_replace_on_change + + availability_zone = var.availability_zone + subnet_id = var.subnet_id + vpc_security_group_ids = var.vpc_security_group_ids + + key_name = var.key_name + monitoring = var.monitoring + get_password_data = var.get_password_data + iam_instance_profile = var.create_iam_instance_profile ? aws_iam_instance_profile.this[0].name : var.iam_instance_profile + + associate_public_ip_address = var.associate_public_ip_address + private_ip = var.private_ip + secondary_private_ips = var.secondary_private_ips + ipv6_address_count = var.ipv6_address_count + ipv6_addresses = var.ipv6_addresses + + ebs_optimized = var.ebs_optimized + + dynamic "cpu_options" { + for_each = length(var.cpu_options) > 0 ? [var.cpu_options] : [] + + content { + core_count = try(cpu_options.value.core_count, null) + threads_per_core = try(cpu_options.value.threads_per_core, null) + amd_sev_snp = try(cpu_options.value.amd_sev_snp, null) + } + } + + dynamic "capacity_reservation_specification" { + for_each = length(var.capacity_reservation_specification) > 0 ? [var.capacity_reservation_specification] : [] + + content { + capacity_reservation_preference = try(capacity_reservation_specification.value.capacity_reservation_preference, null) + + dynamic "capacity_reservation_target" { + for_each = try([capacity_reservation_specification.value.capacity_reservation_target], []) + + content { + capacity_reservation_id = try(capacity_reservation_target.value.capacity_reservation_id, null) + capacity_reservation_resource_group_arn = try(capacity_reservation_target.value.capacity_reservation_resource_group_arn, null) + } + } + } + } + + dynamic "root_block_device" { + for_each = var.root_block_device + + content { + delete_on_termination = try(root_block_device.value.delete_on_termination, null) + encrypted = try(root_block_device.value.encrypted, null) + iops = try(root_block_device.value.iops, null) + kms_key_id = lookup(root_block_device.value, "kms_key_id", null) + volume_size = try(root_block_device.value.volume_size, null) + volume_type = try(root_block_device.value.volume_type, null) + throughput = try(root_block_device.value.throughput, null) + tags = try(root_block_device.value.tags, null) + } + } + + dynamic "ebs_block_device" { + for_each = var.ebs_block_device + + content { + delete_on_termination = try(ebs_block_device.value.delete_on_termination, null) + device_name = ebs_block_device.value.device_name + encrypted = try(ebs_block_device.value.encrypted, null) + iops = try(ebs_block_device.value.iops, null) + kms_key_id = lookup(ebs_block_device.value, "kms_key_id", null) + snapshot_id = lookup(ebs_block_device.value, "snapshot_id", null) + volume_size = try(ebs_block_device.value.volume_size, null) + volume_type = try(ebs_block_device.value.volume_type, null) + throughput = try(ebs_block_device.value.throughput, null) + tags = try(ebs_block_device.value.tags, null) + } + } + + dynamic "ephemeral_block_device" { + for_each = var.ephemeral_block_device + + content { + device_name = ephemeral_block_device.value.device_name + no_device = try(ephemeral_block_device.value.no_device, null) + virtual_name = try(ephemeral_block_device.value.virtual_name, null) + } + } + + dynamic "metadata_options" { + for_each = length(var.metadata_options) > 0 ? [var.metadata_options] : [] + + content { + http_endpoint = try(metadata_options.value.http_endpoint, "enabled") + http_tokens = try(metadata_options.value.http_tokens, "optional") + http_put_response_hop_limit = try(metadata_options.value.http_put_response_hop_limit, 1) + instance_metadata_tags = try(metadata_options.value.instance_metadata_tags, null) + } + } + + dynamic "network_interface" { + for_each = var.network_interface + + content { + device_index = network_interface.value.device_index + network_interface_id = lookup(network_interface.value, "network_interface_id", null) + delete_on_termination = try(network_interface.value.delete_on_termination, false) + } + } + + dynamic "launch_template" { + for_each = length(var.launch_template) > 0 ? [var.launch_template] : [] + + content { + id = lookup(var.launch_template, "id", null) + name = lookup(var.launch_template, "name", null) + version = lookup(var.launch_template, "version", null) + } + } + + dynamic "maintenance_options" { + for_each = length(var.maintenance_options) > 0 ? [var.maintenance_options] : [] + + content { + auto_recovery = try(maintenance_options.value.auto_recovery, null) + } + } + + enclave_options { + enabled = var.enclave_options_enabled + } + + source_dest_check = length(var.network_interface) > 0 ? null : var.source_dest_check + disable_api_termination = var.disable_api_termination + disable_api_stop = var.disable_api_stop + instance_initiated_shutdown_behavior = var.instance_initiated_shutdown_behavior + placement_group = var.placement_group + tenancy = var.tenancy + host_id = var.host_id + + credit_specification { + cpu_credits = local.is_t_instance_type ? var.cpu_credits : null + } + + timeouts { + create = try(var.timeouts.create, null) + update = try(var.timeouts.update, null) + delete = try(var.timeouts.delete, null) + } + + tags = merge({ "Name" = var.name }, var.instance_tags, var.tags) + volume_tags = var.enable_volume_tags ? merge({ "Name" = var.name }, var.volume_tags) : null + + lifecycle { + ignore_changes = [ + ami + ] + } +} + +################################################################################ +# Spot Instance +################################################################################ + +resource "aws_spot_instance_request" "this" { + count = local.create && var.create_spot_instance ? 1 : 0 + + ami = try(coalesce(var.ami, nonsensitive(data.aws_ssm_parameter.this[0].value)), null) + instance_type = var.instance_type + cpu_core_count = var.cpu_core_count + cpu_threads_per_core = var.cpu_threads_per_core + hibernation = var.hibernation + + user_data = var.user_data + user_data_base64 = var.user_data_base64 + user_data_replace_on_change = var.user_data_replace_on_change + + availability_zone = var.availability_zone + subnet_id = var.subnet_id + vpc_security_group_ids = var.vpc_security_group_ids + + key_name = var.key_name + monitoring = var.monitoring + get_password_data = var.get_password_data + iam_instance_profile = var.create_iam_instance_profile ? aws_iam_instance_profile.this[0].name : var.iam_instance_profile + + associate_public_ip_address = var.associate_public_ip_address + private_ip = var.private_ip + secondary_private_ips = var.secondary_private_ips + ipv6_address_count = var.ipv6_address_count + ipv6_addresses = var.ipv6_addresses + + ebs_optimized = var.ebs_optimized + + # Spot request specific attributes + spot_price = var.spot_price + wait_for_fulfillment = var.spot_wait_for_fulfillment + spot_type = var.spot_type + launch_group = var.spot_launch_group + block_duration_minutes = var.spot_block_duration_minutes + instance_interruption_behavior = var.spot_instance_interruption_behavior + valid_until = var.spot_valid_until + valid_from = var.spot_valid_from + # End spot request specific attributes + + dynamic "cpu_options" { + for_each = length(var.cpu_options) > 0 ? [var.cpu_options] : [] + + content { + core_count = try(cpu_options.value.core_count, null) + threads_per_core = try(cpu_options.value.threads_per_core, null) + amd_sev_snp = try(cpu_options.value.amd_sev_snp, null) + } + } + + dynamic "capacity_reservation_specification" { + for_each = length(var.capacity_reservation_specification) > 0 ? [var.capacity_reservation_specification] : [] + + content { + capacity_reservation_preference = try(capacity_reservation_specification.value.capacity_reservation_preference, null) + + dynamic "capacity_reservation_target" { + for_each = try([capacity_reservation_specification.value.capacity_reservation_target], []) + content { + capacity_reservation_id = try(capacity_reservation_target.value.capacity_reservation_id, null) + capacity_reservation_resource_group_arn = try(capacity_reservation_target.value.capacity_reservation_resource_group_arn, null) + } + } + } + } + + dynamic "root_block_device" { + for_each = var.root_block_device + + content { + delete_on_termination = try(root_block_device.value.delete_on_termination, null) + encrypted = try(root_block_device.value.encrypted, null) + iops = try(root_block_device.value.iops, null) + kms_key_id = lookup(root_block_device.value, "kms_key_id", null) + volume_size = try(root_block_device.value.volume_size, null) + volume_type = try(root_block_device.value.volume_type, null) + throughput = try(root_block_device.value.throughput, null) + tags = try(root_block_device.value.tags, null) + } + } + + dynamic "ebs_block_device" { + for_each = var.ebs_block_device + + content { + delete_on_termination = try(ebs_block_device.value.delete_on_termination, null) + device_name = ebs_block_device.value.device_name + encrypted = try(ebs_block_device.value.encrypted, null) + iops = try(ebs_block_device.value.iops, null) + kms_key_id = lookup(ebs_block_device.value, "kms_key_id", null) + snapshot_id = lookup(ebs_block_device.value, "snapshot_id", null) + volume_size = try(ebs_block_device.value.volume_size, null) + volume_type = try(ebs_block_device.value.volume_type, null) + throughput = try(ebs_block_device.value.throughput, null) + tags = try(ebs_block_device.value.tags, null) + } + } + + dynamic "ephemeral_block_device" { + for_each = var.ephemeral_block_device + + content { + device_name = ephemeral_block_device.value.device_name + no_device = try(ephemeral_block_device.value.no_device, null) + virtual_name = try(ephemeral_block_device.value.virtual_name, null) + } + } + + dynamic "metadata_options" { + for_each = length(var.metadata_options) > 0 ? [var.metadata_options] : [] + + content { + http_endpoint = try(metadata_options.value.http_endpoint, "enabled") + http_tokens = try(metadata_options.value.http_tokens, "optional") + http_put_response_hop_limit = try(metadata_options.value.http_put_response_hop_limit, 1) + instance_metadata_tags = try(metadata_options.value.instance_metadata_tags, null) + } + } + + dynamic "network_interface" { + for_each = var.network_interface + + content { + device_index = network_interface.value.device_index + network_interface_id = lookup(network_interface.value, "network_interface_id", null) + delete_on_termination = try(network_interface.value.delete_on_termination, false) + } + } + + dynamic "launch_template" { + for_each = length(var.launch_template) > 0 ? [var.launch_template] : [] + + content { + id = lookup(var.launch_template, "id", null) + name = lookup(var.launch_template, "name", null) + version = lookup(var.launch_template, "version", null) + } + } + + enclave_options { + enabled = var.enclave_options_enabled + } + + source_dest_check = length(var.network_interface) > 0 ? null : var.source_dest_check + disable_api_termination = var.disable_api_termination + instance_initiated_shutdown_behavior = var.instance_initiated_shutdown_behavior + placement_group = var.placement_group + tenancy = var.tenancy + host_id = var.host_id + + credit_specification { + cpu_credits = local.is_t_instance_type ? var.cpu_credits : null + } + + timeouts { + create = try(var.timeouts.create, null) + delete = try(var.timeouts.delete, null) + } + + tags = merge({ "Name" = var.name }, var.instance_tags, var.tags) + volume_tags = var.enable_volume_tags ? merge({ "Name" = var.name }, var.volume_tags) : null +} + +################################################################################ +# IAM Role / Instance Profile +################################################################################ + +locals { + iam_role_name = try(coalesce(var.iam_role_name, var.name), "") +} + +data "aws_iam_policy_document" "assume_role_policy" { + count = var.create && var.create_iam_instance_profile ? 1 : 0 + + statement { + sid = "EC2AssumeRole" + actions = ["sts:AssumeRole"] + + principals { + type = "Service" + identifiers = ["ec2.${data.aws_partition.current.dns_suffix}"] + } + } +} + +resource "aws_iam_role" "this" { + count = var.create && var.create_iam_instance_profile ? 1 : 0 + + name = var.iam_role_use_name_prefix ? null : local.iam_role_name + name_prefix = var.iam_role_use_name_prefix ? "${local.iam_role_name}-" : null + path = var.iam_role_path + description = var.iam_role_description + + assume_role_policy = data.aws_iam_policy_document.assume_role_policy[0].json + permissions_boundary = var.iam_role_permissions_boundary + force_detach_policies = true + + tags = merge(var.tags, var.iam_role_tags) +} + +resource "aws_iam_role_policy_attachment" "this" { + for_each = { for k, v in var.iam_role_policies : k => v if var.create && var.create_iam_instance_profile } + + policy_arn = each.value + role = aws_iam_role.this[0].name +} + +resource "aws_iam_instance_profile" "this" { + count = var.create && var.create_iam_instance_profile ? 1 : 0 + + role = aws_iam_role.this[0].name + + name = var.iam_role_use_name_prefix ? null : local.iam_role_name + name_prefix = var.iam_role_use_name_prefix ? "${local.iam_role_name}-" : null + path = var.iam_role_path + + tags = merge(var.tags, var.iam_role_tags) + + lifecycle { + create_before_destroy = true + } +} diff --git a/modules/aws-ec2-instance/outputs.tf b/modules/aws-ec2-instance/outputs.tf new file mode 100644 index 0000000..d79484c --- /dev/null +++ b/modules/aws-ec2-instance/outputs.tf @@ -0,0 +1,221 @@ +output "id" { + description = "The ID of the instance" + value = try( + aws_instance.this[0].id, + aws_instance.ignore_ami[0].id, + aws_spot_instance_request.this[0].id, + null, + ) +} + +output "arn" { + description = "The ARN of the instance" + value = try( + aws_instance.this[0].arn, + aws_instance.ignore_ami[0].arn, + aws_spot_instance_request.this[0].arn, + null, + ) +} + +output "capacity_reservation_specification" { + description = "Capacity reservation specification of the instance" + value = try( + aws_instance.this[0].capacity_reservation_specification, + aws_instance.ignore_ami[0].capacity_reservation_specification, + aws_spot_instance_request.this[0].capacity_reservation_specification, + null, + ) +} + +output "instance_state" { + description = "The state of the instance" + value = try( + aws_instance.this[0].instance_state, + aws_instance.ignore_ami[0].instance_state, + aws_spot_instance_request.this[0].instance_state, + null, + ) +} + +output "outpost_arn" { + description = "The ARN of the Outpost the instance is assigned to" + value = try( + aws_instance.this[0].outpost_arn, + aws_instance.ignore_ami[0].outpost_arn, + aws_spot_instance_request.this[0].outpost_arn, + null, + ) +} + +output "password_data" { + description = "Base-64 encoded encrypted password data for the instance. Useful for getting the administrator password for instances running Microsoft Windows. This attribute is only exported if `get_password_data` is true" + value = try( + aws_instance.this[0].password_data, + aws_instance.ignore_ami[0].password_data, + aws_spot_instance_request.this[0].password_data, + null, + ) +} + +output "primary_network_interface_id" { + description = "The ID of the instance's primary network interface" + value = try( + aws_instance.this[0].primary_network_interface_id, + aws_instance.ignore_ami[0].primary_network_interface_id, + aws_spot_instance_request.this[0].primary_network_interface_id, + null, + ) +} + +output "private_dns" { + description = "The private DNS name assigned to the instance. Can only be used inside the Amazon EC2, and only available if you've enabled DNS hostnames for your VPC" + value = try( + aws_instance.this[0].private_dns, + aws_instance.ignore_ami[0].private_dns, + aws_spot_instance_request.this[0].private_dns, + null, + ) +} + +output "public_dns" { + description = "The public DNS name assigned to the instance. For EC2-VPC, this is only available if you've enabled DNS hostnames for your VPC" + value = try( + aws_instance.this[0].public_dns, + aws_instance.ignore_ami[0].public_dns, + aws_spot_instance_request.this[0].public_dns, + null, + ) +} + +output "public_ip" { + description = "The public IP address assigned to the instance, if applicable. NOTE: If you are using an aws_eip with your instance, you should refer to the EIP's address directly and not use `public_ip` as this field will change after the EIP is attached" + value = try( + aws_instance.this[0].public_ip, + aws_instance.ignore_ami[0].public_ip, + aws_spot_instance_request.this[0].public_ip, + null, + ) +} + +output "private_ip" { + description = "The private IP address assigned to the instance" + value = try( + aws_instance.this[0].private_ip, + aws_instance.ignore_ami[0].private_ip, + aws_spot_instance_request.this[0].private_ip, + null, + ) +} + +output "ipv6_addresses" { + description = "The IPv6 address assigned to the instance, if applicable" + value = try( + aws_instance.this[0].ipv6_addresses, + aws_instance.ignore_ami[0].ipv6_addresses, + aws_spot_instance_request.this[0].ipv6_addresses, + [], + ) +} + +output "tags_all" { + description = "A map of tags assigned to the resource, including those inherited from the provider default_tags configuration block" + value = try( + aws_instance.this[0].tags_all, + aws_instance.ignore_ami[0].tags_all, + aws_spot_instance_request.this[0].tags_all, + {}, + ) +} + +output "spot_bid_status" { + description = "The current bid status of the Spot Instance Request" + value = try(aws_spot_instance_request.this[0].spot_bid_status, null) +} + +output "spot_request_state" { + description = "The current request state of the Spot Instance Request" + value = try(aws_spot_instance_request.this[0].spot_request_state, null) +} + +output "spot_instance_id" { + description = "The Instance ID (if any) that is currently fulfilling the Spot Instance request" + value = try(aws_spot_instance_request.this[0].spot_instance_id, null) +} + +output "ami" { + description = "AMI ID that was used to create the instance" + value = try( + aws_instance.this[0].ami, + aws_instance.ignore_ami[0].ami, + aws_spot_instance_request.this[0].ami, + null, + ) +} + +################################################################################ +# IAM Role / Instance Profile +################################################################################ + +output "iam_role_name" { + description = "The name of the IAM role" + value = try(aws_iam_role.this[0].name, null) +} + +output "iam_role_arn" { + description = "The Amazon Resource Name (ARN) specifying the IAM role" + value = try(aws_iam_role.this[0].arn, null) +} + +output "iam_role_unique_id" { + description = "Stable and unique string identifying the IAM role" + value = try(aws_iam_role.this[0].unique_id, null) +} + +output "iam_instance_profile_arn" { + description = "ARN assigned by AWS to the instance profile" + value = try(aws_iam_instance_profile.this[0].arn, null) +} + +output "iam_instance_profile_id" { + description = "Instance profile's ID" + value = try(aws_iam_instance_profile.this[0].id, null) +} + +output "iam_instance_profile_unique" { + description = "Stable and unique string identifying the IAM instance profile" + value = try(aws_iam_instance_profile.this[0].unique_id, null) +} + +################################################################################ +# Block Devices +################################################################################ +output "root_block_device" { + description = "Root block device information" + value = try( + aws_instance.this[0].root_block_device, + aws_instance.ignore_ami[0].root_block_device, + aws_spot_instance_request.this[0].root_block_device, + null + ) +} + +output "ebs_block_device" { + description = "EBS block device information" + value = try( + aws_instance.this[0].ebs_block_device, + aws_instance.ignore_ami[0].ebs_block_device, + aws_spot_instance_request.this[0].ebs_block_device, + null + ) +} + +output "ephemeral_block_device" { + description = "Ephemeral block device information" + value = try( + aws_instance.this[0].ephemeral_block_device, + aws_instance.ignore_ami[0].ephemeral_block_device, + aws_spot_instance_request.this[0].ephemeral_block_device, + null + ) +} diff --git a/modules/aws-ec2-instance/variables.tf b/modules/aws-ec2-instance/variables.tf new file mode 100644 index 0000000..a05e304 --- /dev/null +++ b/modules/aws-ec2-instance/variables.tf @@ -0,0 +1,404 @@ +variable "create" { + description = "Whether to create an instance" + type = bool + default = true +} + +variable "name" { + description = "Name to be used on EC2 instance created" + type = string + default = "" +} + +variable "ami_ssm_parameter" { + description = "SSM parameter name for the AMI ID. For Amazon Linux AMI SSM parameters see [reference](https://docs.aws.amazon.com/systems-manager/latest/userguide/parameter-store-public-parameters-ami.html)" + type = string + default = "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2" +} + +variable "ami" { + description = "ID of AMI to use for the instance" + type = string + default = null +} + +variable "ignore_ami_changes" { + description = "Whether changes to the AMI ID changes should be ignored by Terraform. Note - changing this value will result in the replacement of the instance" + type = bool + default = false +} + +variable "associate_public_ip_address" { + description = "Whether to associate a public IP address with an instance in a VPC" + type = bool + default = null +} + +variable "maintenance_options" { + description = "The maintenance options for the instance" + type = any + default = {} +} + +variable "availability_zone" { + description = "AZ to start the instance in" + type = string + default = null +} + +variable "capacity_reservation_specification" { + description = "Describes an instance's Capacity Reservation targeting option" + type = any + default = {} +} + +variable "cpu_credits" { + description = "The credit option for CPU usage (unlimited or standard)" + type = string + default = null +} + +variable "disable_api_termination" { + description = "If true, enables EC2 Instance Termination Protection" + type = bool + default = null +} + +variable "ebs_block_device" { + description = "Additional EBS block devices to attach to the instance" + type = list(any) + default = [] +} + +variable "ebs_optimized" { + description = "If true, the launched EC2 instance will be EBS-optimized" + type = bool + default = null +} + +variable "enclave_options_enabled" { + description = "Whether Nitro Enclaves will be enabled on the instance. Defaults to `false`" + type = bool + default = null +} + +variable "ephemeral_block_device" { + description = "Customize Ephemeral (also known as Instance Store) volumes on the instance" + type = list(map(string)) + default = [] +} + +variable "get_password_data" { + description = "If true, wait for password data to become available and retrieve it" + type = bool + default = null +} + +variable "hibernation" { + description = "If true, the launched EC2 instance will support hibernation" + type = bool + default = null +} + +variable "host_id" { + description = "ID of a dedicated host that the instance will be assigned to. Use when an instance is to be launched on a specific dedicated host" + type = string + default = null +} + +variable "iam_instance_profile" { + description = "IAM Instance Profile to launch the instance with. Specified as the name of the Instance Profile" + type = string + default = null +} + +variable "instance_initiated_shutdown_behavior" { + description = "Shutdown behavior for the instance. Amazon defaults this to stop for EBS-backed instances and terminate for instance-store instances. Cannot be set on instance-store instance" # https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/terminating-instances.html#Using_ChangingInstanceInitiatedShutdownBehavior + type = string + default = null +} + +variable "instance_type" { + description = "The type of instance to start" + type = string + default = "t3.micro" +} + +variable "instance_tags" { + description = "Additional tags for the instance" + type = map(string) + default = {} +} + +variable "ipv6_address_count" { + description = "A number of IPv6 addresses to associate with the primary network interface. Amazon EC2 chooses the IPv6 addresses from the range of your subnet" + type = number + default = null +} + +variable "ipv6_addresses" { + description = "Specify one or more IPv6 addresses from the range of the subnet to associate with the primary network interface" + type = list(string) + default = null +} + +variable "key_name" { + description = "Key name of the Key Pair to use for the instance; which can be managed using the `aws_key_pair` resource" + type = string + default = null +} + +variable "launch_template" { + description = "Specifies a Launch Template to configure the instance. Parameters configured on this resource will override the corresponding parameters in the Launch Template" + type = map(string) + default = {} +} + +variable "metadata_options" { + description = "Customize the metadata options of the instance" + type = map(string) + default = { + "http_endpoint" = "enabled" + "http_put_response_hop_limit" = 1 + "http_tokens" = "optional" + } +} + +variable "monitoring" { + description = "If true, the launched EC2 instance will have detailed monitoring enabled" + type = bool + default = null +} + +variable "network_interface" { + description = "Customize network interfaces to be attached at instance boot time" + type = list(map(string)) + default = [] +} + +variable "placement_group" { + description = "The Placement Group to start the instance in" + type = string + default = null +} + +variable "private_ip" { + description = "Private IP address to associate with the instance in a VPC" + type = string + default = null +} + +variable "root_block_device" { + description = "Customize details about the root block device of the instance. See Block Devices below for details" + type = list(any) + default = [] +} + +variable "secondary_private_ips" { + description = "A list of secondary private IPv4 addresses to assign to the instance's primary network interface (eth0) in a VPC. Can only be assigned to the primary network interface (eth0) attached at instance creation, not a pre-existing network interface i.e. referenced in a `network_interface block`" + type = list(string) + default = null +} + +variable "source_dest_check" { + description = "Controls if traffic is routed to the instance when the destination address does not match the instance. Used for NAT or VPNs" + type = bool + default = null +} + +variable "subnet_id" { + description = "The VPC Subnet ID to launch in" + type = string + default = null +} + +variable "tags" { + description = "A mapping of tags to assign to the resource" + type = map(string) + default = {} +} + +variable "tenancy" { + description = "The tenancy of the instance (if the instance is running in a VPC). Available values: default, dedicated, host" + type = string + default = null +} + +variable "user_data" { + description = "The user data to provide when launching the instance. Do not pass gzip-compressed data via this argument; see user_data_base64 instead" + type = string + default = null +} + +variable "user_data_base64" { + description = "Can be used instead of user_data to pass base64-encoded binary data directly. Use this instead of user_data whenever the value is not a valid UTF-8 string. For example, gzip-encoded user data must be base64-encoded and passed via this argument to avoid corruption" + type = string + default = null +} + +variable "user_data_replace_on_change" { + description = "When used in combination with user_data or user_data_base64 will trigger a destroy and recreate when set to true. Defaults to false if not set" + type = bool + default = null +} + +variable "volume_tags" { + description = "A mapping of tags to assign to the devices created by the instance at launch time" + type = map(string) + default = {} +} + +variable "enable_volume_tags" { + description = "Whether to enable volume tags (if enabled it conflicts with root_block_device tags)" + type = bool + default = true +} + +variable "vpc_security_group_ids" { + description = "A list of security group IDs to associate with" + type = list(string) + default = null +} + +variable "timeouts" { + description = "Define maximum timeout for creating, updating, and deleting EC2 instance resources" + type = map(string) + default = {} +} + +variable "cpu_options" { + description = "Defines CPU options to apply to the instance at launch time." + type = any + default = {} +} + +variable "cpu_core_count" { + description = "Sets the number of CPU cores for an instance" # This option is only supported on creation of instance type that support CPU Options https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-optimize-cpu.html#cpu-options-supported-instances-values + type = number + default = null +} + +variable "cpu_threads_per_core" { + description = "Sets the number of CPU threads per core for an instance (has no effect unless cpu_core_count is also set)" + type = number + default = null +} + +# Spot instance request +variable "create_spot_instance" { + description = "Depicts if the instance is a spot instance" + type = bool + default = false +} + +variable "spot_price" { + description = "The maximum price to request on the spot market. Defaults to on-demand price" + type = string + default = null +} + +variable "spot_wait_for_fulfillment" { + description = "If set, Terraform will wait for the Spot Request to be fulfilled, and will throw an error if the timeout of 10m is reached" + type = bool + default = null +} + +variable "spot_type" { + description = "If set to one-time, after the instance is terminated, the spot request will be closed. Default `persistent`" + type = string + default = null +} + +variable "spot_launch_group" { + description = "A launch group is a group of spot instances that launch together and terminate together. If left empty instances are launched and terminated individually" + type = string + default = null +} + +variable "spot_block_duration_minutes" { + description = "The required duration for the Spot instances, in minutes. This value must be a multiple of 60 (60, 120, 180, 240, 300, or 360)" + type = number + default = null +} + +variable "spot_instance_interruption_behavior" { + description = "Indicates Spot instance behavior when it is interrupted. Valid values are `terminate`, `stop`, or `hibernate`" + type = string + default = null +} + +variable "spot_valid_until" { + description = "The end date and time of the request, in UTC RFC3339 format(for example, YYYY-MM-DDTHH:MM:SSZ)" + type = string + default = null +} + +variable "spot_valid_from" { + description = "The start date and time of the request, in UTC RFC3339 format(for example, YYYY-MM-DDTHH:MM:SSZ)" + type = string + default = null +} + +variable "disable_api_stop" { + description = "If true, enables EC2 Instance Stop Protection" + type = bool + default = null + +} +variable "putin_khuylo" { + description = "Do you agree that Putin doesn't respect Ukrainian sovereignty and territorial integrity? More info: https://en.wikipedia.org/wiki/Putin_khuylo!" + type = bool + default = true +} + +################################################################################ +# IAM Role / Instance Profile +################################################################################ + +variable "create_iam_instance_profile" { + description = "Determines whether an IAM instance profile is created or to use an existing IAM instance profile" + type = bool + default = false +} + +variable "iam_role_name" { + description = "Name to use on IAM role created" + type = string + default = null +} + +variable "iam_role_use_name_prefix" { + description = "Determines whether the IAM role name (`iam_role_name` or `name`) is used as a prefix" + type = bool + default = true +} + +variable "iam_role_path" { + description = "IAM role path" + type = string + default = null +} + +variable "iam_role_description" { + description = "Description of the role" + type = string + default = null +} + +variable "iam_role_permissions_boundary" { + description = "ARN of the policy that is used to set the permissions boundary for the IAM role" + type = string + default = null +} + +variable "iam_role_policies" { + description = "Policies attached to the IAM role" + type = map(string) + default = {} +} + +variable "iam_role_tags" { + description = "A map of additional tags to add to the IAM role/profile created" + type = map(string) + default = {} +} diff --git a/modules/aws-ec2-instance/versions.tf b/modules/aws-ec2-instance/versions.tf new file mode 100644 index 0000000..fd4d116 --- /dev/null +++ b/modules/aws-ec2-instance/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.66" + } + } +} diff --git a/modules/aws-ec2-instance/wrappers/README.md b/modules/aws-ec2-instance/wrappers/README.md new file mode 100644 index 0000000..dbb2afd --- /dev/null +++ b/modules/aws-ec2-instance/wrappers/README.md @@ -0,0 +1,100 @@ +# Wrapper for the root module + +The configuration in this directory contains an implementation of a single module wrapper pattern, which allows managing several copies of a module in places where using the native Terraform 0.13+ `for_each` feature is not feasible (e.g., with Terragrunt). + +You may want to use a single Terragrunt configuration file to manage multiple resources without duplicating `terragrunt.hcl` files for each copy of the same module. + +This wrapper does not implement any extra functionality. + +## Usage with Terragrunt + +`terragrunt.hcl`: + +```hcl +terraform { + source = "tfr:///terraform-aws-modules/ec2-instance/aws//wrappers" + # Alternative source: + # source = "git::git@github.com:terraform-aws-modules/terraform-aws-ec2-instance.git//wrappers?ref=master" +} + +inputs = { + defaults = { # Default values + create = true + tags = { + Terraform = "true" + Environment = "dev" + } + } + + items = { + my-item = { + # omitted... can be any argument supported by the module + } + my-second-item = { + # omitted... can be any argument supported by the module + } + # omitted... + } +} +``` + +## Usage with Terraform + +```hcl +module "wrapper" { + source = "terraform-aws-modules/ec2-instance/aws//wrappers" + + defaults = { # Default values + create = true + tags = { + Terraform = "true" + Environment = "dev" + } + } + + items = { + my-item = { + # omitted... can be any argument supported by the module + } + my-second-item = { + # omitted... can be any argument supported by the module + } + # omitted... + } +} +``` + +## Example: Manage multiple S3 buckets in one Terragrunt layer + +`eu-west-1/s3-buckets/terragrunt.hcl`: + +```hcl +terraform { + source = "tfr:///terraform-aws-modules/s3-bucket/aws//wrappers" + # Alternative source: + # source = "git::git@github.com:terraform-aws-modules/terraform-aws-s3-bucket.git//wrappers?ref=master" +} + +inputs = { + defaults = { + force_destroy = true + + attach_elb_log_delivery_policy = true + attach_lb_log_delivery_policy = true + attach_deny_insecure_transport_policy = true + attach_require_latest_tls_policy = true + } + + items = { + bucket1 = { + bucket = "my-random-bucket-1" + } + bucket2 = { + bucket = "my-random-bucket-2" + tags = { + Secure = "probably" + } + } + } +} +``` diff --git a/modules/aws-ec2-instance/wrappers/main.tf b/modules/aws-ec2-instance/wrappers/main.tf new file mode 100644 index 0000000..c6639ee --- /dev/null +++ b/modules/aws-ec2-instance/wrappers/main.tf @@ -0,0 +1,76 @@ +module "wrapper" { + source = "../" + + for_each = var.items + + create = try(each.value.create, var.defaults.create, true) + name = try(each.value.name, var.defaults.name, "") + ami_ssm_parameter = try(each.value.ami_ssm_parameter, var.defaults.ami_ssm_parameter, "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2") + ami = try(each.value.ami, var.defaults.ami, null) + ignore_ami_changes = try(each.value.ignore_ami_changes, var.defaults.ignore_ami_changes, false) + associate_public_ip_address = try(each.value.associate_public_ip_address, var.defaults.associate_public_ip_address, null) + maintenance_options = try(each.value.maintenance_options, var.defaults.maintenance_options, {}) + availability_zone = try(each.value.availability_zone, var.defaults.availability_zone, null) + capacity_reservation_specification = try(each.value.capacity_reservation_specification, var.defaults.capacity_reservation_specification, {}) + cpu_credits = try(each.value.cpu_credits, var.defaults.cpu_credits, null) + disable_api_termination = try(each.value.disable_api_termination, var.defaults.disable_api_termination, null) + ebs_block_device = try(each.value.ebs_block_device, var.defaults.ebs_block_device, []) + ebs_optimized = try(each.value.ebs_optimized, var.defaults.ebs_optimized, null) + enclave_options_enabled = try(each.value.enclave_options_enabled, var.defaults.enclave_options_enabled, null) + ephemeral_block_device = try(each.value.ephemeral_block_device, var.defaults.ephemeral_block_device, []) + get_password_data = try(each.value.get_password_data, var.defaults.get_password_data, null) + hibernation = try(each.value.hibernation, var.defaults.hibernation, null) + host_id = try(each.value.host_id, var.defaults.host_id, null) + iam_instance_profile = try(each.value.iam_instance_profile, var.defaults.iam_instance_profile, null) + instance_initiated_shutdown_behavior = try(each.value.instance_initiated_shutdown_behavior, var.defaults.instance_initiated_shutdown_behavior, null) + instance_type = try(each.value.instance_type, var.defaults.instance_type, "t3.micro") + instance_tags = try(each.value.instance_tags, var.defaults.instance_tags, {}) + ipv6_address_count = try(each.value.ipv6_address_count, var.defaults.ipv6_address_count, null) + ipv6_addresses = try(each.value.ipv6_addresses, var.defaults.ipv6_addresses, null) + key_name = try(each.value.key_name, var.defaults.key_name, null) + launch_template = try(each.value.launch_template, var.defaults.launch_template, {}) + metadata_options = try(each.value.metadata_options, var.defaults.metadata_options, { + "http_endpoint" = "enabled" + "http_put_response_hop_limit" = 1 + "http_tokens" = "optional" + }) + monitoring = try(each.value.monitoring, var.defaults.monitoring, null) + network_interface = try(each.value.network_interface, var.defaults.network_interface, []) + placement_group = try(each.value.placement_group, var.defaults.placement_group, null) + private_ip = try(each.value.private_ip, var.defaults.private_ip, null) + root_block_device = try(each.value.root_block_device, var.defaults.root_block_device, []) + secondary_private_ips = try(each.value.secondary_private_ips, var.defaults.secondary_private_ips, null) + source_dest_check = try(each.value.source_dest_check, var.defaults.source_dest_check, null) + subnet_id = try(each.value.subnet_id, var.defaults.subnet_id, null) + tags = try(each.value.tags, var.defaults.tags, {}) + tenancy = try(each.value.tenancy, var.defaults.tenancy, null) + user_data = try(each.value.user_data, var.defaults.user_data, null) + user_data_base64 = try(each.value.user_data_base64, var.defaults.user_data_base64, null) + user_data_replace_on_change = try(each.value.user_data_replace_on_change, var.defaults.user_data_replace_on_change, null) + volume_tags = try(each.value.volume_tags, var.defaults.volume_tags, {}) + enable_volume_tags = try(each.value.enable_volume_tags, var.defaults.enable_volume_tags, true) + vpc_security_group_ids = try(each.value.vpc_security_group_ids, var.defaults.vpc_security_group_ids, null) + timeouts = try(each.value.timeouts, var.defaults.timeouts, {}) + cpu_options = try(each.value.cpu_options, var.defaults.cpu_options, {}) + cpu_core_count = try(each.value.cpu_core_count, var.defaults.cpu_core_count, null) + cpu_threads_per_core = try(each.value.cpu_threads_per_core, var.defaults.cpu_threads_per_core, null) + create_spot_instance = try(each.value.create_spot_instance, var.defaults.create_spot_instance, false) + spot_price = try(each.value.spot_price, var.defaults.spot_price, null) + spot_wait_for_fulfillment = try(each.value.spot_wait_for_fulfillment, var.defaults.spot_wait_for_fulfillment, null) + spot_type = try(each.value.spot_type, var.defaults.spot_type, null) + spot_launch_group = try(each.value.spot_launch_group, var.defaults.spot_launch_group, null) + spot_block_duration_minutes = try(each.value.spot_block_duration_minutes, var.defaults.spot_block_duration_minutes, null) + spot_instance_interruption_behavior = try(each.value.spot_instance_interruption_behavior, var.defaults.spot_instance_interruption_behavior, null) + spot_valid_until = try(each.value.spot_valid_until, var.defaults.spot_valid_until, null) + spot_valid_from = try(each.value.spot_valid_from, var.defaults.spot_valid_from, null) + disable_api_stop = try(each.value.disable_api_stop, var.defaults.disable_api_stop, null) + putin_khuylo = try(each.value.putin_khuylo, var.defaults.putin_khuylo, true) + create_iam_instance_profile = try(each.value.create_iam_instance_profile, var.defaults.create_iam_instance_profile, false) + iam_role_name = try(each.value.iam_role_name, var.defaults.iam_role_name, null) + iam_role_use_name_prefix = try(each.value.iam_role_use_name_prefix, var.defaults.iam_role_use_name_prefix, true) + iam_role_path = try(each.value.iam_role_path, var.defaults.iam_role_path, null) + iam_role_description = try(each.value.iam_role_description, var.defaults.iam_role_description, null) + iam_role_permissions_boundary = try(each.value.iam_role_permissions_boundary, var.defaults.iam_role_permissions_boundary, null) + iam_role_policies = try(each.value.iam_role_policies, var.defaults.iam_role_policies, {}) + iam_role_tags = try(each.value.iam_role_tags, var.defaults.iam_role_tags, {}) +} diff --git a/modules/aws-ec2-instance/wrappers/outputs.tf b/modules/aws-ec2-instance/wrappers/outputs.tf new file mode 100644 index 0000000..ec6da5f --- /dev/null +++ b/modules/aws-ec2-instance/wrappers/outputs.tf @@ -0,0 +1,5 @@ +output "wrapper" { + description = "Map of outputs of a wrapper." + value = module.wrapper + # sensitive = false # No sensitive module output found +} diff --git a/modules/aws-ec2-instance/wrappers/variables.tf b/modules/aws-ec2-instance/wrappers/variables.tf new file mode 100644 index 0000000..a6ea096 --- /dev/null +++ b/modules/aws-ec2-instance/wrappers/variables.tf @@ -0,0 +1,11 @@ +variable "defaults" { + description = "Map of default values which will be used for each item." + type = any + default = {} +} + +variable "items" { + description = "Maps of items to create a wrapper from. Values are passed through to the module." + type = any + default = {} +} diff --git a/modules/aws-ec2-instance/wrappers/versions.tf b/modules/aws-ec2-instance/wrappers/versions.tf new file mode 100644 index 0000000..51cad10 --- /dev/null +++ b/modules/aws-ec2-instance/wrappers/versions.tf @@ -0,0 +1,3 @@ +terraform { + required_version = ">= 0.13.1" +} diff --git a/modules/aws-ecr/main.tf b/modules/aws-ecr/main.tf new file mode 100644 index 0000000..c18b6ff --- /dev/null +++ b/modules/aws-ecr/main.tf @@ -0,0 +1,124 @@ +data "aws_caller_identity" "current" {} + +resource "aws_ecr_repository" "this" { + for_each = toset(var.ecr_repo_names) + + name = each.value + + image_tag_mutability = var.image_tag_mutability + + image_scanning_configuration { + scan_on_push = var.scan_on_pushing + } + + tags = var.tags +} + +data "aws_iam_policy_document" "ecs_ecr_read_perms" { + statement { + sid = "ECRRead" + + effect = "Allow" + + actions = [ + "ecr:BatchCheckLayerAvailability", + "ecr:GetAuthorizationToken", + "ecr:GetDownloadUrlForLayer", + "ecr:GetRepositoryPolicy", + "ecr:DescribeRepositories", + "ecr:ListImages", + "ecr:DescribeImages", + "ecr:BatchGetImage", + ] + + principals { + identifiers = var.allowed_read_principals + type = "AWS" + } + condition { + test = "StringLike" + variable = "aws:PrincipalOrgID" + values = [var.organization_id] + } + } +} + +data "aws_iam_policy_document" "ecr_read_and_write_perms" { + statement { + sid = "ECRRead" + + effect = "Allow" + + actions = [ + "ecr:BatchCheckLayerAvailability", + "ecr:GetAuthorizationToken", + "ecr:GetDownloadUrlForLayer", + "ecr:GetRepositoryPolicy", + "ecr:DescribeRepositories", + "ecr:ListImages", + "ecr:DescribeImages", + "ecr:BatchGetImage", + ] + + principals { + identifiers = var.allowed_read_principals + type = "AWS" + } + condition { + test = "StringLike" + variable = "aws:PrincipalOrgID" + values = [var.organization_id] + } + } + + statement { + sid = "ECRWrite" + + effect = "Allow" + + actions = [ + "ecr:GetAuthorizationToken", + "ecr:GetDownloadUrlForLayer", + "ecr:BatchGetImage", + "ecr:BatchCheckLayerAvailability", + "ecr:PutImage", + "ecr:InitiateLayerUpload", + "ecr:UploadLayerPart", + "ecr:CompleteLayerUpload", + "ecr:DescribeRepositories", + "ecr:ListImages", + "ecr:DescribeImages", + ] + + principals { + identifiers = var.allowed_write_principals + type = "AWS" + } + condition { + test = "StringLike" + variable = "aws:PrincipalOrgID" + values = [var.organization_id] + } + } +} + +resource "aws_ecr_repository_policy" "this" { + for_each = toset(var.ecr_repo_names) + + repository = each.value + + policy = length(var.allowed_write_principals) > 0 ? data.aws_iam_policy_document.ecr_read_and_write_perms.json : data.aws_iam_policy_document.ecs_ecr_read_perms.json + + depends_on = [aws_ecr_repository.this] +} + +resource "aws_ecr_replication_configuration" "example" { + replication_configuration { + rule { + destination { + region = var.secondary_region + registry_id = data.aws_caller_identity.current.account_id + } + } + } +} diff --git a/modules/aws-ecr/outputs.tf b/modules/aws-ecr/outputs.tf new file mode 100644 index 0000000..e69de29 diff --git a/modules/aws-ecr/variables.tf b/modules/aws-ecr/variables.tf new file mode 100644 index 0000000..cb88030 --- /dev/null +++ b/modules/aws-ecr/variables.tf @@ -0,0 +1,63 @@ +#variable "namespace" { +# description = "The namespace we interpolate in all resources" +#} + +variable "create" { + description = "create defines if resources need to be created true/false" + default = true +} + +# The name of the ECR repository +variable "ecr_repo_names" { + description = "name defines the name of the repository, by default it will be interpolated to {namespace}-{name}" + type = list(any) +} + + +variable "allowed_read_principals" { + description = "allowed_read_principals defines which external principals are allowed to read from the ECR repository" + type = list(any) +} + +variable "allowed_write_principals" { + description = "allowed_write_principals defines which external principals are allowed to write to the ECR repository" + type = list(any) + default = [] +} + +variable "lifecycle_policy_rules_count" { + description = "The amount of lifecycle_policy_rules, this to make sure we are not running into computed count problems" + default = "0" +} + +variable "lifecycle_policy_rules" { + description = "List of json lifecycle policy rules, created by another module: doingcloudright/ecr-lifecycle-policy-rule/aws" + default = [] +} + +variable "image_tag_mutability" { + description = "The tag mutability setting for the repository. Must be one of: MUTABLE or IMMUTABLE." + default = "MUTABLE" +} + +variable "scan_on_pushing" { + description = "Indicates whether images are scanned after being pushed to the repository (true) or not scanned (false)." + default = false +} + +variable "tags" { + description = "A map of tags to assign to the resource." + default = {} +} + + +variable "secondary_region" { + description = "Region to Create ECR Registry" + type = string +} + +variable "organization_id" { + type = string + default = "" + description = "organization id" +} \ No newline at end of file diff --git a/modules/aws-ecr/versions.tf b/modules/aws-ecr/versions.tf new file mode 100644 index 0000000..35402be --- /dev/null +++ b/modules/aws-ecr/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.6" + } + } +} diff --git a/modules/aws-ecs-load-balancer/main.tf b/modules/aws-ecs-load-balancer/main.tf new file mode 100644 index 0000000..d874863 --- /dev/null +++ b/modules/aws-ecs-load-balancer/main.tf @@ -0,0 +1,288 @@ +#------------------------------------------------------------------------------ +# S3 BUCKET - For access logs +#------------------------------------------------------------------------------ +data "aws_elb_service_account" "default" {} + +resource "random_string" "log_s3_name" { + count = var.enable_s3_logs ? 1 : 0 + length = 8 + numeric = true + special = false + upper = false +} + +module "lb_logs_s3" { + source = "../terraform-aws-s3" + count = var.enable_s3_logs ? 1 : 0 + + + bucket = "ecs-alb-log-bucket-${random_string.log_s3_name[0].result}" + acl = "log-delivery-write" + + # Allow deletion of non-empty bucket + force_destroy = true + + attach_elb_log_delivery_policy = true # Required for ALB logs + attach_lb_log_delivery_policy = true # Required for ALB/NLB logs + attach_cross_account_policy = false + +} + +#------------------------------------------------------------------------------ +# APPLICATION LOAD BALANCER +#------------------------------------------------------------------------------ +resource "random_string" "lb_name" { + count = var.use_random_name_for_lb ? 1 : 0 + length = 32 + numeric = true + special = false +} + +resource "aws_lb" "lb" { + name = var.use_random_name_for_lb ? random_string.lb_name[0].result : substr("${var.name_prefix}-lb", 0, 31) + + internal = var.internal + load_balancer_type = "application" + drop_invalid_header_fields = var.drop_invalid_header_fields + subnets = var.internal ? var.private_subnets : var.public_subnets + idle_timeout = var.idle_timeout + enable_deletion_protection = var.enable_deletion_protection + enable_cross_zone_load_balancing = var.enable_cross_zone_load_balancing + enable_http2 = var.enable_http2 + ip_address_type = var.ip_address_type + security_groups = compact(var.security_groups) + + dynamic "access_logs" { + for_each = var.enable_s3_logs ? [1] : [] + content { + bucket = module.lb_logs_s3[0].s3_bucket_id + enabled = var.enable_s3_logs + } + } + + tags = merge( + var.tags, + { + Name = "${var.name_prefix}-lb" + }, + ) +} + +resource "aws_wafv2_web_acl_association" "waf_association" { + count = var.waf_web_acl_arn != "" ? 1 : 0 + resource_arn = aws_lb.lb.arn + web_acl_arn = var.waf_web_acl_arn +} + +#------------------------------------------------------------------------------ +# AWS LOAD BALANCER - Target Groups +#------------------------------------------------------------------------------ +resource "aws_lb_target_group" "lb_http_tgs" { + for_each = { + for name, config in var.http_ports : name => config + if lookup(config, "type", "") == "" || lookup(config, "type", "") == "forward" + } + name = "${var.name_prefix}-http-${each.value.target_group_port}" + port = each.value.target_group_port + protocol = lookup(each.value, "target_group_protocol", "") == "" ? "HTTP" : each.value.target_group_protocol + vpc_id = var.vpc_id + deregistration_delay = var.deregistration_delay + slow_start = var.slow_start + load_balancing_algorithm_type = var.load_balancing_algorithm_type + dynamic "stickiness" { + for_each = var.stickiness == null ? [] : [var.stickiness] + content { + type = stickiness.value.type + cookie_duration = stickiness.value.cookie_duration + enabled = stickiness.value.enabled + } + } + health_check { + enabled = var.target_group_health_check_enabled + interval = var.target_group_health_check_interval + path = var.target_group_health_check_path + protocol = lookup(each.value, "target_group_protocol", "") == "" ? "HTTP" : each.value.target_group_protocol + timeout = var.target_group_health_check_timeout + healthy_threshold = var.target_group_health_check_healthy_threshold + unhealthy_threshold = var.target_group_health_check_unhealthy_threshold + matcher = var.target_group_health_check_matcher + } + target_type = "ip" + tags = merge( + var.tags, + { + Name = "${var.name_prefix}-http-${each.value.target_group_port}" + }, + ) + lifecycle { + create_before_destroy = true + } + depends_on = [aws_lb.lb] +} + +resource "aws_lb_target_group" "lb_https_tgs" { + for_each = { + for name, config in var.https_ports : name => config + if lookup(config, "type", "") == "" || lookup(config, "type", "") == "forward" + } + name = "${var.name_prefix}-https-${each.value.target_group_port}" + port = each.value.target_group_port + protocol = lookup(each.value, "target_group_protocol", "") == "" ? "HTTPS" : each.value.target_group_protocol + vpc_id = var.vpc_id + deregistration_delay = var.deregistration_delay + slow_start = var.slow_start + load_balancing_algorithm_type = var.load_balancing_algorithm_type + dynamic "stickiness" { + for_each = var.stickiness == null ? [] : [var.stickiness] + content { + type = stickiness.value.type + cookie_duration = stickiness.value.cookie_duration + enabled = stickiness.value.enabled + } + } + health_check { + enabled = var.target_group_health_check_enabled + interval = var.target_group_health_check_interval + path = var.target_group_health_check_path + protocol = lookup(each.value, "target_group_protocol", "") == "" ? "HTTPS" : each.value.target_group_protocol + timeout = var.target_group_health_check_timeout + healthy_threshold = var.target_group_health_check_healthy_threshold + unhealthy_threshold = var.target_group_health_check_unhealthy_threshold + matcher = var.target_group_health_check_matcher + } + target_type = "ip" + tags = merge( + var.tags, + { + Name = "${var.name_prefix}-https-${each.value.target_group_port}" + }, + ) + lifecycle { + create_before_destroy = true + } + depends_on = [aws_lb.lb] +} + +#------------------------------------------------------------------------------ +# AWS LOAD BALANCER - Listeners +#------------------------------------------------------------------------------ +resource "aws_lb_listener" "lb_http_listeners" { + for_each = var.http_ports + load_balancer_arn = aws_lb.lb.arn + port = each.value.listener_port + protocol = "HTTP" + + dynamic "default_action" { + for_each = lookup(each.value, "type", "") == "redirect" ? [1] : [] + content { + type = "redirect" + + redirect { + host = lookup(each.value, "host", "#{host}") + path = lookup(each.value, "path", "/#{path}") + port = lookup(each.value, "port", "#{port}") + protocol = lookup(each.value, "protocol", "#{protocol}") + query = lookup(each.value, "query", "#{query}") + status_code = lookup(each.value, "status_code", "HTTP_301") + } + } + } + + dynamic "default_action" { + for_each = lookup(each.value, "type", "") == "fixed-response" ? [1] : [] + content { + type = "fixed-response" + + fixed_response { + content_type = lookup(each.value, "content_type", "text/plain") + message_body = lookup(each.value, "message_body", "Fixed response content") + status_code = lookup(each.value, "status_code", "200") + } + } + } + + # We fallback to using forward type action if type is not defined + dynamic "default_action" { + for_each = (lookup(each.value, "type", "") == "" || lookup(each.value, "type", "") == "forward") ? [1] : [] + content { + target_group_arn = aws_lb_target_group.lb_http_tgs[each.key].arn + type = "forward" + } + } + + tags = var.tags +} + +resource "aws_lb_listener" "lb_https_listeners" { + for_each = var.https_ports + load_balancer_arn = aws_lb.lb.arn + port = each.value.listener_port + protocol = "HTTPS" + ssl_policy = var.ssl_policy + certificate_arn = var.default_certificate_arn + + dynamic "default_action" { + for_each = lookup(each.value, "type", "") == "redirect" ? [1] : [] + content { + type = "redirect" + + redirect { + host = lookup(each.value, "host", "#{host}") + path = lookup(each.value, "path", "/#{path}") + port = lookup(each.value, "port", "#{port}") + protocol = lookup(each.value, "protocol", "#{protocol}") + query = lookup(each.value, "query", "#{query}") + status_code = lookup(each.value, "status_code", "HTTP_301") + } + } + } + + dynamic "default_action" { + for_each = lookup(each.value, "type", "") == "fixed-response" ? [1] : [] + content { + type = "fixed-response" + + fixed_response { + content_type = lookup(each.value, "content_type", "text/plain") + message_body = lookup(each.value, "message_body", "Fixed response content") + status_code = lookup(each.value, "status_code", "200") + } + } + } + + # We fallback to using forward type action if type is not defined + dynamic "default_action" { + for_each = (lookup(each.value, "type", "") == "" || lookup(each.value, "type", "") == "forward") ? [1] : [] + content { + target_group_arn = aws_lb_target_group.lb_https_tgs[each.key].arn + type = "forward" + } + } + + tags = var.tags +} + +locals { + list_maps_listener_certificate_arns = flatten([ + for cert_arn in var.additional_certificates_arn_for_https_listeners : [ + for listener in aws_lb_listener.lb_https_listeners : { + name = "${listener}-${cert_arn}" + listener_arn = listener.arn + certificate_arn = cert_arn + } + ] + ]) + + map_listener_certificate_arns = { + for obj in local.list_maps_listener_certificate_arns : obj.name => { + listener_arn = obj.listener_arn, + certificate_arn = obj.certificate_arn + } + } +} + +resource "aws_lb_listener_certificate" "additional_certificates_for_https_listeners" { + for_each = local.map_listener_certificate_arns + listener_arn = each.value.listener_arn + certificate_arn = each.value.certificate_arn +} diff --git a/modules/aws-ecs-load-balancer/outputs.tf b/modules/aws-ecs-load-balancer/outputs.tf new file mode 100644 index 0000000..59ce89b --- /dev/null +++ b/modules/aws-ecs-load-balancer/outputs.tf @@ -0,0 +1,125 @@ +#------------------------------------------------------------------------------ +# APPLICATION LOAD BALANCER +#------------------------------------------------------------------------------ +output "aws_lb_lb_id" { + description = "The ARN of the load balancer (matches arn)." + value = aws_lb.lb.id +} + +output "aws_lb_lb_arn" { + description = "The ARN of the load balancer (matches id)." + value = aws_lb.lb.arn +} + +output "aws_lb_lb_name" { + description = "The ARN of the load balancer (matches id)." + value = aws_lb.lb.arn +} + +output "aws_lb_lb_arn_suffix" { + description = "The ARN suffix for use with CloudWatch Metrics." + value = aws_lb.lb.arn_suffix +} + +output "aws_lb_lb_dns_name" { + description = "The DNS name of the load balancer." + value = aws_lb.lb.dns_name +} + +output "aws_lb_lb_zone_id" { + description = "The canonical hosted zone ID of the load balancer (to be used in a Route 53 Alias record)." + value = aws_lb.lb.zone_id +} + +#------------------------------------------------------------------------------ +# AWS LOAD BALANCER - Target Groups +#------------------------------------------------------------------------------ +output "lb_http_tgs_ids" { + description = "List of HTTP Target Groups IDs" + value = [for tg in aws_lb_target_group.lb_http_tgs : tg.id] +} + +output "lb_http_tgs_arns" { + description = "List of HTTP Target Groups ARNs" + value = [for tg in aws_lb_target_group.lb_http_tgs : tg.arn] +} + +output "lb_http_tgs_names" { + description = "List of HTTP Target Groups Names" + value = [for tg in aws_lb_target_group.lb_http_tgs : tg.name] +} + +output "lb_http_tgs_ports" { + description = "List of HTTP Target Groups ports" + value = [for tg in aws_lb_target_group.lb_http_tgs : tostring(tg.port)] +} + +output "lb_http_tgs_map_arn_port" { + value = zipmap( + [for tg in aws_lb_target_group.lb_http_tgs : tg.arn], + [for tg in aws_lb_target_group.lb_http_tgs : tostring(tg.port)] + ) +} + +output "lb_https_tgs_ids" { + description = "List of HTTPS Target Groups IDs" + value = [for tg in aws_lb_target_group.lb_https_tgs : tg.id] +} + +output "lb_https_tgs_arns" { + description = "List of HTTPS Target Groups ARNs" + value = [for tg in aws_lb_target_group.lb_https_tgs : tg.arn] +} + +output "lb_https_tgs_names" { + description = "List of HTTPS Target Groups Names" + value = [for tg in aws_lb_target_group.lb_https_tgs : tg.name] +} + +output "lb_https_tgs_ports" { + description = "List of HTTPS Target Groups ports" + value = [for tg in aws_lb_target_group.lb_https_tgs : tostring(tg.port)] +} + +output "lb_https_tgs_map_arn_port" { + value = zipmap( + [for tg in aws_lb_target_group.lb_https_tgs : tg.arn], + [for tg in aws_lb_target_group.lb_https_tgs : tostring(tg.port)] + ) +} + +#------------------------------------------------------------------------------ +# AWS LOAD BALANCER - Listeners +#------------------------------------------------------------------------------ +output "lb_http_listeners_ids" { + description = "List of HTTP Listeners IDs" + value = [for listener in aws_lb_listener.lb_http_listeners : listener.id] +} + +output "lb_http_listeners_arns" { + description = "List of HTTP Listeners ARNs" + value = [for listener in aws_lb_listener.lb_http_listeners : listener.arn] +} + +output "lb_https_listeners_ids" { + description = "List of HTTPS Listeners IDs" + value = [for listener in aws_lb_listener.lb_https_listeners : listener.id] +} + +output "lb_https_listeners_arns" { + description = "List of HTTPS Listeners ARNs" + value = [for listener in aws_lb_listener.lb_https_listeners : listener.arn] +} + +#------------------------------------------------------------------------------ +# S3 LB Logging Bucket +#------------------------------------------------------------------------------ +output "lb_logs_s3_bucket_id" { + description = "LB Logging S3 Bucket ID" + value = var.enable_s3_logs ? module.lb_logs_s3[0].s3_bucket_id : null +} + +output "lb_logs_s3_bucket_arn" { + description = "LB Logging S3 Bucket ARN" + value = var.enable_s3_logs ? module.lb_logs_s3[0].s3_bucket_arn : null +} \ No newline at end of file diff --git a/modules/aws-ecs-load-balancer/variable.tf b/modules/aws-ecs-load-balancer/variable.tf new file mode 100644 index 0000000..f1499f7 --- /dev/null +++ b/modules/aws-ecs-load-balancer/variable.tf @@ -0,0 +1,249 @@ +#------------------------------------------------------------------------------ +# Misc +#------------------------------------------------------------------------------ +variable "name_prefix" { + description = "Name prefix for resources on AWS" +} + +variable "use_random_name_for_lb" { + description = "If true the LB name will be a random string" + type = bool + default = false +} + +variable "tags" { + type = map(string) + default = {} + description = "Resource tags" +} + +#------------------------------------------------------------------------------ +# AWS Networking +#------------------------------------------------------------------------------ +variable "vpc_id" { + description = "ID of the VPC" +} + +#------------------------------------------------------------------------------ +# S3 logs bucket +#------------------------------------------------------------------------------ +variable "enable_s3_logs" { + description = "(Optional) If true, all resources to send LB logs to S3 will be created" + type = bool + default = true +} + + +#------------------------------------------------------------------------------ +# APPLICATION LOAD BALANCER +#------------------------------------------------------------------------------ +variable "internal" { + description = "(Optional) If true, the LB will be internal." + type = bool + default = false +} + +variable "security_groups" { + description = "(Optional) A list of security group IDs to assign to the LB." + type = list(string) + default = [] +} + +variable "drop_invalid_header_fields" { + description = "(Optional) Indicates whether HTTP headers with header fields that are not valid are removed by the load balancer (true) or routed to targets (false). The default is false. Elastic Load Balancing requires that message header names contain only alphanumeric characters and hyphens." + type = bool + default = false +} + +variable "private_subnets" { + description = "A list of private subnet IDs to attach to the LB if it is INTERNAL." + type = list(string) +} + +variable "public_subnets" { + description = "A list of public subnet IDs to attach to the LB if it is NOT internal." + type = list(string) +} + +variable "idle_timeout" { + description = "(Optional) The time in seconds that the connection is allowed to be idle. Default: 60." + type = number + default = 60 +} + +variable "enable_deletion_protection" { + description = "(Optional) If true, deletion of the load balancer will be disabled via the AWS API. This will prevent Terraform from deleting the load balancer. Defaults to false." + type = bool + default = false +} + +variable "enable_cross_zone_load_balancing" { + description = "(Optional) If true, cross-zone load balancing of the load balancer will be enabled. Defaults to false." + type = bool + default = false +} + +variable "enable_http2" { + description = "(Optional) Indicates whether HTTP/2 is enabled in the load balancer. Defaults to true." + type = bool + default = true +} + +variable "ip_address_type" { + description = "(Optional) The type of IP addresses used by the subnets for your load balancer. The possible values are ipv4 and dualstack. Defaults to ipv4" + type = string + default = "ipv4" +} + +variable "waf_web_acl_arn" { + description = "ARN of a WAFV2 to associate with the ALB" + type = string + default = "" +} + +#------------------------------------------------------------------------------ +# ACCESS CONTROL TO APPLICATION LOAD BALANCER +#------------------------------------------------------------------------------ +variable "http_ports" { + description = "Map containing objects to define listeners behaviour based on type field. If type field is `forward`, include listener_port and the target_group_port. For `redirect` type, include listener port, host, path, port, protocol, query and status_code. For `fixed-response`, include listener_port, content_type, message_body and status_code" + type = map(any) + default = { + default_http = { + type = "forward" + listener_port = 80 + target_group_port = 80 + } + } +} + +variable "https_ports" { + description = "Map containing objects to define listeners behaviour based on type field. If type field is `forward`, include listener_port and the target_group_port. For `redirect` type, include listener port, host, path, port, protocol, query and status_code. For `fixed-response`, include listener_port, content_type, message_body and status_code" + type = map(any) + default = { + default_http = { + type = "forward" + listener_port = 443 + target_group_port = 443 + } + } +} + + +variable "http_ingress_cidr_blocks" { + description = "List of CIDR blocks to allowed to access the Load Balancer through HTTP" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "http_ingress_prefix_list_ids" { + description = "List of prefix list IDs blocks to allowed to access the Load Balancer through HTTP" + type = list(string) + default = [] +} + +variable "https_ingress_cidr_blocks" { + description = "List of CIDR blocks to allowed to access the Load Balancer through HTTPS" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "https_ingress_prefix_list_ids" { + description = "List of prefix list IDs blocks to allowed to access the Load Balancer through HTTPS" + type = list(string) + default = [] +} + +#------------------------------------------------------------------------------ +# AWS LOAD BALANCER - Target Groups +#------------------------------------------------------------------------------ +variable "deregistration_delay" { + description = "(Optional) The amount time for Elastic Load Balancing to wait before changing the state of a deregistering target from draining to unused. The range is 0-3600 seconds. The default value is 300 seconds." + type = number + default = 300 +} + +variable "slow_start" { + description = "(Optional) The amount time for targets to warm up before the load balancer sends them a full share of requests. The range is 30-900 seconds or 0 to disable. The default value is 0 seconds." + type = number + default = 0 +} + +variable "load_balancing_algorithm_type" { + description = "(Optional) Determines how the load balancer selects targets when routing requests. The value is round_robin or least_outstanding_requests. The default is round_robin." + type = string + default = "round_robin" +} + +variable "stickiness" { + description = "(Optional) A Stickiness block. Provide three fields. type, the type of sticky sessions. The only current possible value is lb_cookie. cookie_duration, the time period, in seconds, during which requests from a client should be routed to the same target. After this time period expires, the load balancer-generated cookie is considered stale. The range is 1 second to 1 week (604800 seconds). The default value is 1 day (86400 seconds). enabled, boolean to enable / disable stickiness. Default is true." + type = object({ + type = string + cookie_duration = string + enabled = bool + }) + default = { + type = "lb_cookie" + cookie_duration = 86400 + enabled = true + } +} + +variable "target_group_health_check_enabled" { + description = "(Optional) Indicates whether health checks are enabled. Defaults to true." + type = bool + default = true +} + +variable "target_group_health_check_interval" { + description = "(Optional) The approximate amount of time, in seconds, between health checks of an individual target. Minimum value 5 seconds, Maximum value 300 seconds. Default 30 seconds." + type = number + default = 30 +} + +variable "target_group_health_check_path" { + description = "The destination for the health check request." + type = string + default = "/" +} + +variable "target_group_health_check_timeout" { + description = "(Optional) The amount of time, in seconds, during which no response means a failed health check. The range is 2 to 120 seconds, and the default is 5 seconds." + type = number + default = 5 +} + +variable "target_group_health_check_healthy_threshold" { + description = "(Optional) The number of consecutive health checks successes required before considering an unhealthy target healthy. Defaults to 3." + type = number + default = 3 +} + +variable "target_group_health_check_unhealthy_threshold" { + description = "(Optional) The number of consecutive health check failures required before considering the target unhealthy. Defaults to 3." + type = number + default = 3 +} + +variable "target_group_health_check_matcher" { + description = "The HTTP codes to use when checking for a successful response from a target. You can specify multiple values (for example, \"200,202\") or a range of values (for example, \"200-299\"). Default is 200." + type = string + default = "200" +} + +variable "ssl_policy" { + description = "(Optional) The name of the SSL Policy for the listener. . Required if var.https_ports is set." + type = string + default = null +} + +variable "default_certificate_arn" { + description = "(Optional) The ARN of the default SSL server certificate. Required if var.https_ports is set." + type = string + default = null +} + +variable "additional_certificates_arn_for_https_listeners" { + description = "(Optional) List of SSL server certificate ARNs for HTTPS listener. Use it if you need to set additional certificates besides default_certificate_arn" + type = list(any) + default = [] +} \ No newline at end of file diff --git a/modules/aws-ecs-load-balancer/versions.tf b/modules/aws-ecs-load-balancer/versions.tf new file mode 100644 index 0000000..35402be --- /dev/null +++ b/modules/aws-ecs-load-balancer/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.6" + } + } +} diff --git a/modules/aws-ecs-service/main.tf b/modules/aws-ecs-service/main.tf new file mode 100644 index 0000000..d292256 --- /dev/null +++ b/modules/aws-ecs-service/main.tf @@ -0,0 +1,161 @@ +resource "aws_ecs_service" "service" { + name = "${var.name_prefix}-service" + cluster = var.ecs_cluster_arn + deployment_maximum_percent = var.deployment_maximum_percent + deployment_minimum_healthy_percent = var.deployment_minimum_healthy_percent + desired_count = var.desired_count + enable_ecs_managed_tags = var.enable_ecs_managed_tags + enable_execute_command = var.enable_execute_command + health_check_grace_period_seconds = var.health_check_grace_period_seconds + launch_type = "FARGATE" + force_new_deployment = var.force_new_deployment + + dynamic "load_balancer" { + for_each = var.lb_http_tgs_map_arn_port + content { + target_group_arn = load_balancer.key + container_name = var.container_name + container_port = load_balancer.value + } + } + dynamic "load_balancer" { + for_each = var.lb_https_tgs_map_arn_port + content { + target_group_arn = load_balancer.key + container_name = var.container_name + container_port = load_balancer.value + } + } + network_configuration { + security_groups = var.security_groups + subnets = var.assign_public_ip ? var.public_subnets : var.private_subnets + assign_public_ip = var.assign_public_ip + } + dynamic "ordered_placement_strategy" { + for_each = var.ordered_placement_strategy + content { + type = ordered_placement_strategy.value.type + field = lookup(ordered_placement_strategy.value, "field", null) + } + } + dynamic "deployment_controller" { + for_each = var.deployment_controller + content { + type = deployment_controller.value.type + } + } + dynamic "placement_constraints" { + for_each = var.placement_constraints + content { + expression = lookup(placement_constraints.value, "expression", null) + type = placement_constraints.value.type + } + } + platform_version = var.platform_version + propagate_tags = var.propagate_tags + dynamic "service_registries" { + for_each = var.service_registries + content { + registry_arn = service_registries.value.registry_arn + port = lookup(service_registries.value, "port", null) + container_name = lookup(service_registries.value, "container_name", null) + container_port = lookup(service_registries.value, "container_port", null) + } + } + task_definition = var.task_definition_arn + tags = var.tags + +} + +#------------------------------------------------------------------------------ +# AWS Auto Scaling - CloudWatch Alarm CPU High +#------------------------------------------------------------------------------ +resource "aws_cloudwatch_metric_alarm" "cpu_high" { + alarm_name = "${var.name_prefix}-cpu-high" + comparison_operator = "GreaterThanOrEqualToThreshold" + evaluation_periods = var.max_cpu_evaluation_period + metric_name = "CPUUtilization" + namespace = "AWS/ECS" + period = var.max_cpu_period + statistic = "Maximum" + threshold = var.max_cpu_threshold + dimensions = { + ClusterName = var.ecs_cluster_name + ServiceName = aws_ecs_service.service.name + } + alarm_actions = [aws_appautoscaling_policy.scale_up_policy.arn] + + tags = var.tags +} + +#------------------------------------------------------------------------------ +# AWS Auto Scaling - CloudWatch Alarm CPU Low +#------------------------------------------------------------------------------ +resource "aws_cloudwatch_metric_alarm" "cpu_low" { + alarm_name = "${var.name_prefix}-cpu-low" + comparison_operator = "LessThanOrEqualToThreshold" + evaluation_periods = var.min_cpu_evaluation_period + metric_name = "CPUUtilization" + namespace = "AWS/ECS" + period = var.min_cpu_period + statistic = "Average" + threshold = var.min_cpu_threshold + dimensions = { + ClusterName = var.ecs_cluster_name + ServiceName = aws_ecs_service.service.name + } + alarm_actions = [aws_appautoscaling_policy.scale_down_policy.arn] + + tags = var.tags +} + +#------------------------------------------------------------------------------ +# AWS Auto Scaling - Scaling Up Policy +#------------------------------------------------------------------------------ +resource "aws_appautoscaling_policy" "scale_up_policy" { + name = "${var.name_prefix}-scale-up-policy" + depends_on = [aws_appautoscaling_target.scale_target] + service_namespace = "ecs" + resource_id = "service/${var.ecs_cluster_name}/${aws_ecs_service.service.name}" + scalable_dimension = "ecs:service:DesiredCount" + step_scaling_policy_configuration { + adjustment_type = "ChangeInCapacity" + cooldown = 60 + metric_aggregation_type = "Maximum" + step_adjustment { + metric_interval_lower_bound = 0 + scaling_adjustment = 1 + } + } +} + +#------------------------------------------------------------------------------ +# AWS Auto Scaling - Scaling Down Policy +#------------------------------------------------------------------------------ +resource "aws_appautoscaling_policy" "scale_down_policy" { + name = "${var.name_prefix}-scale-down-policy" + depends_on = [aws_appautoscaling_target.scale_target] + service_namespace = "ecs" + resource_id = "service/${var.ecs_cluster_name}/${aws_ecs_service.service.name}" + scalable_dimension = "ecs:service:DesiredCount" + step_scaling_policy_configuration { + adjustment_type = "ChangeInCapacity" + cooldown = 60 + metric_aggregation_type = "Maximum" + step_adjustment { + metric_interval_upper_bound = 0 + scaling_adjustment = -1 + } + } +} + +#------------------------------------------------------------------------------ +# AWS Auto Scaling - Scaling Target +#------------------------------------------------------------------------------ +resource "aws_appautoscaling_target" "scale_target" { + service_namespace = "ecs" + resource_id = "service/${var.ecs_cluster_name}/${aws_ecs_service.service.name}" + scalable_dimension = "ecs:service:DesiredCount" + min_capacity = var.scale_target_min_capacity + max_capacity = var.scale_target_max_capacity +} diff --git a/modules/aws-ecs-service/output.tf b/modules/aws-ecs-service/output.tf new file mode 100644 index 0000000..cb0d76d --- /dev/null +++ b/modules/aws-ecs-service/output.tf @@ -0,0 +1,22 @@ +#------------------------------------------------------------------------------ +# AWS ECS SERVICE +#------------------------------------------------------------------------------ +output "service_arn" { + description = "The Amazon Resource Name (ARN) that identifies the service." + value = aws_ecs_service.service.id +} + +output "service_name" { + description = "The name of the service." + value = aws_ecs_service.service.name +} + +output "service_cluster" { + description = "The Amazon Resource Name (ARN) of cluster which the service runs on." + value = aws_ecs_service.service.cluster +} + +output "desired_count" { + description = "The number of instances of the task definition" + value = aws_ecs_service.service.desired_count +} \ No newline at end of file diff --git a/modules/aws-ecs-service/variables.tf b/modules/aws-ecs-service/variables.tf new file mode 100644 index 0000000..7dace3a --- /dev/null +++ b/modules/aws-ecs-service/variables.tf @@ -0,0 +1,204 @@ +#------------------------------------------------------------------------------ +# Misc +#------------------------------------------------------------------------------ +variable "name_prefix" { + description = "Name prefix for resources on AWS" +} + +#------------------------------------------------------------------------------ +# AWS Networking +#------------------------------------------------------------------------------ +variable "vpc_id" { + description = "ID of the VPC" +} + +#------------------------------------------------------------------------------ +# AWS ECS SERVICE +#------------------------------------------------------------------------------ +variable "ecs_cluster_arn" { + description = "ARN of an ECS cluster" +} + +variable "deployment_maximum_percent" { + description = "(Optional) The upper limit (as a percentage of the service's desiredCount) of the number of running tasks that can be running in a service during a deployment." + type = number + default = 200 +} + +variable "deployment_minimum_healthy_percent" { + description = "(Optional) The lower limit (as a percentage of the service's desiredCount) of the number of running tasks that must remain running and healthy in a service during a deployment." + type = number + default = 100 +} + +variable "desired_count" { + description = "(Optional) The number of instances of the task definition to place and keep running. Defaults to 0." + type = number + default = 1 +} + +variable "tags" { + type = map(string) + default = {} + description = "Resource tags" +} + +variable "enable_ecs_managed_tags" { + description = "(Optional) Specifies whether to enable Amazon ECS managed tags for the tasks within the service." + type = bool + default = false +} + +variable "health_check_grace_period_seconds" { + description = "(Optional) Seconds to ignore failing load balancer health checks on newly instantiated tasks to prevent premature shutdown, up to 2147483647. Only valid for services configured to use load balancers." + type = number + default = 0 +} + +variable "ordered_placement_strategy" { + description = "(Optional) Service level strategy rules that are taken into consideration during task placement. List from top to bottom in order of precedence. The maximum number of ordered_placement_strategy blocks is 5. This is a list of maps where each map should contain \"id\" and \"field\"" + type = list(any) + default = [] +} + +variable "deployment_controller" { + description = "(Optional) Deployment controller" + type = list(string) + default = [] +} + +variable "placement_constraints" { + type = list(any) + description = "(Optional) rules that are taken into consideration during task placement. Maximum number of placement_constraints is 10. This is a list of maps, where each map should contain \"type\" and \"expression\"" + default = [] +} + +variable "platform_version" { + description = "(Optional) The platform version on which to run your service. Defaults to 1.4.0. More information about Fargate platform versions can be found in the AWS ECS User Guide." + default = "1.4.0" +} + +variable "propagate_tags" { + description = "(Optional) Specifies whether to propagate the tags from the task definition or the service to the tasks. The valid values are SERVICE and TASK_DEFINITION. Default to SERVICE" + default = "SERVICE" +} + +variable "service_registries" { + description = "(Optional) The service discovery registries for the service. The maximum number of service_registries blocks is 1. This is a map that should contain the following fields \"registry_arn\", \"port\", \"container_port\" and \"container_name\"" + type = map(any) + default = {} +} + +variable "task_definition_arn" { + description = "(Required) The full ARN of the task definition that you want to run in your service." +} + +variable "force_new_deployment" { + description = "(Optional) Enable to force a new task deployment of the service. This can be used to update tasks to use a newer Docker image with same image/tag combination (e.g. myimage:latest), roll Fargate tasks onto a newer platform version, or immediately deploy ordered_placement_strategy and placement_constraints updates." + type = bool + default = false +} + +variable "enable_execute_command" { + description = "(Optional) Specifies whether to enable Amazon ECS Exec for the tasks within the service." + type = bool + default = false +} + +#------------------------------------------------------------------------------ +# AWS ECS SERVICE network_configuration BLOCK +#------------------------------------------------------------------------------ +variable "public_subnets" { + description = "The public subnets associated with the task or service." + type = list(any) +} + +variable "private_subnets" { + description = "The private subnets associated with the task or service." + type = list(any) +} + +variable "security_groups" { + description = "(Optional) The security groups associated with the task or service. If you do not specify a security group, the default security group for the VPC is used." + type = list(any) + default = [] +} + +variable "assign_public_ip" { + description = "(Optional) Assign a public IP address to the ENI (Fargate launch type only). If true service will be associated with public subnets. Default false. " + type = bool + default = false +} + + +#------------------------------------------------------------------------------ +# AWS ECS SERVICE load_balancer BLOCK +#------------------------------------------------------------------------------ +variable "container_name" { + description = "Name of the running container" +} + +variable "lb_http_tgs_map_arn_port" { + type = map(any) + description = "Load balancer https target groups arns" + default = {} +} + + +variable "lb_https_tgs_map_arn_port" { + type = map(any) + description = "Load balancer https target groups arns" + default = {} +} + +#------------------------------------------------------------------------------ +# AWS ECS SERVICE AUTOSCALING +#------------------------------------------------------------------------------ +variable "ecs_cluster_name" { + description = "Name of the ECS cluster" +} + +variable "max_cpu_threshold" { + description = "Threshold for max CPU usage" + default = "85" + type = string +} +variable "min_cpu_threshold" { + description = "Threshold for min CPU usage" + default = "10" + type = string +} + +variable "max_cpu_evaluation_period" { + description = "The number of periods over which data is compared to the specified threshold for max cpu metric alarm" + default = "3" + type = string +} +variable "min_cpu_evaluation_period" { + description = "The number of periods over which data is compared to the specified threshold for min cpu metric alarm" + default = "3" + type = string +} + +variable "max_cpu_period" { + description = "The period in seconds over which the specified statistic is applied for max cpu metric alarm" + default = "60" + type = string +} +variable "min_cpu_period" { + description = "The period in seconds over which the specified statistic is applied for min cpu metric alarm" + default = "60" + type = string +} + +variable "scale_target_max_capacity" { + description = "The max capacity of the scalable target" + default = 5 + type = number +} + +variable "scale_target_min_capacity" { + description = "The min capacity of the scalable target" + default = 1 + type = number +} \ No newline at end of file diff --git a/modules/aws-ecs-service/versions.tf b/modules/aws-ecs-service/versions.tf new file mode 100644 index 0000000..35402be --- /dev/null +++ b/modules/aws-ecs-service/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.6" + } + } +} diff --git a/modules/aws-ecs-task-definition/files/iam/ecs_task_execution_iam_role.json b/modules/aws-ecs-task-definition/files/iam/ecs_task_execution_iam_role.json new file mode 100644 index 0000000..e11b137 --- /dev/null +++ b/modules/aws-ecs-task-definition/files/iam/ecs_task_execution_iam_role.json @@ -0,0 +1,13 @@ +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": { + "Service": "ecs-tasks.amazonaws.com" + }, + "Action": "sts:AssumeRole", + "Sid": "" + } + ] +} \ No newline at end of file diff --git a/modules/aws-ecs-task-definition/main.tf b/modules/aws-ecs-task-definition/main.tf new file mode 100644 index 0000000..59b6952 --- /dev/null +++ b/modules/aws-ecs-task-definition/main.tf @@ -0,0 +1,119 @@ +#------------------------------------------------------------------------------ +# AWS ECS Task Execution Role +#------------------------------------------------------------------------------ +resource "aws_iam_role" "ecs_task_execution_role" { + name = "${var.name_prefix}-ecs-task-execution-role" + assume_role_policy = file("${path.module}/files/iam/ecs_task_execution_iam_role.json") + permissions_boundary = var.permissions_boundary + tags = var.tags +} + +resource "aws_iam_role_policy_attachment" "ecs_task_execution_role_policy_attach" { + role = aws_iam_role.ecs_task_execution_role.name + policy_arn = "arn:${var.iam_partition}:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy" +} + +resource "aws_iam_policy" "ecs_task_execution_role_custom_policy" { + count = length(var.ecs_task_execution_role_custom_policies) + name = "${var.name_prefix}-ecs-task-execution-role-custom-policy-${count.index}" + description = "A custom policy for ${var.name_prefix}-ecs-task-execution-role IAM Role" + policy = var.ecs_task_execution_role_custom_policies[count.index] + tags = var.tags +} + +resource "aws_iam_role_policy_attachment" "ecs_task_execution_role_custom_policy" { + count = length(var.ecs_task_execution_role_custom_policies) + role = aws_iam_role.ecs_task_execution_role.name + policy_arn = aws_iam_policy.ecs_task_execution_role_custom_policy[count.index].arn +} + +#------------------------------------------------------------------------------ +# ECS Task Definition +#------------------------------------------------------------------------------ +# Task Definition +resource "aws_ecs_task_definition" "td" { + family = "${var.name_prefix}-td" + container_definitions = jsonencode([ + { + name = var.container_name + image = var.container_image + cpu = var.container_cpu + memory = var.container_memory + essential = true + portMappings = [ + { + containerPort = var.container_port + hostPort = var.container_host_port + } + ] + } + ]) + task_role_arn = var.task_role_arn == null ? aws_iam_role.ecs_task_execution_role.arn : var.task_role_arn + execution_role_arn = aws_iam_role.ecs_task_execution_role.arn + network_mode = "awsvpc" + dynamic "placement_constraints" { + for_each = var.placement_constraints + content { + expression = lookup(placement_constraints.value, "expression", null) + type = placement_constraints.value.type + } + } + cpu = var.container_cpu + memory = var.container_memory + requires_compatibilities = ["FARGATE"] + dynamic "proxy_configuration" { + for_each = var.proxy_configuration + content { + container_name = proxy_configuration.value.container_name + properties = lookup(proxy_configuration.value, "properties", null) + type = lookup(proxy_configuration.value, "type", null) + } + } + dynamic "ephemeral_storage" { + for_each = var.ephemeral_storage_size == 0 ? [] : [var.ephemeral_storage_size] + content { + size_in_gib = var.ephemeral_storage_size + } + } + dynamic "volume" { + for_each = var.volumes + content { + name = volume.value.name + + host_path = lookup(volume.value, "host_path", null) + + dynamic "docker_volume_configuration" { + for_each = lookup(volume.value, "docker_volume_configuration", []) + content { + autoprovision = lookup(docker_volume_configuration.value, "autoprovision", null) + driver = lookup(docker_volume_configuration.value, "driver", null) + driver_opts = lookup(docker_volume_configuration.value, "driver_opts", null) + labels = lookup(docker_volume_configuration.value, "labels", null) + scope = lookup(docker_volume_configuration.value, "scope", null) + } + } + + dynamic "efs_volume_configuration" { + for_each = lookup(volume.value, "efs_volume_configuration", []) + content { + file_system_id = lookup(efs_volume_configuration.value, "file_system_id", null) + root_directory = lookup(efs_volume_configuration.value, "root_directory", null) + transit_encryption = lookup(efs_volume_configuration.value, "transit_encryption", null) + transit_encryption_port = lookup(efs_volume_configuration.value, "transit_encryption_port", null) + dynamic "authorization_config" { + for_each = lookup(efs_volume_configuration.value, "authorization_config", []) + content { + access_point_id = lookup(authorization_config.value, "access_point_id", null) + iam = lookup(authorization_config.value, "iam", null) + } + } + } + } + } + } + + tags = var.tags +} + +# TODO - Add this missing parameter +# inference_accelerator - (Optional) Configuration block(s) with Inference Accelerators settings. Detailed below. \ No newline at end of file diff --git a/modules/aws-ecs-task-definition/outputs.tf b/modules/aws-ecs-task-definition/outputs.tf new file mode 100644 index 0000000..09bc01f --- /dev/null +++ b/modules/aws-ecs-task-definition/outputs.tf @@ -0,0 +1,7 @@ +output "task_definition_arn" { + value = aws_ecs_task_definition.td.arn +} + +output "container_name" { + value = var.container_name +} \ No newline at end of file diff --git a/modules/aws-ecs-task-definition/variable.tf b/modules/aws-ecs-task-definition/variable.tf new file mode 100644 index 0000000..dbb6132 --- /dev/null +++ b/modules/aws-ecs-task-definition/variable.tf @@ -0,0 +1,416 @@ +#------------------------------------------------------------------------------ +# Misc +#------------------------------------------------------------------------------ +variable "name_prefix" { + description = "Name prefix for resources on AWS" +} + +variable "tags" { + type = map(string) + default = {} + description = "Resource tags" +} + +#------------------------------------------------------------------------------ +# AWS ECS Container Definition Variables for Cloudposse module +#------------------------------------------------------------------------------ +variable "container_name" { + type = string + default = null + description = "The name of the container. Up to 255 characters ([a-z], [A-Z], [0-9], -, _ allowed)" +} + +variable "container_image" { + type = string + default = null + description = "The image used to start the container. Images in the Docker Hub registry available by default" +} + +variable "container_memory" { + type = number + description = "(Optional) The amount of memory (in MiB) to allow the container to use. This is a hard limit, if the container attempts to exceed the container_memory, the container is killed. This field is optional for Fargate launch type and the total amount of container_memory of all containers in a task will need to be lower than the task memory value" + default = 4096 # 4 GB +} + +variable "container_port" { + type = number + description = "Container port" + default = 80 # 80 +} + +variable "container_host_port" { + type = number + description = "Container host port" + default = 80 # 80 +} + +variable "container_memory_reservation" { + type = number + description = "(Optional) The amount of memory (in MiB) to reserve for the container. If container needs to exceed this threshold, it can do so up to the set container_memory hard limit" + default = 2048 # 2 GB +} + +variable "container_definition" { + type = map(any) + description = "Container definition overrides which allows for extra keys or overriding existing keys." + default = {} +} + +variable "containers" { + type = list(any) + description = "Container definitions to use for the task. If this is used, all other container options will be ignored." + default = [] +} + +variable "port_mappings" { + description = "The port mappings to configure for the container. This is a list of maps. Each map should contain \"containerPort\", \"hostPort\", and \"protocol\", where \"protocol\" is one of \"tcp\" or \"udp\". If using containers in a task with the awsvpc or host network mode, the hostPort can either be left blank or set to the same value as the containerPort" + type = list(object({ + containerPort = number + hostPort = number + protocol = string + })) + default = [ + { + containerPort = 80 + hostPort = 80 + protocol = "tcp" + } + ] +} + +# https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_HealthCheck.html +variable "healthcheck" { + description = "(Optional) A map containing command (string), timeout, interval (duration in seconds), retries (1-10, number of times to retry before marking container unhealthy), and startPeriod (0-300, optional grace period to wait, in seconds, before failed healthchecks count toward retries)" + type = object({ + command = list(string) + retries = number + timeout = number + interval = number + startPeriod = number + }) + default = null +} + +variable "container_cpu" { + # https://docs.aws.amazon.com/AmazonECS/latest/developerguide/AWS_Fargate.html#fargate-task-defs + type = number + description = "(Optional) The number of cpu units to reserve for the container. This is optional for tasks using Fargate launch type and the total amount of container_cpu of all containers in a task will need to be lower than the task-level cpu value" + default = 1024 # 1 vCPU +} + +variable "essential" { + type = bool + description = "Determines whether all other containers in a task are stopped, if this container fails or stops for any reason. Due to how Terraform type casts booleans in json it is required to double quote this value" + default = true +} + +variable "entrypoint" { + type = list(string) + description = "The entry point that is passed to the container" + default = null +} + +variable "command" { + type = list(string) + description = "The command that is passed to the container" + default = null +} + +variable "working_directory" { + type = string + description = "The working directory to run commands inside the container" + default = null +} + +variable "environment" { + type = list(object({ + name = string + value = string + })) + description = "The environment variables to pass to the container. This is a list of maps. map_environment overrides environment" + default = [] +} + +variable "extra_hosts" { + type = list(object({ + ipAddress = string + hostname = string + })) + description = "A list of hostnames and IP address mappings to append to the /etc/hosts file on the container. This is a list of maps" + default = null +} + +variable "map_environment" { + type = map(string) + description = "The environment variables to pass to the container. This is a map of string: {key: value}. map_environment overrides environment" + default = null +} + +# https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_EnvironmentFile.html +variable "environment_files" { + type = list(object({ + value = string + type = string + })) + description = "One or more files containing the environment variables to pass to the container. This maps to the --env-file option to docker run. The file must be hosted in Amazon S3. This option is only available to tasks using the EC2 launch type. This is a list of maps" + default = [] +} + +variable "secrets" { + type = list(object({ + name = string + valueFrom = string + })) + description = "The secrets to pass to the container. This is a list of maps" + default = [] +} + +variable "readonly_root_filesystem" { + type = bool + description = "Determines whether a container is given read-only access to its root filesystem. Due to how Terraform type casts booleans in json it is required to double quote this value" + default = false +} + +# https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_LinuxParameters.html +variable "linux_parameters" { + type = object({ + capabilities = object({ + add = list(string) + drop = list(string) + }) + devices = list(object({ + containerPath = string + hostPath = string + permissions = list(string) + })) + initProcessEnabled = bool + maxSwap = number + sharedMemorySize = number + swappiness = number + tmpfs = list(object({ + containerPath = string + mountOptions = list(string) + size = number + })) + }) + description = "Linux-specific modifications that are applied to the container, such as Linux kernel capabilities. For more details, see https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_LinuxParameters.html" + default = null +} + +# https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_LogConfiguration.html +variable "log_configuration" { + type = any + description = "Log configuration options to send to a custom log driver for the container. For more details, see https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_LogConfiguration.html" + default = null +} + +# https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_FirelensConfiguration.html +variable "firelens_configuration" { + type = object({ + type = string + options = map(string) + }) + description = "The FireLens configuration for the container. This is used to specify and configure a log router for container logs. For more details, see https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_FirelensConfiguration.html" + default = null +} + +variable "mount_points" { + type = list(any) + + description = "Container mount points. This is a list of maps, where each map should contain a `containerPath` and `sourceVolume`. The `readOnly` key is optional." + default = [] +} + +variable "dns_servers" { + type = list(string) + description = "Container DNS servers. This is a list of strings specifying the IP addresses of the DNS servers" + default = [] +} + +variable "dns_search_domains" { + type = list(string) + description = "Container DNS search domains. A list of DNS search domains that are presented to the container" + default = [] +} + +variable "ulimits" { + type = list(object({ + name = string + hardLimit = number + softLimit = number + })) + description = "Container ulimit settings. This is a list of maps, where each map should contain \"name\", \"hardLimit\" and \"softLimit\"" + default = null +} + +variable "repository_credentials" { + type = map(string) + description = "Container repository credentials; required when using a private repo. This map currently supports a single key; \"credentialsParameter\", which should be the ARN of a Secrets Manager's secret holding the credentials" + default = null +} + +variable "volumes_from" { + type = list(object({ + sourceContainer = string + readOnly = bool + })) + description = "A list of VolumesFrom maps which contain \"sourceContainer\" (name of the container that has the volumes to mount) and \"readOnly\" (whether the container can write to the volume)" + default = [] +} + +variable "links" { + type = list(string) + description = "List of container names this container can communicate with without port mappings" + default = [] +} + +variable "user" { + type = string + description = "The user to run as inside the container. Can be any of these formats: user, user:group, uid, uid:gid, user:gid, uid:group. The default (null) will use the container's configured `USER` directive or root if not set." + default = null +} + +variable "container_depends_on" { + type = list(object({ + containerName = string + condition = string + })) + description = "The dependencies defined for container startup and shutdown. A container can contain multiple dependencies. When a dependency is defined for container startup, for container shutdown it is reversed. The condition can be one of START, COMPLETE, SUCCESS or HEALTHY" + default = [] +} + +variable "docker_labels" { + type = map(string) + description = "The configuration options to send to the `docker_labels`" + default = null +} + +variable "start_timeout" { + type = number + description = "Time duration (in seconds) to wait before giving up on resolving dependencies for a container" + default = null +} + +variable "stop_timeout" { + type = number + description = "Time duration (in seconds) to wait before the container is forcefully killed if it doesn't exit normally on its own" + default = null +} + +variable "privileged" { + type = bool + description = "When this variable is `true`, the container is given elevated privileges on the host container instance (similar to the root user). This parameter is not supported for Windows containers or tasks using the Fargate launch type." + default = null +} + +variable "system_controls" { + type = list(map(string)) + description = "A list of namespaced kernel parameters to set in the container, mapping to the --sysctl option to docker run. This is a list of maps: { namespace = \"\", value = \"\"}" + default = [] +} + +variable "hostname" { + type = string + description = "The hostname to use for your container." + default = null +} + +variable "disable_networking" { + type = bool + description = "When this parameter is true, networking is disabled within the container." + default = null +} + +variable "interactive" { + type = bool + description = "When this parameter is true, this allows you to deploy containerized applications that require stdin or a tty to be allocated." + default = null +} + +variable "pseudo_terminal" { + type = bool + description = "When this parameter is true, a TTY is allocated. " + default = null +} + +variable "docker_security_options" { + type = list(string) + description = "A list of strings to provide custom labels for SELinux and AppArmor multi-level security systems." + default = [] +} + +#------------------------------------------------------------------------------ +# AWS ECS Task Definition Variables +#------------------------------------------------------------------------------ +variable "iam_partition" { + description = "IAM partition to use when referencing standard policies. GovCloud and some other regions use different partitions" + type = string + default = "aws" +} + +variable "permissions_boundary" { + description = "(Optional) The ARN of the policy that is used to set the permissions boundary for the `ecs_task_execution_role` role." + type = string + default = null +} + +variable "task_role_arn" { + description = "(Optional) The ARN of IAM role that allows your Amazon ECS container task to make calls to other AWS services. If not specified, `aws_iam_role.ecs_task_execution_role.arn` is used" + type = string + default = null +} + +variable "ecs_task_execution_role_custom_policies" { + description = "(Optional) Custom policies to attach to the ECS task execution role. For example for reading secrets from AWS Systems Manager Parameter Store or Secrets Manager" + type = list(string) + default = [] +} + +variable "placement_constraints" { + description = "(Optional) A set of placement constraints rules that are taken into consideration during task placement. Maximum number of placement_constraints is 10. This is a list of maps, where each map should contain \"type\" and \"expression\"" + type = list(any) + default = [] +} + +variable "proxy_configuration" { + description = "(Optional) The proxy configuration details for the App Mesh proxy. This is a list of maps, where each map should contain \"container_name\", \"properties\" and \"type\"" + type = list(any) + default = [] +} + +variable "ephemeral_storage_size" { + type = number + description = "The number of GBs to provision for ephemeral storage on Fargate tasks. Must be greater than or equal to 21 and less than or equal to 200" + default = 0 + + validation { + condition = var.ephemeral_storage_size == 0 || (var.ephemeral_storage_size >= 21 && var.ephemeral_storage_size <= 200) + error_message = "The ephemeral_storage_size value must be inclusively between 21 and 200." + } +} + +variable "volumes" { + description = "(Optional) A set of volume blocks that containers in your task may use" + type = list(object({ + host_path = string + name = string + docker_volume_configuration = list(object({ + autoprovision = bool + driver = string + driver_opts = map(string) + labels = map(string) + scope = string + })) + efs_volume_configuration = list(object({ + file_system_id = string + root_directory = string + transit_encryption = string + transit_encryption_port = string + authorization_config = list(object({ + access_point_id = string + iam = string + })) + })) + })) + default = [] +} \ No newline at end of file diff --git a/modules/aws-ecs-task-definition/versions.tf b/modules/aws-ecs-task-definition/versions.tf new file mode 100644 index 0000000..35402be --- /dev/null +++ b/modules/aws-ecs-task-definition/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.6" + } + } +} diff --git a/modules/aws-ecs/README.md b/modules/aws-ecs/README.md new file mode 100644 index 0000000..e542897 --- /dev/null +++ b/modules/aws-ecs/README.md @@ -0,0 +1,247 @@ +# AWS ECS Terraform module + +Terraform module which creates ECS (Elastic Container Service) resources on AWS. + +## Available Features + +- ECS cluster +- Fargate capacity providers +- EC2 AutoScaling Group capacity providers + +## Usage + +### Fargate Capacity Providers + +```hcl +module "ecs" { + source = "terraform-aws-modules/ecs/aws" + + cluster_name = "ecs-fargate" + + cluster_configuration = { + execute_command_configuration = { + logging = "OVERRIDE" + log_configuration = { + cloud_watch_log_group_name = "/aws/ecs/aws-ec2" + } + } + } + + fargate_capacity_providers = { + FARGATE = { + default_capacity_provider_strategy = { + weight = 50 + } + } + FARGATE_SPOT = { + default_capacity_provider_strategy = { + weight = 50 + } + } + } + + tags = { + Environment = "Development" + Project = "EcsEc2" + } +} +``` + +### EC2 Autoscaling Capacity Providers + +```hcl +module "ecs" { + source = "terraform-aws-modules/ecs/aws" + + cluster_name = "ecs-ec2" + + cluster_configuration = { + execute_command_configuration = { + logging = "OVERRIDE" + log_configuration = { + cloud_watch_log_group_name = "/aws/ecs/aws-ec2" + } + } + } + + autoscaling_capacity_providers = { + one = { + auto_scaling_group_arn = "arn:aws:autoscaling:eu-west-1:012345678901:autoScalingGroup:08419a61:autoScalingGroupName/ecs-ec2-one-20220603194933774300000011" + managed_termination_protection = "ENABLED" + + managed_scaling = { + maximum_scaling_step_size = 5 + minimum_scaling_step_size = 1 + status = "ENABLED" + target_capacity = 60 + } + + default_capacity_provider_strategy = { + weight = 60 + base = 20 + } + } + two = { + auto_scaling_group_arn = "arn:aws:autoscaling:eu-west-1:012345678901:autoScalingGroup:08419a61:autoScalingGroupName/ecs-ec2-two-20220603194933774300000022" + managed_termination_protection = "ENABLED" + + managed_scaling = { + maximum_scaling_step_size = 15 + minimum_scaling_step_size = 5 + status = "ENABLED" + target_capacity = 90 + } + + default_capacity_provider_strategy = { + weight = 40 + } + } + } + + tags = { + Environment = "Development" + Project = "EcsEc2" + } +} +``` + +### Fargate & EC2 Autoscaling Capacity Providers + +```hcl +module "ecs" { + source = "terraform-aws-modules/ecs/aws" + + cluster_name = "ecs-mixed" + + cluster_configuration = { + execute_command_configuration = { + logging = "OVERRIDE" + log_configuration = { + cloud_watch_log_group_name = "/aws/ecs/aws-ec2" + } + } + } + + fargate_capacity_providers = { + FARGATE = { + default_capacity_provider_strategy = { + weight = 50 + } + } + FARGATE_SPOT = { + default_capacity_provider_strategy = { + weight = 50 + } + } + } + + autoscaling_capacity_providers = { + one = { + auto_scaling_group_arn = "arn:aws:autoscaling:eu-west-1:012345678901:autoScalingGroup:08419a61:autoScalingGroupName/ecs-ec2-one-20220603194933774300000011" + managed_termination_protection = "ENABLED" + + managed_scaling = { + maximum_scaling_step_size = 5 + minimum_scaling_step_size = 1 + status = "ENABLED" + target_capacity = 60 + } + + default_capacity_provider_strategy = { + weight = 60 + base = 20 + } + } + two = { + auto_scaling_group_arn = "arn:aws:autoscaling:eu-west-1:012345678901:autoScalingGroup:08419a61:autoScalingGroupName/ecs-ec2-two-20220603194933774300000022" + managed_termination_protection = "ENABLED" + + managed_scaling = { + maximum_scaling_step_size = 15 + minimum_scaling_step_size = 5 + status = "ENABLED" + target_capacity = 90 + } + + default_capacity_provider_strategy = { + weight = 40 + } + } + } + + tags = { + Environment = "Development" + Project = "EcsEc2" + } +} +``` + +## Conditional Creation + +The following values are provided to toggle on/off creation of the associated resources as desired: + +```hcl +module "ecs" { + source = "terraform-aws-modules/ecs/aws" + + # Disable creation of cluster and all resources + create = false + + # ... omitted +} +``` + +## Examples + +- [ECS Cluster w/ EC2 Autoscaling Capacity Provider](https://github.com/terraform-aws-modules/terraform-aws-ecs/tree/master/examples/complete) +- [ECS Cluster w/ Fargate Capacity Provider](https://github.com/terraform-aws-modules/terraform-aws-ecs/tree/master/examples/fargate) + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.0 | +| [aws](#requirement\_aws) | >= 4.6 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 4.6 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_ecs_capacity_provider.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecs_capacity_provider) | resource | +| [aws_ecs_cluster.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecs_cluster) | resource | +| [aws_ecs_cluster_capacity_providers.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecs_cluster_capacity_providers) | resource | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [autoscaling\_capacity\_providers](#input\_autoscaling\_capacity\_providers) | Map of autoscaling capacity provider definitons to create for the cluster | `any` | `{}` | no | +| [cluster\_configuration](#input\_cluster\_configuration) | The execute command configuration for the cluster | `any` | `{}` | no | +| [cluster\_name](#input\_cluster\_name) | Name of the cluster (up to 255 letters, numbers, hyphens, and underscores) | `string` | `""` | no | +| [cluster\_settings](#input\_cluster\_settings) | Configuration block(s) with cluster settings. For example, this can be used to enable CloudWatch Container Insights for a cluster | `map(string)` |
"http_endpoint": "enabled",
"http_put_response_hop_limit": 1,
"http_tokens": "optional"
}
{| no | +| [create](#input\_create) | Determines whether resources will be created (affects all resources) | `bool` | `true` | no | +| [default\_capacity\_provider\_use\_fargate](#input\_default\_capacity\_provider\_use\_fargate) | Determines whether to use Fargate or autoscaling for default capacity provider strategy | `bool` | `true` | no | +| [fargate\_capacity\_providers](#input\_fargate\_capacity\_providers) | Map of Fargate capacity provider definitions to use for the cluster | `any` | `{}` | no | +| [tags](#input\_tags) | A map of tags to add to all resources | `map(string)` | `{}` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [autoscaling\_capacity\_providers](#output\_autoscaling\_capacity\_providers) | Map of autoscaling capacity providers created and their attributes | +| [cluster\_arn](#output\_cluster\_arn) | ARN that identifies the cluster | +| [cluster\_capacity\_providers](#output\_cluster\_capacity\_providers) | Map of cluster capacity providers attributes | +| [cluster\_id](#output\_cluster\_id) | ID that identifies the cluster | +| [cluster\_name](#output\_cluster\_name) | Name that identifies the cluster | + \ No newline at end of file diff --git a/modules/aws-ecs/examples/complete/README.md b/modules/aws-ecs/examples/complete/README.md new file mode 100644 index 0000000..977980b --- /dev/null +++ b/modules/aws-ecs/examples/complete/README.md @@ -0,0 +1,66 @@ +# ECS Cluster w/ EC2 Autoscaling + +Configuration in this directory creates: + +- ECS cluster using autoscaling group capacity provider +- Autoscaling groups with IAM instance profile to be used by ECS cluster +- Example ECS service + +## Usage + +To run this example you need to execute: + +```bash +$ terraform init +$ terraform plan +$ terraform apply +``` + +Note that this example may create resources which will incur monetary charges on your AWS bill. Run `terraform destroy` when you no longer need these resources. + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.0 | +| [aws](#requirement\_aws) | >= 4.6 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 4.6 | + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [autoscaling](#module\_autoscaling) | terraform-aws-modules/autoscaling/aws | ~> 6.5 | +| [autoscaling\_sg](#module\_autoscaling\_sg) | terraform-aws-modules/security-group/aws | ~> 4.0 | +| [ecs](#module\_ecs) | ../.. | n/a | +| [ecs\_disabled](#module\_ecs\_disabled) | ../.. | n/a | +| [hello\_world](#module\_hello\_world) | ./service-hello-world | n/a | +| [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 3.0 | + +## Resources + +| Name | Type | +|------|------| +| [aws_cloudwatch_log_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) | resource | +| [aws_ssm_parameter.ecs_optimized_ami](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ssm_parameter) | data source | + +## Inputs + +No inputs. + +## Outputs + +| Name | Description | +|------|-------------| +| [autoscaling\_capacity\_providers](#output\_autoscaling\_capacity\_providers) | Map of capacity providers created and their attributes | +| [cluster\_arn](#output\_cluster\_arn) | ARN that identifies the cluster | +| [cluster\_capacity\_providers](#output\_cluster\_capacity\_providers) | Map of cluster capacity providers attributes | +| [cluster\_id](#output\_cluster\_id) | ID that identifies the cluster | +| [cluster\_name](#output\_cluster\_name) | Name that identifies the cluster | + diff --git a/modules/aws-ecs/examples/complete/main.tf b/modules/aws-ecs/examples/complete/main.tf new file mode 100644 index 0000000..9c70e5e --- /dev/null +++ b/modules/aws-ecs/examples/complete/main.tf @@ -0,0 +1,199 @@ +provider "aws" { + region = local.region +} + +locals { + region = "eu-west-1" + name = "ecs-ex-${replace(basename(path.cwd), "_", "-")}" + + user_data = <<-EOT + #!/bin/bash + cat <<'EOF' >> /etc/ecs/ecs.config + ECS_CLUSTER=${local.name} + ECS_LOGLEVEL=debug + EOF + EOT + + tags = { + Name = local.name + Example = local.name + Repository = "https://github.com/terraform-aws-modules/terraform-aws-ecs" + } +} + +################################################################################ +# ECS Module +################################################################################ + +module "ecs" { + source = "../.." + + cluster_name = local.name + + cluster_configuration = { + execute_command_configuration = { + logging = "OVERRIDE" + log_configuration = { + # You can set a simple string and ECS will create the CloudWatch log group for you + # or you can create the resource yourself as shown here to better manage retetion, tagging, etc. + # Embedding it into the module is not trivial and therefore it is externalized + cloud_watch_log_group_name = aws_cloudwatch_log_group.this.name + } + } + } + + default_capacity_provider_use_fargate = false + + # Capacity provider - Fargate + fargate_capacity_providers = { + FARGATE = {} + FARGATE_SPOT = {} + } + + # Capacity provider - autoscaling groups + autoscaling_capacity_providers = { + one = { + auto_scaling_group_arn = module.autoscaling["one"].autoscaling_group_arn + managed_termination_protection = "ENABLED" + + managed_scaling = { + maximum_scaling_step_size = 5 + minimum_scaling_step_size = 1 + status = "ENABLED" + target_capacity = 60 + } + + default_capacity_provider_strategy = { + weight = 60 + base = 20 + } + } + two = { + auto_scaling_group_arn = module.autoscaling["two"].autoscaling_group_arn + managed_termination_protection = "ENABLED" + + managed_scaling = { + maximum_scaling_step_size = 15 + minimum_scaling_step_size = 5 + status = "ENABLED" + target_capacity = 90 + } + + default_capacity_provider_strategy = { + weight = 40 + } + } + } + + tags = local.tags +} + +module "hello_world" { + source = "./service-hello-world" + + cluster_id = module.ecs.cluster_id +} + +module "ecs_disabled" { + source = "../.." + + create = false +} + +################################################################################ +# Supporting Resources +################################################################################ + +# https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-optimized_AMI.html#ecs-optimized-ami-linux +data "aws_ssm_parameter" "ecs_optimized_ami" { + name = "/aws/service/ecs/optimized-ami/amazon-linux-2/recommended" +} + +module "autoscaling" { + source = "terraform-aws-modules/autoscaling/aws" + version = "~> 6.5" + + for_each = { + one = { + instance_type = "t3.micro" + } + two = { + instance_type = "t3.small" + } + } + + name = "${local.name}-${each.key}" + + image_id = jsondecode(data.aws_ssm_parameter.ecs_optimized_ami.value)["image_id"] + instance_type = each.value.instance_type + + security_groups = [module.autoscaling_sg.security_group_id] + user_data = base64encode(local.user_data) + ignore_desired_capacity_changes = true + + create_iam_instance_profile = true + iam_role_name = local.name + iam_role_description = "ECS role for ${local.name}" + iam_role_policies = { + AmazonEC2ContainerServiceforEC2Role = "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role" + AmazonSSMManagedInstanceCore = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore" + } + + vpc_zone_identifier = module.vpc.private_subnets + health_check_type = "EC2" + min_size = 0 + max_size = 2 + desired_capacity = 1 + + # https://github.com/hashicorp/terraform-provider-aws/issues/12582 + autoscaling_group_tags = { + AmazonECSManaged = true + } + + # Required for managed_termination_protection = "ENABLED" + protect_from_scale_in = true + + tags = local.tags +} + +module "autoscaling_sg" { + source = "terraform-aws-modules/security-group/aws" + version = "~> 4.0" + + name = local.name + description = "Autoscaling group security group" + vpc_id = module.vpc.vpc_id + + ingress_cidr_blocks = ["0.0.0.0/0"] + ingress_rules = ["https-443-tcp"] + + egress_rules = ["all-all"] + + tags = local.tags +} + +module "vpc" { + source = "terraform-aws-modules/vpc/aws" + version = "~> 3.0" + + name = local.name + cidr = "10.99.0.0/18" + + azs = ["${local.region}a", "${local.region}b", "${local.region}c"] + public_subnets = ["10.99.0.0/24", "10.99.1.0/24", "10.99.2.0/24"] + private_subnets = ["10.99.3.0/24", "10.99.4.0/24", "10.99.5.0/24"] + + enable_nat_gateway = true + single_nat_gateway = true + enable_dns_hostnames = true + map_public_ip_on_launch = false + + tags = local.tags +} + +resource "aws_cloudwatch_log_group" "this" { + name = "/aws/ecs/${local.name}" + retention_in_days = 7 + + tags = local.tags +} diff --git a/modules/aws-ecs/examples/complete/outputs.tf b/modules/aws-ecs/examples/complete/outputs.tf new file mode 100644 index 0000000..4436a96 --- /dev/null +++ b/modules/aws-ecs/examples/complete/outputs.tf @@ -0,0 +1,36 @@ +################################################################################ +# Cluster +################################################################################ + +output "cluster_arn" { + description = "ARN that identifies the cluster" + value = module.ecs.cluster_arn +} + +output "cluster_id" { + description = "ID that identifies the cluster" + value = module.ecs.cluster_id +} + +output "cluster_name" { + description = "Name that identifies the cluster" + value = module.ecs.cluster_name +} + +################################################################################ +# Cluster Capacity Providers +################################################################################ + +output "cluster_capacity_providers" { + description = "Map of cluster capacity providers attributes" + value = module.ecs.cluster_capacity_providers +} + +################################################################################ +# Capacity Provider +################################################################################ + +output "autoscaling_capacity_providers" { + description = "Map of capacity providers created and their attributes" + value = module.ecs.autoscaling_capacity_providers +} diff --git a/modules/aws-ecs/examples/complete/service-hello-world/main.tf b/modules/aws-ecs/examples/complete/service-hello-world/main.tf new file mode 100644 index 0000000..b9661bb --- /dev/null +++ b/modules/aws-ecs/examples/complete/service-hello-world/main.tf @@ -0,0 +1,38 @@ +resource "aws_cloudwatch_log_group" "this" { + name_prefix = "hello_world-" + retention_in_days = 1 +} + +resource "aws_ecs_task_definition" "this" { + family = "hello_world" + + container_definitions = <
"name": "containerInsights",
"value": "enabled"
}
[| no | +| [cluster\_encryption\_config](#input\_cluster\_encryption\_config) | Configuration block with encryption configuration for the cluster | `list(any)` | `[]` | no | +| [cluster\_encryption\_policy\_description](#input\_cluster\_encryption\_policy\_description) | Description of the cluster encryption policy created | `string` | `"Cluster encryption policy to allow cluster role to utilize CMK provided"` | no | +| [cluster\_encryption\_policy\_name](#input\_cluster\_encryption\_policy\_name) | Name to use on cluster encryption policy created | `string` | `null` | no | +| [cluster\_encryption\_policy\_path](#input\_cluster\_encryption\_policy\_path) | Cluster encryption policy path | `string` | `null` | no | +| [cluster\_encryption\_policy\_tags](#input\_cluster\_encryption\_policy\_tags) | A map of additional tags to add to the cluster encryption policy created | `map(string)` | `{}` | no | +| [cluster\_encryption\_policy\_use\_name\_prefix](#input\_cluster\_encryption\_policy\_use\_name\_prefix) | Determines whether cluster encryption policy name (`cluster_encryption_policy_name`) is used as a prefix | `bool` | `true` | no | +| [cluster\_endpoint\_private\_access](#input\_cluster\_endpoint\_private\_access) | Indicates whether or not the Amazon EKS private API server endpoint is enabled | `bool` | `false` | no | +| [cluster\_endpoint\_public\_access](#input\_cluster\_endpoint\_public\_access) | Indicates whether or not the Amazon EKS public API server endpoint is enabled | `bool` | `true` | no | +| [cluster\_endpoint\_public\_access\_cidrs](#input\_cluster\_endpoint\_public\_access\_cidrs) | List of CIDR blocks which can access the Amazon EKS public API server endpoint | `list(string)` |
"audit",
"api",
"authenticator"
]
[| no | +| [cluster\_iam\_role\_dns\_suffix](#input\_cluster\_iam\_role\_dns\_suffix) | Base DNS domain name for the current partition (e.g., amazonaws.com in AWS Commercial, amazonaws.com.cn in AWS China) | `string` | `null` | no | +| [cluster\_identity\_providers](#input\_cluster\_identity\_providers) | Map of cluster identity provider configurations to enable for the cluster. Note - this is different/separate from IRSA | `any` | `{}` | no | +| [cluster\_ip\_family](#input\_cluster\_ip\_family) | The IP family used to assign Kubernetes pod and service addresses. Valid values are `ipv4` (default) and `ipv6`. You can only specify an IP family when you create a cluster, changing this value will force a new cluster to be created | `string` | `null` | no | +| [cluster\_name](#input\_cluster\_name) | Name of the EKS cluster | `string` | `""` | no | +| [cluster\_security\_group\_additional\_rules](#input\_cluster\_security\_group\_additional\_rules) | List of additional security group rules to add to the cluster security group created. Set `source_node_security_group = true` inside rules to set the `node_security_group` as source | `any` | `{}` | no | +| [cluster\_security\_group\_description](#input\_cluster\_security\_group\_description) | Description of the cluster security group created | `string` | `"EKS cluster security group"` | no | +| [cluster\_security\_group\_id](#input\_cluster\_security\_group\_id) | Existing security group ID to be attached to the cluster. Required if `create_cluster_security_group` = `false` | `string` | `""` | no | +| [cluster\_security\_group\_name](#input\_cluster\_security\_group\_name) | Name to use on cluster security group created | `string` | `null` | no | +| [cluster\_security\_group\_tags](#input\_cluster\_security\_group\_tags) | A map of additional tags to add to the cluster security group created | `map(string)` | `{}` | no | +| [cluster\_security\_group\_use\_name\_prefix](#input\_cluster\_security\_group\_use\_name\_prefix) | Determines whether cluster security group name (`cluster_security_group_name`) is used as a prefix | `bool` | `true` | no | +| [cluster\_service\_ipv4\_cidr](#input\_cluster\_service\_ipv4\_cidr) | The CIDR block to assign Kubernetes service IP addresses from. If you don't specify a block, Kubernetes assigns addresses from either the 10.100.0.0/16 or 172.20.0.0/16 CIDR blocks | `string` | `null` | no | +| [cluster\_tags](#input\_cluster\_tags) | A map of additional tags to add to the cluster | `map(string)` | `{}` | no | +| [cluster\_timeouts](#input\_cluster\_timeouts) | Create, update, and delete timeout configurations for the cluster | `map(string)` | `{}` | no | +| [cluster\_version](#input\_cluster\_version) | Kubernetes `
"0.0.0.0/0"
]
[| no | +| [node\_security\_group\_ntp\_ipv6\_cidr\_block](#input\_node\_security\_group\_ntp\_ipv6\_cidr\_block) | IPv4 CIDR block to allow NTP egress. Default is public IP space, but [Amazon Time Sync Service](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/set-time.html) can be used as well with `["fd00:ec2::123/128"]` | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [node\_security\_group\_tags](#input\_node\_security\_group\_tags) | A map of additional tags to add to the node security group created | `map(string)` | `{}` | no | +| [node\_security\_group\_use\_name\_prefix](#input\_node\_security\_group\_use\_name\_prefix) | Determines whether node security group name (`node_security_group_name`) is used as a prefix | `bool` | `true` | no | +| [openid\_connect\_audiences](#input\_openid\_connect\_audiences) | List of OpenID Connect audience client IDs to add to the IRSA provider | `list(string)` | `[]` | no | +| [prefix\_separator](#input\_prefix\_separator) | The separator to use between the prefix and the generated timestamp for resource names | `string` | `"-"` | no | + +| [self\_managed\_node\_group\_defaults](#input\_self\_managed\_node\_group\_defaults) | Map of self-managed node group default configurations | `any` | `{}` | no | +| [self\_managed\_node\_groups](#input\_self\_managed\_node\_groups) | Map of self-managed node group definitions to create | `any` | `{}` | no | +| [subnet\_ids](#input\_subnet\_ids) | A list of subnet IDs where the nodes/node groups will be provisioned. If `control_plane_subnet_ids` is not provided, the EKS cluster control plane (ENIs) will be provisioned in these subnets | `list(string)` | `[]` | no | +| [tags](#input\_tags) | A map of tags to add to all resources | `map(string)` | `{}` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where the cluster and its nodes will be provisioned | `string` | `null` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [aws\_auth\_configmap\_yaml](#output\_aws\_auth\_configmap\_yaml) | [DEPRECATED - use `var.manage_aws_auth_configmap`] Formatted yaml output for base aws-auth configmap containing roles used in cluster node groups/fargate profiles | +| [cloudwatch\_log\_group\_arn](#output\_cloudwatch\_log\_group\_arn) | Arn of cloudwatch log group created | +| [cloudwatch\_log\_group\_name](#output\_cloudwatch\_log\_group\_name) | Name of cloudwatch log group created | +| [cluster\_addons](#output\_cluster\_addons) | Map of attribute maps for all EKS cluster addons enabled | +| [cluster\_arn](#output\_cluster\_arn) | The Amazon Resource Name (ARN) of the cluster | +| [cluster\_certificate\_authority\_data](#output\_cluster\_certificate\_authority\_data) | Base64 encoded certificate data required to communicate with the cluster | +| [cluster\_endpoint](#output\_cluster\_endpoint) | Endpoint for your Kubernetes API server | +| [cluster\_iam\_role\_arn](#output\_cluster\_iam\_role\_arn) | IAM role ARN of the EKS cluster | +| [cluster\_iam\_role\_name](#output\_cluster\_iam\_role\_name) | IAM role name of the EKS cluster | +| [cluster\_iam\_role\_unique\_id](#output\_cluster\_iam\_role\_unique\_id) | Stable and unique string identifying the IAM role | +| [cluster\_id](#output\_cluster\_id) | The name/id of the EKS cluster. Will block on cluster creation until the cluster is really ready | +| [cluster\_identity\_providers](#output\_cluster\_identity\_providers) | Map of attribute maps for all EKS identity providers enabled | +| [cluster\_oidc\_issuer\_url](#output\_cluster\_oidc\_issuer\_url) | The URL on the EKS cluster for the OpenID Connect identity provider | +| [cluster\_platform\_version](#output\_cluster\_platform\_version) | Platform version for the cluster | +| [cluster\_primary\_security\_group\_id](#output\_cluster\_primary\_security\_group\_id) | Cluster security group that was created by Amazon EKS for the cluster. Managed node groups use this security group for control-plane-to-data-plane communication. Referred to as 'Cluster security group' in the EKS console | +| [cluster\_security\_group\_arn](#output\_cluster\_security\_group\_arn) | Amazon Resource Name (ARN) of the cluster security group | +| [cluster\_security\_group\_id](#output\_cluster\_security\_group\_id) | ID of the cluster security group | +| [cluster\_status](#output\_cluster\_status) | Status of the EKS cluster. One of `CREATING`, `ACTIVE`, `DELETING`, `FAILED` | +| [cluster\_version](#output\_cluster\_version) | The Kubernetes version for the cluster | +| [eks\_managed\_node\_groups](#output\_eks\_managed\_node\_groups) | Map of attribute maps for all EKS managed node groups created | +| [eks\_managed\_node\_groups\_autoscaling\_group\_names](#output\_eks\_managed\_node\_groups\_autoscaling\_group\_names) | List of the autoscaling group names created by EKS managed node groups | +| [fargate\_profiles](#output\_fargate\_profiles) | Map of attribute maps for all EKS Fargate Profiles created | +| [kms\_key\_arn](#output\_kms\_key\_arn) | The Amazon Resource Name (ARN) of the key | +| [kms\_key\_id](#output\_kms\_key\_id) | The globally unique identifier for the key | +| [kms\_key\_policy](#output\_kms\_key\_policy) | The IAM resource policy set on the key | +| [node\_security\_group\_arn](#output\_node\_security\_group\_arn) | Amazon Resource Name (ARN) of the node shared security group | +| [node\_security\_group\_id](#output\_node\_security\_group\_id) | ID of the node shared security group | +| [oidc\_provider](#output\_oidc\_provider) | The OpenID Connect identity provider (issuer URL without leading `https://`) | +| [oidc\_provider\_arn](#output\_oidc\_provider\_arn) | The ARN of the OIDC Provider if `enable_irsa = true` | +| [self\_managed\_node\_groups](#output\_self\_managed\_node\_groups) | Map of attribute maps for all self managed node groups created | +| [self\_managed\_node\_groups\_autoscaling\_group\_names](#output\_self\_managed\_node\_groups\_autoscaling\_group\_names) | List of the autoscaling group names created by self-managed node groups | + \ No newline at end of file diff --git a/modules/aws-eks/docs/compute_resources.md b/modules/aws-eks/docs/compute_resources.md new file mode 100644 index 0000000..5f75632 --- /dev/null +++ b/modules/aws-eks/docs/compute_resources.md @@ -0,0 +1,199 @@ +# Compute Resources + +## Table of Contents + +ℹ️ Only the pertinent attributes are shown below for brevity + +### EKS Managed Node Groups + +1. The module creates a custom launch template by default to ensure settings such as tags are propagated to instances. To use the default template provided by the AWS EKS managed node group service, disable the launch template creation and set the `launch_template_name` to an empty string: + +```hcl + eks_managed_node_groups = { + default = { + create_launch_template = false + launch_template_name = "" + } + } +``` + +2. Native support for Bottlerocket OS is provided by providing the respective AMI type: + +```hcl + eks_managed_node_groups = { + bottlerocket_default = { + create_launch_template = false + launch_template_name = "" + + ami_type = "BOTTLEROCKET_x86_64" + platform = "bottlerocket" + } + } +``` + +3. Users have limited support to extend the user data that is pre-pended to the user data provided by the AWS EKS Managed Node Group service: + +```hcl + eks_managed_node_groups = { + prepend_userdata = { + # See issue https://github.com/awslabs/amazon-eks-ami/issues/844 + pre_bootstrap_user_data = <<-EOT + #!/bin/bash + set -ex + cat <<-EOF > /etc/profile.d/bootstrap.sh + export CONTAINER_RUNTIME="containerd" + export USE_MAX_PODS=false + export KUBELET_EXTRA_ARGS="--max-pods=110" + EOF + # Source extra environment variables in bootstrap script + sed -i '/^set -o errexit/a\\nsource /etc/profile.d/bootstrap.sh' /etc/eks/bootstrap.sh + EOT + } + } +``` + +4. Bottlerocket OS is supported in a similar manner. However, note that the user data for Bottlerocket OS uses the TOML format: + +```hcl + eks_managed_node_groups = { + bottlerocket_prepend_userdata = { + ami_type = "BOTTLEROCKET_x86_64" + platform = "bottlerocket" + + bootstrap_extra_args = <<-EOT + # extra args added + [settings.kernel] + lockdown = "integrity" + EOT + } + } +``` + +5. When using a custom AMI, the AWS EKS Managed Node Group service will NOT inject the necessary bootstrap script into the supplied user data. Users can elect to provide their own user data to bootstrap and connect or opt in to use the module provided user data: + +```hcl + eks_managed_node_groups = { + custom_ami = { + ami_id = "ami-0caf35bc73450c396" + + # By default, EKS managed node groups will not append bootstrap script; + # this adds it back in using the default template provided by the module + # Note: this assumes the AMI provided is an EKS optimized AMI derivative + enable_bootstrap_user_data = true + + bootstrap_extra_args = "--container-runtime containerd --kubelet-extra-args '--max-pods=20'" + + pre_bootstrap_user_data = <<-EOT + export CONTAINER_RUNTIME="containerd" + export USE_MAX_PODS=false + EOT + + # Because we have full control over the user data supplied, we can also run additional + # scripts/configuration changes after the bootstrap script has been run + post_bootstrap_user_data = <<-EOT + echo "you are free little kubelet!" + EOT + } + } +``` + +6. There is similar support for Bottlerocket OS: + +```hcl + eks_managed_node_groups = { + bottlerocket_custom_ami = { + ami_id = "ami-0ff61e0bcfc81dc94" + platform = "bottlerocket" + + # use module user data template to bootstrap + enable_bootstrap_user_data = true + # this will get added to the template + bootstrap_extra_args = <<-EOT + # extra args added + [settings.kernel] + lockdown = "integrity" + + [settings.kubernetes.node-labels] + "label1" = "foo" + "label2" = "bar" + + [settings.kubernetes.node-taints] + "dedicated" = "experimental:PreferNoSchedule" + "special" = "true:NoSchedule" + EOT + } + } +``` + + +### Self Managed Node Groups + + +1. The `self-managed-node-group` uses the latest AWS EKS Optimized AMI (Linux) for the given Kubernetes version by default: + +```hcl + cluster_version = "1.22" + + # This self managed node group will use the latest AWS EKS Optimized AMI for Kubernetes 1.22 + self_managed_node_groups = { + default = {} + } +``` + +2. To use Bottlerocket, specify the `platform` as `bottlerocket` and supply a Bottlerocket OS AMI: + +```hcl + cluster_version = "1.22" + + self_managed_node_groups = { + bottlerocket = { + platform = "bottlerocket" + ami_id = data.aws_ami.bottlerocket_ami.id + } + } +``` + + +### Fargate Profiles + +Fargate profiles are straightforward to use and therefore no further details are provided here. See the for a working example of various configurations. + +### Default Configurations + +Each type of compute resource (EKS managed node group, self managed node group, or Fargate profile) provides the option for users to specify a default configuration. These default configurations can be overridden from within the compute resource's individual definition. The order of precedence for configurations (from highest to least precedence): + +- Compute resource individual configuration + - Compute resource family default configuration (`eks_managed_node_group_defaults`, `self_managed_node_group_defaults`, `fargate_profile_defaults`) + - Module default configuration (see `variables.tf` and `node_groups.tf`) + +For example, the following creates 4 AWS EKS Managed Node Groups: + +```hcl + eks_managed_node_group_defaults = { + ami_type = "AL2_x86_64" + disk_size = 50 + instance_types = ["m6i.large", "m5.large", "m5n.large", "m5zn.large"] + } + + eks_managed_node_groups = { + # Uses module default configurations overridden by configuration above + default = {} + + # This further overrides the instance types used + compute = { + instance_types = ["c5.large", "c6i.large", "c6d.large"] + } + + # This further overrides the instance types and disk size used + persistent = { + disk_size = 1024 + instance_types = ["r5.xlarge", "r6i.xlarge", "r5b.xlarge"] + } + + # This overrides the OS used + bottlerocket = { + ami_type = "BOTTLEROCKET_x86_64" + platform = "bottlerocket" + } + } +``` diff --git a/modules/aws-eks/docs/faq.md b/modules/aws-eks/docs/faq.md new file mode 100644 index 0000000..70c456b --- /dev/null +++ b/modules/aws-eks/docs/faq.md @@ -0,0 +1,137 @@ +# Frequently Asked Questions + +- [I received an error: `expect exactly one securityGroup tagged with kubernetes.io/cluster/
"::/0"
]
+ +
diff --git a/modules/aws-eks/examples/README.md b/modules/aws-eks/examples/README.md new file mode 100644 index 0000000..f417c0a --- /dev/null +++ b/modules/aws-eks/examples/README.md @@ -0,0 +1,8 @@ +# Examples + +Please note - the examples provided serve two primary means: + +1. Show users working examples of the various ways in which the module can be configured and features supported +2. A means of testing/validating module changes + +Please do not mistake the examples provided as "best practices". It is up to users to consult the AWS service documentation for best practices, usage recommendations, etc. diff --git a/modules/aws-eks/examples/complete/README.md b/modules/aws-eks/examples/complete/README.md new file mode 100644 index 0000000..7aa52f0 --- /dev/null +++ b/modules/aws-eks/examples/complete/README.md @@ -0,0 +1,101 @@ +# Complete AWS EKS Cluster + +Configuration in this directory creates an AWS EKS cluster with a broad mix of various features and settings provided by this module: + +- AWS EKS cluster +- Disabled EKS cluster +- Self managed node group +- Externally attached self managed node group +- Disabled self managed node group +- EKS managed node group +- Externally attached EKS managed node group +- Disabled self managed node group +- Fargate profile +- Externally attached Fargate profile +- Disabled Fargate profile +- Cluster addons: CoreDNS, Kube-Proxy, and VPC-CNI +- IAM roles for service accounts + +## Usage + +To run this example you need to execute: + +```bash +$ terraform init +$ terraform plan +$ terraform apply +``` + +Note that this example may create resources which cost money. Run `terraform destroy` when you don't need these resources. + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.72 | +| [kubernetes](#requirement\_kubernetes) | >= 2.10 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 3.72 | + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [disabled\_eks](#module\_disabled\_eks) | ../.. | n/a | +| [disabled\_eks\_managed\_node\_group](#module\_disabled\_eks\_managed\_node\_group) | ../../modules/eks-managed-node-group | n/a | +| [disabled\_fargate\_profile](#module\_disabled\_fargate\_profile) | ../../modules/fargate-profile | n/a | +| [disabled\_self\_managed\_node\_group](#module\_disabled\_self\_managed\_node\_group) | ../../modules/self-managed-node-group | n/a | +| [eks](#module\_eks) | ../.. | n/a | +| [eks\_managed\_node\_group](#module\_eks\_managed\_node\_group) | ../../modules/eks-managed-node-group | n/a | +| [fargate\_profile](#module\_fargate\_profile) | ../../modules/fargate-profile | n/a | +| [self\_managed\_node\_group](#module\_self\_managed\_node\_group) | ../../modules/self-managed-node-group | n/a | +| [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 3.0 | + +## Resources + +| Name | Type | +|------|------| +| [aws_security_group.additional](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource | + +## Inputs + +No inputs. + +## Outputs + +| Name | Description | +|------|-------------| +| [aws\_auth\_configmap\_yaml](#output\_aws\_auth\_configmap\_yaml) | Formatted yaml output for base aws-auth configmap containing roles used in cluster node groups/fargate profiles | +| [cloudwatch\_log\_group\_arn](#output\_cloudwatch\_log\_group\_arn) | Arn of cloudwatch log group created | +| [cloudwatch\_log\_group\_name](#output\_cloudwatch\_log\_group\_name) | Name of cloudwatch log group created | +| [cluster\_addons](#output\_cluster\_addons) | Map of attribute maps for all EKS cluster addons enabled | +| [cluster\_arn](#output\_cluster\_arn) | The Amazon Resource Name (ARN) of the cluster | +| [cluster\_certificate\_authority\_data](#output\_cluster\_certificate\_authority\_data) | Base64 encoded certificate data required to communicate with the cluster | +| [cluster\_endpoint](#output\_cluster\_endpoint) | Endpoint for your Kubernetes API server | +| [cluster\_iam\_role\_arn](#output\_cluster\_iam\_role\_arn) | IAM role ARN of the EKS cluster | +| [cluster\_iam\_role\_name](#output\_cluster\_iam\_role\_name) | IAM role name of the EKS cluster | +| [cluster\_iam\_role\_unique\_id](#output\_cluster\_iam\_role\_unique\_id) | Stable and unique string identifying the IAM role | +| [cluster\_id](#output\_cluster\_id) | The name/id of the EKS cluster. Will block on cluster creation until the cluster is really ready | +| [cluster\_identity\_providers](#output\_cluster\_identity\_providers) | Map of attribute maps for all EKS identity providers enabled | +| [cluster\_oidc\_issuer\_url](#output\_cluster\_oidc\_issuer\_url) | The URL on the EKS cluster for the OpenID Connect identity provider | +| [cluster\_platform\_version](#output\_cluster\_platform\_version) | Platform version for the cluster | +| [cluster\_security\_group\_arn](#output\_cluster\_security\_group\_arn) | Amazon Resource Name (ARN) of the cluster security group | +| [cluster\_security\_group\_id](#output\_cluster\_security\_group\_id) | Cluster security group that was created by Amazon EKS for the cluster. Managed node groups use this security group for control-plane-to-data-plane communication. Referred to as 'Cluster security group' in the EKS console | +| [cluster\_status](#output\_cluster\_status) | Status of the EKS cluster. One of `CREATING`, `ACTIVE`, `DELETING`, `FAILED` | +| [eks\_managed\_node\_groups](#output\_eks\_managed\_node\_groups) | Map of attribute maps for all EKS managed node groups created | +| [eks\_managed\_node\_groups\_autoscaling\_group\_names](#output\_eks\_managed\_node\_groups\_autoscaling\_group\_names) | List of the autoscaling group names created by EKS managed node groups | +| [fargate\_profiles](#output\_fargate\_profiles) | Map of attribute maps for all EKS Fargate Profiles created | +| [kms\_key\_arn](#output\_kms\_key\_arn) | The Amazon Resource Name (ARN) of the key | +| [kms\_key\_id](#output\_kms\_key\_id) | The globally unique identifier for the key | +| [kms\_key\_policy](#output\_kms\_key\_policy) | The IAM resource policy set on the key | +| [oidc\_provider](#output\_oidc\_provider) | The OpenID Connect identity provider (issuer URL without leading `https://`) | +| [oidc\_provider\_arn](#output\_oidc\_provider\_arn) | The ARN of the OIDC Provider if `enable_irsa = true` | +| [self\_managed\_node\_groups](#output\_self\_managed\_node\_groups) | Map of attribute maps for all self managed node groups created | +| [self\_managed\_node\_groups\_autoscaling\_group\_names](#output\_self\_managed\_node\_groups\_autoscaling\_group\_names) | List of the autoscaling group names created by self-managed node groups | + diff --git a/modules/aws-eks/examples/complete/main.tf b/modules/aws-eks/examples/complete/main.tf new file mode 100644 index 0000000..112e3b5 --- /dev/null +++ b/modules/aws-eks/examples/complete/main.tf @@ -0,0 +1,385 @@ +provider "aws" { + region = local.region + + default_tags { + tags = { + ExampleDefaultTag = "ExampleDefaultValue" + } + } +} + +provider "kubernetes" { + host = module.eks.cluster_endpoint + cluster_ca_certificate = base64decode(module.eks.cluster_certificate_authority_data) + + exec { + api_version = "client.authentication.k8s.io/v1beta1" + command = "aws" + # This requires the awscli to be installed locally where Terraform is executed + args = ["eks", "get-token", "--cluster-name", module.eks.cluster_id] + } +} + +locals { + name = "ex-${replace(basename(path.cwd), "_", "-")}" + region = "eu-west-1" + + tags = { + Example = local.name + GithubRepo = "terraform-aws-eks" + GithubOrg = "terraform-aws-modules" + } +} + +################################################################################ +# EKS Module +################################################################################ + +module "eks" { + source = "../.." + + cluster_name = local.name + cluster_endpoint_private_access = true + cluster_endpoint_public_access = true + + cluster_addons = { + coredns = { + resolve_conflicts = "OVERWRITE" + } + kube-proxy = {} + vpc-cni = { + resolve_conflicts = "OVERWRITE" + } + } + + # Encryption key + create_kms_key = true + cluster_encryption_config = [{ + resources = ["secrets"] + }] + kms_key_deletion_window_in_days = 7 + enable_kms_key_rotation = true + + vpc_id = module.vpc.vpc_id + subnet_ids = module.vpc.private_subnets + control_plane_subnet_ids = module.vpc.intra_subnets + + # Extend cluster security group rules + cluster_security_group_additional_rules = { + egress_nodes_ephemeral_ports_tcp = { + description = "To node 1025-65535" + protocol = "tcp" + from_port = 1025 + to_port = 65535 + type = "egress" + source_node_security_group = true + } + } + + # Extend node-to-node security group rules + node_security_group_ntp_ipv4_cidr_block = ["169.254.169.123/32"] + node_security_group_additional_rules = { + ingress_self_all = { + description = "Node to node all ports/protocols" + protocol = "-1" + from_port = 0 + to_port = 0 + type = "ingress" + self = true + } + egress_all = { + description = "Node all egress" + protocol = "-1" + from_port = 0 + to_port = 0 + type = "egress" + cidr_blocks = ["0.0.0.0/0"] + ipv6_cidr_blocks = ["::/0"] + } + } + + # Self Managed Node Group(s) + self_managed_node_group_defaults = { + vpc_security_group_ids = [aws_security_group.additional.id] + iam_role_additional_policies = ["arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"] + } + + self_managed_node_groups = { + spot = { + instance_type = "m5.large" + instance_market_options = { + market_type = "spot" + } + + pre_bootstrap_user_data = <<-EOT + echo "foo" + export FOO=bar + EOT + + bootstrap_extra_args = "--kubelet-extra-args '--node-labels=node.kubernetes.io/lifecycle=spot'" + + post_bootstrap_user_data = <<-EOT + cd /tmp + sudo yum install -y https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/linux_amd64/amazon-ssm-agent.rpm + sudo systemctl enable amazon-ssm-agent + sudo systemctl start amazon-ssm-agent + EOT + } + } + + # EKS Managed Node Group(s) + eks_managed_node_group_defaults = { + ami_type = "AL2_x86_64" + instance_types = ["m6i.large", "m5.large", "m5n.large", "m5zn.large"] + + attach_cluster_primary_security_group = true + vpc_security_group_ids = [aws_security_group.additional.id] + } + + eks_managed_node_groups = { + blue = {} + green = { + min_size = 1 + max_size = 10 + desired_size = 1 + + instance_types = ["t3.large"] + capacity_type = "SPOT" + labels = { + Environment = "test" + GithubRepo = "terraform-aws-eks" + GithubOrg = "terraform-aws-modules" + } + + taints = { + dedicated = { + key = "dedicated" + value = "gpuGroup" + effect = "NO_SCHEDULE" + } + } + + update_config = { + max_unavailable_percentage = 50 # or set `max_unavailable` + } + + tags = { + ExtraTag = "example" + } + } + } + + # Fargate Profile(s) + fargate_profiles = { + default = { + name = "default" + selectors = [ + { + namespace = "kube-system" + labels = { + k8s-app = "kube-dns" + } + }, + { + namespace = "default" + } + ] + + tags = { + Owner = "test" + } + + timeouts = { + create = "20m" + delete = "20m" + } + } + } + + # OIDC Identity provider + cluster_identity_providers = { + sts = { + client_id = "sts.amazonaws.com" + } + } + + # aws-auth configmap + manage_aws_auth_configmap = true + + aws_auth_node_iam_role_arns_non_windows = [ + module.eks_managed_node_group.iam_role_arn, + module.self_managed_node_group.iam_role_arn, + ] + aws_auth_fargate_profile_pod_execution_role_arns = [ + module.fargate_profile.fargate_profile_pod_execution_role_arn + ] + + aws_auth_roles = [ + { + rolearn = "arn:aws:iam::66666666666:role/role1" + username = "role1" + groups = ["system:masters"] + }, + ] + + aws_auth_users = [ + { + userarn = "arn:aws:iam::66666666666:user/user1" + username = "user1" + groups = ["system:masters"] + }, + { + userarn = "arn:aws:iam::66666666666:user/user2" + username = "user2" + groups = ["system:masters"] + }, + ] + + aws_auth_accounts = [ + "777777777777", + "888888888888", + ] + + tags = local.tags +} + +################################################################################ +# Sub-Module Usage on Existing/Separate Cluster +################################################################################ + +module "eks_managed_node_group" { + source = "../../modules/eks-managed-node-group" + + name = "separate-eks-mng" + cluster_name = module.eks.cluster_id + cluster_version = module.eks.cluster_version + + vpc_id = module.vpc.vpc_id + subnet_ids = module.vpc.private_subnets + cluster_primary_security_group_id = module.eks.cluster_primary_security_group_id + vpc_security_group_ids = [ + module.eks.cluster_security_group_id, + ] + + tags = merge(local.tags, { Separate = "eks-managed-node-group" }) +} + +module "self_managed_node_group" { + source = "../../modules/self-managed-node-group" + + name = "separate-self-mng" + cluster_name = module.eks.cluster_id + cluster_version = module.eks.cluster_version + cluster_endpoint = module.eks.cluster_endpoint + cluster_auth_base64 = module.eks.cluster_certificate_authority_data + + instance_type = "m5.large" + + vpc_id = module.vpc.vpc_id + subnet_ids = module.vpc.private_subnets + vpc_security_group_ids = [ + module.eks.cluster_primary_security_group_id, + module.eks.cluster_security_group_id, + ] + + use_default_tags = true + + tags = merge(local.tags, { Separate = "self-managed-node-group" }) +} + +module "fargate_profile" { + source = "../../modules/fargate-profile" + + name = "separate-fargate-profile" + cluster_name = module.eks.cluster_id + + subnet_ids = module.vpc.private_subnets + selectors = [{ + namespace = "kube-system" + }] + + tags = merge(local.tags, { Separate = "fargate-profile" }) +} + +################################################################################ +# Disabled creation +################################################################################ + +module "disabled_eks" { + source = "../.." + + create = false +} + +module "disabled_fargate_profile" { + source = "../../modules/fargate-profile" + + create = false +} + +module "disabled_eks_managed_node_group" { + source = "../../modules/eks-managed-node-group" + + create = false +} + +module "disabled_self_managed_node_group" { + source = "../../modules/self-managed-node-group" + + create = false +} + +################################################################################ +# Supporting resources +################################################################################ + +module "vpc" { + source = "terraform-aws-modules/vpc/aws" + version = "~> 3.0" + + name = local.name + cidr = "10.0.0.0/16" + + azs = ["${local.region}a", "${local.region}b", "${local.region}c"] + private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"] + public_subnets = ["10.0.4.0/24", "10.0.5.0/24", "10.0.6.0/24"] + intra_subnets = ["10.0.7.0/28", "10.0.7.16/28", "10.0.7.32/28"] + + enable_nat_gateway = true + single_nat_gateway = true + enable_dns_hostnames = true + + enable_flow_log = true + create_flow_log_cloudwatch_iam_role = true + create_flow_log_cloudwatch_log_group = true + + public_subnet_tags = { + "kubernetes.io/cluster/${local.name}" = "shared" + "kubernetes.io/role/elb" = 1 + } + + private_subnet_tags = { + "kubernetes.io/cluster/${local.name}" = "shared" + "kubernetes.io/role/internal-elb" = 1 + } + + tags = local.tags +} + +resource "aws_security_group" "additional" { + name_prefix = "${local.name}-additional" + vpc_id = module.vpc.vpc_id + + ingress { + from_port = 22 + to_port = 22 + protocol = "tcp" + cidr_blocks = [ + "10.0.0.0/8", + "172.16.0.0/12", + "192.168.0.0/16", + ] + } + + tags = local.tags +} diff --git a/modules/aws-eks/examples/complete/outputs.tf b/modules/aws-eks/examples/complete/outputs.tf new file mode 100644 index 0000000..c612b0f --- /dev/null +++ b/modules/aws-eks/examples/complete/outputs.tf @@ -0,0 +1,182 @@ +################################################################################ +# Cluster +################################################################################ + +output "cluster_arn" { + description = "The Amazon Resource Name (ARN) of the cluster" + value = module.eks.cluster_arn +} + +output "cluster_certificate_authority_data" { + description = "Base64 encoded certificate data required to communicate with the cluster" + value = module.eks.cluster_certificate_authority_data +} + +output "cluster_endpoint" { + description = "Endpoint for your Kubernetes API server" + value = module.eks.cluster_endpoint +} + +output "cluster_id" { + description = "The name/id of the EKS cluster. Will block on cluster creation until the cluster is really ready" + value = module.eks.cluster_id +} + +output "cluster_oidc_issuer_url" { + description = "The URL on the EKS cluster for the OpenID Connect identity provider" + value = module.eks.cluster_oidc_issuer_url +} + +output "cluster_platform_version" { + description = "Platform version for the cluster" + value = module.eks.cluster_platform_version +} + +output "cluster_status" { + description = "Status of the EKS cluster. One of `CREATING`, `ACTIVE`, `DELETING`, `FAILED`" + value = module.eks.cluster_status +} + +output "cluster_security_group_id" { + description = "Cluster security group that was created by Amazon EKS for the cluster. Managed node groups use this security group for control-plane-to-data-plane communication. Referred to as 'Cluster security group' in the EKS console" + value = module.eks.cluster_security_group_id +} + +################################################################################ +# KMS Key +################################################################################ + +output "kms_key_arn" { + description = "The Amazon Resource Name (ARN) of the key" + value = module.eks.kms_key_arn +} + +output "kms_key_id" { + description = "The globally unique identifier for the key" + value = module.eks.kms_key_id +} + +output "kms_key_policy" { + description = "The IAM resource policy set on the key" + value = module.eks.kms_key_policy +} + +################################################################################ +# Security Group +################################################################################ + +output "cluster_security_group_arn" { + description = "Amazon Resource Name (ARN) of the cluster security group" + value = module.eks.cluster_security_group_arn +} + +################################################################################ +# IRSA +################################################################################ + +output "oidc_provider" { + description = "The OpenID Connect identity provider (issuer URL without leading `https://`)" + value = module.eks.oidc_provider +} + +output "oidc_provider_arn" { + description = "The ARN of the OIDC Provider if `enable_irsa = true`" + value = module.eks.oidc_provider_arn +} + +################################################################################ +# IAM Role +################################################################################ + +output "cluster_iam_role_name" { + description = "IAM role name of the EKS cluster" + value = module.eks.cluster_iam_role_name +} + +output "cluster_iam_role_arn" { + description = "IAM role ARN of the EKS cluster" + value = module.eks.cluster_iam_role_arn +} + +output "cluster_iam_role_unique_id" { + description = "Stable and unique string identifying the IAM role" + value = module.eks.cluster_iam_role_unique_id +} + +################################################################################ +# EKS Addons +################################################################################ + +output "cluster_addons" { + description = "Map of attribute maps for all EKS cluster addons enabled" + value = module.eks.cluster_addons +} + +################################################################################ +# EKS Identity Provider +################################################################################ + +output "cluster_identity_providers" { + description = "Map of attribute maps for all EKS identity providers enabled" + value = module.eks.cluster_identity_providers +} + +################################################################################ +# CloudWatch Log Group +################################################################################ + +output "cloudwatch_log_group_name" { + description = "Name of cloudwatch log group created" + value = module.eks.cloudwatch_log_group_name +} + +output "cloudwatch_log_group_arn" { + description = "Arn of cloudwatch log group created" + value = module.eks.cloudwatch_log_group_arn +} + +################################################################################ +# Fargate Profile +################################################################################ + +output "fargate_profiles" { + description = "Map of attribute maps for all EKS Fargate Profiles created" + value = module.eks.fargate_profiles +} + +################################################################################ +# EKS Managed Node Group +################################################################################ + +output "eks_managed_node_groups" { + description = "Map of attribute maps for all EKS managed node groups created" + value = module.eks.eks_managed_node_groups +} + +output "eks_managed_node_groups_autoscaling_group_names" { + description = "List of the autoscaling group names created by EKS managed node groups" + value = module.eks.eks_managed_node_groups_autoscaling_group_names +} + +################################################################################ +# Self Managed Node Group +################################################################################ + +output "self_managed_node_groups" { + description = "Map of attribute maps for all self managed node groups created" + value = module.eks.self_managed_node_groups +} + +output "self_managed_node_groups_autoscaling_group_names" { + description = "List of the autoscaling group names created by self-managed node groups" + value = module.eks.self_managed_node_groups_autoscaling_group_names +} + +################################################################################ +# Additional +################################################################################ + +output "aws_auth_configmap_yaml" { + description = "Formatted yaml output for base aws-auth configmap containing roles used in cluster node groups/fargate profiles" + value = module.eks.aws_auth_configmap_yaml +} diff --git a/modules/aws-eks/examples/complete/variables.tf b/modules/aws-eks/examples/complete/variables.tf new file mode 100644 index 0000000..e69de29 diff --git a/modules/aws-eks/examples/complete/versions.tf b/modules/aws-eks/examples/complete/versions.tf new file mode 100644 index 0000000..6d6dc45 --- /dev/null +++ b/modules/aws-eks/examples/complete/versions.tf @@ -0,0 +1,14 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.72" + } + kubernetes = { + source = "hashicorp/kubernetes" + version = ">= 2.10" + } + } +} diff --git a/modules/aws-eks/examples/eks_managed_node_group/README.md b/modules/aws-eks/examples/eks_managed_node_group/README.md new file mode 100644 index 0000000..654a116 --- /dev/null +++ b/modules/aws-eks/examples/eks_managed_node_group/README.md @@ -0,0 +1,138 @@ +# EKS Managed Node Group Example + +Configuration in this directory creates an AWS EKS cluster with various EKS Managed Node Groups demonstrating the various methods of configuring/customizing: + +- A default, "out of the box" EKS managed node group as supplied by AWS EKS +- A default, "out of the box" Bottlerocket EKS managed node group as supplied by AWS EKS +- A Bottlerocket EKS managed node group that supplies additional bootstrap settings +- A Bottlerocket EKS managed node group that demonstrates many of the configuration/customizations offered by the `eks-managed-node-group` sub-module for the Bottlerocket OS +- An EKS managed node group created from a launch template created outside of the module +- An EKS managed node group that utilizes a custom AMI that is an EKS optimized AMI derivative +- An EKS managed node group that demonstrates nearly all of the configurations/customizations offered by the `eks-managed-node-group` sub-module + +See the [AWS documentation](https://docs.aws.amazon.com/eks/latest/userguide/managed-node-groups.html) for further details. + +## Container Runtime & User Data + +When using the default AMI provided by the EKS Managed Node Group service (i.e. - not specifying a value for `ami_id`), users should be aware of the limitations of configuring the node bootstrap process via user data. Due to not having direct access to the bootrap.sh script invocation and therefore its configuration flags (this is provided by the EKS Managed Node Group service in the node user data), a workaround for ensuring the appropriate configuration settings is shown below. The following example shows how to inject configuration variables ahead of the merged user data provided by the EKS Managed Node Group service as well as how to enable the containerd runtime using this approach. More details can be found [here](https://github.com/awslabs/amazon-eks-ami/issues/844). + +```hcl + ... + # Demo of containerd usage when not specifying a custom AMI ID + # (merged into user data before EKS MNG provided user data) + containerd = { + name = "containerd" + + # See issue https://github.com/awslabs/amazon-eks-ami/issues/844 + pre_bootstrap_user_data = <<-EOT + #!/bin/bash + set -ex + cat <<-EOF > /etc/profile.d/bootstrap.sh + export CONTAINER_RUNTIME="containerd" + export USE_MAX_PODS=false + export KUBELET_EXTRA_ARGS="--max-pods=110" + EOF + # Source extra environment variables in bootstrap script + sed -i '/^set -o errexit/a\\nsource /etc/profile.d/bootstrap.sh' /etc/eks/bootstrap.sh + sed -i 's/KUBELET_EXTRA_ARGS=$2/KUBELET_EXTRA_ARGS="$2 $KUBELET_EXTRA_ARGS"/' /etc/eks/bootstrap.sh + EOT + } + ... +``` + +## Usage + +To run this example you need to execute: + +```bash +$ terraform init +$ terraform plan +$ terraform apply +``` + +Note that this example may create resources which cost money. Run `terraform destroy` when you don't need these resources. + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.72 | +| [kubernetes](#requirement\_kubernetes) | >= 2.10 | +| [tls](#requirement\_tls) | >= 3.0 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 3.72 | +| [tls](#provider\_tls) | >= 3.0 | + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [eks](#module\_eks) | ../.. | n/a | +| [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 3.0 | +| [vpc\_cni\_irsa](#module\_vpc\_cni\_irsa) | terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts-eks | ~> 4.12 | + +## Resources + +| Name | Type | +|------|------| +| [aws_autoscaling_group_tag.cluster_autoscaler_label_tags](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/autoscaling_group_tag) | resource | +| [aws_iam_policy.node_additional](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | +| [aws_iam_role_policy_attachment.additional](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_key_pair.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/key_pair) | resource | +| [aws_kms_key.ebs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | resource | +| [aws_kms_key.eks](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | resource | +| [aws_launch_template.external](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/launch_template) | resource | +| [aws_security_group.additional](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource | +| [aws_security_group.remote_access](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource | +| [tls_private_key.this](https://registry.terraform.io/providers/hashicorp/tls/latest/docs/resources/private_key) | resource | +| [aws_ami.eks_default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ami) | data source | +| [aws_ami.eks_default_arm](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ami) | data source | +| [aws_ami.eks_default_bottlerocket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ami) | data source | +| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source | +| [aws_iam_policy_document.ebs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | + +## Inputs + +No inputs. + +## Outputs + +| Name | Description | +|------|-------------| +| [aws\_auth\_configmap\_yaml](#output\_aws\_auth\_configmap\_yaml) | Formatted yaml output for base aws-auth configmap containing roles used in cluster node groups/fargate profiles | +| [cloudwatch\_log\_group\_arn](#output\_cloudwatch\_log\_group\_arn) | Arn of cloudwatch log group created | +| [cloudwatch\_log\_group\_name](#output\_cloudwatch\_log\_group\_name) | Name of cloudwatch log group created | +| [cluster\_addons](#output\_cluster\_addons) | Map of attribute maps for all EKS cluster addons enabled | +| [cluster\_arn](#output\_cluster\_arn) | The Amazon Resource Name (ARN) of the cluster | +| [cluster\_certificate\_authority\_data](#output\_cluster\_certificate\_authority\_data) | Base64 encoded certificate data required to communicate with the cluster | +| [cluster\_endpoint](#output\_cluster\_endpoint) | Endpoint for your Kubernetes API server | +| [cluster\_iam\_role\_arn](#output\_cluster\_iam\_role\_arn) | IAM role ARN of the EKS cluster | +| [cluster\_iam\_role\_name](#output\_cluster\_iam\_role\_name) | IAM role name of the EKS cluster | +| [cluster\_iam\_role\_unique\_id](#output\_cluster\_iam\_role\_unique\_id) | Stable and unique string identifying the IAM role | +| [cluster\_id](#output\_cluster\_id) | The name/id of the EKS cluster. Will block on cluster creation until the cluster is really ready | +| [cluster\_identity\_providers](#output\_cluster\_identity\_providers) | Map of attribute maps for all EKS identity providers enabled | +| [cluster\_oidc\_issuer\_url](#output\_cluster\_oidc\_issuer\_url) | The URL on the EKS cluster for the OpenID Connect identity provider | +| [cluster\_platform\_version](#output\_cluster\_platform\_version) | Platform version for the cluster | +| [cluster\_primary\_security\_group\_id](#output\_cluster\_primary\_security\_group\_id) | Cluster security group that was created by Amazon EKS for the cluster. Managed node groups use this security group for control-plane-to-data-plane communication. Referred to as 'Cluster security group' in the EKS console | +| [cluster\_security\_group\_arn](#output\_cluster\_security\_group\_arn) | Amazon Resource Name (ARN) of the cluster security group | +| [cluster\_security\_group\_id](#output\_cluster\_security\_group\_id) | ID of the cluster security group | +| [cluster\_status](#output\_cluster\_status) | Status of the EKS cluster. One of `CREATING`, `ACTIVE`, `DELETING`, `FAILED` | +| [eks\_managed\_node\_groups](#output\_eks\_managed\_node\_groups) | Map of attribute maps for all EKS managed node groups created | +| [eks\_managed\_node\_groups\_autoscaling\_group\_names](#output\_eks\_managed\_node\_groups\_autoscaling\_group\_names) | List of the autoscaling group names created by EKS managed node groups | +| [fargate\_profiles](#output\_fargate\_profiles) | Map of attribute maps for all EKS Fargate Profiles created | +| [kms\_key\_arn](#output\_kms\_key\_arn) | The Amazon Resource Name (ARN) of the key | +| [kms\_key\_id](#output\_kms\_key\_id) | The globally unique identifier for the key | +| [kms\_key\_policy](#output\_kms\_key\_policy) | The IAM resource policy set on the key | +| [node\_security\_group\_arn](#output\_node\_security\_group\_arn) | Amazon Resource Name (ARN) of the node shared security group | +| [node\_security\_group\_id](#output\_node\_security\_group\_id) | ID of the node shared security group | +| [oidc\_provider](#output\_oidc\_provider) | The OpenID Connect identity provider (issuer URL without leading `https://`) | +| [oidc\_provider\_arn](#output\_oidc\_provider\_arn) | The ARN of the OIDC Provider if `enable_irsa = true` | +| [self\_managed\_node\_groups](#output\_self\_managed\_node\_groups) | Map of attribute maps for all self managed node groups created | +| [self\_managed\_node\_groups\_autoscaling\_group\_names](#output\_self\_managed\_node\_groups\_autoscaling\_group\_names) | List of the autoscaling group names created by self-managed node groups | + diff --git a/modules/aws-eks/examples/eks_managed_node_group/main.tf b/modules/aws-eks/examples/eks_managed_node_group/main.tf new file mode 100644 index 0000000..deb1426 --- /dev/null +++ b/modules/aws-eks/examples/eks_managed_node_group/main.tf @@ -0,0 +1,718 @@ +provider "aws" { + region = local.region +} + +provider "kubernetes" { + host = module.eks.cluster_endpoint + cluster_ca_certificate = base64decode(module.eks.cluster_certificate_authority_data) + + exec { + api_version = "client.authentication.k8s.io/v1beta1" + command = "aws" + # This requires the awscli to be installed locally where Terraform is executed + args = ["eks", "get-token", "--cluster-name", module.eks.cluster_id] + } +} + +locals { + name = "ex-${replace(basename(path.cwd), "_", "-")}" + cluster_version = "1.22" + region = "eu-west-1" + + tags = { + Example = local.name + GithubRepo = "terraform-aws-eks" + GithubOrg = "terraform-aws-modules" + } +} + +data "aws_caller_identity" "current" {} + +################################################################################ +# EKS Module +################################################################################ + +module "eks" { + source = "../.." + + cluster_name = local.name + cluster_version = local.cluster_version + cluster_endpoint_private_access = true + cluster_endpoint_public_access = true + + # IPV6 + cluster_ip_family = "ipv6" + + # We are using the IRSA created below for permissions + # However, we have to deploy with the policy attached FIRST (when creating a fresh cluster) + # and then turn this off after the cluster/node group is created. Without this initial policy, + # the VPC CNI fails to assign IPs and nodes cannot join the cluster + # See https://github.com/aws/containers-roadmap/issues/1666 for more context + # TODO - remove this policy once AWS releases a managed version similar to AmazonEKS_CNI_Policy (IPv4) + create_cni_ipv6_iam_policy = true + + cluster_addons = { + coredns = { + resolve_conflicts = "OVERWRITE" + } + kube-proxy = {} + vpc-cni = { + resolve_conflicts = "OVERWRITE" + service_account_role_arn = module.vpc_cni_irsa.iam_role_arn + } + } + + cluster_encryption_config = [{ + provider_key_arn = aws_kms_key.eks.arn + resources = ["secrets"] + }] + + cluster_tags = { + # This should not affect the name of the cluster primary security group + Name = local.name + } + + vpc_id = module.vpc.vpc_id + subnet_ids = module.vpc.private_subnets + + manage_aws_auth_configmap = true + + # Extend cluster security group rules + cluster_security_group_additional_rules = { + egress_nodes_ephemeral_ports_tcp = { + description = "To node 1025-65535" + protocol = "tcp" + from_port = 1025 + to_port = 65535 + type = "egress" + source_node_security_group = true + } + } + + # Extend node-to-node security group rules + node_security_group_ntp_ipv6_cidr_block = ["fd00:ec2::123/128"] + node_security_group_additional_rules = { + ingress_self_all = { + description = "Node to node all ports/protocols" + protocol = "-1" + from_port = 0 + to_port = 0 + type = "ingress" + self = true + } + egress_all = { + description = "Node all egress" + protocol = "-1" + from_port = 0 + to_port = 0 + type = "egress" + cidr_blocks = ["0.0.0.0/0"] + ipv6_cidr_blocks = ["::/0"] + } + } + + eks_managed_node_group_defaults = { + ami_type = "AL2_x86_64" + instance_types = ["m6i.large", "m5.large", "m5n.large", "m5zn.large"] + + # We are using the IRSA created below for permissions + # However, we have to deploy with the policy attached FIRST (when creating a fresh cluster) + # and then turn this off after the cluster/node group is created. Without this initial policy, + # the VPC CNI fails to assign IPs and nodes cannot join the cluster + # See https://github.com/aws/containers-roadmap/issues/1666 for more context + iam_role_attach_cni_policy = true + } + + eks_managed_node_groups = { + # Default node group - as provided by AWS EKS + default_node_group = { + # By default, the module creates a launch template to ensure tags are propagated to instances, etc., + # so we need to disable it to use the default template provided by the AWS EKS managed node group service + create_launch_template = false + launch_template_name = "" + + disk_size = 50 + + # Remote access cannot be specified with a launch template + remote_access = { + ec2_ssh_key = aws_key_pair.this.key_name + source_security_group_ids = [aws_security_group.remote_access.id] + } + } + + # Default node group - as provided by AWS EKS using Bottlerocket + bottlerocket_default = { + # By default, the module creates a launch template to ensure tags are propagated to instances, etc., + # so we need to disable it to use the default template provided by the AWS EKS managed node group service + create_launch_template = false + launch_template_name = "" + + ami_type = "BOTTLEROCKET_x86_64" + platform = "bottlerocket" + } + + # Adds to the AWS provided user data + bottlerocket_add = { + ami_type = "BOTTLEROCKET_x86_64" + platform = "bottlerocket" + + # this will get added to what AWS provides + bootstrap_extra_args = <<-EOT + # extra args added + [settings.kernel] + lockdown = "integrity" + EOT + } + + # Custom AMI, using module provided bootstrap data + bottlerocket_custom = { + # Current bottlerocket AMI + ami_id = data.aws_ami.eks_default_bottlerocket.image_id + platform = "bottlerocket" + + # use module user data template to boostrap + enable_bootstrap_user_data = true + # this will get added to the template + bootstrap_extra_args = <<-EOT + # extra args added + [settings.kernel] + lockdown = "integrity" + + [settings.kubernetes.node-labels] + "label1" = "foo" + "label2" = "bar" + + [settings.kubernetes.node-taints] + "dedicated" = "experimental:PreferNoSchedule" + "special" = "true:NoSchedule" + EOT + } + + # Use existing/external launch template + external_lt = { + create_launch_template = false + launch_template_name = aws_launch_template.external.name + launch_template_version = aws_launch_template.external.default_version + } + + # Use a custom AMI + custom_ami = { + ami_type = "AL2_ARM_64" + # Current default AMI used by managed node groups - pseudo "custom" + ami_id = data.aws_ami.eks_default_arm.image_id + + # This will ensure the boostrap user data is used to join the node + # By default, EKS managed node groups will not append bootstrap script; + # this adds it back in using the default template provided by the module + # Note: this assumes the AMI provided is an EKS optimized AMI derivative + enable_bootstrap_user_data = true + + instance_types = ["t4g.medium"] + } + + # Demo of containerd usage when not specifying a custom AMI ID + # (merged into user data before EKS MNG provided user data) + containerd = { + name = "containerd" + + # See issue https://github.com/awslabs/amazon-eks-ami/issues/844 + pre_bootstrap_user_data = <<-EOT + #!/bin/bash + set -ex + cat <<-EOF > /etc/profile.d/bootstrap.sh + export CONTAINER_RUNTIME="containerd" + export USE_MAX_PODS=false + export KUBELET_EXTRA_ARGS="--max-pods=110" + EOF + # Source extra environment variables in bootstrap script + sed -i '/^set -o errexit/a\\nsource /etc/profile.d/bootstrap.sh' /etc/eks/bootstrap.sh + EOT + } + + # Complete + complete = { + name = "complete-eks-mng" + use_name_prefix = true + + subnet_ids = module.vpc.private_subnets + + min_size = 1 + max_size = 7 + desired_size = 1 + + ami_id = data.aws_ami.eks_default.image_id + enable_bootstrap_user_data = true + bootstrap_extra_args = "--container-runtime containerd --kubelet-extra-args '--max-pods=20'" + + pre_bootstrap_user_data = <<-EOT + export CONTAINER_RUNTIME="containerd" + export USE_MAX_PODS=false + EOT + + post_bootstrap_user_data = <<-EOT + echo "you are free little kubelet!" + EOT + + capacity_type = "SPOT" + force_update_version = true + instance_types = ["m6i.large", "m5.large", "m5n.large", "m5zn.large"] + labels = { + GithubRepo = "terraform-aws-eks" + GithubOrg = "terraform-aws-modules" + } + + taints = [ + { + key = "dedicated" + value = "gpuGroup" + effect = "NO_SCHEDULE" + } + ] + + update_config = { + max_unavailable_percentage = 50 # or set `max_unavailable` + } + + description = "EKS managed node group example launch template" + + ebs_optimized = true + vpc_security_group_ids = [aws_security_group.additional.id] + disable_api_termination = false + enable_monitoring = true + + block_device_mappings = { + xvda = { + device_name = "/dev/xvda" + ebs = { + volume_size = 75 + volume_type = "gp3" + iops = 3000 + throughput = 150 + encrypted = true + kms_key_id = aws_kms_key.ebs.arn + delete_on_termination = true + } + } + } + + metadata_options = { + http_endpoint = "enabled" + http_tokens = "required" + http_put_response_hop_limit = 2 + instance_metadata_tags = "disabled" + } + + create_iam_role = true + iam_role_name = "eks-managed-node-group-complete-example" + iam_role_use_name_prefix = false + iam_role_description = "EKS managed node group complete example role" + iam_role_tags = { + Purpose = "Protector of the kubelet" + } + iam_role_additional_policies = [ + "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly" + ] + + create_security_group = true + security_group_name = "eks-managed-node-group-complete-example" + security_group_use_name_prefix = false + security_group_description = "EKS managed node group complete example security group" + security_group_rules = { + phoneOut = { + description = "Hello CloudFlare" + protocol = "udp" + from_port = 53 + to_port = 53 + type = "egress" + cidr_blocks = ["1.1.1.1/32"] + } + phoneHome = { + description = "Hello cluster" + protocol = "udp" + from_port = 53 + to_port = 53 + type = "egress" + source_cluster_security_group = true # bit of reflection lookup + } + } + security_group_tags = { + Purpose = "Protector of the kubelet" + } + + tags = { + ExtraTag = "EKS managed node group complete example" + } + } + } + + tags = local.tags +} + +# References to resources that do not exist yet when creating a cluster will cause a plan failure due to https://github.com/hashicorp/terraform/issues/4149 +# There are two options users can take +# 1. Create the dependent resources before the cluster => `terraform apply -target{| no | +| [min\_size](#input\_min\_size) | Minimum number of instances/nodes | `number` | `0` | no | +| [name](#input\_name) | Name of the EKS managed node group | `string` | `""` | no | +| [network\_interfaces](#input\_network\_interfaces) | Customize network interfaces to be attached at instance boot time | `list(any)` | `[]` | no | +| [placement](#input\_placement) | The placement of the instance | `map(string)` | `{}` | no | +| [platform](#input\_platform) | Identifies if the OS platform is `bottlerocket` or `linux` based; `windows` is not supported | `string` | `"linux"` | no | +| [post\_bootstrap\_user\_data](#input\_post\_bootstrap\_user\_data) | User data that is appended to the user data script after of the EKS bootstrap script. Not used when `platform` = `bottlerocket` | `string` | `""` | no | +| [pre\_bootstrap\_user\_data](#input\_pre\_bootstrap\_user\_data) | User data that is injected into the user data script ahead of the EKS bootstrap script. Not used when `platform` = `bottlerocket` | `string` | `""` | no | +| [ram\_disk\_id](#input\_ram\_disk\_id) | The ID of the ram disk | `string` | `null` | no | +| [remote\_access](#input\_remote\_access) | Configuration block with remote access settings | `any` | `{}` | no | +| [security\_group\_description](#input\_security\_group\_description) | Description for the security group created | `string` | `"EKS managed node group security group"` | no | +| [security\_group\_name](#input\_security\_group\_name) | Name to use on security group created | `string` | `null` | no | +| [security\_group\_rules](#input\_security\_group\_rules) | List of security group rules to add to the security group created | `any` | `{}` | no | +| [security\_group\_tags](#input\_security\_group\_tags) | A map of additional tags to add to the security group created | `map(string)` | `{}` | no | +| [security\_group\_use\_name\_prefix](#input\_security\_group\_use\_name\_prefix) | Determines whether the security group name (`security_group_name`) is used as a prefix | `bool` | `true` | no | +| [subnet\_ids](#input\_subnet\_ids) | Identifiers of EC2 Subnets to associate with the EKS Node Group. These subnets must have the following resource tag: `kubernetes.io/cluster/CLUSTER_NAME` | `list(string)` | `null` | no | +| [tags](#input\_tags) | A map of tags to add to all resources | `map(string)` | `{}` | no | +| [taints](#input\_taints) | The Kubernetes taints to be applied to the nodes in the node group. Maximum of 50 taints per node group | `any` | `{}` | no | +| [timeouts](#input\_timeouts) | Create, update, and delete timeout configurations for the node group | `map(string)` | `{}` | no | +| [update\_config](#input\_update\_config) | Configuration block of settings for max unavailable resources during node group updates | `map(string)` | `{}` | no | +| [update\_launch\_template\_default\_version](#input\_update\_launch\_template\_default\_version) | Whether to update the launch templates default version on each update. Conflicts with `launch_template_default_version` | `bool` | `true` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Determines whether to use `name` as is or create a unique name beginning with the `name` as the prefix | `bool` | `true` | no | +| [user\_data\_template\_path](#input\_user\_data\_template\_path) | Path to a local, custom user data template file to use when rendering user data | `string` | `""` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where the security group/nodes will be provisioned | `string` | `null` | no | +| [vpc\_security\_group\_ids](#input\_vpc\_security\_group\_ids) | A list of security group IDs to associate | `list(string)` | `[]` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [iam\_role\_arn](#output\_iam\_role\_arn) | The Amazon Resource Name (ARN) specifying the IAM role | +| [iam\_role\_name](#output\_iam\_role\_name) | The name of the IAM role | +| [iam\_role\_unique\_id](#output\_iam\_role\_unique\_id) | Stable and unique string identifying the IAM role | +| [launch\_template\_arn](#output\_launch\_template\_arn) | The ARN of the launch template | +| [launch\_template\_id](#output\_launch\_template\_id) | The ID of the launch template | +| [launch\_template\_latest\_version](#output\_launch\_template\_latest\_version) | The latest version of the launch template | +| [launch\_template\_name](#output\_launch\_template\_name) | The name of the launch template | +| [node\_group\_arn](#output\_node\_group\_arn) | Amazon Resource Name (ARN) of the EKS Node Group | +| [node\_group\_autoscaling\_group\_names](#output\_node\_group\_autoscaling\_group\_names) | List of the autoscaling group names | +| [node\_group\_id](#output\_node\_group\_id) | EKS Cluster name and EKS Node Group name separated by a colon (`:`) | +| [node\_group\_labels](#output\_node\_group\_labels) | Map of labels applied to the node group | +| [node\_group\_resources](#output\_node\_group\_resources) | List of objects containing information about underlying resources | +| [node\_group\_status](#output\_node\_group\_status) | Status of the EKS Node Group | +| [node\_group\_taints](#output\_node\_group\_taints) | List of objects containing information about taints applied to the node group | +| [security\_group\_arn](#output\_security\_group\_arn) | Amazon Resource Name (ARN) of the security group | +| [security\_group\_id](#output\_security\_group\_id) | ID of the security group | + diff --git a/modules/aws-eks/modules/eks-managed-node-group/main.tf b/modules/aws-eks/modules/eks-managed-node-group/main.tf new file mode 100644 index 0000000..65b3d23 --- /dev/null +++ b/modules/aws-eks/modules/eks-managed-node-group/main.tf @@ -0,0 +1,456 @@ +data "aws_partition" "current" {} + +data "aws_caller_identity" "current" {} + +################################################################################ +# User Data +################################################################################ + +module "user_data" { + source = "../_user_data" + + create = var.create + platform = var.platform + + cluster_name = var.cluster_name + cluster_endpoint = var.cluster_endpoint + cluster_auth_base64 = var.cluster_auth_base64 + + cluster_service_ipv4_cidr = var.cluster_service_ipv4_cidr + + enable_bootstrap_user_data = var.enable_bootstrap_user_data + pre_bootstrap_user_data = var.pre_bootstrap_user_data + post_bootstrap_user_data = var.post_bootstrap_user_data + bootstrap_extra_args = var.bootstrap_extra_args + user_data_template_path = var.user_data_template_path +} + +################################################################################ +# Launch template +################################################################################ + +locals { + # There are 4 scenarios here that have to be considered for `use_custom_launch_template`: + # 1. `var.create_launch_template = false && var.launch_template_name == ""` => EKS MNG will use its own default LT + # 2. `var.create_launch_template = false && var.launch_template_name == "something"` => User provided custom LT will be used + # 3. `var.create_launch_template = true && var.launch_template_name == ""` => Custom LT will be used, module will provide a default name + # 4. `var.create_launch_template = true && var.launch_template_name == "something"` => Custom LT will be used, LT name is provided by user + use_custom_launch_template = var.create_launch_template || var.launch_template_name != "" + + launch_template_name_int = coalesce(var.launch_template_name, "${var.name}-eks-node-group") + + security_group_ids = compact(concat([try(aws_security_group.this[0].id, ""), var.cluster_primary_security_group_id], var.vpc_security_group_ids)) +} + +resource "aws_launch_template" "this" { + count = var.create && var.create_launch_template ? 1 : 0 + + name = var.launch_template_use_name_prefix ? null : local.launch_template_name_int + name_prefix = var.launch_template_use_name_prefix ? "${local.launch_template_name_int}-" : null + description = var.launch_template_description + + ebs_optimized = var.ebs_optimized + image_id = var.ami_id + # # Set on node group instead + # instance_type = var.launch_template_instance_type + key_name = var.key_name + user_data = module.user_data.user_data + + vpc_security_group_ids = length(var.network_interfaces) > 0 ? [] : local.security_group_ids + + default_version = var.launch_template_default_version + update_default_version = var.update_launch_template_default_version + disable_api_termination = var.disable_api_termination + # Set on EKS managed node group, will fail if set here + # https://docs.aws.amazon.com/eks/latest/userguide/launch-templates.html#launch-template-basics + # instance_initiated_shutdown_behavior = var.instance_initiated_shutdown_behavior + kernel_id = var.kernel_id + ram_disk_id = var.ram_disk_id + + dynamic "block_device_mappings" { + for_each = var.block_device_mappings + content { + device_name = block_device_mappings.value.device_name + no_device = lookup(block_device_mappings.value, "no_device", null) + virtual_name = lookup(block_device_mappings.value, "virtual_name", null) + + dynamic "ebs" { + for_each = flatten([lookup(block_device_mappings.value, "ebs", [])]) + content { + delete_on_termination = lookup(ebs.value, "delete_on_termination", null) + encrypted = lookup(ebs.value, "encrypted", null) + kms_key_id = lookup(ebs.value, "kms_key_id", null) + iops = lookup(ebs.value, "iops", null) + throughput = lookup(ebs.value, "throughput", null) + snapshot_id = lookup(ebs.value, "snapshot_id", null) + volume_size = var.disk_size #lookup(ebs.value, "volume_size", null) + volume_type = lookup(ebs.value, "volume_type", null) + } + } + } + } + + dynamic "capacity_reservation_specification" { + for_each = length(var.capacity_reservation_specification) > 0 ? [var.capacity_reservation_specification] : [] + content { + capacity_reservation_preference = lookup(capacity_reservation_specification.value, "capacity_reservation_preference", null) + + dynamic "capacity_reservation_target" { + for_each = try([capacity_reservation_specification.value.capacity_reservation_target], []) + content { + capacity_reservation_id = lookup(capacity_reservation_target.value, "capacity_reservation_id", null) + } + } + } + } + + dynamic "cpu_options" { + for_each = length(var.cpu_options) > 0 ? [var.cpu_options] : [] + content { + core_count = cpu_options.value.core_count + threads_per_core = cpu_options.value.threads_per_core + } + } + + dynamic "credit_specification" { + for_each = length(var.credit_specification) > 0 ? [var.credit_specification] : [] + content { + cpu_credits = credit_specification.value.cpu_credits + } + } + + dynamic "elastic_gpu_specifications" { + for_each = length(var.elastic_gpu_specifications) > 0 ? [var.elastic_gpu_specifications] : [] + content { + type = elastic_gpu_specifications.value.type + } + } + + dynamic "elastic_inference_accelerator" { + for_each = length(var.elastic_inference_accelerator) > 0 ? [var.elastic_inference_accelerator] : [] + content { + type = elastic_inference_accelerator.value.type + } + } + + dynamic "enclave_options" { + for_each = length(var.enclave_options) > 0 ? [var.enclave_options] : [] + content { + enabled = enclave_options.value.enabled + } + } + + # Set on EKS managed node group, will fail if set here + # https://docs.aws.amazon.com/eks/latest/userguide/launch-templates.html#launch-template-basics + # dynamic "hibernation_options" { + # for_each = var.hibernation_options != null ? [var.hibernation_options] : [] + # content { + # configured = hibernation_options.value.configured + # } + # } + + # Set on EKS managed node group, will fail if set here + # https://docs.aws.amazon.com/eks/latest/userguide/launch-templates.html#launch-template-basics + # dynamic "iam_instance_profile" { + # for_each = [var.iam_instance_profile] + # content { + # name = lookup(var.iam_instance_profile, "name", null) + # arn = lookup(var.iam_instance_profile, "arn", null) + # } + # } + + dynamic "instance_market_options" { + for_each = length(var.instance_market_options) > 0 ? [var.instance_market_options] : [] + content { + market_type = instance_market_options.value.market_type + + dynamic "spot_options" { + for_each = length(lookup(instance_market_options.value, "spot_options", {})) > 0 ? [instance_market_options.value.spot_options] : [] + content { + block_duration_minutes = lookup(spot_options.value, "block_duration_minutes", null) + instance_interruption_behavior = lookup(spot_options.value, "instance_interruption_behavior", null) + max_price = lookup(spot_options.value, "max_price", null) + spot_instance_type = lookup(spot_options.value, "spot_instance_type", null) + valid_until = lookup(spot_options.value, "valid_until", null) + } + } + } + } + + dynamic "license_specification" { + for_each = length(var.license_specifications) > 0 ? [var.license_specifications] : [] + content { + license_configuration_arn = license_specifications.value.license_configuration_arn + } + } + + dynamic "metadata_options" { + for_each = length(var.metadata_options) > 0 ? [var.metadata_options] : [] + content { + http_endpoint = lookup(metadata_options.value, "http_endpoint", null) + http_tokens = lookup(metadata_options.value, "http_tokens", null) + http_put_response_hop_limit = lookup(metadata_options.value, "http_put_response_hop_limit", null) + http_protocol_ipv6 = lookup(metadata_options.value, "http_protocol_ipv6", null) + instance_metadata_tags = lookup(metadata_options.value, "instance_metadata_tags", null) + } + } + + dynamic "monitoring" { + for_each = var.enable_monitoring != null ? [1] : [] + content { + enabled = var.enable_monitoring + } + } + + dynamic "network_interfaces" { + for_each = var.network_interfaces + content { + associate_carrier_ip_address = lookup(network_interfaces.value, "associate_carrier_ip_address", null) + associate_public_ip_address = lookup(network_interfaces.value, "associate_public_ip_address", null) + delete_on_termination = lookup(network_interfaces.value, "delete_on_termination", null) + description = lookup(network_interfaces.value, "description", null) + device_index = lookup(network_interfaces.value, "device_index", null) + interface_type = lookup(network_interfaces.value, "interface_type", null) + ipv4_addresses = try(network_interfaces.value.ipv4_addresses, []) + ipv4_address_count = lookup(network_interfaces.value, "ipv4_address_count", null) + ipv6_addresses = try(network_interfaces.value.ipv6_addresses, []) + ipv6_address_count = lookup(network_interfaces.value, "ipv6_address_count", null) + network_interface_id = lookup(network_interfaces.value, "network_interface_id", null) + private_ip_address = lookup(network_interfaces.value, "private_ip_address", null) + security_groups = compact(concat(try(network_interfaces.value.security_groups, []), local.security_group_ids)) + # Set on EKS managed node group, will fail if set here + # https://docs.aws.amazon.com/eks/latest/userguide/launch-templates.html#launch-template-basics + # subnet_id = lookup(network_interfaces.value, "subnet_id", null) + } + } + + dynamic "placement" { + for_each = length(var.placement) > 0 ? [var.placement] : [] + content { + affinity = lookup(placement.value, "affinity", null) + availability_zone = lookup(placement.value, "availability_zone", null) + group_name = lookup(placement.value, "group_name", null) + host_id = lookup(placement.value, "host_id", null) + spread_domain = lookup(placement.value, "spread_domain", null) + tenancy = lookup(placement.value, "tenancy", null) + partition_number = lookup(placement.value, "partition_number", null) + } + } + + dynamic "tag_specifications" { + for_each = toset(["instance", "volume", "network-interface"]) + content { + resource_type = tag_specifications.key + tags = merge(var.tags, { Name = var.name }, var.launch_template_tags) + } + } + + lifecycle { + create_before_destroy = true + } + + # Prevent premature access of security group roles and policies by pods that + # require permissions on create/destroy that depend on nodes + depends_on = [ + aws_security_group_rule.this, + aws_iam_role_policy_attachment.this, + ] + + tags = var.tags +} + +################################################################################ +# Node Group +################################################################################ + +locals { + launch_template_name = try(aws_launch_template.this[0].name, var.launch_template_name, null) + # Change order to allow users to set version priority before using defaults + launch_template_version = coalesce(var.launch_template_version, try(aws_launch_template.this[0].default_version, "$Default")) +} + +resource "aws_eks_node_group" "this" { + count = var.create ? 1 : 0 + + # Required + cluster_name = var.cluster_name + node_role_arn = var.create_iam_role ? aws_iam_role.this[0].arn : var.iam_role_arn + subnet_ids = var.subnet_ids + + scaling_config { + min_size = var.min_size + max_size = var.max_size + desired_size = var.desired_size + } + + # Optional + node_group_name = var.use_name_prefix ? null : var.name + node_group_name_prefix = var.use_name_prefix ? "${var.name}-" : null + + # https://docs.aws.amazon.com/eks/latest/userguide/launch-templates.html#launch-template-custom-ami + ami_type = var.ami_id != "" ? null : var.ami_type + release_version = var.ami_id != "" ? null : var.ami_release_version + version = var.ami_id != "" ? null : var.cluster_version + + capacity_type = var.capacity_type + disk_size = local.use_custom_launch_template ? null : var.disk_size # if using LT, set disk size on LT or else it will error here + force_update_version = var.force_update_version + instance_types = var.instance_types + labels = var.labels + + dynamic "launch_template" { + for_each = local.use_custom_launch_template ? [1] : [] + content { + name = local.launch_template_name + version = local.launch_template_version + } + } + + dynamic "remote_access" { + for_each = length(var.remote_access) > 0 ? [var.remote_access] : [] + content { + ec2_ssh_key = try(remote_access.value.ec2_ssh_key, null) + source_security_group_ids = try(remote_access.value.source_security_group_ids, []) + } + } + + dynamic "taint" { + for_each = var.taints + content { + key = taint.value.key + value = lookup(taint.value, "value") + effect = taint.value.effect + } + } + + dynamic "update_config" { + for_each = length(var.update_config) > 0 ? [var.update_config] : [] + content { + max_unavailable_percentage = try(update_config.value.max_unavailable_percentage, null) + max_unavailable = try(update_config.value.max_unavailable, null) + } + } + + timeouts { + create = lookup(var.timeouts, "create", null) + update = lookup(var.timeouts, "update", null) + delete = lookup(var.timeouts, "delete", null) + } + + lifecycle { + create_before_destroy = true + ignore_changes = [ + scaling_config[0].desired_size, + ] + } + + tags = merge( + var.tags, + { Name = var.name } + ) +} + +################################################################################ +# Security Group +################################################################################ + +locals { + security_group_name = coalesce(var.security_group_name, "${var.name}-eks-node-group") + create_security_group = var.create && var.create_security_group +} + +resource "aws_security_group" "this" { + count = local.create_security_group ? 1 : 0 + + name = var.security_group_use_name_prefix ? null : local.security_group_name + name_prefix = var.security_group_use_name_prefix ? "${local.security_group_name}-" : null + description = var.security_group_description + vpc_id = var.vpc_id + + tags = merge( + var.tags, + { "Name" = local.security_group_name }, + var.security_group_tags + ) + + # https://github.com/hashicorp/terraform-provider-aws/issues/2445 + # https://github.com/hashicorp/terraform-provider-aws/issues/9692 + lifecycle { + create_before_destroy = true + } +} + +resource "aws_security_group_rule" "this" { + for_each = { for k, v in var.security_group_rules : k => v if local.create_security_group } + + # Required + security_group_id = aws_security_group.this[0].id + protocol = each.value.protocol + from_port = each.value.from_port + to_port = each.value.to_port + type = each.value.type + + # Optional + description = try(each.value.description, null) + cidr_blocks = try(each.value.cidr_blocks, null) + ipv6_cidr_blocks = try(each.value.ipv6_cidr_blocks, null) + prefix_list_ids = try(each.value.prefix_list_ids, []) + self = try(each.value.self, null) + source_security_group_id = try( + each.value.source_security_group_id, + try(each.value.source_cluster_security_group, false) ? var.cluster_security_group_id : null + ) +} + +################################################################################ +# IAM Role +################################################################################ + +locals { + iam_role_name = coalesce(var.iam_role_name, "${var.name}-eks-node-group") + + iam_role_policy_prefix = "arn:${data.aws_partition.current.partition}:iam::aws:policy" + + cni_policy = var.cluster_ip_family == "ipv6" ? "arn:${data.aws_partition.current.partition}:iam::${data.aws_caller_identity.current.account_id}:policy/AmazonEKS_CNI_IPv6_Policy" : "${local.iam_role_policy_prefix}/AmazonEKS_CNI_Policy" +} + +data "aws_iam_policy_document" "assume_role_policy" { + count = var.create && var.create_iam_role ? 1 : 0 + + statement { + sid = "EKSNodeAssumeRole" + actions = ["sts:AssumeRole"] + + principals { + type = "Service" + identifiers = ["ec2.${data.aws_partition.current.dns_suffix}"] + } + } +} + +resource "aws_iam_role" "this" { + count = var.create && var.create_iam_role ? 1 : 0 + + name = var.iam_role_use_name_prefix ? null : local.iam_role_name + name_prefix = var.iam_role_use_name_prefix ? "${local.iam_role_name}-" : null + path = var.iam_role_path + description = var.iam_role_description + + assume_role_policy = data.aws_iam_policy_document.assume_role_policy[0].json + permissions_boundary = var.iam_role_permissions_boundary + force_detach_policies = true + + tags = merge(var.tags, var.iam_role_tags) +} + +# Policies attached ref https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_node_group +resource "aws_iam_role_policy_attachment" "this" { + for_each = var.create && var.create_iam_role ? toset(compact(distinct(concat([ + "${local.iam_role_policy_prefix}/AmazonEKSWorkerNodePolicy", + "${local.iam_role_policy_prefix}/AmazonEC2ContainerRegistryReadOnly", + var.iam_role_attach_cni_policy ? local.cni_policy : "", + ], var.iam_role_additional_policies)))) : toset([]) + + policy_arn = each.value + role = aws_iam_role.this[0].name +} diff --git a/modules/aws-eks/modules/eks-managed-node-group/outputs.tf b/modules/aws-eks/modules/eks-managed-node-group/outputs.tf new file mode 100644 index 0000000..9d75353 --- /dev/null +++ b/modules/aws-eks/modules/eks-managed-node-group/outputs.tf @@ -0,0 +1,95 @@ +################################################################################ +# Launch template +################################################################################ + +output "launch_template_id" { + description = "The ID of the launch template" + value = try(aws_launch_template.this[0].id, "") +} + +output "launch_template_arn" { + description = "The ARN of the launch template" + value = try(aws_launch_template.this[0].arn, "") +} + +output "launch_template_latest_version" { + description = "The latest version of the launch template" + value = try(aws_launch_template.this[0].latest_version, "") +} + +output "launch_template_name" { + description = "The name of the launch template" + value = try(aws_launch_template.this[0].name, "") +} + +################################################################################ +# Node Group +################################################################################ + +output "node_group_arn" { + description = "Amazon Resource Name (ARN) of the EKS Node Group" + value = try(aws_eks_node_group.this[0].arn, "") +} + +output "node_group_id" { + description = "EKS Cluster name and EKS Node Group name separated by a colon (`:`)" + value = try(aws_eks_node_group.this[0].id, "") +} + +output "node_group_resources" { + description = "List of objects containing information about underlying resources" + value = try(aws_eks_node_group.this[0].resources, "") +} + +output "node_group_autoscaling_group_names" { + description = "List of the autoscaling group names" + value = try(flatten(aws_eks_node_group.this[0].resources[*].autoscaling_groups[*].name), []) +} + +output "node_group_status" { + description = "Status of the EKS Node Group" + value = try(aws_eks_node_group.this[0].arn, "") +} + +output "node_group_labels" { + description = "Map of labels applied to the node group" + value = try(aws_eks_node_group.this[0].labels, {}) +} + +output "node_group_taints" { + description = "List of objects containing information about taints applied to the node group" + value = try(aws_eks_node_group.this[0].taint, []) +} + +################################################################################ +# Security Group +################################################################################ + +output "security_group_arn" { + description = "Amazon Resource Name (ARN) of the security group" + value = try(aws_security_group.this[0].arn, "") +} + +output "security_group_id" { + description = "ID of the security group" + value = try(aws_security_group.this[0].id, "") +} + +################################################################################ +# IAM Role +################################################################################ + +output "iam_role_name" { + description = "The name of the IAM role" + value = try(aws_iam_role.this[0].name, "") +} + +output "iam_role_arn" { + description = "The Amazon Resource Name (ARN) specifying the IAM role" + value = try(aws_iam_role.this[0].arn, var.iam_role_arn) +} + +output "iam_role_unique_id" { + description = "Stable and unique string identifying the IAM role" + value = try(aws_iam_role.this[0].unique_id, "") +} diff --git a/modules/aws-eks/modules/eks-managed-node-group/variables.tf b/modules/aws-eks/modules/eks-managed-node-group/variables.tf new file mode 100644 index 0000000..72a5aa7 --- /dev/null +++ b/modules/aws-eks/modules/eks-managed-node-group/variables.tf @@ -0,0 +1,491 @@ +variable "create" { + description = "Determines whether to create EKS managed node group or not" + type = bool + default = true +} + +variable "tags" { + description = "A map of tags to add to all resources" + type = map(string) + default = {} +} + +variable "platform" { + description = "Identifies if the OS platform is `bottlerocket` or `linux` based; `windows` is not supported" + type = string + default = "linux" +} + +################################################################################ +# User Data +################################################################################ + +variable "enable_bootstrap_user_data" { + description = "Determines whether the bootstrap configurations are populated within the user data template" + type = bool + default = false +} + +variable "cluster_name" { + description = "Name of associated EKS cluster" + type = string + default = null +} + +variable "cluster_endpoint" { + description = "Endpoint of associated EKS cluster" + type = string + default = "" +} + +variable "cluster_auth_base64" { + description = "Base64 encoded CA of associated EKS cluster" + type = string + default = "" +} + +variable "cluster_service_ipv4_cidr" { + description = "The CIDR block to assign Kubernetes service IP addresses from. If you don't specify a block, Kubernetes assigns addresses from either the 10.100.0.0/16 or 172.20.0.0/16 CIDR blocks" + type = string + default = null +} + +variable "pre_bootstrap_user_data" { + description = "User data that is injected into the user data script ahead of the EKS bootstrap script. Not used when `platform` = `bottlerocket`" + type = string + default = "" +} + +variable "post_bootstrap_user_data" { + description = "User data that is appended to the user data script after of the EKS bootstrap script. Not used when `platform` = `bottlerocket`" + type = string + default = "" +} + +variable "bootstrap_extra_args" { + description = "Additional arguments passed to the bootstrap script. When `platform` = `bottlerocket`; these are additional [settings](https://github.com/bottlerocket-os/bottlerocket#settings) that are provided to the Bottlerocket user data" + type = string + default = "" +} + +variable "user_data_template_path" { + description = "Path to a local, custom user data template file to use when rendering user data" + type = string + default = "" +} + +################################################################################ +# Launch template +################################################################################ + +variable "create_launch_template" { + description = "Determines whether to create a launch template or not. If set to `false`, EKS will use its own default launch template" + type = bool + default = true +} + +variable "launch_template_name" { + description = "Launch template name - either to be created (`var.create_launch_template` = `true`) or existing (`var.create_launch_template` = `false`)" + type = string + default = "" +} + +variable "launch_template_use_name_prefix" { + description = "Determines whether to use `launch_template_name` as is or create a unique name beginning with the `launch_template_name` as the prefix" + type = bool + default = true +} + +variable "launch_template_description" { + description = "Description of the launch template" + type = string + default = null +} + +variable "ebs_optimized" { + description = "If true, the launched EC2 instance(s) will be EBS-optimized" + type = bool + default = null +} + +variable "ami_id" { + description = "The AMI from which to launch the instance. If not supplied, EKS will use its own default image" + type = string + default = "" +} + +variable "key_name" { + description = "The key name that should be used for the instance(s)" + type = string + default = null +} + +variable "vpc_security_group_ids" { + description = "A list of security group IDs to associate" + type = list(string) + default = [] +} + +variable "cluster_primary_security_group_id" { + description = "The ID of the EKS cluster primary security group to associate with the instance(s). This is the security group that is automatically created by the EKS service" + type = string + default = null +} + +variable "launch_template_default_version" { + description = "Default version of the launch template" + type = string + default = null +} + +variable "update_launch_template_default_version" { + description = "Whether to update the launch templates default version on each update. Conflicts with `launch_template_default_version`" + type = bool + default = true +} + +variable "disable_api_termination" { + description = "If true, enables EC2 instance termination protection" + type = bool + default = null +} + +variable "kernel_id" { + description = "The kernel ID" + type = string + default = null +} + +variable "ram_disk_id" { + description = "The ID of the ram disk" + type = string + default = null +} + +variable "block_device_mappings" { + description = "Specify volumes to attach to the instance besides the volumes specified by the AMI" + type = any + default = {} +} + +variable "capacity_reservation_specification" { + description = "Targeting for EC2 capacity reservations" + type = any + default = {} +} + +variable "cpu_options" { + description = "The CPU options for the instance" + type = map(string) + default = {} +} + +variable "credit_specification" { + description = "Customize the credit specification of the instance" + type = map(string) + default = {} +} + +variable "elastic_gpu_specifications" { + description = "The elastic GPU to attach to the instance" + type = map(string) + default = {} +} + +variable "elastic_inference_accelerator" { + description = "Configuration block containing an Elastic Inference Accelerator to attach to the instance" + type = map(string) + default = {} +} + +variable "enclave_options" { + description = "Enable Nitro Enclaves on launched instances" + type = map(string) + default = {} +} + +variable "instance_market_options" { + description = "The market (purchasing) option for the instance" + type = any + default = {} +} + +variable "license_specifications" { + description = "A list of license specifications to associate with" + type = map(string) + default = {} +} + +variable "metadata_options" { + description = "Customize the metadata options for the instance" + type = map(string) + default = { + http_endpoint = "enabled" + http_tokens = "required" + http_put_response_hop_limit = 2 + } +} + +variable "enable_monitoring" { + description = "Enables/disables detailed monitoring" + type = bool + default = true +} + +variable "network_interfaces" { + description = "Customize network interfaces to be attached at instance boot time" + type = list(any) + default = [] +} + +variable "placement" { + description = "The placement of the instance" + type = map(string) + default = {} +} + +variable "launch_template_tags" { + description = "A map of additional tags to add to the tag_specifications of launch template created" + type = map(string) + default = {} +} + +################################################################################ +# EKS Managed Node Group +################################################################################ + +variable "subnet_ids" { + description = "Identifiers of EC2 Subnets to associate with the EKS Node Group. These subnets must have the following resource tag: `kubernetes.io/cluster/CLUSTER_NAME`" + type = list(string) + default = null +} + +variable "min_size" { + description = "Minimum number of instances/nodes" + type = number + default = 0 +} + +variable "max_size" { + description = "Maximum number of instances/nodes" + type = number + default = 3 +} + +variable "desired_size" { + description = "Desired number of instances/nodes" + type = number + default = 1 +} + +variable "name" { + description = "Name of the EKS managed node group" + type = string + default = "" +} + +variable "use_name_prefix" { + description = "Determines whether to use `name` as is or create a unique name beginning with the `name` as the prefix" + type = bool + default = true +} + +variable "ami_type" { + description = "Type of Amazon Machine Image (AMI) associated with the EKS Node Group. Valid values are `AL2_x86_64`, `AL2_x86_64_GPU`, `AL2_ARM_64`, `CUSTOM`, `BOTTLEROCKET_ARM_64`, `BOTTLEROCKET_x86_64`" + type = string + default = null +} + +variable "ami_release_version" { + description = "AMI version of the EKS Node Group. Defaults to latest version for Kubernetes version" + type = string + default = null +} + +variable "capacity_type" { + description = "Type of capacity associated with the EKS Node Group. Valid values: `ON_DEMAND`, `SPOT`" + type = string + default = "ON_DEMAND" +} + +variable "disk_size" { + description = "Disk size in GiB for nodes. Defaults to `20`" + type = number + default = null +} + +variable "force_update_version" { + description = "Force version update if existing pods are unable to be drained due to a pod disruption budget issue" + type = bool + default = null +} + +variable "instance_types" { + description = "Set of instance types associated with the EKS Node Group. Defaults to `[\"t3.medium\"]`" + type = list(string) + default = null +} + +variable "labels" { + description = "Key-value map of Kubernetes labels. Only labels that are applied with the EKS API are managed by this argument. Other Kubernetes labels applied to the EKS Node Group will not be managed" + type = map(string) + default = null +} + +variable "cluster_version" { + description = "Kubernetes version. Defaults to EKS Cluster Kubernetes version" + type = string + default = null +} + +variable "launch_template_version" { + description = "Launch template version number. The default is `$Default`" + type = string + default = null +} + +variable "remote_access" { + description = "Configuration block with remote access settings" + type = any + default = {} +} + +variable "taints" { + description = "The Kubernetes taints to be applied to the nodes in the node group. Maximum of 50 taints per node group" + type = any + default = {} +} + +variable "update_config" { + description = "Configuration block of settings for max unavailable resources during node group updates" + type = map(string) + default = {} +} + +variable "timeouts" { + description = "Create, update, and delete timeout configurations for the node group" + type = map(string) + default = {} +} + +################################################################################ +# Security Group +################################################################################ + +variable "create_security_group" { + description = "Determines whether to create a security group" + type = bool + default = true +} + +variable "security_group_name" { + description = "Name to use on security group created" + type = string + default = null +} + +variable "security_group_use_name_prefix" { + description = "Determines whether the security group name (`security_group_name`) is used as a prefix" + type = bool + default = true +} + +variable "security_group_description" { + description = "Description for the security group created" + type = string + default = "EKS managed node group security group" +} + +variable "vpc_id" { + description = "ID of the VPC where the security group/nodes will be provisioned" + type = string + default = null +} + +variable "security_group_rules" { + description = "List of security group rules to add to the security group created" + type = any + default = {} +} + +variable "cluster_security_group_id" { + description = "Cluster control plane security group ID" + type = string + default = null +} + +variable "security_group_tags" { + description = "A map of additional tags to add to the security group created" + type = map(string) + default = {} +} + +################################################################################ +# IAM Role +################################################################################ + +variable "create_iam_role" { + description = "Determines whether an IAM role is created or to use an existing IAM role" + type = bool + default = true +} + +variable "cluster_ip_family" { + description = "The IP family used to assign Kubernetes pod and service addresses. Valid values are `ipv4` (default) and `ipv6`" + type = string + default = null +} + +variable "iam_role_arn" { + description = "Existing IAM role ARN for the node group. Required if `create_iam_role` is set to `false`" + type = string + default = null +} + +variable "iam_role_name" { + description = "Name to use on IAM role created" + type = string + default = null +} + +variable "iam_role_use_name_prefix" { + description = "Determines whether the IAM role name (`iam_role_name`) is used as a prefix" + type = bool + default = true +} + +variable "iam_role_path" { + description = "IAM role path" + type = string + default = null +} + +variable "iam_role_description" { + description = "Description of the role" + type = string + default = null +} + +variable "iam_role_permissions_boundary" { + description = "ARN of the policy that is used to set the permissions boundary for the IAM role" + type = string + default = null +} + +variable "iam_role_attach_cni_policy" { + description = "Whether to attach the `AmazonEKS_CNI_Policy`/`AmazonEKS_CNI_IPv6_Policy` IAM policy to the IAM IAM role. WARNING: If set `false` the permissions must be assigned to the `aws-node` DaemonSet pods via another method or nodes will not be able to join the cluster" + type = bool + default = true +} + +variable "iam_role_additional_policies" { + description = "Additional policies to be added to the IAM role" + type = list(string) + default = [] +} + +variable "iam_role_tags" { + description = "A map of additional tags to add to the IAM role created" + type = map(string) + default = {} +} diff --git a/modules/aws-eks/modules/eks-managed-node-group/versions.tf b/modules/aws-eks/modules/eks-managed-node-group/versions.tf new file mode 100644 index 0000000..22e8d72 --- /dev/null +++ b/modules/aws-eks/modules/eks-managed-node-group/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.72" + } + } +} diff --git a/modules/aws-eks/modules/fargate-profile/README.md b/modules/aws-eks/modules/fargate-profile/README.md new file mode 100644 index 0000000..97dd0d3 --- /dev/null +++ b/modules/aws-eks/modules/fargate-profile/README.md @@ -0,0 +1,89 @@ +# EKS Fargate Profile Module + +Configuration in this directory creates a Fargate EKS Profile + +## Usage + +```hcl +module "fargate_profile" { + source = "terraform-aws-modules/eks/aws//modules/fargate-profile" + + name = "separate-fargate-profile" + cluster_name = "my-cluster" + + subnet_ids = ["subnet-abcde012", "subnet-bcde012a", "subnet-fghi345a"] + selectors = [{ + namespace = "kube-system" + }] + + tags = { + Environment = "dev" + Terraform = "true" + } +} +``` + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.72 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 3.72 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_eks_fargate_profile.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_fargate_profile) | resource | +| [aws_iam_role.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | +| [aws_iam_role_policy_attachment.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source | +| [aws_iam_policy_document.assume_role_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_partition.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/partition) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [cluster\_ip\_family](#input\_cluster\_ip\_family) | The IP family used to assign Kubernetes pod and service addresses. Valid values are `ipv4` (default) and `ipv6` | `string` | `null` | no | +| [cluster\_name](#input\_cluster\_name) | Name of the EKS cluster | `string` | `null` | no | +| [create](#input\_create) | Determines whether to create Fargate profile or not | `bool` | `true` | no | +| [create\_iam\_role](#input\_create\_iam\_role) | Determines whether an IAM role is created or to use an existing IAM role | `bool` | `true` | no | +| [iam\_role\_additional\_policies](#input\_iam\_role\_additional\_policies) | Additional policies to be added to the IAM role | `list(string)` | `[]` | no | +| [iam\_role\_arn](#input\_iam\_role\_arn) | Existing IAM role ARN for the Fargate profile. Required if `create_iam_role` is set to `false` | `string` | `null` | no | +| [iam\_role\_attach\_cni\_policy](#input\_iam\_role\_attach\_cni\_policy) | Whether to attach the `AmazonEKS_CNI_Policy`/`AmazonEKS_CNI_IPv6_Policy` IAM policy to the IAM IAM role. WARNING: If set `false` the permissions must be assigned to the `aws-node` DaemonSet pods via another method or nodes will not be able to join the cluster | `bool` | `true` | no | +| [iam\_role\_description](#input\_iam\_role\_description) | Description of the role | `string` | `null` | no | +| [iam\_role\_name](#input\_iam\_role\_name) | Name to use on IAM role created | `string` | `""` | no | +| [iam\_role\_path](#input\_iam\_role\_path) | IAM role path | `string` | `null` | no | +| [iam\_role\_permissions\_boundary](#input\_iam\_role\_permissions\_boundary) | ARN of the policy that is used to set the permissions boundary for the IAM role | `string` | `null` | no | +| [iam\_role\_tags](#input\_iam\_role\_tags) | A map of additional tags to add to the IAM role created | `map(string)` | `{}` | no | +| [iam\_role\_use\_name\_prefix](#input\_iam\_role\_use\_name\_prefix) | Determines whether the IAM role name (`iam_role_name`) is used as a prefix | `bool` | `true` | no | +| [name](#input\_name) | Name of the EKS Fargate Profile | `string` | `""` | no | +| [selectors](#input\_selectors) | Configuration block(s) for selecting Kubernetes Pods to execute with this Fargate Profile | `any` | `[]` | no | +| [subnet\_ids](#input\_subnet\_ids) | A list of subnet IDs for the EKS Fargate Profile | `list(string)` | `[]` | no | +| [tags](#input\_tags) | A map of tags to add to all resources | `map(string)` | `{}` | no | +| [timeouts](#input\_timeouts) | Create and delete timeout configurations for the Fargate Profile | `map(string)` | `{}` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [fargate\_profile\_arn](#output\_fargate\_profile\_arn) | Amazon Resource Name (ARN) of the EKS Fargate Profile | +| [fargate\_profile\_id](#output\_fargate\_profile\_id) | EKS Cluster name and EKS Fargate Profile name separated by a colon (`:`) | +| [fargate\_profile\_pod\_execution\_role\_arn](#output\_fargate\_profile\_pod\_execution\_role\_arn) | Amazon Resource Name (ARN) of the EKS Fargate Profile Pod execution role ARN | +| [fargate\_profile\_status](#output\_fargate\_profile\_status) | Status of the EKS Fargate Profile | +| [iam\_role\_arn](#output\_iam\_role\_arn) | The Amazon Resource Name (ARN) specifying the IAM role | +| [iam\_role\_name](#output\_iam\_role\_name) | The name of the IAM role | +| [iam\_role\_unique\_id](#output\_iam\_role\_unique\_id) | Stable and unique string identifying the IAM role | + diff --git a/modules/aws-eks/modules/fargate-profile/main.tf b/modules/aws-eks/modules/fargate-profile/main.tf new file mode 100644 index 0000000..554b0e8 --- /dev/null +++ b/modules/aws-eks/modules/fargate-profile/main.tf @@ -0,0 +1,86 @@ +data "aws_partition" "current" {} + +data "aws_caller_identity" "current" {} + +locals { + iam_role_name = coalesce(var.iam_role_name, var.name, "fargate-profile") + + iam_role_policy_prefix = "arn:${data.aws_partition.current.partition}:iam::aws:policy" + + cni_policy = var.cluster_ip_family == "ipv6" ? "arn:${data.aws_partition.current.partition}:iam::${data.aws_caller_identity.current.account_id}:policy/AmazonEKS_CNI_IPv6_Policy" : "${local.iam_role_policy_prefix}/AmazonEKS_CNI_Policy" +} + +################################################################################ +# IAM Role +################################################################################ + +data "aws_iam_policy_document" "assume_role_policy" { + count = var.create && var.create_iam_role ? 1 : 0 + + statement { + effect = "Allow" + actions = ["sts:AssumeRole"] + + principals { + type = "Service" + identifiers = ["eks-fargate-pods.amazonaws.com"] + } + } +} + +resource "aws_iam_role" "this" { + count = var.create && var.create_iam_role ? 1 : 0 + + name = var.iam_role_use_name_prefix ? null : local.iam_role_name + name_prefix = var.iam_role_use_name_prefix ? "${local.iam_role_name}-" : null + path = var.iam_role_path + description = var.iam_role_description + + assume_role_policy = data.aws_iam_policy_document.assume_role_policy[0].json + permissions_boundary = var.iam_role_permissions_boundary + force_detach_policies = true + + tags = merge(var.tags, var.iam_role_tags) +} + +resource "aws_iam_role_policy_attachment" "this" { + for_each = var.create && var.create_iam_role ? toset(compact(distinct(concat([ + "${local.iam_role_policy_prefix}/AmazonEKSFargatePodExecutionRolePolicy", + var.iam_role_attach_cni_policy ? local.cni_policy : "", + ], var.iam_role_additional_policies)))) : toset([]) + + policy_arn = each.value + role = aws_iam_role.this[0].name +} + +################################################################################ +# Fargate Profile +################################################################################ + +resource "aws_eks_fargate_profile" "this" { + count = var.create ? 1 : 0 + + cluster_name = var.cluster_name + fargate_profile_name = var.name + pod_execution_role_arn = var.create_iam_role ? aws_iam_role.this[0].arn : var.iam_role_arn + subnet_ids = var.subnet_ids + + dynamic "selector" { + for_each = var.selectors + + content { + namespace = selector.value.namespace + labels = lookup(selector.value, "labels", {}) + } + } + + dynamic "timeouts" { + for_each = [var.timeouts] + content { + create = lookup(var.timeouts, "create", null) + delete = lookup(var.timeouts, "delete", null) + } + } + + tags = var.tags +} diff --git a/modules/aws-eks/modules/fargate-profile/outputs.tf b/modules/aws-eks/modules/fargate-profile/outputs.tf new file mode 100644 index 0000000..c8b663e --- /dev/null +++ b/modules/aws-eks/modules/fargate-profile/outputs.tf @@ -0,0 +1,42 @@ +################################################################################ +# IAM Role +################################################################################ + +output "iam_role_name" { + description = "The name of the IAM role" + value = try(aws_iam_role.this[0].name, "") +} + +output "iam_role_arn" { + description = "The Amazon Resource Name (ARN) specifying the IAM role" + value = try(aws_iam_role.this[0].arn, var.iam_role_arn) +} + +output "iam_role_unique_id" { + description = "Stable and unique string identifying the IAM role" + value = try(aws_iam_role.this[0].unique_id, "") +} + +################################################################################ +# Fargate Profile +################################################################################ + +output "fargate_profile_arn" { + description = "Amazon Resource Name (ARN) of the EKS Fargate Profile" + value = try(aws_eks_fargate_profile.this[0].arn, "") +} + +output "fargate_profile_id" { + description = "EKS Cluster name and EKS Fargate Profile name separated by a colon (`:`)" + value = try(aws_eks_fargate_profile.this[0].id, "") +} + +output "fargate_profile_status" { + description = "Status of the EKS Fargate Profile" + value = try(aws_eks_fargate_profile.this[0].status, "") +} + +output "fargate_profile_pod_execution_role_arn" { + description = "Amazon Resource Name (ARN) of the EKS Fargate Profile Pod execution role ARN" + value = try(aws_eks_fargate_profile.this[0].pod_execution_role_arn, "") +} diff --git a/modules/aws-eks/modules/fargate-profile/variables.tf b/modules/aws-eks/modules/fargate-profile/variables.tf new file mode 100644 index 0000000..4d5e95c --- /dev/null +++ b/modules/aws-eks/modules/fargate-profile/variables.tf @@ -0,0 +1,115 @@ +variable "create" { + description = "Determines whether to create Fargate profile or not" + type = bool + default = true +} + +variable "tags" { + description = "A map of tags to add to all resources" + type = map(string) + default = {} +} + +################################################################################ +# IAM Role +################################################################################ + +variable "create_iam_role" { + description = "Determines whether an IAM role is created or to use an existing IAM role" + type = bool + default = true +} + +variable "cluster_ip_family" { + description = "The IP family used to assign Kubernetes pod and service addresses. Valid values are `ipv4` (default) and `ipv6`" + type = string + default = null +} + +variable "iam_role_arn" { + description = "Existing IAM role ARN for the Fargate profile. Required if `create_iam_role` is set to `false`" + type = string + default = null +} + +variable "iam_role_name" { + description = "Name to use on IAM role created" + type = string + default = "" +} + +variable "iam_role_use_name_prefix" { + description = "Determines whether the IAM role name (`iam_role_name`) is used as a prefix" + type = bool + default = true +} + +variable "iam_role_path" { + description = "IAM role path" + type = string + default = null +} + +variable "iam_role_description" { + description = "Description of the role" + type = string + default = null +} + +variable "iam_role_permissions_boundary" { + description = "ARN of the policy that is used to set the permissions boundary for the IAM role" + type = string + default = null +} + +variable "iam_role_attach_cni_policy" { + description = "Whether to attach the `AmazonEKS_CNI_Policy`/`AmazonEKS_CNI_IPv6_Policy` IAM policy to the IAM IAM role. WARNING: If set `false` the permissions must be assigned to the `aws-node` DaemonSet pods via another method or nodes will not be able to join the cluster" + type = bool + default = true +} + +variable "iam_role_additional_policies" { + description = "Additional policies to be added to the IAM role" + type = list(string) + default = [] +} + +variable "iam_role_tags" { + description = "A map of additional tags to add to the IAM role created" + type = map(string) + default = {} +} + +################################################################################ +# Fargate Profile +################################################################################ + +variable "cluster_name" { + description = "Name of the EKS cluster" + type = string + default = null +} + +variable "name" { + description = "Name of the EKS Fargate Profile" + type = string + default = "" +} + +variable "subnet_ids" { + description = "A list of subnet IDs for the EKS Fargate Profile" + type = list(string) + default = [] +} + +variable "selectors" { + description = "Configuration block(s) for selecting Kubernetes Pods to execute with this Fargate Profile" + type = any + default = [] +} + +variable "timeouts" { + description = "Create and delete timeout configurations for the Fargate Profile" + type = map(string) + default = {} +} diff --git a/modules/aws-eks/modules/fargate-profile/versions.tf b/modules/aws-eks/modules/fargate-profile/versions.tf new file mode 100644 index 0000000..22e8d72 --- /dev/null +++ b/modules/aws-eks/modules/fargate-profile/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.72" + } + } +} diff --git a/modules/aws-eks/modules/karpenter/README.md b/modules/aws-eks/modules/karpenter/README.md new file mode 100644 index 0000000..8e9b6dc --- /dev/null +++ b/modules/aws-eks/modules/karpenter/README.md @@ -0,0 +1,200 @@ +# Karpenter Module + +Configuration in this directory creates the AWS resources required by Karpenter + +## Usage + +### All Resources (Default) + +In the following example, the Karpenter module will create: +- An IAM role for service accounts (IRSA) with a narrowly scoped IAM policy for the Karpenter controller to utilize +- An IAM role and instance profile for the nodes created by Karpenter to utilize + - Note: This IAM role ARN will need to be added to the `aws-auth` configmap for nodes to join the cluster successfully +- An SQS queue and Eventbridge event rules for Karpenter to utilize for spot termination handling, capacity rebalancing, etc. + +This setup is great for running Karpenter on EKS Fargate: + +```hcl +module "eks" { + source = "terraform-aws-modules/eks" + + # Shown just for connection between cluster and Karpenter sub-module below + manage_aws_auth_configmap = true + aws_auth_roles = [ + # We need to add in the Karpenter node IAM role for nodes launched by Karpenter + { + rolearn = module.karpenter.role_arn + username = "system:node:{{EC2PrivateDNSName}}" + groups = [ + "system:bootstrappers", + "system:nodes", + ] + }, + ] + ... +} + +module "karpenter" { + source = "terraform-aws-modules/eks/aws//modules/karpenter" + + cluster_name = module.eks.cluster_name + + irsa_oidc_provider_arn = module.eks.oidc_provider_arn + irsa_namespace_service_accounts = ["karpenter:karpenter"] + + tags = { + Environment = "dev" + Terraform = "true" + } +} +``` + +### External Node IAM Role (Default) + +In the following example, the Karpenter module will create: +- An IAM role for service accounts (IRSA) with a narrowly scoped IAM policy for the Karpenter controller to utilize +- An IAM instance profile for the nodes created by Karpenter to utilize + - Note: This setup will utilize the existing IAM role created by the EKS Managed Node group which means the role is already populated in the `aws-auth` configmap and no further updates are required. +- An SQS queue and Eventbridge event rules for Karpenter to utilize for spot termination handling, capacity rebalancing, etc. + +In this scenario, Karpenter would run atop the EKS Managed Node group and scale out nodes as needed from there: + +```hcl +module "eks" { + source = "terraform-aws-modules/eks" + + # Shown just for connection between cluster and Karpenter sub-module below + eks_managed_node_groups = { + initial = { + instance_types = ["t3.medium"] + + min_size = 1 + max_size = 3 + desired_size = 1 + } + } + ... +} + +module "karpenter" { + source = "terraform-aws-modules/eks/aws//modules/karpenter" + + cluster_name = module.eks.cluster_name + + irsa_oidc_provider_arn = module.eks.oidc_provider_arn + irsa_namespace_service_accounts = ["karpenter:karpenter"] + + create_iam_role = false + iam_role_arn = module.eks.eks_managed_node_groups["initial"].iam_role_arn + + tags = { + Environment = "dev" + Terraform = "true" + } +} +``` + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.0 | +| [aws](#requirement\_aws) | >= 4.47 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 4.47 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_cloudwatch_event_rule.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_rule) | resource | +| [aws_cloudwatch_event_target.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_target) | resource | +| [aws_iam_instance_profile.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_instance_profile) | resource | +| [aws_iam_policy.irsa](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | +| [aws_iam_role.irsa](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | +| [aws_iam_role.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | +| [aws_iam_role_policy_attachment.additional](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_iam_role_policy_attachment.irsa](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_iam_role_policy_attachment.irsa_additional](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_iam_role_policy_attachment.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_sqs_queue.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sqs_queue) | resource | +| [aws_sqs_queue_policy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sqs_queue_policy) | resource | +| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source | +| [aws_iam_policy_document.assume_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.irsa](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.irsa_assume_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.queue](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_partition.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/partition) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [cluster\_ip\_family](#input\_cluster\_ip\_family) | The IP family used to assign Kubernetes pod and service addresses. Valid values are `ipv4` (default) and `ipv6` | `string` | `null` | no | +| [cluster\_name](#input\_cluster\_name) | The name of the EKS cluster | `string` | `""` | no | +| [create](#input\_create) | Determines whether to create EKS managed node group or not | `bool` | `true` | no | +| [create\_iam\_role](#input\_create\_iam\_role) | Determines whether an IAM role is created or to use an existing IAM role | `bool` | `true` | no | +| [create\_instance\_profile](#input\_create\_instance\_profile) | Whether to create an IAM instance profile | `bool` | `true` | no | +| [create\_irsa](#input\_create\_irsa) | Determines whether an IAM role for service accounts is created | `bool` | `true` | no | +| [enable\_spot\_termination](#input\_enable\_spot\_termination) | Determines whether to enable native spot termination handling | `bool` | `true` | no | +| [iam\_role\_additional\_policies](#input\_iam\_role\_additional\_policies) | Additional policies to be added to the IAM role | `list(string)` | `[]` | no | +| [iam\_role\_arn](#input\_iam\_role\_arn) | Existing IAM role ARN for the IAM instance profile. Required if `create_iam_role` is set to `false` | `string` | `null` | no | +| [iam\_role\_attach\_cni\_policy](#input\_iam\_role\_attach\_cni\_policy) | Whether to attach the `AmazonEKS_CNI_Policy`/`AmazonEKS_CNI_IPv6_Policy` IAM policy to the IAM IAM role. WARNING: If set `false` the permissions must be assigned to the `aws-node` DaemonSet pods via another method or nodes will not be able to join the cluster | `bool` | `true` | no | +| [iam\_role\_description](#input\_iam\_role\_description) | Description of the role | `string` | `null` | no | +| [iam\_role\_max\_session\_duration](#input\_iam\_role\_max\_session\_duration) | Maximum API session duration in seconds between 3600 and 43200 | `number` | `null` | no | +| [iam\_role\_name](#input\_iam\_role\_name) | Name to use on IAM role created | `string` | `null` | no | +| [iam\_role\_path](#input\_iam\_role\_path) | IAM role path | `string` | `"/"` | no | +| [iam\_role\_permissions\_boundary](#input\_iam\_role\_permissions\_boundary) | ARN of the policy that is used to set the permissions boundary for the IAM role | `string` | `null` | no | +| [iam\_role\_tags](#input\_iam\_role\_tags) | A map of additional tags to add to the IAM role created | `map(string)` | `{}` | no | +| [iam\_role\_use\_name\_prefix](#input\_iam\_role\_use\_name\_prefix) | Determines whether the IAM role name (`iam_role_name`) is used as a prefix | `bool` | `true` | no | +| [irsa\_assume\_role\_condition\_test](#input\_irsa\_assume\_role\_condition\_test) | Name of the [IAM condition operator](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html) to evaluate when assuming the role | `string` | `"StringEquals"` | no | +| [irsa\_description](#input\_irsa\_description) | IAM role for service accounts description | `string` | `"Karpenter IAM role for service account"` | no | +| [irsa\_max\_session\_duration](#input\_irsa\_max\_session\_duration) | Maximum API session duration in seconds between 3600 and 43200 | `number` | `null` | no | +| [irsa\_name](#input\_irsa\_name) | Name of IAM role for service accounts | `string` | `null` | no | +| [irsa\_namespace\_service\_accounts](#input\_irsa\_namespace\_service\_accounts) | List of `namespace:serviceaccount`pairs to use in trust policy for IAM role for service accounts | `list(string)` |
"http_endpoint": "enabled",
"http_put_response_hop_limit": 2,
"http_tokens": "required"
}
[| no | +| [irsa\_oidc\_provider\_arn](#input\_irsa\_oidc\_provider\_arn) | OIDC provider arn used in trust policy for IAM role for service accounts | `string` | `""` | no | +| [irsa\_path](#input\_irsa\_path) | Path of IAM role for service accounts | `string` | `"/"` | no | +| [irsa\_permissions\_boundary\_arn](#input\_irsa\_permissions\_boundary\_arn) | Permissions boundary ARN to use for IAM role for service accounts | `string` | `null` | no | +| [irsa\_policy\_name](#input\_irsa\_policy\_name) | Name of IAM policy for service accounts | `string` | `null` | no | +| [irsa\_ssm\_parameter\_arns](#input\_irsa\_ssm\_parameter\_arns) | List of SSM Parameter ARNs that contain AMI IDs launched by Karpenter | `list(string)` |
"karpenter:karpenter"
]
[| no | +| [irsa\_subnet\_account\_id](#input\_irsa\_subnet\_account\_id) | Account ID of where the subnets Karpenter will utilize resides. Used when subnets are shared from another account | `string` | `""` | no | +| [irsa\_tag\_key](#input\_irsa\_tag\_key) | Tag key (`{key = value}`) applied to resources launched by Karpenter through the Karpenter provisioner | `string` | `"karpenter.sh/discovery"` | no | +| [irsa\_tag\_values](#input\_irsa\_tag\_values) | Tag values (`{key = value}`) applied to resources launched by Karpenter through the Karpenter provisioner. Defaults to cluster name when not set. | `list(string)` | `[]` | no | +| [irsa\_tags](#input\_irsa\_tags) | A map of additional tags to add the the IAM role for service accounts | `map(any)` | `{}` | no | +| [irsa\_use\_name\_prefix](#input\_irsa\_use\_name\_prefix) | Determines whether the IAM role for service accounts name (`irsa_name`) is used as a prefix | `bool` | `true` | no | +| [policies](#input\_policies) | Policies to attach to the IAM role in `{'static_name' = 'policy_arn'}` format | `map(string)` | `{}` | no | +| [queue\_kms\_data\_key\_reuse\_period\_seconds](#input\_queue\_kms\_data\_key\_reuse\_period\_seconds) | The length of time, in seconds, for which Amazon SQS can reuse a data key to encrypt or decrypt messages before calling AWS KMS again | `number` | `null` | no | +| [queue\_kms\_master\_key\_id](#input\_queue\_kms\_master\_key\_id) | The ID of an AWS-managed customer master key (CMK) for Amazon SQS or a custom CMK | `string` | `null` | no | +| [queue\_managed\_sse\_enabled](#input\_queue\_managed\_sse\_enabled) | Boolean to enable server-side encryption (SSE) of message content with SQS-owned encryption keys | `bool` | `true` | no | +| [queue\_name](#input\_queue\_name) | Name of the SQS queue | `string` | `null` | no | +| [rule\_name\_prefix](#input\_rule\_name\_prefix) | Prefix used for all event bridge rules | `string` | `"Karpenter"` | no | +| [tags](#input\_tags) | A map of tags to add to all resources | `map(string)` | `{}` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [event\_rules](#output\_event\_rules) | Map of the event rules created and their attributes | +| [instance\_profile\_arn](#output\_instance\_profile\_arn) | ARN assigned by AWS to the instance profile | +| [instance\_profile\_id](#output\_instance\_profile\_id) | Instance profile's ID | +| [instance\_profile\_name](#output\_instance\_profile\_name) | Name of the instance profile | +| [instance\_profile\_unique](#output\_instance\_profile\_unique) | Stable and unique string identifying the IAM instance profile | +| [irsa\_arn](#output\_irsa\_arn) | The Amazon Resource Name (ARN) specifying the IAM role for service accounts | +| [irsa\_name](#output\_irsa\_name) | The name of the IAM role for service accounts | +| [irsa\_unique\_id](#output\_irsa\_unique\_id) | Stable and unique string identifying the IAM role for service accounts | +| [queue\_arn](#output\_queue\_arn) | The ARN of the SQS queue | +| [queue\_name](#output\_queue\_name) | The name of the created Amazon SQS queue | +| [queue\_url](#output\_queue\_url) | The URL for the created Amazon SQS queue | +| [role\_arn](#output\_role\_arn) | The Amazon Resource Name (ARN) specifying the IAM role | +| [role\_name](#output\_role\_name) | The name of the IAM role | +| [role\_unique\_id](#output\_role\_unique\_id) | Stable and unique string identifying the IAM role | + diff --git a/modules/aws-eks/modules/karpenter/main.tf b/modules/aws-eks/modules/karpenter/main.tf new file mode 100644 index 0000000..592ac28 --- /dev/null +++ b/modules/aws-eks/modules/karpenter/main.tf @@ -0,0 +1,379 @@ +data "aws_partition" "current" {} +data "aws_caller_identity" "current" {} + +locals { + account_id = data.aws_caller_identity.current.account_id + partition = data.aws_partition.current.partition + dns_suffix = data.aws_partition.current.dns_suffix +} + +################################################################################ +# IAM Role for Service Account (IRSA) +# This is used by the Karpenter controller +################################################################################ + +locals { + create_irsa = var.create && var.create_irsa + irsa_name = coalesce(var.irsa_name, "KarpenterIRSA-${var.cluster_name}") + irsa_policy_name = coalesce(var.irsa_policy_name, local.irsa_name) + + irsa_oidc_provider_url = replace(var.irsa_oidc_provider_arn, "/^(.*provider/)/", "") +} + +data "aws_iam_policy_document" "irsa_assume_role" { + count = local.create_irsa ? 1 : 0 + + statement { + effect = "Allow" + actions = ["sts:AssumeRoleWithWebIdentity"] + + principals { + type = "Federated" + identifiers = [var.irsa_oidc_provider_arn] + } + + condition { + test = var.irsa_assume_role_condition_test + variable = "${local.irsa_oidc_provider_url}:sub" + values = [for sa in var.irsa_namespace_service_accounts : "system:serviceaccount:${sa}"] + } + + # https://aws.amazon.com/premiumsupport/knowledge-center/eks-troubleshoot-oidc-and-irsa/?nc1=h_ls + condition { + test = var.irsa_assume_role_condition_test + variable = "${local.irsa_oidc_provider_url}:aud" + values = ["sts.amazonaws.com"] + } + } +} + +resource "aws_iam_role" "irsa" { + count = local.create_irsa ? 1 : 0 + + name = var.irsa_use_name_prefix ? null : local.irsa_name + name_prefix = var.irsa_use_name_prefix ? "${local.irsa_name}-" : null + path = var.irsa_path + description = var.irsa_description + + assume_role_policy = data.aws_iam_policy_document.irsa_assume_role[0].json + max_session_duration = var.irsa_max_session_duration + permissions_boundary = var.irsa_permissions_boundary_arn + force_detach_policies = true + + tags = merge(var.tags, var.irsa_tags) +} + +locals { + irsa_tag_values = coalescelist(var.irsa_tag_values, [var.cluster_name]) +} + +data "aws_iam_policy_document" "irsa" { + count = local.create_irsa ? 1 : 0 + + statement { + actions = [ + "ec2:CreateLaunchTemplate", + "ec2:CreateFleet", + "ec2:CreateTags", + "ec2:DescribeLaunchTemplates", + "ec2:DescribeImages", + "ec2:DescribeInstances", + "ec2:DescribeSecurityGroups", + "ec2:DescribeSubnets", + "ec2:DescribeInstanceTypes", + "ec2:DescribeInstanceTypeOfferings", + "ec2:DescribeAvailabilityZones", + "ec2:DescribeSpotPriceHistory", + "pricing:GetProducts", + ] + + resources = ["*"] + } + + statement { + actions = [ + "ec2:TerminateInstances", + "ec2:DeleteLaunchTemplate", + ] + + resources = ["*"] + + condition { + test = "StringEquals" + variable = "ec2:ResourceTag/${var.irsa_tag_key}" + values = local.irsa_tag_values + } + } + + statement { + actions = ["ec2:RunInstances"] + resources = [ + "arn:${local.partition}:ec2:*:${local.account_id}:launch-template/*", + ] + + condition { + test = "StringEquals" + variable = "ec2:ResourceTag/${var.irsa_tag_key}" + values = local.irsa_tag_values + } + } + + statement { + actions = ["ec2:RunInstances"] + resources = [ + "arn:${local.partition}:ec2:*::image/*", + "arn:${local.partition}:ec2:*::snapshot/*", + "arn:${local.partition}:ec2:*:${local.account_id}:instance/*", + "arn:${local.partition}:ec2:*:${local.account_id}:spot-instances-request/*", + "arn:${local.partition}:ec2:*:${local.account_id}:security-group/*", + "arn:${local.partition}:ec2:*:${local.account_id}:volume/*", + "arn:${local.partition}:ec2:*:${local.account_id}:network-interface/*", + "arn:${local.partition}:ec2:*:${coalesce(var.irsa_subnet_account_id, local.account_id)}:subnet/*", + ] + } + + statement { + actions = ["ssm:GetParameter"] + resources = var.irsa_ssm_parameter_arns + } + + statement { + actions = ["eks:DescribeCluster"] + resources = ["arn:${local.partition}:eks:*:${local.account_id}:cluster/${var.cluster_name}"] + } + + statement { + actions = ["iam:PassRole"] + resources = [var.create_iam_role ? aws_iam_role.this[0].arn : var.iam_role_arn] + } + + dynamic "statement" { + for_each = local.enable_spot_termination ? [1] : [] + + content { + actions = [ + "sqs:DeleteMessage", + "sqs:GetQueueUrl", + "sqs:GetQueueAttributes", + "sqs:ReceiveMessage", + ] + resources = [aws_sqs_queue.this[0].arn] + } + } +} + +resource "aws_iam_policy" "irsa" { + count = local.create_irsa ? 1 : 0 + + name_prefix = "${local.irsa_policy_name}-" + path = var.irsa_path + description = var.irsa_description + policy = data.aws_iam_policy_document.irsa[0].json + + tags = var.tags +} + +resource "aws_iam_role_policy_attachment" "irsa" { + count = local.create_irsa ? 1 : 0 + + role = aws_iam_role.irsa[0].name + policy_arn = aws_iam_policy.irsa[0].arn +} + +resource "aws_iam_role_policy_attachment" "irsa_additional" { + for_each = { for k, v in var.policies : k => v if local.create_irsa } + + role = aws_iam_role.irsa[0].name + policy_arn = each.value +} + +################################################################################ +# Node Termination Queue +################################################################################ + +locals { + enable_spot_termination = var.create && var.enable_spot_termination + + queue_name = coalesce(var.queue_name, "Karpenter-${var.cluster_name}") +} + +resource "aws_sqs_queue" "this" { + count = local.enable_spot_termination ? 1 : 0 + + name = local.queue_name + message_retention_seconds = 300 + sqs_managed_sse_enabled = var.queue_managed_sse_enabled ? var.queue_managed_sse_enabled : null + kms_master_key_id = var.queue_kms_master_key_id + kms_data_key_reuse_period_seconds = var.queue_kms_data_key_reuse_period_seconds + + tags = var.tags +} + +data "aws_iam_policy_document" "queue" { + count = local.enable_spot_termination ? 1 : 0 + + statement { + sid = "SqsWrite" + actions = ["sqs:SendMessage"] + resources = [aws_sqs_queue.this[0].arn] + + principals { + type = "Service" + identifiers = [ + "events.${local.dns_suffix}", + "sqs.${local.dns_suffix}", + ] + } + + } +} + +resource "aws_sqs_queue_policy" "this" { + count = local.enable_spot_termination ? 1 : 0 + + queue_url = aws_sqs_queue.this[0].url + policy = data.aws_iam_policy_document.queue[0].json +} + +################################################################################ +# Node Termination Event Rules +################################################################################ + +locals { + events = { + health_event = { + name = "HealthEvent" + description = "Karpenter interrupt - AWS health event" + event_pattern = { + source = ["aws.health"] + detail-type = ["AWS Health Event"] + } + } + spot_interupt = { + name = "SpotInterrupt" + description = "Karpenter interrupt - EC2 spot instance interruption warning" + event_pattern = { + source = ["aws.ec2"] + detail-type = ["EC2 Spot Instance Interruption Warning"] + } + } + instance_rebalance = { + name = "InstanceRebalance" + description = "Karpenter interrupt - EC2 instance rebalance recommendation" + event_pattern = { + source = ["aws.ec2"] + detail-type = ["EC2 Instance Rebalance Recommendation"] + } + } + instance_state_change = { + name = "InstanceStateChange" + description = "Karpenter interrupt - EC2 instance state-change notification" + event_pattern = { + source = ["aws.ec2"] + detail-type = ["EC2 Instance State-change Notification"] + } + } + } +} + +resource "aws_cloudwatch_event_rule" "this" { + for_each = { for k, v in local.events : k => v if local.enable_spot_termination } + + description = each.value.description + event_pattern = jsonencode(each.value.event_pattern) + + tags = merge( + { "ClusterName" : var.cluster_name }, + var.tags, + ) +} + +resource "aws_cloudwatch_event_target" "this" { + for_each = { for k, v in local.events : k => v if local.enable_spot_termination } + + rule = aws_cloudwatch_event_rule.this[each.key].name + target_id = "KarpenterInterruptionQueueTarget" + arn = aws_sqs_queue.this[0].arn +} + +################################################################################ +# Node IAM Role +# This is used by the nodes launched by Karpenter +################################################################################ + +locals { + create_iam_role = var.create && var.create_iam_role + + iam_role_name = coalesce(var.iam_role_name, "Karpenter-${var.cluster_name}") + iam_role_policy_prefix = "arn:${local.partition}:iam::aws:policy" + cni_policy = var.cluster_ip_family == "ipv6" ? "${local.iam_role_policy_prefix}/AmazonEKS_CNI_IPv6_Policy" : "${local.iam_role_policy_prefix}/AmazonEKS_CNI_Policy" +} + +data "aws_iam_policy_document" "assume_role" { + count = local.create_iam_role ? 1 : 0 + + statement { + sid = "EKSNodeAssumeRole" + actions = ["sts:AssumeRole"] + + principals { + type = "Service" + identifiers = ["ec2.${local.dns_suffix}"] + } + } +} + +resource "aws_iam_role" "this" { + count = local.create_iam_role ? 1 : 0 + + name = var.iam_role_use_name_prefix ? null : local.iam_role_name + name_prefix = var.iam_role_use_name_prefix ? "${local.iam_role_name}-" : null + path = var.iam_role_path + description = var.iam_role_description + + assume_role_policy = data.aws_iam_policy_document.assume_role[0].json + max_session_duration = var.iam_role_max_session_duration + permissions_boundary = var.iam_role_permissions_boundary + force_detach_policies = true + + tags = merge(var.tags, var.iam_role_tags) +} + +# Policies attached ref https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_node_group +resource "aws_iam_role_policy_attachment" "this" { + for_each = { for k, v in toset(compact([ + "${local.iam_role_policy_prefix}/AmazonEKSWorkerNodePolicy", + "${local.iam_role_policy_prefix}/AmazonEC2ContainerRegistryReadOnly", + var.iam_role_attach_cni_policy ? local.cni_policy : "", + ])) : k => v if local.create_iam_role } + + policy_arn = each.value + role = aws_iam_role.this[0].name +} + +resource "aws_iam_role_policy_attachment" "additional" { + for_each = { for k, v in var.iam_role_additional_policies : k => v if local.create_iam_role } + + policy_arn = each.value + role = aws_iam_role.this[0].name +} + +################################################################################ +# Node IAM Instance Profile +# This is used by the nodes launched by Karpenter +################################################################################ + +locals { + external_role_name = try(replace(var.iam_role_arn, "/^(.*role/)/", ""), null) +} + +resource "aws_iam_instance_profile" "this" { + count = var.create && var.create_instance_profile ? 1 : 0 + + name = var.iam_role_use_name_prefix ? null : local.iam_role_name + name_prefix = var.iam_role_use_name_prefix ? "${local.iam_role_name}-" : null + path = var.iam_role_path + role = var.create_iam_role ? aws_iam_role.this[0].name : local.external_role_name + + tags = merge(var.tags, var.iam_role_tags) +} diff --git a/modules/aws-eks/modules/karpenter/outputs.tf b/modules/aws-eks/modules/karpenter/outputs.tf new file mode 100644 index 0000000..947de39 --- /dev/null +++ b/modules/aws-eks/modules/karpenter/outputs.tf @@ -0,0 +1,89 @@ +################################################################################ +# IAM Role for Service Account (IRSA) +################################################################################ + +output "irsa_name" { + description = "The name of the IAM role for service accounts" + value = try(aws_iam_role.irsa[0].name, null) +} + +output "irsa_arn" { + description = "The Amazon Resource Name (ARN) specifying the IAM role for service accounts" + value = try(aws_iam_role.irsa[0].arn, null) +} + +output "irsa_unique_id" { + description = "Stable and unique string identifying the IAM role for service accounts" + value = try(aws_iam_role.irsa[0].unique_id, null) +} + +################################################################################ +# Node Termination Queue +################################################################################ + +output "queue_arn" { + description = "The ARN of the SQS queue" + value = try(aws_sqs_queue.this[0].arn, null) +} + +output "queue_name" { + description = "The name of the created Amazon SQS queue" + value = try(aws_sqs_queue.this[0].name, null) +} + +output "queue_url" { + description = "The URL for the created Amazon SQS queue" + value = try(aws_sqs_queue.this[0].url, null) +} + +################################################################################ +# Node Termination Event Rules +################################################################################ + +output "event_rules" { + description = "Map of the event rules created and their attributes" + value = aws_cloudwatch_event_rule.this +} + +################################################################################ +# Node IAM Role +################################################################################ + +output "role_name" { + description = "The name of the IAM role" + value = try(aws_iam_role.this[0].name, null) +} + +output "role_arn" { + description = "The Amazon Resource Name (ARN) specifying the IAM role" + value = try(aws_iam_role.this[0].arn, var.iam_role_arn) +} + +output "role_unique_id" { + description = "Stable and unique string identifying the IAM role" + value = try(aws_iam_role.this[0].unique_id, null) +} + +################################################################################ +# Node IAM Instance Profile +################################################################################ + +output "instance_profile_arn" { + description = "ARN assigned by AWS to the instance profile" + value = try(aws_iam_instance_profile.this[0].arn, null) +} + +output "instance_profile_id" { + description = "Instance profile's ID" + value = try(aws_iam_instance_profile.this[0].id, null) +} + +output "instance_profile_name" { + description = "Name of the instance profile" + value = try(aws_iam_instance_profile.this[0].name, null) +} + +output "instance_profile_unique" { + description = "Stable and unique string identifying the IAM instance profile" + value = try(aws_iam_instance_profile.this[0].unique_id, null) +} diff --git a/modules/aws-eks/modules/karpenter/provider.tf b/modules/aws-eks/modules/karpenter/provider.tf new file mode 100644 index 0000000..e5657de --- /dev/null +++ b/modules/aws-eks/modules/karpenter/provider.tf @@ -0,0 +1,6 @@ +provider "aws" { + assume_role { + role_arn = var.provider_assume_role_arn + } + region = var.provider_region +} diff --git a/modules/aws-eks/modules/karpenter/variables.tf b/modules/aws-eks/modules/karpenter/variables.tf new file mode 100644 index 0000000..9e6ed77 --- /dev/null +++ b/modules/aws-eks/modules/karpenter/variables.tf @@ -0,0 +1,271 @@ +variable "create" { + description = "Creates the resources under this module" + type = bool + default = true +} + +variable "tags" { + description = "A map of tags to add to all resources" + type = map(string) + default = {} +} + +variable "cluster_name" { + description = "The name of the EKS cluster" + type = string + default = "" +} + +################################################################################ +# IAM Role for Service Account (IRSA) +################################################################################ + +variable "create_irsa" { + description = "Determines whether an IAM role for service accounts is created" + type = bool + default = true +} + +variable "irsa_name" { + description = "Name of IAM role for service accounts" + type = string + default = null +} + +variable "irsa_policy_name" { + description = "Name of IAM policy for service accounts" + type = string + default = null +} + +variable "irsa_use_name_prefix" { + description = "Determines whether the IAM role for service accounts name (`irsa_name`) is used as a prefix" + type = bool + default = true +} + +variable "irsa_path" { + description = "Path of IAM role for service accounts" + type = string + default = "/" +} + +variable "irsa_description" { + description = "IAM role for service accounts description" + type = string + default = "Karpenter IAM role for service account" +} + +variable "irsa_max_session_duration" { + description = "Maximum API session duration in seconds between 3600 and 43200" + type = number + default = null +} + +variable "irsa_permissions_boundary_arn" { + description = "Permissions boundary ARN to use for IAM role for service accounts" + type = string + default = null +} + +variable "irsa_tags" { + description = "A map of additional tags to add the the IAM role for service accounts" + type = map(any) + default = {} +} + +variable "policies" { + description = "Policies to attach to the IAM role in `{'static_name' = 'policy_arn'}` format" + type = map(string) + default = {} +} + +variable "irsa_tag_key" { + description = "Tag key (`{key = value}`) applied to resources launched by Karpenter through the Karpenter provisioner" + type = string + default = "karpenter.sh/discovery" +} + +variable "irsa_tag_values" { + description = "Tag values (`{key = value}`) applied to resources launched by Karpenter through the Karpenter provisioner. Defaults to cluster name when not set." + type = list(string) + default = [] +} + +variable "irsa_ssm_parameter_arns" { + description = "List of SSM Parameter ARNs that contain AMI IDs launched by Karpenter" + type = list(string) + # https://github.com/aws/karpenter/blob/ed9473a9863ca949b61b9846c8b9f33f35b86dbd/pkg/cloudprovider/aws/ami.go#L105-L123 + default = ["arn:aws:ssm:*:*:parameter/aws/service/*"] +} + +variable "irsa_subnet_account_id" { + description = "Account ID of where the subnets Karpenter will utilize resides. Used when subnets are shared from another account" + type = string + default = "" +} + +variable "irsa_oidc_provider_arn" { + description = "OIDC provider arn used in trust policy for IAM role for service accounts" + type = string + default = "" +} + +variable "irsa_namespace_service_accounts" { + description = "List of `namespace:serviceaccount`pairs to use in trust policy for IAM role for service accounts" + type = list(string) + default = ["karpenter:karpenter"] +} + +variable "irsa_assume_role_condition_test" { + description = "Name of the [IAM condition operator](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html) to evaluate when assuming the role" + type = string + default = "StringEquals" +} + +################################################################################ +# Node Termination Queue +################################################################################ + +variable "enable_spot_termination" { + description = "Determines whether to enable native spot termination handling" + type = bool + default = true +} + +variable "queue_name" { + description = "Name of the SQS queue" + type = string + default = null +} + +variable "queue_managed_sse_enabled" { + description = "Boolean to enable server-side encryption (SSE) of message content with SQS-owned encryption keys" + type = bool + default = true +} + +variable "queue_kms_master_key_id" { + description = "The ID of an AWS-managed customer master key (CMK) for Amazon SQS or a custom CMK" + type = string + default = null +} + +variable "queue_kms_data_key_reuse_period_seconds" { + description = "The length of time, in seconds, for which Amazon SQS can reuse a data key to encrypt or decrypt messages before calling AWS KMS again" + type = number + default = null +} + +################################################################################ +# Node IAM Role & Instance Profile +################################################################################ + +variable "create_iam_role" { + description = "Determines whether an IAM role is created or to use an existing IAM role" + type = bool + default = true +} + +variable "cluster_ip_family" { + description = "The IP family used to assign Kubernetes pod and service addresses. Valid values are `ipv4` (default) and `ipv6`" + type = string + default = null +} + +variable "iam_role_arn" { + description = "Existing IAM role ARN for the IAM instance profile. Required if `create_iam_role` is set to `false`" + type = string + default = null +} + +variable "iam_role_name" { + description = "Name to use on IAM role created" + type = string + default = null +} + +variable "iam_role_use_name_prefix" { + description = "Determines whether the IAM role name (`iam_role_name`) is used as a prefix" + type = bool + default = true +} + +variable "iam_role_path" { + description = "IAM role path" + type = string + default = "/" +} + +variable "iam_role_description" { + description = "Description of the role" + type = string + default = null +} + +variable "iam_role_max_session_duration" { + description = "Maximum API session duration in seconds between 3600 and 43200" + type = number + default = null +} + +variable "iam_role_permissions_boundary" { + description = "ARN of the policy that is used to set the permissions boundary for the IAM role" + type = string + default = null +} + +variable "iam_role_attach_cni_policy" { + description = "Whether to attach the `AmazonEKS_CNI_Policy`/`AmazonEKS_CNI_IPv6_Policy` IAM policy to the IAM IAM role. WARNING: If set `false` the permissions must be assigned to the `aws-node` DaemonSet pods via another method or nodes will not be able to join the cluster" + type = bool + default = true +} + +variable "iam_role_additional_policies" { + description = "Additional policies to be added to the IAM role" + type = list(string) + default = [] +} + +variable "iam_role_tags" { + description = "A map of additional tags to add to the IAM role created" + type = map(string) + default = {} +} + +################################################################################ +# Node IAM Instance Profile +################################################################################ + +variable "create_instance_profile" { + description = "Whether to create an IAM instance profile" + type = bool + default = true +} + +################################################################################ +# Event Bridge Rules +################################################################################ + +variable "rule_name_prefix" { + description = "Prefix used for all event bridge rules" + type = string + default = "Karpenter" +} + + +################################################################################ +# Provider configuration +################################################################################ + +variable "provider_region" { + description = "Region to provision resources" + type = string + default = "eu-west-1" +} + +variable "provider_assume_role_arn" { + description = "Provider to assume role for account access" + type = string + default = "" +} \ No newline at end of file diff --git a/modules/aws-eks/modules/karpenter/versions.tf b/modules/aws-eks/modules/karpenter/versions.tf new file mode 100644 index 0000000..55eff62 --- /dev/null +++ b/modules/aws-eks/modules/karpenter/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.47" + } + } +} diff --git a/modules/aws-eks/modules/self-managed-node-group/README.md b/modules/aws-eks/modules/self-managed-node-group/README.md new file mode 100644 index 0000000..eb0b484 --- /dev/null +++ b/modules/aws-eks/modules/self-managed-node-group/README.md @@ -0,0 +1,208 @@ +# Self Managed Node Group Module + +Configuration in this directory creates a Self Managed Node Group (AutoScaling Group) along with an IAM role, security group, and launch template + +## Usage + +```hcl +module "self_managed_node_group" { + source = "terraform-aws-modules/eks/aws//modules/self-managed-node-group" + + name = "separate-self-mng" + cluster_name = "my-cluster" + cluster_version = "1.22" + cluster_endpoint = "https://012345678903AB2BAE5D1E0BFE0E2B50.gr7.us-east-1.eks.amazonaws.com" + cluster_auth_base64 = "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM1ekNDQWMrZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKbXFqQ1VqNGdGR2w3ZW5PeWthWnZ2RjROOTVOUEZCM2o0cGhVZUsrWGFtN2ZSQnZya0d6OGxKZmZEZWF2b2plTwpQK2xOZFlqdHZncmxCUEpYdHZIZmFzTzYxVzdIZmdWQ2EvamdRM2w3RmkvL1dpQmxFOG9oWUZkdWpjc0s1SXM2CnNkbk5KTTNYUWN2TysrSitkV09NT2ZlNzlsSWdncmdQLzgvRU9CYkw3eUY1aU1hS3lsb1RHL1V3TlhPUWt3ZUcKblBNcjdiUmdkQ1NCZTlXYXowOGdGRmlxV2FOditsTDhsODBTdFZLcWVNVlUxbjQyejVwOVpQRTd4T2l6L0xTNQpYV2lXWkVkT3pMN0xBWGVCS2gzdkhnczFxMkI2d1BKZnZnS1NzWllQRGFpZTloT1NNOUJkNFNPY3JrZTRYSVBOCkVvcXVhMlYrUDRlTWJEQzhMUkVWRDdCdVZDdWdMTldWOTBoL3VJUy9WU2VOcEdUOGVScE5DakszSjc2aFlsWm8KWjNGRG5QWUY0MWpWTHhiOXF0U1ROdEp6amYwWXBEYnFWci9xZzNmQWlxbVorMzd3YWM1eHlqMDZ4cmlaRUgzZgpUM002d2lCUEVHYVlGeWN5TmNYTk5aYW9DWDJVL0N1d2JsUHAKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQ==" + + vpc_id = "vpc-1234556abcdef" + subnet_ids = ["subnet-abcde012", "subnet-bcde012a", "subnet-fghi345a"] + vpc_security_group_ids = [ + # cluster_security_group_id, + ] + + min_size = 1 + max_size = 10 + desired_size = 1 + + launch_template_name = "separate-self-mng" + instance_type = "m5.large" + + tags = { + Environment = "dev" + Terraform = "true" + } +} +``` + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.72 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 3.72 | + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [user\_data](#module\_user\_data) | ../_user_data | n/a | + +## Resources + +| Name | Type | +|------|------| +| [aws_autoscaling_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/autoscaling_group) | resource | +| [aws_autoscaling_schedule.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/autoscaling_schedule) | resource | +| [aws_iam_instance_profile.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_instance_profile) | resource | +| [aws_iam_role.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | +| [aws_iam_role_policy_attachment.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_launch_template.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/launch_template) | resource | +| [aws_security_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource | +| [aws_security_group_rule.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | +| [aws_ami.eks_default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ami) | data source | +| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source | +| [aws_default_tags.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/default_tags) | data source | +| [aws_iam_policy_document.assume_role_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_partition.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/partition) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [ami\_id](#input\_ami\_id) | The AMI from which to launch the instance | `string` | `""` | no | +| [autoscaling\_group\_tags](#input\_autoscaling\_group\_tags) | A map of additional tags to add to the autoscaling group created. Tags are applied to the autoscaling group only and are NOT propagated to instances | `map(string)` | `{}` | no | +| [availability\_zones](#input\_availability\_zones) | A list of one or more availability zones for the group. Used for EC2-Classic and default subnets when not specified with `subnet_ids` argument. Conflicts with `subnet_ids` | `list(string)` | `null` | no | +| [block\_device\_mappings](#input\_block\_device\_mappings) | Specify volumes to attach to the instance besides the volumes specified by the AMI | `any` | `{}` | no | +| [bootstrap\_extra\_args](#input\_bootstrap\_extra\_args) | Additional arguments passed to the bootstrap script. When `platform` = `bottlerocket`; these are additional [settings](https://github.com/bottlerocket-os/bottlerocket#settings) that are provided to the Bottlerocket user data | `string` | `""` | no | +| [capacity\_rebalance](#input\_capacity\_rebalance) | Indicates whether capacity rebalance is enabled | `bool` | `null` | no | +| [capacity\_reservation\_specification](#input\_capacity\_reservation\_specification) | Targeting for EC2 capacity reservations | `any` | `{}` | no | +| [cluster\_auth\_base64](#input\_cluster\_auth\_base64) | Base64 encoded CA of associated EKS cluster | `string` | `""` | no | +| [cluster\_endpoint](#input\_cluster\_endpoint) | Endpoint of associated EKS cluster | `string` | `""` | no | +| [cluster\_ip\_family](#input\_cluster\_ip\_family) | The IP family used to assign Kubernetes pod and service addresses. Valid values are `ipv4` (default) and `ipv6` | `string` | `null` | no | +| [cluster\_name](#input\_cluster\_name) | Name of associated EKS cluster | `string` | `""` | no | +| [cluster\_primary\_security\_group\_id](#input\_cluster\_primary\_security\_group\_id) | The ID of the EKS cluster primary security group to associate with the instance(s). This is the security group that is automatically created by the EKS service | `string` | `null` | no | +| [cluster\_security\_group\_id](#input\_cluster\_security\_group\_id) | Cluster control plane security group ID | `string` | `null` | no | +| [cluster\_version](#input\_cluster\_version) | Kubernetes cluster version - used to lookup default AMI ID if one is not provided | `string` | `null` | no | +| [cpu\_options](#input\_cpu\_options) | The CPU options for the instance | `map(string)` | `{}` | no | +| [create](#input\_create) | Determines whether to create self managed node group or not | `bool` | `true` | no | +| [create\_autoscaling\_group](#input\_create\_autoscaling\_group) | Determines whether to create autoscaling group or not | `bool` | `true` | no | +| [create\_iam\_instance\_profile](#input\_create\_iam\_instance\_profile) | Determines whether an IAM instance profile is created or to use an existing IAM instance profile | `bool` | `true` | no | +| [create\_launch\_template](#input\_create\_launch\_template) | Determines whether to create launch template or not | `bool` | `true` | no | +| [create\_schedule](#input\_create\_schedule) | Determines whether to create autoscaling group schedule or not | `bool` | `true` | no | +| [create\_security\_group](#input\_create\_security\_group) | Determines whether to create a security group | `bool` | `true` | no | +| [credit\_specification](#input\_credit\_specification) | Customize the credit specification of the instance | `map(string)` | `{}` | no | +| [default\_cooldown](#input\_default\_cooldown) | The amount of time, in seconds, after a scaling activity completes before another scaling activity can start | `number` | `null` | no | +| [delete\_timeout](#input\_delete\_timeout) | Delete timeout to wait for destroying autoscaling group | `string` | `null` | no | +| [desired\_size](#input\_desired\_size) | The number of Amazon EC2 instances that should be running in the autoscaling group | `number` | `1` | no | +| [disable\_api\_termination](#input\_disable\_api\_termination) | If true, enables EC2 instance termination protection | `bool` | `null` | no | +| [ebs\_optimized](#input\_ebs\_optimized) | If true, the launched EC2 instance will be EBS-optimized | `bool` | `null` | no | +| [elastic\_gpu\_specifications](#input\_elastic\_gpu\_specifications) | The elastic GPU to attach to the instance | `map(string)` | `{}` | no | +| [elastic\_inference\_accelerator](#input\_elastic\_inference\_accelerator) | Configuration block containing an Elastic Inference Accelerator to attach to the instance | `map(string)` | `{}` | no | +| [enable\_monitoring](#input\_enable\_monitoring) | Enables/disables detailed monitoring | `bool` | `true` | no | +| [enabled\_metrics](#input\_enabled\_metrics) | A list of metrics to collect. The allowed values are `GroupDesiredCapacity`, `GroupInServiceCapacity`, `GroupPendingCapacity`, `GroupMinSize`, `GroupMaxSize`, `GroupInServiceInstances`, `GroupPendingInstances`, `GroupStandbyInstances`, `GroupStandbyCapacity`, `GroupTerminatingCapacity`, `GroupTerminatingInstances`, `GroupTotalCapacity`, `GroupTotalInstances` | `list(string)` | `[]` | no | +| [enclave\_options](#input\_enclave\_options) | Enable Nitro Enclaves on launched instances | `map(string)` | `{}` | no | +| [force\_delete](#input\_force\_delete) | Allows deleting the Auto Scaling Group without waiting for all instances in the pool to terminate. You can force an Auto Scaling Group to delete even if it's in the process of scaling a resource. Normally, Terraform drains all the instances before deleting the group. This bypasses that behavior and potentially leaves resources dangling | `bool` | `null` | no | +| [health\_check\_grace\_period](#input\_health\_check\_grace\_period) | Time (in seconds) after instance comes into service before checking health | `number` | `null` | no | +| [health\_check\_type](#input\_health\_check\_type) | `EC2` or `ELB`. Controls how health checking is done | `string` | `null` | no | +| [hibernation\_options](#input\_hibernation\_options) | The hibernation options for the instance | `map(string)` | `{}` | no | +| [iam\_instance\_profile\_arn](#input\_iam\_instance\_profile\_arn) | Amazon Resource Name (ARN) of an existing IAM instance profile that provides permissions for the node group. Required if `create_iam_instance_profile` = `false` | `string` | `null` | no | +| [iam\_role\_additional\_policies](#input\_iam\_role\_additional\_policies) | Additional policies to be added to the IAM role | `list(string)` | `[]` | no | +| [iam\_role\_attach\_cni\_policy](#input\_iam\_role\_attach\_cni\_policy) | Whether to attach the `AmazonEKS_CNI_Policy`/`AmazonEKS_CNI_IPv6_Policy` IAM policy to the IAM IAM role. WARNING: If set `false` the permissions must be assigned to the `aws-node` DaemonSet pods via another method or nodes will not be able to join the cluster | `bool` | `true` | no | +| [iam\_role\_description](#input\_iam\_role\_description) | Description of the role | `string` | `null` | no | +| [iam\_role\_name](#input\_iam\_role\_name) | Name to use on IAM role created | `string` | `null` | no | +| [iam\_role\_path](#input\_iam\_role\_path) | IAM role path | `string` | `null` | no | +| [iam\_role\_permissions\_boundary](#input\_iam\_role\_permissions\_boundary) | ARN of the policy that is used to set the permissions boundary for the IAM role | `string` | `null` | no | +| [iam\_role\_tags](#input\_iam\_role\_tags) | A map of additional tags to add to the IAM role created | `map(string)` | `{}` | no | +| [iam\_role\_use\_name\_prefix](#input\_iam\_role\_use\_name\_prefix) | Determines whether cluster IAM role name (`iam_role_name`) is used as a prefix | `bool` | `true` | no | +| [initial\_lifecycle\_hooks](#input\_initial\_lifecycle\_hooks) | One or more Lifecycle Hooks to attach to the Auto Scaling Group before instances are launched. The syntax is exactly the same as the separate `aws_autoscaling_lifecycle_hook` resource, without the `autoscaling_group_name` attribute. Please note that this will only work when creating a new Auto Scaling Group. For all other use-cases, please use `aws_autoscaling_lifecycle_hook` resource | `list(map(string))` | `[]` | no | +| [instance\_initiated\_shutdown\_behavior](#input\_instance\_initiated\_shutdown\_behavior) | Shutdown behavior for the instance. Can be `stop` or `terminate`. (Default: `stop`) | `string` | `null` | no | +| [instance\_market\_options](#input\_instance\_market\_options) | The market (purchasing) option for the instance | `any` | `{}` | no | +| [instance\_refresh](#input\_instance\_refresh) | If this block is configured, start an Instance Refresh when this Auto Scaling Group is updated | `any` | `{}` | no | +| [instance\_type](#input\_instance\_type) | The type of the instance to launch | `string` | `""` | no | +| [kernel\_id](#input\_kernel\_id) | The kernel ID | `string` | `null` | no | +| [key\_name](#input\_key\_name) | The key name that should be used for the instance | `string` | `null` | no | +| [launch\_template\_default\_version](#input\_launch\_template\_default\_version) | Default Version of the launch template | `string` | `null` | no | +| [launch\_template\_description](#input\_launch\_template\_description) | Description of the launch template | `string` | `null` | no | +| [launch\_template\_name](#input\_launch\_template\_name) | Launch template name - either to be created (`var.create_launch_template` = `true`) or existing (`var.create_launch_template` = `false`) | `string` | `null` | no | +| [launch\_template\_tags](#input\_launch\_template\_tags) | A map of additional tags to add to the tag\_specifications of launch template created | `map(string)` | `{}` | no | +| [launch\_template\_use\_name\_prefix](#input\_launch\_template\_use\_name\_prefix) | Determines whether to use `launch_template_name` as is or create a unique name beginning with the `launch_template_name` as the prefix | `bool` | `true` | no | +| [launch\_template\_version](#input\_launch\_template\_version) | Launch template version. Can be version number, `$Latest`, or `$Default` | `string` | `null` | no | +| [license\_specifications](#input\_license\_specifications) | A list of license specifications to associate with | `map(string)` | `{}` | no | +| [max\_instance\_lifetime](#input\_max\_instance\_lifetime) | The maximum amount of time, in seconds, that an instance can be in service, values must be either equal to 0 or between 604800 and 31536000 seconds | `number` | `null` | no | +| [max\_size](#input\_max\_size) | The maximum size of the autoscaling group | `number` | `3` | no | +| [metadata\_options](#input\_metadata\_options) | Customize the metadata options for the instance | `map(string)` |
"arn:aws:ssm:*:*:parameter/aws/service/*"
]
{| no | +| [metrics\_granularity](#input\_metrics\_granularity) | The granularity to associate with the metrics to collect. The only valid value is `1Minute` | `string` | `null` | no | +| [min\_elb\_capacity](#input\_min\_elb\_capacity) | Setting this causes Terraform to wait for this number of instances to show up healthy in the ELB only on creation. Updates will not wait on ELB instance number changes | `number` | `null` | no | +| [min\_size](#input\_min\_size) | The minimum size of the autoscaling group | `number` | `0` | no | +| [mixed\_instances\_policy](#input\_mixed\_instances\_policy) | Configuration block containing settings to define launch targets for Auto Scaling groups | `any` | `null` | no | +| [name](#input\_name) | Name of the Self managed Node Group | `string` | `""` | no | +| [network\_interfaces](#input\_network\_interfaces) | Customize network interfaces to be attached at instance boot time | `list(any)` | `[]` | no | +| [placement](#input\_placement) | The placement of the instance | `map(string)` | `{}` | no | +| [placement\_group](#input\_placement\_group) | The name of the placement group into which you'll launch your instances, if any | `string` | `null` | no | +| [platform](#input\_platform) | Identifies if the OS platform is `bottlerocket`, `linux`, or `windows` based | `string` | `"linux"` | no | +| [post\_bootstrap\_user\_data](#input\_post\_bootstrap\_user\_data) | User data that is appended to the user data script after of the EKS bootstrap script. Not used when `platform` = `bottlerocket` | `string` | `""` | no | +| [pre\_bootstrap\_user\_data](#input\_pre\_bootstrap\_user\_data) | User data that is injected into the user data script ahead of the EKS bootstrap script. Not used when `platform` = `bottlerocket` | `string` | `""` | no | +| [protect\_from\_scale\_in](#input\_protect\_from\_scale\_in) | Allows setting instance protection. The autoscaling group will not select instances with this setting for termination during scale in events. | `bool` | `false` | no | +| [ram\_disk\_id](#input\_ram\_disk\_id) | The ID of the ram disk | `string` | `null` | no | +| [schedules](#input\_schedules) | Map of autoscaling group schedule to create | `map(any)` | `{}` | no | +| [security\_group\_description](#input\_security\_group\_description) | Description for the security group created | `string` | `"EKS self-managed node group security group"` | no | +| [security\_group\_name](#input\_security\_group\_name) | Name to use on security group created | `string` | `null` | no | +| [security\_group\_rules](#input\_security\_group\_rules) | List of security group rules to add to the security group created | `any` | `{}` | no | +| [security\_group\_tags](#input\_security\_group\_tags) | A map of additional tags to add to the security group created | `map(string)` | `{}` | no | +| [security\_group\_use\_name\_prefix](#input\_security\_group\_use\_name\_prefix) | Determines whether the security group name (`security_group_name`) is used as a prefix | `bool` | `true` | no | +| [service\_linked\_role\_arn](#input\_service\_linked\_role\_arn) | The ARN of the service-linked role that the ASG will use to call other AWS services | `string` | `null` | no | +| [subnet\_ids](#input\_subnet\_ids) | A list of subnet IDs to launch resources in. Subnets automatically determine which availability zones the group will reside. Conflicts with `availability_zones` | `list(string)` | `null` | no | +| [suspended\_processes](#input\_suspended\_processes) | A list of processes to suspend for the Auto Scaling Group. The allowed values are `Launch`, `Terminate`, `HealthCheck`, `ReplaceUnhealthy`, `AZRebalance`, `AlarmNotification`, `ScheduledActions`, `AddToLoadBalancer`. Note that if you suspend either the `Launch` or `Terminate` process types, it can prevent your Auto Scaling Group from functioning properly | `list(string)` | `[]` | no | +| [tags](#input\_tags) | A map of tags to add to all resources | `map(string)` | `{}` | no | +| [target\_group\_arns](#input\_target\_group\_arns) | A set of `aws_alb_target_group` ARNs, for use with Application or Network Load Balancing | `list(string)` | `[]` | no | +| [termination\_policies](#input\_termination\_policies) | A list of policies to decide how the instances in the Auto Scaling Group should be terminated. The allowed values are `OldestInstance`, `NewestInstance`, `OldestLaunchConfiguration`, `ClosestToNextInstanceHour`, `OldestLaunchTemplate`, `AllocationStrategy`, `Default` | `list(string)` | `[]` | no | +| [update\_launch\_template\_default\_version](#input\_update\_launch\_template\_default\_version) | Whether to update Default Version each update. Conflicts with `launch_template_default_version` | `bool` | `true` | no | +| [use\_default\_tags](#input\_use\_default\_tags) | Enables/disables the use of provider default tags in the tag\_specifications of the Auto Scaling group | `bool` | `false` | no | +| [use\_mixed\_instances\_policy](#input\_use\_mixed\_instances\_policy) | Determines whether to use a mixed instances policy in the autoscaling group or not | `bool` | `false` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Determines whether to use `name` as is or create a unique name beginning with the `name` as the prefix | `bool` | `true` | no | +| [user\_data\_template\_path](#input\_user\_data\_template\_path) | Path to a local, custom user data template file to use when rendering user data | `string` | `""` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where the security group/nodes will be provisioned | `string` | `null` | no | +| [vpc\_security\_group\_ids](#input\_vpc\_security\_group\_ids) | A list of security group IDs to associate | `list(string)` | `[]` | no | +| [wait\_for\_capacity\_timeout](#input\_wait\_for\_capacity\_timeout) | A maximum duration that Terraform should wait for ASG instances to be healthy before timing out. (See also Waiting for Capacity below.) Setting this to '0' causes Terraform to skip all Capacity Waiting behavior. | `string` | `null` | no | +| [wait\_for\_elb\_capacity](#input\_wait\_for\_elb\_capacity) | Setting this will cause Terraform to wait for exactly this number of healthy instances in all attached load balancers on both create and update operations. Takes precedence over `min_elb_capacity` behavior. | `number` | `null` | no | +| [warm\_pool](#input\_warm\_pool) | If this block is configured, add a Warm Pool to the specified Auto Scaling group | `any` | `{}` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [autoscaling\_group\_arn](#output\_autoscaling\_group\_arn) | The ARN for this autoscaling group | +| [autoscaling\_group\_availability\_zones](#output\_autoscaling\_group\_availability\_zones) | The availability zones of the autoscaling group | +| [autoscaling\_group\_default\_cooldown](#output\_autoscaling\_group\_default\_cooldown) | Time between a scaling activity and the succeeding scaling activity | +| [autoscaling\_group\_desired\_capacity](#output\_autoscaling\_group\_desired\_capacity) | The number of Amazon EC2 instances that should be running in the group | +| [autoscaling\_group\_health\_check\_grace\_period](#output\_autoscaling\_group\_health\_check\_grace\_period) | Time after instance comes into service before checking health | +| [autoscaling\_group\_health\_check\_type](#output\_autoscaling\_group\_health\_check\_type) | EC2 or ELB. Controls how health checking is done | +| [autoscaling\_group\_id](#output\_autoscaling\_group\_id) | The autoscaling group id | +| [autoscaling\_group\_max\_size](#output\_autoscaling\_group\_max\_size) | The maximum size of the autoscaling group | +| [autoscaling\_group\_min\_size](#output\_autoscaling\_group\_min\_size) | The minimum size of the autoscaling group | +| [autoscaling\_group\_name](#output\_autoscaling\_group\_name) | The autoscaling group name | +| [autoscaling\_group\_schedule\_arns](#output\_autoscaling\_group\_schedule\_arns) | ARNs of autoscaling group schedules | +| [autoscaling\_group\_vpc\_zone\_identifier](#output\_autoscaling\_group\_vpc\_zone\_identifier) | The VPC zone identifier | +| [iam\_instance\_profile\_arn](#output\_iam\_instance\_profile\_arn) | ARN assigned by AWS to the instance profile | +| [iam\_instance\_profile\_id](#output\_iam\_instance\_profile\_id) | Instance profile's ID | +| [iam\_instance\_profile\_unique](#output\_iam\_instance\_profile\_unique) | Stable and unique string identifying the IAM instance profile | +| [iam\_role\_arn](#output\_iam\_role\_arn) | The Amazon Resource Name (ARN) specifying the IAM role | +| [iam\_role\_name](#output\_iam\_role\_name) | The name of the IAM role | +| [iam\_role\_unique\_id](#output\_iam\_role\_unique\_id) | Stable and unique string identifying the IAM role | +| [image\_id](#output\_image\_id) | ID of the image | +| [launch\_template\_arn](#output\_launch\_template\_arn) | The ARN of the launch template | +| [launch\_template\_id](#output\_launch\_template\_id) | The ID of the launch template | +| [launch\_template\_latest\_version](#output\_launch\_template\_latest\_version) | The latest version of the launch template | +| [launch\_template\_name](#output\_launch\_template\_name) | The name of the launch template | +| [platform](#output\_platform) | Identifies if the OS platform is `bottlerocket`, `linux`, or `windows` based | +| [security\_group\_arn](#output\_security\_group\_arn) | Amazon Resource Name (ARN) of the security group | +| [security\_group\_id](#output\_security\_group\_id) | ID of the security group | +| [user\_data](#output\_user\_data) | Base64 encoded user data | + diff --git a/modules/aws-eks/modules/self-managed-node-group/main.tf b/modules/aws-eks/modules/self-managed-node-group/main.tf new file mode 100644 index 0000000..f74fb81 --- /dev/null +++ b/modules/aws-eks/modules/self-managed-node-group/main.tf @@ -0,0 +1,568 @@ +data "aws_partition" "current" {} + +data "aws_caller_identity" "current" {} + +data "aws_default_tags" "current" {} + +data "aws_ami" "eks_default" { + count = var.create ? 1 : 0 + + filter { + name = "name" + values = ["amazon-eks-node-${var.cluster_version}-v*"] + } + + most_recent = true + owners = ["amazon"] +} + +################################################################################ +# User Data +################################################################################ + +module "user_data" { + source = "../_user_data" + + create = var.create + platform = var.platform + is_eks_managed_node_group = false + + cluster_name = var.cluster_name + cluster_endpoint = var.cluster_endpoint + cluster_auth_base64 = var.cluster_auth_base64 + + enable_bootstrap_user_data = true + pre_bootstrap_user_data = var.pre_bootstrap_user_data + post_bootstrap_user_data = var.post_bootstrap_user_data + bootstrap_extra_args = var.bootstrap_extra_args + user_data_template_path = var.user_data_template_path +} + +################################################################################ +# Launch template +################################################################################ + +locals { + launch_template_name_int = coalesce(var.launch_template_name, "${var.name}-node-group") + + security_group_ids = compact(concat([try(aws_security_group.this[0].id, ""), var.cluster_primary_security_group_id], var.vpc_security_group_ids)) +} + +resource "aws_launch_template" "this" { + count = var.create && var.create_launch_template ? 1 : 0 + + name = var.launch_template_use_name_prefix ? null : local.launch_template_name_int + name_prefix = var.launch_template_use_name_prefix ? "${local.launch_template_name_int}-" : null + description = var.launch_template_description + + ebs_optimized = var.ebs_optimized + image_id = coalesce(var.ami_id, data.aws_ami.eks_default[0].image_id) + instance_type = var.instance_type + key_name = var.key_name + user_data = module.user_data.user_data + + vpc_security_group_ids = length(var.network_interfaces) > 0 ? [] : local.security_group_ids + + default_version = var.launch_template_default_version + update_default_version = var.update_launch_template_default_version + disable_api_termination = var.disable_api_termination + instance_initiated_shutdown_behavior = var.instance_initiated_shutdown_behavior + kernel_id = var.kernel_id + ram_disk_id = var.ram_disk_id + + dynamic "block_device_mappings" { + for_each = var.block_device_mappings + content { + device_name = block_device_mappings.value.device_name + no_device = lookup(block_device_mappings.value, "no_device", null) + virtual_name = lookup(block_device_mappings.value, "virtual_name", null) + + dynamic "ebs" { + for_each = flatten([lookup(block_device_mappings.value, "ebs", [])]) + content { + delete_on_termination = lookup(ebs.value, "delete_on_termination", null) + encrypted = lookup(ebs.value, "encrypted", null) + kms_key_id = lookup(ebs.value, "kms_key_id", null) + iops = lookup(ebs.value, "iops", null) + throughput = lookup(ebs.value, "throughput", null) + snapshot_id = lookup(ebs.value, "snapshot_id", null) + volume_size = lookup(ebs.value, "volume_size", null) + volume_type = lookup(ebs.value, "volume_type", null) + } + } + } + } + + dynamic "capacity_reservation_specification" { + for_each = length(var.capacity_reservation_specification) > 0 ? [var.capacity_reservation_specification] : [] + content { + capacity_reservation_preference = lookup(capacity_reservation_specification.value, "capacity_reservation_preference", null) + + dynamic "capacity_reservation_target" { + for_each = try([capacity_reservation_specification.value.capacity_reservation_target], []) + content { + capacity_reservation_id = lookup(capacity_reservation_target.value, "capacity_reservation_id", null) + } + } + } + } + + dynamic "cpu_options" { + for_each = length(var.cpu_options) > 0 ? [var.cpu_options] : [] + content { + core_count = cpu_options.value.core_count + threads_per_core = cpu_options.value.threads_per_core + } + } + + dynamic "credit_specification" { + for_each = length(var.credit_specification) > 0 ? [var.credit_specification] : [] + content { + cpu_credits = credit_specification.value.cpu_credits + } + } + + dynamic "elastic_gpu_specifications" { + for_each = length(var.elastic_gpu_specifications) > 0 ? [var.elastic_gpu_specifications] : [] + content { + type = elastic_gpu_specifications.value.type + } + } + + dynamic "elastic_inference_accelerator" { + for_each = length(var.elastic_inference_accelerator) > 0 ? [var.elastic_inference_accelerator] : [] + content { + type = elastic_inference_accelerator.value.type + } + } + + dynamic "enclave_options" { + for_each = length(var.enclave_options) > 0 ? [var.enclave_options] : [] + content { + enabled = enclave_options.value.enabled + } + } + + dynamic "hibernation_options" { + for_each = length(var.hibernation_options) > 0 ? [var.hibernation_options] : [] + content { + configured = hibernation_options.value.configured + } + } + + iam_instance_profile { + arn = var.create_iam_instance_profile ? aws_iam_instance_profile.this[0].arn : var.iam_instance_profile_arn + } + + dynamic "instance_market_options" { + for_each = length(var.instance_market_options) > 0 ? [var.instance_market_options] : [] + content { + market_type = instance_market_options.value.market_type + + dynamic "spot_options" { + for_each = length(lookup(instance_market_options.value, "spot_options", {})) > 0 ? [instance_market_options.value.spot_options] : [] + content { + block_duration_minutes = lookup(spot_options.value, "block_duration_minutes", null) + instance_interruption_behavior = lookup(spot_options.value, "instance_interruption_behavior", null) + max_price = lookup(spot_options.value, "max_price", null) + spot_instance_type = lookup(spot_options.value, "spot_instance_type", null) + valid_until = lookup(spot_options.value, "valid_until", null) + } + } + } + } + + dynamic "license_specification" { + for_each = length(var.license_specifications) > 0 ? [var.license_specifications] : [] + content { + license_configuration_arn = license_specifications.value.license_configuration_arn + } + } + + dynamic "metadata_options" { + for_each = length(var.metadata_options) > 0 ? [var.metadata_options] : [] + content { + http_endpoint = lookup(metadata_options.value, "http_endpoint", null) + http_tokens = lookup(metadata_options.value, "http_tokens", null) + http_put_response_hop_limit = lookup(metadata_options.value, "http_put_response_hop_limit", null) + http_protocol_ipv6 = lookup(metadata_options.value, "http_protocol_ipv6", null) + instance_metadata_tags = lookup(metadata_options.value, "instance_metadata_tags", null) + } + } + + dynamic "monitoring" { + for_each = var.enable_monitoring != null ? [1] : [] + content { + enabled = var.enable_monitoring + } + } + + dynamic "network_interfaces" { + for_each = var.network_interfaces + content { + associate_carrier_ip_address = lookup(network_interfaces.value, "associate_carrier_ip_address", null) + associate_public_ip_address = lookup(network_interfaces.value, "associate_public_ip_address", null) + delete_on_termination = lookup(network_interfaces.value, "delete_on_termination", null) + description = lookup(network_interfaces.value, "description", null) + device_index = lookup(network_interfaces.value, "device_index", null) + interface_type = lookup(network_interfaces.value, "interface_type", null) + ipv4_addresses = try(network_interfaces.value.ipv4_addresses, []) + ipv4_address_count = lookup(network_interfaces.value, "ipv4_address_count", null) + ipv6_addresses = try(network_interfaces.value.ipv6_addresses, []) + ipv6_address_count = lookup(network_interfaces.value, "ipv6_address_count", null) + network_interface_id = lookup(network_interfaces.value, "network_interface_id", null) + private_ip_address = lookup(network_interfaces.value, "private_ip_address", null) + security_groups = compact(concat(try(network_interfaces.value.security_groups, []), local.security_group_ids)) + subnet_id = lookup(network_interfaces.value, "subnet_id", null) + } + } + + dynamic "placement" { + for_each = length(var.placement) > 0 ? [var.placement] : [] + content { + affinity = lookup(placement.value, "affinity", null) + availability_zone = lookup(placement.value, "availability_zone", null) + group_name = lookup(placement.value, "group_name", null) + host_id = lookup(placement.value, "host_id", null) + spread_domain = lookup(placement.value, "spread_domain", null) + tenancy = lookup(placement.value, "tenancy", null) + partition_number = lookup(placement.value, "partition_number", null) + } + } + + dynamic "tag_specifications" { + for_each = toset(["instance", "volume", "network-interface"]) + content { + resource_type = tag_specifications.key + tags = merge(var.tags, { Name = var.name }, var.launch_template_tags) + } + } + + lifecycle { + create_before_destroy = true + } + + # Prevent premature access of security group roles and policies by pods that + # require permissions on create/destroy that depend on nodes + depends_on = [ + aws_security_group_rule.this, + aws_iam_role_policy_attachment.this, + ] + + tags = var.tags +} + +################################################################################ +# Node Group +################################################################################ + +locals { + launch_template_name = try(aws_launch_template.this[0].name, var.launch_template_name) + # Change order to allow users to set version priority before using defaults + launch_template_version = coalesce(var.launch_template_version, try(aws_launch_template.this[0].default_version, "$Default")) +} + +resource "aws_autoscaling_group" "this" { + count = var.create && var.create_autoscaling_group ? 1 : 0 + + name = var.use_name_prefix ? null : var.name + name_prefix = var.use_name_prefix ? "${var.name}-" : null + + dynamic "launch_template" { + for_each = var.use_mixed_instances_policy ? [] : [1] + + content { + name = local.launch_template_name + version = local.launch_template_version + } + } + + availability_zones = var.availability_zones + vpc_zone_identifier = var.subnet_ids + + min_size = var.min_size + max_size = var.max_size + desired_capacity = var.desired_size + capacity_rebalance = var.capacity_rebalance + min_elb_capacity = var.min_elb_capacity + wait_for_elb_capacity = var.wait_for_elb_capacity + wait_for_capacity_timeout = var.wait_for_capacity_timeout + default_cooldown = var.default_cooldown + protect_from_scale_in = var.protect_from_scale_in + + target_group_arns = var.target_group_arns + placement_group = var.placement_group + health_check_type = var.health_check_type + health_check_grace_period = var.health_check_grace_period + + force_delete = var.force_delete + termination_policies = var.termination_policies + suspended_processes = var.suspended_processes + max_instance_lifetime = var.max_instance_lifetime + + enabled_metrics = var.enabled_metrics + metrics_granularity = var.metrics_granularity + service_linked_role_arn = var.service_linked_role_arn + + dynamic "initial_lifecycle_hook" { + for_each = var.initial_lifecycle_hooks + content { + name = initial_lifecycle_hook.value.name + default_result = lookup(initial_lifecycle_hook.value, "default_result", null) + heartbeat_timeout = lookup(initial_lifecycle_hook.value, "heartbeat_timeout", null) + lifecycle_transition = initial_lifecycle_hook.value.lifecycle_transition + notification_metadata = lookup(initial_lifecycle_hook.value, "notification_metadata", null) + notification_target_arn = lookup(initial_lifecycle_hook.value, "notification_target_arn", null) + role_arn = lookup(initial_lifecycle_hook.value, "role_arn", null) + } + } + + dynamic "instance_refresh" { + for_each = length(var.instance_refresh) > 0 ? [var.instance_refresh] : [] + content { + strategy = instance_refresh.value.strategy + triggers = lookup(instance_refresh.value, "triggers", null) + + dynamic "preferences" { + for_each = length(lookup(instance_refresh.value, "preferences", {})) > 0 ? [instance_refresh.value.preferences] : [] + content { + instance_warmup = lookup(preferences.value, "instance_warmup", null) + min_healthy_percentage = lookup(preferences.value, "min_healthy_percentage", null) + checkpoint_delay = lookup(preferences.value, "checkpoint_delay", null) + checkpoint_percentages = lookup(preferences.value, "checkpoint_percentages", null) + } + } + } + } + + dynamic "mixed_instances_policy" { + for_each = var.use_mixed_instances_policy ? [var.mixed_instances_policy] : [] + content { + dynamic "instances_distribution" { + for_each = try([mixed_instances_policy.value.instances_distribution], []) + content { + on_demand_allocation_strategy = lookup(instances_distribution.value, "on_demand_allocation_strategy", null) + on_demand_base_capacity = lookup(instances_distribution.value, "on_demand_base_capacity", null) + on_demand_percentage_above_base_capacity = lookup(instances_distribution.value, "on_demand_percentage_above_base_capacity", null) + spot_allocation_strategy = lookup(instances_distribution.value, "spot_allocation_strategy", null) + spot_instance_pools = lookup(instances_distribution.value, "spot_instance_pools", null) + spot_max_price = lookup(instances_distribution.value, "spot_max_price", null) + } + } + + launch_template { + launch_template_specification { + launch_template_name = local.launch_template_name + version = local.launch_template_version + } + + dynamic "override" { + for_each = try(mixed_instances_policy.value.override, []) + content { + instance_type = lookup(override.value, "instance_type", null) + weighted_capacity = lookup(override.value, "weighted_capacity", null) + + dynamic "launch_template_specification" { + for_each = length(lookup(override.value, "launch_template_specification", {})) > 0 ? override.value.launch_template_specification : [] + content { + launch_template_id = lookup(launch_template_specification.value, "launch_template_id", null) + } + } + } + } + } + } + } + + dynamic "warm_pool" { + for_each = length(var.warm_pool) > 0 ? [var.warm_pool] : [] + content { + pool_state = lookup(warm_pool.value, "pool_state", null) + min_size = lookup(warm_pool.value, "min_size", null) + max_group_prepared_capacity = lookup(warm_pool.value, "max_group_prepared_capacity", null) + } + } + + dynamic "tag" { + for_each = merge( + { + "Name" = var.name + "kubernetes.io/cluster/${var.cluster_name}" = "owned" + "k8s.io/cluster/${var.cluster_name}" = "owned" + }, + var.use_default_tags ? merge(data.aws_default_tags.current.tags, var.tags) : var.tags + ) + + content { + key = tag.key + value = tag.value + propagate_at_launch = true + } + } + + dynamic "tag" { + for_each = var.autoscaling_group_tags + + content { + key = tag.key + value = tag.value + propagate_at_launch = false + } + } + + timeouts { + delete = var.delete_timeout + } + + lifecycle { + create_before_destroy = true + ignore_changes = [ + desired_capacity + ] + } +} + +################################################################################ +# Autoscaling group schedule +################################################################################ + +resource "aws_autoscaling_schedule" "this" { + for_each = var.create && var.create_schedule ? var.schedules : {} + + scheduled_action_name = each.key + autoscaling_group_name = aws_autoscaling_group.this[0].name + + min_size = lookup(each.value, "min_size", null) + max_size = lookup(each.value, "max_size", null) + desired_capacity = lookup(each.value, "desired_size", null) + start_time = lookup(each.value, "start_time", null) + end_time = lookup(each.value, "end_time", null) + time_zone = lookup(each.value, "time_zone", null) + + # [Minute] [Hour] [Day_of_Month] [Month_of_Year] [Day_of_Week] + # Cron examples: https://crontab.guru/examples.html + recurrence = lookup(each.value, "recurrence", null) +} + +################################################################################ +# Security Group +################################################################################ + +locals { + security_group_name = coalesce(var.security_group_name, "${var.name}-node-group") + create_security_group = var.create && var.create_security_group +} + +resource "aws_security_group" "this" { + count = local.create_security_group ? 1 : 0 + + name = var.security_group_use_name_prefix ? null : local.security_group_name + name_prefix = var.security_group_use_name_prefix ? "${local.security_group_name}-" : null + description = var.security_group_description + vpc_id = var.vpc_id + + tags = merge( + var.tags, + { + "Name" = local.security_group_name + }, + var.security_group_tags + ) + + # https://github.com/hashicorp/terraform-provider-aws/issues/2445 + # https://github.com/hashicorp/terraform-provider-aws/issues/9692 + lifecycle { + create_before_destroy = true + } +} + +resource "aws_security_group_rule" "this" { + for_each = { for k, v in var.security_group_rules : k => v if local.create_security_group } + + # Required + security_group_id = aws_security_group.this[0].id + protocol = each.value.protocol + from_port = each.value.from_port + to_port = each.value.to_port + type = each.value.type + + # Optional + description = try(each.value.description, null) + cidr_blocks = try(each.value.cidr_blocks, null) + ipv6_cidr_blocks = try(each.value.ipv6_cidr_blocks, null) + prefix_list_ids = try(each.value.prefix_list_ids, []) + self = try(each.value.self, null) + source_security_group_id = try( + each.value.source_security_group_id, + try(each.value.source_cluster_security_group, false) ? var.cluster_security_group_id : null + ) +} + +################################################################################ +# IAM Role +################################################################################ + +locals { + iam_role_name = coalesce(var.iam_role_name, "${var.name}-node-group") + + iam_role_policy_prefix = "arn:${data.aws_partition.current.partition}:iam::aws:policy" + + cni_policy = var.cluster_ip_family == "ipv6" ? "arn:${data.aws_partition.current.partition}:iam::${data.aws_caller_identity.current.account_id}:policy/AmazonEKS_CNI_IPv6_Policy" : "${local.iam_role_policy_prefix}/AmazonEKS_CNI_Policy" +} + +data "aws_iam_policy_document" "assume_role_policy" { + count = var.create && var.create_iam_instance_profile ? 1 : 0 + + statement { + sid = "EKSNodeAssumeRole" + actions = ["sts:AssumeRole"] + + principals { + type = "Service" + identifiers = ["ec2.${data.aws_partition.current.dns_suffix}"] + } + } +} + +resource "aws_iam_role" "this" { + count = var.create && var.create_iam_instance_profile ? 1 : 0 + + name = var.iam_role_use_name_prefix ? null : local.iam_role_name + name_prefix = var.iam_role_use_name_prefix ? "${local.iam_role_name}-" : null + path = var.iam_role_path + description = var.iam_role_description + + assume_role_policy = data.aws_iam_policy_document.assume_role_policy[0].json + permissions_boundary = var.iam_role_permissions_boundary + force_detach_policies = true + + tags = merge(var.tags, var.iam_role_tags) +} + +resource "aws_iam_role_policy_attachment" "this" { + for_each = var.create && var.create_iam_instance_profile ? toset(compact(distinct(concat([ + "${local.iam_role_policy_prefix}/AmazonEKSWorkerNodePolicy", + "${local.iam_role_policy_prefix}/AmazonEC2ContainerRegistryReadOnly", + var.iam_role_attach_cni_policy ? local.cni_policy : "", + ], var.iam_role_additional_policies)))) : toset([]) + + policy_arn = each.value + role = aws_iam_role.this[0].name +} + +# Only self-managed node group requires instance profile +resource "aws_iam_instance_profile" "this" { + count = var.create && var.create_iam_instance_profile ? 1 : 0 + + role = aws_iam_role.this[0].name + + name = var.iam_role_use_name_prefix ? null : local.iam_role_name + name_prefix = var.iam_role_use_name_prefix ? "${local.iam_role_name}-" : null + path = var.iam_role_path + + lifecycle { + create_before_destroy = true + } + + tags = merge(var.tags, var.iam_role_tags) +} diff --git a/modules/aws-eks/modules/self-managed-node-group/outputs.tf b/modules/aws-eks/modules/self-managed-node-group/outputs.tf new file mode 100644 index 0000000..0cfba97 --- /dev/null +++ b/modules/aws-eks/modules/self-managed-node-group/outputs.tf @@ -0,0 +1,162 @@ +################################################################################ +# Launch template +################################################################################ + +output "launch_template_id" { + description = "The ID of the launch template" + value = try(aws_launch_template.this[0].id, "") +} + +output "launch_template_arn" { + description = "The ARN of the launch template" + value = try(aws_launch_template.this[0].arn, "") +} + +output "launch_template_latest_version" { + description = "The latest version of the launch template" + value = try(aws_launch_template.this[0].latest_version, "") +} + +output "launch_template_name" { + description = "The name of the launch template" + value = try(aws_launch_template.this[0].name, "") +} + +################################################################################ +# autoscaling group +################################################################################ + +output "autoscaling_group_arn" { + description = "The ARN for this autoscaling group" + value = try(aws_autoscaling_group.this[0].arn, "") +} + +output "autoscaling_group_id" { + description = "The autoscaling group id" + value = try(aws_autoscaling_group.this[0].id, "") +} + +output "autoscaling_group_name" { + description = "The autoscaling group name" + value = try(aws_autoscaling_group.this[0].name, "") +} + +output "autoscaling_group_min_size" { + description = "The minimum size of the autoscaling group" + value = try(aws_autoscaling_group.this[0].min_size, "") +} + +output "autoscaling_group_max_size" { + description = "The maximum size of the autoscaling group" + value = try(aws_autoscaling_group.this[0].max_size, "") +} + +output "autoscaling_group_desired_capacity" { + description = "The number of Amazon EC2 instances that should be running in the group" + value = try(aws_autoscaling_group.this[0].desired_capacity, "") +} + +output "autoscaling_group_default_cooldown" { + description = "Time between a scaling activity and the succeeding scaling activity" + value = try(aws_autoscaling_group.this[0].default_cooldown, "") +} + +output "autoscaling_group_health_check_grace_period" { + description = "Time after instance comes into service before checking health" + value = try(aws_autoscaling_group.this[0].health_check_grace_period, "") +} + +output "autoscaling_group_health_check_type" { + description = "EC2 or ELB. Controls how health checking is done" + value = try(aws_autoscaling_group.this[0].health_check_type, "") +} + +output "autoscaling_group_availability_zones" { + description = "The availability zones of the autoscaling group" + value = try(aws_autoscaling_group.this[0].availability_zones, "") +} + +output "autoscaling_group_vpc_zone_identifier" { + description = "The VPC zone identifier" + value = try(aws_autoscaling_group.this[0].vpc_zone_identifier, "") +} + +################################################################################ +# autoscaling group schedule +################################################################################ + +output "autoscaling_group_schedule_arns" { + description = "ARNs of autoscaling group schedules" + value = { for k, v in aws_autoscaling_schedule.this : k => v.arn } +} + +################################################################################ +# Security Group +################################################################################ + +output "security_group_arn" { + description = "Amazon Resource Name (ARN) of the security group" + value = try(aws_security_group.this[0].arn, "") +} + +output "security_group_id" { + description = "ID of the security group" + value = try(aws_security_group.this[0].id, "") +} + +################################################################################ +# IAM Role +################################################################################ + +output "iam_role_name" { + description = "The name of the IAM role" + value = try(aws_iam_role.this[0].name, "") +} + +output "iam_role_arn" { + description = "The Amazon Resource Name (ARN) specifying the IAM role" + value = try(aws_iam_role.this[0].arn, "") +} + +output "iam_role_unique_id" { + description = "Stable and unique string identifying the IAM role" + value = try(aws_iam_role.this[0].unique_id, "") +} + +################################################################################ +# IAM Instance Profile +################################################################################ + +output "iam_instance_profile_arn" { + description = "ARN assigned by AWS to the instance profile" + value = try(aws_iam_instance_profile.this[0].arn, var.iam_instance_profile_arn) +} + +output "iam_instance_profile_id" { + description = "Instance profile's ID" + value = try(aws_iam_instance_profile.this[0].id, "") +} + +output "iam_instance_profile_unique" { + description = "Stable and unique string identifying the IAM instance profile" + value = try(aws_iam_instance_profile.this[0].unique_id, "") +} + +################################################################################ +# Additional +################################################################################ + +output "platform" { + description = "Identifies if the OS platform is `bottlerocket`, `linux`, or `windows` based" + value = var.platform +} + +output "image_id" { + description = "ID of the image" + value = try(data.aws_ami.eks_default[0].image_id, "") +} + +output "user_data" { + description = "Base64 encoded user data" + value = try(module.user_data.user_data, "") +} diff --git a/modules/aws-eks/modules/self-managed-node-group/variables.tf b/modules/aws-eks/modules/self-managed-node-group/variables.tf new file mode 100644 index 0000000..3734d90 --- /dev/null +++ b/modules/aws-eks/modules/self-managed-node-group/variables.tf @@ -0,0 +1,609 @@ +variable "create" { + description = "Determines whether to create self managed node group or not" + type = bool + default = true +} + +variable "tags" { + description = "A map of tags to add to all resources" + type = map(string) + default = {} +} + +variable "platform" { + description = "Identifies if the OS platform is `bottlerocket`, `linux`, or `windows` based" + type = string + default = "linux" +} + +################################################################################ +# User Data +################################################################################ + +variable "cluster_name" { + description = "Name of associated EKS cluster" + type = string + default = "" +} + +variable "cluster_endpoint" { + description = "Endpoint of associated EKS cluster" + type = string + default = "" +} + +variable "cluster_auth_base64" { + description = "Base64 encoded CA of associated EKS cluster" + type = string + default = "" +} + +variable "pre_bootstrap_user_data" { + description = "User data that is injected into the user data script ahead of the EKS bootstrap script. Not used when `platform` = `bottlerocket`" + type = string + default = "" +} + +variable "post_bootstrap_user_data" { + description = "User data that is appended to the user data script after of the EKS bootstrap script. Not used when `platform` = `bottlerocket`" + type = string + default = "" +} + +variable "bootstrap_extra_args" { + description = "Additional arguments passed to the bootstrap script. When `platform` = `bottlerocket`; these are additional [settings](https://github.com/bottlerocket-os/bottlerocket#settings) that are provided to the Bottlerocket user data" + type = string + default = "" +} + +variable "user_data_template_path" { + description = "Path to a local, custom user data template file to use when rendering user data" + type = string + default = "" +} + +################################################################################ +# Launch template +################################################################################ + +variable "create_launch_template" { + description = "Determines whether to create launch template or not" + type = bool + default = true +} + +variable "launch_template_name" { + description = "Launch template name - either to be created (`var.create_launch_template` = `true`) or existing (`var.create_launch_template` = `false`)" + type = string + default = null +} + +variable "launch_template_use_name_prefix" { + description = "Determines whether to use `launch_template_name` as is or create a unique name beginning with the `launch_template_name` as the prefix" + type = bool + default = true +} + +variable "launch_template_description" { + description = "Description of the launch template" + type = string + default = null +} + +variable "launch_template_default_version" { + description = "Default Version of the launch template" + type = string + default = null +} + +variable "update_launch_template_default_version" { + description = "Whether to update Default Version each update. Conflicts with `launch_template_default_version`" + type = bool + default = true +} + +variable "disable_api_termination" { + description = "If true, enables EC2 instance termination protection" + type = bool + default = null +} + +variable "instance_initiated_shutdown_behavior" { + description = "Shutdown behavior for the instance. Can be `stop` or `terminate`. (Default: `stop`)" + type = string + default = null +} + +variable "kernel_id" { + description = "The kernel ID" + type = string + default = null +} + +variable "ram_disk_id" { + description = "The ID of the ram disk" + type = string + default = null +} + +variable "block_device_mappings" { + description = "Specify volumes to attach to the instance besides the volumes specified by the AMI" + type = any + default = {} +} + +variable "capacity_reservation_specification" { + description = "Targeting for EC2 capacity reservations" + type = any + default = {} +} + +variable "cpu_options" { + description = "The CPU options for the instance" + type = map(string) + default = {} +} + +variable "credit_specification" { + description = "Customize the credit specification of the instance" + type = map(string) + default = {} +} + +variable "elastic_gpu_specifications" { + description = "The elastic GPU to attach to the instance" + type = map(string) + default = {} +} + +variable "elastic_inference_accelerator" { + description = "Configuration block containing an Elastic Inference Accelerator to attach to the instance" + type = map(string) + default = {} +} + +variable "enclave_options" { + description = "Enable Nitro Enclaves on launched instances" + type = map(string) + default = {} +} + +variable "hibernation_options" { + description = "The hibernation options for the instance" + type = map(string) + default = {} +} + +variable "instance_market_options" { + description = "The market (purchasing) option for the instance" + type = any + default = {} +} + +variable "license_specifications" { + description = "A list of license specifications to associate with" + type = map(string) + default = {} +} + +variable "network_interfaces" { + description = "Customize network interfaces to be attached at instance boot time" + type = list(any) + default = [] +} + +variable "placement" { + description = "The placement of the instance" + type = map(string) + default = {} +} + +variable "ebs_optimized" { + description = "If true, the launched EC2 instance will be EBS-optimized" + type = bool + default = null +} + +variable "ami_id" { + description = "The AMI from which to launch the instance" + type = string + default = "" +} + +variable "cluster_version" { + description = "Kubernetes cluster version - used to lookup default AMI ID if one is not provided" + type = string + default = null +} + +variable "instance_type" { + description = "The type of the instance to launch" + type = string + default = "" +} + +variable "key_name" { + description = "The key name that should be used for the instance" + type = string + default = null +} + +variable "vpc_security_group_ids" { + description = "A list of security group IDs to associate" + type = list(string) + default = [] +} + +variable "cluster_primary_security_group_id" { + description = "The ID of the EKS cluster primary security group to associate with the instance(s). This is the security group that is automatically created by the EKS service" + type = string + default = null +} + +variable "enable_monitoring" { + description = "Enables/disables detailed monitoring" + type = bool + default = true +} + +variable "metadata_options" { + description = "Customize the metadata options for the instance" + type = map(string) + default = { + http_endpoint = "enabled" + http_tokens = "required" + http_put_response_hop_limit = 2 + } +} + +variable "launch_template_tags" { + description = "A map of additional tags to add to the tag_specifications of launch template created" + type = map(string) + default = {} +} + +################################################################################ +# Autoscaling group +################################################################################ + +variable "create_autoscaling_group" { + description = "Determines whether to create autoscaling group or not" + type = bool + default = true +} + +variable "name" { + description = "Name of the Self managed Node Group" + type = string + default = "" +} + +variable "use_name_prefix" { + description = "Determines whether to use `name` as is or create a unique name beginning with the `name` as the prefix" + type = bool + default = true +} + +variable "launch_template_version" { + description = "Launch template version. Can be version number, `$Latest`, or `$Default`" + type = string + default = null +} + +variable "availability_zones" { + description = "A list of one or more availability zones for the group. Used for EC2-Classic and default subnets when not specified with `subnet_ids` argument. Conflicts with `subnet_ids`" + type = list(string) + default = null +} + +variable "subnet_ids" { + description = "A list of subnet IDs to launch resources in. Subnets automatically determine which availability zones the group will reside. Conflicts with `availability_zones`" + type = list(string) + default = null +} + +variable "min_size" { + description = "The minimum size of the autoscaling group" + type = number + default = 0 +} + +variable "max_size" { + description = "The maximum size of the autoscaling group" + type = number + default = 3 +} + +variable "desired_size" { + description = "The number of Amazon EC2 instances that should be running in the autoscaling group" + type = number + default = 1 +} + +variable "capacity_rebalance" { + description = "Indicates whether capacity rebalance is enabled" + type = bool + default = null +} + +variable "min_elb_capacity" { + description = "Setting this causes Terraform to wait for this number of instances to show up healthy in the ELB only on creation. Updates will not wait on ELB instance number changes" + type = number + default = null +} + +variable "wait_for_elb_capacity" { + description = "Setting this will cause Terraform to wait for exactly this number of healthy instances in all attached load balancers on both create and update operations. Takes precedence over `min_elb_capacity` behavior." + type = number + default = null +} + +variable "wait_for_capacity_timeout" { + description = "A maximum duration that Terraform should wait for ASG instances to be healthy before timing out. (See also Waiting for Capacity below.) Setting this to '0' causes Terraform to skip all Capacity Waiting behavior." + type = string + default = null +} + +variable "default_cooldown" { + description = "The amount of time, in seconds, after a scaling activity completes before another scaling activity can start" + type = number + default = null +} + +variable "protect_from_scale_in" { + description = "Allows setting instance protection. The autoscaling group will not select instances with this setting for termination during scale in events." + type = bool + default = false +} + +variable "target_group_arns" { + description = "A set of `aws_alb_target_group` ARNs, for use with Application or Network Load Balancing" + type = list(string) + default = [] +} + +variable "placement_group" { + description = "The name of the placement group into which you'll launch your instances, if any" + type = string + default = null +} + +variable "health_check_type" { + description = "`EC2` or `ELB`. Controls how health checking is done" + type = string + default = null +} + +variable "health_check_grace_period" { + description = "Time (in seconds) after instance comes into service before checking health" + type = number + default = null +} + +variable "force_delete" { + description = "Allows deleting the Auto Scaling Group without waiting for all instances in the pool to terminate. You can force an Auto Scaling Group to delete even if it's in the process of scaling a resource. Normally, Terraform drains all the instances before deleting the group. This bypasses that behavior and potentially leaves resources dangling" + type = bool + default = null +} + +variable "termination_policies" { + description = "A list of policies to decide how the instances in the Auto Scaling Group should be terminated. The allowed values are `OldestInstance`, `NewestInstance`, `OldestLaunchConfiguration`, `ClosestToNextInstanceHour`, `OldestLaunchTemplate`, `AllocationStrategy`, `Default`" + type = list(string) + default = [] +} + +variable "suspended_processes" { + description = "A list of processes to suspend for the Auto Scaling Group. The allowed values are `Launch`, `Terminate`, `HealthCheck`, `ReplaceUnhealthy`, `AZRebalance`, `AlarmNotification`, `ScheduledActions`, `AddToLoadBalancer`. Note that if you suspend either the `Launch` or `Terminate` process types, it can prevent your Auto Scaling Group from functioning properly" + type = list(string) + default = [] +} + +variable "max_instance_lifetime" { + description = "The maximum amount of time, in seconds, that an instance can be in service, values must be either equal to 0 or between 604800 and 31536000 seconds" + type = number + default = null +} + +variable "enabled_metrics" { + description = "A list of metrics to collect. The allowed values are `GroupDesiredCapacity`, `GroupInServiceCapacity`, `GroupPendingCapacity`, `GroupMinSize`, `GroupMaxSize`, `GroupInServiceInstances`, `GroupPendingInstances`, `GroupStandbyInstances`, `GroupStandbyCapacity`, `GroupTerminatingCapacity`, `GroupTerminatingInstances`, `GroupTotalCapacity`, `GroupTotalInstances`" + type = list(string) + default = [] +} + +variable "metrics_granularity" { + description = "The granularity to associate with the metrics to collect. The only valid value is `1Minute`" + type = string + default = null +} + +variable "service_linked_role_arn" { + description = "The ARN of the service-linked role that the ASG will use to call other AWS services" + type = string + default = null +} + +variable "initial_lifecycle_hooks" { + description = "One or more Lifecycle Hooks to attach to the Auto Scaling Group before instances are launched. The syntax is exactly the same as the separate `aws_autoscaling_lifecycle_hook` resource, without the `autoscaling_group_name` attribute. Please note that this will only work when creating a new Auto Scaling Group. For all other use-cases, please use `aws_autoscaling_lifecycle_hook` resource" + type = list(map(string)) + default = [] +} + +variable "instance_refresh" { + description = "If this block is configured, start an Instance Refresh when this Auto Scaling Group is updated" + type = any + default = {} +} + +variable "use_mixed_instances_policy" { + description = "Determines whether to use a mixed instances policy in the autoscaling group or not" + type = bool + default = false +} + +variable "mixed_instances_policy" { + description = "Configuration block containing settings to define launch targets for Auto Scaling groups" + type = any + default = null +} + +variable "warm_pool" { + description = "If this block is configured, add a Warm Pool to the specified Auto Scaling group" + type = any + default = {} +} + +variable "delete_timeout" { + description = "Delete timeout to wait for destroying autoscaling group" + type = string + default = null +} + +variable "use_default_tags" { + description = "Enables/disables the use of provider default tags in the tag_specifications of the Auto Scaling group" + type = bool + default = false +} + +variable "autoscaling_group_tags" { + description = "A map of additional tags to add to the autoscaling group created. Tags are applied to the autoscaling group only and are NOT propagated to instances" + type = map(string) + default = {} +} + +################################################################################ +# Autoscaling group schedule +################################################################################ + +variable "create_schedule" { + description = "Determines whether to create autoscaling group schedule or not" + type = bool + default = true +} + +variable "schedules" { + description = "Map of autoscaling group schedule to create" + type = map(any) + default = {} +} + +################################################################################ +# Security Group +################################################################################ + +variable "create_security_group" { + description = "Determines whether to create a security group" + type = bool + default = true +} + +variable "security_group_name" { + description = "Name to use on security group created" + type = string + default = null +} + +variable "security_group_use_name_prefix" { + description = "Determines whether the security group name (`security_group_name`) is used as a prefix" + type = bool + default = true +} + +variable "security_group_description" { + description = "Description for the security group created" + type = string + default = "EKS self-managed node group security group" +} + +variable "vpc_id" { + description = "ID of the VPC where the security group/nodes will be provisioned" + type = string + default = null +} + +variable "security_group_rules" { + description = "List of security group rules to add to the security group created" + type = any + default = {} +} + +variable "cluster_security_group_id" { + description = "Cluster control plane security group ID" + type = string + default = null +} + +variable "security_group_tags" { + description = "A map of additional tags to add to the security group created" + type = map(string) + default = {} +} + +################################################################################ +# IAM Role +################################################################################ + +variable "create_iam_instance_profile" { + description = "Determines whether an IAM instance profile is created or to use an existing IAM instance profile" + type = bool + default = true +} + +variable "cluster_ip_family" { + description = "The IP family used to assign Kubernetes pod and service addresses. Valid values are `ipv4` (default) and `ipv6`" + type = string + default = null +} + +variable "iam_instance_profile_arn" { + description = "Amazon Resource Name (ARN) of an existing IAM instance profile that provides permissions for the node group. Required if `create_iam_instance_profile` = `false`" + type = string + default = null +} + +variable "iam_role_name" { + description = "Name to use on IAM role created" + type = string + default = null +} + +variable "iam_role_use_name_prefix" { + description = "Determines whether cluster IAM role name (`iam_role_name`) is used as a prefix" + type = bool + default = true +} + +variable "iam_role_path" { + description = "IAM role path" + type = string + default = null +} + +variable "iam_role_description" { + description = "Description of the role" + type = string + default = null +} + +variable "iam_role_permissions_boundary" { + description = "ARN of the policy that is used to set the permissions boundary for the IAM role" + type = string + default = null +} + +variable "iam_role_attach_cni_policy" { + description = "Whether to attach the `AmazonEKS_CNI_Policy`/`AmazonEKS_CNI_IPv6_Policy` IAM policy to the IAM IAM role. WARNING: If set `false` the permissions must be assigned to the `aws-node` DaemonSet pods via another method or nodes will not be able to join the cluster" + type = bool + default = true +} + +variable "iam_role_additional_policies" { + description = "Additional policies to be added to the IAM role" + type = list(string) + default = [] +} + +variable "iam_role_tags" { + description = "A map of additional tags to add to the IAM role created" + type = map(string) + default = {} +} diff --git a/modules/aws-eks/modules/self-managed-node-group/versions.tf b/modules/aws-eks/modules/self-managed-node-group/versions.tf new file mode 100644 index 0000000..22e8d72 --- /dev/null +++ b/modules/aws-eks/modules/self-managed-node-group/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.72" + } + } +} diff --git a/modules/aws-eks/node_groups.tf b/modules/aws-eks/node_groups.tf new file mode 100644 index 0000000..73480e8 --- /dev/null +++ b/modules/aws-eks/node_groups.tf @@ -0,0 +1,488 @@ +locals { + metadata_options = { + http_endpoint = "enabled" + http_tokens = "required" + http_put_response_hop_limit = 2 + } +} + +################################################################################ +# EKS IPV6 CNI Policy +# TODO - hopefully AWS releases a managed policy which can replace this +# https://docs.aws.amazon.com/eks/latest/userguide/cni-iam-role.html#cni-iam-role-create-ipv6-policy +################################################################################ + +data "aws_iam_policy_document" "cni_ipv6_policy" { + count = var.create && var.create_cni_ipv6_iam_policy ? 1 : 0 + + statement { + sid = "AssignDescribe" + actions = [ + "ec2:AssignIpv6Addresses", + "ec2:DescribeInstances", + "ec2:DescribeTags", + "ec2:DescribeNetworkInterfaces", + "ec2:DescribeInstanceTypes" + ] + resources = ["*"] + } + + statement { + sid = "CreateTags" + actions = ["ec2:CreateTags"] + resources = ["arn:${data.aws_partition.current.partition}:ec2:*:*:network-interface/*"] + } +} + +# Note - we are keeping this to a minimim in hopes that its soon replaced with an AWS managed policy like `AmazonEKS_CNI_Policy` +resource "aws_iam_policy" "cni_ipv6_policy" { + count = var.create && var.create_cni_ipv6_iam_policy ? 1 : 0 + + # Will cause conflicts if trying to create on multiple clusters but necessary to reference by exact name in sub-modules + name = "AmazonEKS_CNI_IPv6_Policy" + description = "IAM policy for EKS CNI to assign IPV6 addresses" + policy = data.aws_iam_policy_document.cni_ipv6_policy[0].json + + tags = var.tags +} + +################################################################################ +# Node Security Group +# Defaults follow https://docs.aws.amazon.com/eks/latest/userguide/sec-group-reqs.html +# Plus NTP/HTTPS (otherwise nodes fail to launch) +################################################################################ + +locals { + node_sg_name = coalesce(var.node_security_group_name, "${var.cluster_name}-node") + create_node_sg = var.create && var.create_node_security_group + + node_security_group_id = local.create_node_sg ? aws_security_group.node[0].id : var.node_security_group_id + + node_security_group_rules = { + egress_cluster_443 = { + description = "Node groups to cluster API" + protocol = "tcp" + from_port = 443 + to_port = 443 + type = "egress" + source_cluster_security_group = true + } + ingress_cluster_443 = { + description = "Cluster API to node groups" + protocol = "tcp" + from_port = 443 + to_port = 443 + type = "ingress" + source_cluster_security_group = true + } + ingress_apiserver_9443 = { + description = "Cluster API to Kube Apiserver for AWS Load Balancer Controller" + protocol = "tcp" + from_port = 9443 + to_port = 9443 + type = "ingress" + source_cluster_security_group = true + } + ingress_apiserver_8443 = { + description = "Nginx Ingress controller to Kube Apiserver" + protocol = "tcp" + from_port = 8443 + to_port = 8443 + type = "ingress" + source_cluster_security_group = true + } + ingress_cluster_kubelet = { + description = "Cluster API to node kubelets" + protocol = "tcp" + from_port = 10250 + to_port = 10250 + type = "ingress" + source_cluster_security_group = true + } + ingress_self_apiserver_8443 = { + description = "Nginx Ingress controller to Kube Apiserver" + protocol = "tcp" + from_port = 8443 + to_port = 8443 + type = "ingress" + self = true + } + ingress_self_coredns_tcp = { + description = "Node to node CoreDNS" + protocol = "tcp" + from_port = 53 + to_port = 53 + type = "ingress" + self = true + } + egress_self_coredns_tcp = { + description = "Node to node CoreDNS" + protocol = "tcp" + from_port = 53 + to_port = 53 + type = "egress" + self = true + } + ingress_self_coredns_udp = { + description = "Node to node CoreDNS" + protocol = "udp" + from_port = 53 + to_port = 53 + type = "ingress" + self = true + } + egress_self_coredns_udp = { + description = "Node to node CoreDNS" + protocol = "udp" + from_port = 53 + to_port = 53 + type = "egress" + self = true + } + egress_https = { + description = "Egress all HTTPS to internet" + protocol = "tcp" + from_port = 443 + to_port = 443 + type = "egress" + cidr_blocks = ["0.0.0.0/0"] + ipv6_cidr_blocks = var.cluster_ip_family == "ipv6" ? ["::/0"] : null + } + egress_ntp_tcp = { + description = "Egress NTP/TCP to internet" + protocol = "tcp" + from_port = 123 + to_port = 123 + type = "egress" + cidr_blocks = var.node_security_group_ntp_ipv4_cidr_block + ipv6_cidr_blocks = var.cluster_ip_family == "ipv6" ? var.node_security_group_ntp_ipv6_cidr_block : null + } + egress_ntp_udp = { + description = "Egress NTP/UDP to internet" + protocol = "udp" + from_port = 123 + to_port = 123 + type = "egress" + cidr_blocks = var.node_security_group_ntp_ipv4_cidr_block + ipv6_cidr_blocks = var.cluster_ip_family == "ipv6" ? var.node_security_group_ntp_ipv6_cidr_block : null + } + } +} + +resource "aws_security_group" "node" { + count = local.create_node_sg ? 1 : 0 + + name = var.node_security_group_use_name_prefix ? null : local.node_sg_name + name_prefix = var.node_security_group_use_name_prefix ? "${local.node_sg_name}${var.prefix_separator}" : null + description = var.node_security_group_description + vpc_id = var.vpc_id + + tags = merge( + var.tags, + { + "Name" = local.node_sg_name + "kubernetes.io/cluster/${var.cluster_name}" = "owned" + }, + var.node_security_group_tags + ) + + lifecycle { + create_before_destroy = true + } +} + +resource "aws_security_group_rule" "node" { + for_each = { for k, v in merge(local.node_security_group_rules, var.node_security_group_additional_rules) : k => v if local.create_node_sg } + + # Required + security_group_id = aws_security_group.node[0].id + protocol = each.value.protocol + from_port = each.value.from_port + to_port = each.value.to_port + type = each.value.type + + # Optional + description = try(each.value.description, null) + cidr_blocks = try(each.value.cidr_blocks, null) + ipv6_cidr_blocks = try(each.value.ipv6_cidr_blocks, null) + prefix_list_ids = try(each.value.prefix_list_ids, []) + self = try(each.value.self, null) + source_security_group_id = try( + each.value.source_security_group_id, + try(each.value.source_cluster_security_group, false) ? local.cluster_security_group_id : null + ) +} + +################################################################################ +# Fargate Profile +################################################################################ + +module "fargate_profile" { + source = "./modules/fargate-profile" + + for_each = { for k, v in var.fargate_profiles : k => v if var.create } + + create = try(each.value.create, true) + + # Fargate Profile + cluster_name = aws_eks_cluster.this[0].name + cluster_ip_family = var.cluster_ip_family + name = try(each.value.name, each.key) + subnet_ids = try(each.value.subnet_ids, var.fargate_profile_defaults.subnet_ids, var.subnet_ids) + selectors = try(each.value.selectors, var.fargate_profile_defaults.selectors, []) + timeouts = try(each.value.timeouts, var.fargate_profile_defaults.timeouts, {}) + + # IAM role + create_iam_role = try(each.value.create_iam_role, var.fargate_profile_defaults.create_iam_role, true) + iam_role_arn = try(each.value.iam_role_arn, var.fargate_profile_defaults.iam_role_arn, null) + iam_role_name = try(each.value.iam_role_name, var.fargate_profile_defaults.iam_role_name, null) + iam_role_use_name_prefix = try(each.value.iam_role_use_name_prefix, var.fargate_profile_defaults.iam_role_use_name_prefix, true) + iam_role_path = try(each.value.iam_role_path, var.fargate_profile_defaults.iam_role_path, null) + iam_role_description = try(each.value.iam_role_description, var.fargate_profile_defaults.iam_role_description, "Fargate profile IAM role") + iam_role_permissions_boundary = try(each.value.iam_role_permissions_boundary, var.fargate_profile_defaults.iam_role_permissions_boundary, null) + iam_role_tags = try(each.value.iam_role_tags, var.fargate_profile_defaults.iam_role_tags, {}) + iam_role_attach_cni_policy = try(each.value.iam_role_attach_cni_policy, var.fargate_profile_defaults.iam_role_attach_cni_policy, true) + iam_role_additional_policies = try(each.value.iam_role_additional_policies, var.fargate_profile_defaults.iam_role_additional_policies, []) + + tags = merge(var.tags, try(each.value.tags, var.fargate_profile_defaults.tags, {})) +} + +################################################################################ +# EKS Managed Node Group +################################################################################ + +module "eks_managed_node_group" { + source = "./modules/eks-managed-node-group" + + for_each = { for k, v in var.eks_managed_node_groups : k => v if var.create } + + create = try(each.value.create, true) + + cluster_name = aws_eks_cluster.this[0].name + cluster_version = try(each.value.cluster_version, var.eks_managed_node_group_defaults.cluster_version, aws_eks_cluster.this[0].version) + cluster_security_group_id = local.cluster_security_group_id + cluster_ip_family = var.cluster_ip_family + + # EKS Managed Node Group + name = try(each.value.name, each.key) + use_name_prefix = try(each.value.use_name_prefix, var.eks_managed_node_group_defaults.use_name_prefix, true) + + subnet_ids = try(each.value.subnet_ids, var.eks_managed_node_group_defaults.subnet_ids, var.subnet_ids) + + min_size = try(each.value.min_size, var.eks_managed_node_group_defaults.min_size, 1) + max_size = try(each.value.max_size, var.eks_managed_node_group_defaults.max_size, 3) + desired_size = try(each.value.desired_size, var.eks_managed_node_group_defaults.desired_size, 1) + + ami_id = try(each.value.ami_id, var.eks_managed_node_group_defaults.ami_id, "") + ami_type = try(each.value.ami_type, var.eks_managed_node_group_defaults.ami_type, null) + ami_release_version = try(each.value.ami_release_version, var.eks_managed_node_group_defaults.ami_release_version, null) + + capacity_type = try(each.value.capacity_type, var.eks_managed_node_group_defaults.capacity_type, null) + disk_size = try(each.value.disk_size, var.eks_managed_node_group_defaults.disk_size, null) + force_update_version = try(each.value.force_update_version, var.eks_managed_node_group_defaults.force_update_version, null) + instance_types = try(each.value.instance_types, var.eks_managed_node_group_defaults.instance_types, null) + labels = try(each.value.labels, var.eks_managed_node_group_defaults.labels, null) + + remote_access = try(each.value.remote_access, var.eks_managed_node_group_defaults.remote_access, {}) + taints = try(each.value.taints, var.eks_managed_node_group_defaults.taints, {}) + update_config = try(each.value.update_config, var.eks_managed_node_group_defaults.update_config, {}) + timeouts = try(each.value.timeouts, var.eks_managed_node_group_defaults.timeouts, {}) + + # User data + platform = try(each.value.platform, var.eks_managed_node_group_defaults.platform, "linux") + cluster_endpoint = try(aws_eks_cluster.this[0].endpoint, "") + cluster_auth_base64 = try(aws_eks_cluster.this[0].certificate_authority[0].data, "") + cluster_service_ipv4_cidr = var.cluster_service_ipv4_cidr + enable_bootstrap_user_data = try(each.value.enable_bootstrap_user_data, var.eks_managed_node_group_defaults.enable_bootstrap_user_data, false) + pre_bootstrap_user_data = try(each.value.pre_bootstrap_user_data, var.eks_managed_node_group_defaults.pre_bootstrap_user_data, "") + post_bootstrap_user_data = try(each.value.post_bootstrap_user_data, var.eks_managed_node_group_defaults.post_bootstrap_user_data, "") + bootstrap_extra_args = try(each.value.bootstrap_extra_args, var.eks_managed_node_group_defaults.bootstrap_extra_args, "") + user_data_template_path = try(each.value.user_data_template_path, var.eks_managed_node_group_defaults.user_data_template_path, "") + + # Launch Template + create_launch_template = try(each.value.create_launch_template, var.eks_managed_node_group_defaults.create_launch_template, true) + launch_template_name = try(each.value.launch_template_name, var.eks_managed_node_group_defaults.launch_template_name, each.key) + launch_template_use_name_prefix = try(each.value.launch_template_use_name_prefix, var.eks_managed_node_group_defaults.launch_template_use_name_prefix, true) + launch_template_version = try(each.value.launch_template_version, var.eks_managed_node_group_defaults.launch_template_version, null) + launch_template_description = try(each.value.launch_template_description, var.eks_managed_node_group_defaults.launch_template_description, "Custom launch template for ${try(each.value.name, each.key)} EKS managed node group") + launch_template_tags = try(each.value.launch_template_tags, var.eks_managed_node_group_defaults.launch_template_tags, {}) + + ebs_optimized = try(each.value.ebs_optimized, var.eks_managed_node_group_defaults.ebs_optimized, null) + key_name = try(each.value.key_name, var.eks_managed_node_group_defaults.key_name, null) + launch_template_default_version = try(each.value.launch_template_default_version, var.eks_managed_node_group_defaults.launch_template_default_version, null) + update_launch_template_default_version = try(each.value.update_launch_template_default_version, var.eks_managed_node_group_defaults.update_launch_template_default_version, true) + disable_api_termination = try(each.value.disable_api_termination, var.eks_managed_node_group_defaults.disable_api_termination, null) + kernel_id = try(each.value.kernel_id, var.eks_managed_node_group_defaults.kernel_id, null) + ram_disk_id = try(each.value.ram_disk_id, var.eks_managed_node_group_defaults.ram_disk_id, null) + + block_device_mappings = try(each.value.block_device_mappings, var.eks_managed_node_group_defaults.block_device_mappings, {}) + capacity_reservation_specification = try(each.value.capacity_reservation_specification, var.eks_managed_node_group_defaults.capacity_reservation_specification, {}) + cpu_options = try(each.value.cpu_options, var.eks_managed_node_group_defaults.cpu_options, {}) + credit_specification = try(each.value.credit_specification, var.eks_managed_node_group_defaults.credit_specification, {}) + elastic_gpu_specifications = try(each.value.elastic_gpu_specifications, var.eks_managed_node_group_defaults.elastic_gpu_specifications, {}) + elastic_inference_accelerator = try(each.value.elastic_inference_accelerator, var.eks_managed_node_group_defaults.elastic_inference_accelerator, {}) + enclave_options = try(each.value.enclave_options, var.eks_managed_node_group_defaults.enclave_options, {}) + instance_market_options = try(each.value.instance_market_options, var.eks_managed_node_group_defaults.instance_market_options, {}) + license_specifications = try(each.value.license_specifications, var.eks_managed_node_group_defaults.license_specifications, {}) + metadata_options = try(each.value.metadata_options, var.eks_managed_node_group_defaults.metadata_options, local.metadata_options) + enable_monitoring = try(each.value.enable_monitoring, var.eks_managed_node_group_defaults.enable_monitoring, true) + network_interfaces = try(each.value.network_interfaces, var.eks_managed_node_group_defaults.network_interfaces, []) + placement = try(each.value.placement, var.eks_managed_node_group_defaults.placement, {}) + + # IAM role + create_iam_role = try(each.value.create_iam_role, var.eks_managed_node_group_defaults.create_iam_role, true) + iam_role_arn = try(each.value.iam_role_arn, var.eks_managed_node_group_defaults.iam_role_arn, null) + iam_role_name = try(each.value.iam_role_name, var.eks_managed_node_group_defaults.iam_role_name, null) + iam_role_use_name_prefix = try(each.value.iam_role_use_name_prefix, var.eks_managed_node_group_defaults.iam_role_use_name_prefix, true) + iam_role_path = try(each.value.iam_role_path, var.eks_managed_node_group_defaults.iam_role_path, null) + iam_role_description = try(each.value.iam_role_description, var.eks_managed_node_group_defaults.iam_role_description, "EKS managed node group IAM role") + iam_role_permissions_boundary = try(each.value.iam_role_permissions_boundary, var.eks_managed_node_group_defaults.iam_role_permissions_boundary, null) + iam_role_tags = try(each.value.iam_role_tags, var.eks_managed_node_group_defaults.iam_role_tags, {}) + iam_role_attach_cni_policy = try(each.value.iam_role_attach_cni_policy, var.eks_managed_node_group_defaults.iam_role_attach_cni_policy, true) + iam_role_additional_policies = try(each.value.iam_role_additional_policies, var.eks_managed_node_group_defaults.iam_role_additional_policies, []) + + # Security group + vpc_security_group_ids = compact(concat([local.node_security_group_id], try(each.value.vpc_security_group_ids, var.eks_managed_node_group_defaults.vpc_security_group_ids, []))) + cluster_primary_security_group_id = try(each.value.attach_cluster_primary_security_group, var.eks_managed_node_group_defaults.attach_cluster_primary_security_group, false) ? aws_eks_cluster.this[0].vpc_config[0].cluster_security_group_id : null + create_security_group = try(each.value.create_security_group, var.eks_managed_node_group_defaults.create_security_group, true) + security_group_name = try(each.value.security_group_name, var.eks_managed_node_group_defaults.security_group_name, null) + security_group_use_name_prefix = try(each.value.security_group_use_name_prefix, var.eks_managed_node_group_defaults.security_group_use_name_prefix, true) + security_group_description = try(each.value.security_group_description, var.eks_managed_node_group_defaults.security_group_description, "EKS managed node group security group") + vpc_id = try(each.value.vpc_id, var.eks_managed_node_group_defaults.vpc_id, var.vpc_id) + security_group_rules = try(each.value.security_group_rules, var.eks_managed_node_group_defaults.security_group_rules, {}) + security_group_tags = try(each.value.security_group_tags, var.eks_managed_node_group_defaults.security_group_tags, {}) + + tags = merge(var.tags, try(each.value.tags, var.eks_managed_node_group_defaults.tags, {})) +} + +################################################################################ +# Self Managed Node Group +################################################################################ + +module "self_managed_node_group" { + source = "./modules/self-managed-node-group" + + for_each = { for k, v in var.self_managed_node_groups : k => v if var.create } + + create = try(each.value.create, true) + + cluster_name = aws_eks_cluster.this[0].name + cluster_ip_family = var.cluster_ip_family + + # Autoscaling Group + create_autoscaling_group = try(each.value.create_autoscaling_group, var.self_managed_node_group_defaults.create_autoscaling_group, true) + + name = try(each.value.name, each.key) + use_name_prefix = try(each.value.use_name_prefix, var.self_managed_node_group_defaults.use_name_prefix, true) + + availability_zones = try(each.value.availability_zones, var.self_managed_node_group_defaults.availability_zones, null) + subnet_ids = try(each.value.subnet_ids, var.self_managed_node_group_defaults.subnet_ids, var.subnet_ids) + + min_size = try(each.value.min_size, var.self_managed_node_group_defaults.min_size, 0) + max_size = try(each.value.max_size, var.self_managed_node_group_defaults.max_size, 3) + desired_size = try(each.value.desired_size, var.self_managed_node_group_defaults.desired_size, 1) + capacity_rebalance = try(each.value.capacity_rebalance, var.self_managed_node_group_defaults.capacity_rebalance, null) + min_elb_capacity = try(each.value.min_elb_capacity, var.self_managed_node_group_defaults.min_elb_capacity, null) + wait_for_elb_capacity = try(each.value.wait_for_elb_capacity, var.self_managed_node_group_defaults.wait_for_elb_capacity, null) + wait_for_capacity_timeout = try(each.value.wait_for_capacity_timeout, var.self_managed_node_group_defaults.wait_for_capacity_timeout, null) + default_cooldown = try(each.value.default_cooldown, var.self_managed_node_group_defaults.default_cooldown, null) + protect_from_scale_in = try(each.value.protect_from_scale_in, var.self_managed_node_group_defaults.protect_from_scale_in, null) + + target_group_arns = try(each.value.target_group_arns, var.self_managed_node_group_defaults.target_group_arns, []) + placement_group = try(each.value.placement_group, var.self_managed_node_group_defaults.placement_group, null) + health_check_type = try(each.value.health_check_type, var.self_managed_node_group_defaults.health_check_type, null) + health_check_grace_period = try(each.value.health_check_grace_period, var.self_managed_node_group_defaults.health_check_grace_period, null) + + force_delete = try(each.value.force_delete, var.self_managed_node_group_defaults.force_delete, null) + termination_policies = try(each.value.termination_policies, var.self_managed_node_group_defaults.termination_policies, []) + suspended_processes = try(each.value.suspended_processes, var.self_managed_node_group_defaults.suspended_processes, []) + max_instance_lifetime = try(each.value.max_instance_lifetime, var.self_managed_node_group_defaults.max_instance_lifetime, null) + + enabled_metrics = try(each.value.enabled_metrics, var.self_managed_node_group_defaults.enabled_metrics, []) + metrics_granularity = try(each.value.metrics_granularity, var.self_managed_node_group_defaults.metrics_granularity, null) + service_linked_role_arn = try(each.value.service_linked_role_arn, var.self_managed_node_group_defaults.service_linked_role_arn, null) + + initial_lifecycle_hooks = try(each.value.initial_lifecycle_hooks, var.self_managed_node_group_defaults.initial_lifecycle_hooks, []) + instance_refresh = try(each.value.instance_refresh, var.self_managed_node_group_defaults.instance_refresh, {}) + use_mixed_instances_policy = try(each.value.use_mixed_instances_policy, var.self_managed_node_group_defaults.use_mixed_instances_policy, false) + mixed_instances_policy = try(each.value.mixed_instances_policy, var.self_managed_node_group_defaults.mixed_instances_policy, null) + warm_pool = try(each.value.warm_pool, var.self_managed_node_group_defaults.warm_pool, {}) + + create_schedule = try(each.value.create_schedule, var.self_managed_node_group_defaults.create_schedule, false) + schedules = try(each.value.schedules, var.self_managed_node_group_defaults.schedules, {}) + + delete_timeout = try(each.value.delete_timeout, var.self_managed_node_group_defaults.delete_timeout, null) + use_default_tags = try(each.value.use_default_tags, var.self_managed_node_group_defaults.use_default_tags, false) + autoscaling_group_tags = try(each.value.autoscaling_group_tags, var.self_managed_node_group_defaults.autoscaling_group_tags, {}) + + # User data + platform = try(each.value.platform, var.self_managed_node_group_defaults.platform, "linux") + cluster_endpoint = try(aws_eks_cluster.this[0].endpoint, "") + cluster_auth_base64 = try(aws_eks_cluster.this[0].certificate_authority[0].data, "") + pre_bootstrap_user_data = try(each.value.pre_bootstrap_user_data, var.self_managed_node_group_defaults.pre_bootstrap_user_data, "") + post_bootstrap_user_data = try(each.value.post_bootstrap_user_data, var.self_managed_node_group_defaults.post_bootstrap_user_data, "") + bootstrap_extra_args = try(each.value.bootstrap_extra_args, var.self_managed_node_group_defaults.bootstrap_extra_args, "") + user_data_template_path = try(each.value.user_data_template_path, var.self_managed_node_group_defaults.user_data_template_path, "") + + # Launch Template + create_launch_template = try(each.value.create_launch_template, var.self_managed_node_group_defaults.create_launch_template, true) + launch_template_name = try(each.value.launch_template_name, var.self_managed_node_group_defaults.launch_template_name, each.key) + launch_template_use_name_prefix = try(each.value.launch_template_use_name_prefix, var.self_managed_node_group_defaults.launch_template_use_name_prefix, true) + launch_template_version = try(each.value.launch_template_version, var.self_managed_node_group_defaults.launch_template_version, null) + launch_template_description = try(each.value.launch_template_description, var.self_managed_node_group_defaults.launch_template_description, "Custom launch template for ${try(each.value.name, each.key)} self managed node group") + launch_template_tags = try(each.value.launch_template_tags, var.self_managed_node_group_defaults.launch_template_tags, {}) + + ebs_optimized = try(each.value.ebs_optimized, var.self_managed_node_group_defaults.ebs_optimized, null) + ami_id = try(each.value.ami_id, var.self_managed_node_group_defaults.ami_id, "") + cluster_version = try(each.value.cluster_version, var.self_managed_node_group_defaults.cluster_version, aws_eks_cluster.this[0].version) + instance_type = try(each.value.instance_type, var.self_managed_node_group_defaults.instance_type, "m6i.large") + key_name = try(each.value.key_name, var.self_managed_node_group_defaults.key_name, null) + + launch_template_default_version = try(each.value.launch_template_default_version, var.self_managed_node_group_defaults.launch_template_default_version, null) + update_launch_template_default_version = try(each.value.update_launch_template_default_version, var.self_managed_node_group_defaults.update_launch_template_default_version, true) + disable_api_termination = try(each.value.disable_api_termination, var.self_managed_node_group_defaults.disable_api_termination, null) + instance_initiated_shutdown_behavior = try(each.value.instance_initiated_shutdown_behavior, var.self_managed_node_group_defaults.instance_initiated_shutdown_behavior, null) + kernel_id = try(each.value.kernel_id, var.self_managed_node_group_defaults.kernel_id, null) + ram_disk_id = try(each.value.ram_disk_id, var.self_managed_node_group_defaults.ram_disk_id, null) + + block_device_mappings = try(each.value.block_device_mappings, var.self_managed_node_group_defaults.block_device_mappings, {}) + capacity_reservation_specification = try(each.value.capacity_reservation_specification, var.self_managed_node_group_defaults.capacity_reservation_specification, {}) + cpu_options = try(each.value.cpu_options, var.self_managed_node_group_defaults.cpu_options, {}) + credit_specification = try(each.value.credit_specification, var.self_managed_node_group_defaults.credit_specification, {}) + elastic_gpu_specifications = try(each.value.elastic_gpu_specifications, var.self_managed_node_group_defaults.elastic_gpu_specifications, {}) + elastic_inference_accelerator = try(each.value.elastic_inference_accelerator, var.self_managed_node_group_defaults.elastic_inference_accelerator, {}) + enclave_options = try(each.value.enclave_options, var.self_managed_node_group_defaults.enclave_options, {}) + hibernation_options = try(each.value.hibernation_options, var.self_managed_node_group_defaults.hibernation_options, {}) + instance_market_options = try(each.value.instance_market_options, var.self_managed_node_group_defaults.instance_market_options, {}) + license_specifications = try(each.value.license_specifications, var.self_managed_node_group_defaults.license_specifications, {}) + metadata_options = try(each.value.metadata_options, var.self_managed_node_group_defaults.metadata_options, local.metadata_options) + enable_monitoring = try(each.value.enable_monitoring, var.self_managed_node_group_defaults.enable_monitoring, true) + network_interfaces = try(each.value.network_interfaces, var.self_managed_node_group_defaults.network_interfaces, []) + placement = try(each.value.placement, var.self_managed_node_group_defaults.placement, {}) + + # IAM role + create_iam_instance_profile = try(each.value.create_iam_instance_profile, var.self_managed_node_group_defaults.create_iam_instance_profile, true) + iam_instance_profile_arn = try(each.value.iam_instance_profile_arn, var.self_managed_node_group_defaults.iam_instance_profile_arn, null) + iam_role_name = try(each.value.iam_role_name, var.self_managed_node_group_defaults.iam_role_name, null) + iam_role_use_name_prefix = try(each.value.iam_role_use_name_prefix, var.self_managed_node_group_defaults.iam_role_use_name_prefix, true) + iam_role_path = try(each.value.iam_role_path, var.self_managed_node_group_defaults.iam_role_path, null) + iam_role_description = try(each.value.iam_role_description, var.self_managed_node_group_defaults.iam_role_description, "Self managed node group IAM role") + iam_role_permissions_boundary = try(each.value.iam_role_permissions_boundary, var.self_managed_node_group_defaults.iam_role_permissions_boundary, null) + iam_role_tags = try(each.value.iam_role_tags, var.self_managed_node_group_defaults.iam_role_tags, {}) + iam_role_attach_cni_policy = try(each.value.iam_role_attach_cni_policy, var.self_managed_node_group_defaults.iam_role_attach_cni_policy, true) + iam_role_additional_policies = try(each.value.iam_role_additional_policies, var.self_managed_node_group_defaults.iam_role_additional_policies, []) + + # Security group + vpc_security_group_ids = compact(concat([local.node_security_group_id], try(each.value.vpc_security_group_ids, var.self_managed_node_group_defaults.vpc_security_group_ids, []))) + cluster_security_group_id = local.cluster_security_group_id + cluster_primary_security_group_id = try(each.value.attach_cluster_primary_security_group, var.self_managed_node_group_defaults.attach_cluster_primary_security_group, false) ? aws_eks_cluster.this[0].vpc_config[0].cluster_security_group_id : null + create_security_group = try(each.value.create_security_group, var.self_managed_node_group_defaults.create_security_group, true) + security_group_name = try(each.value.security_group_name, var.self_managed_node_group_defaults.security_group_name, null) + security_group_use_name_prefix = try(each.value.security_group_use_name_prefix, var.self_managed_node_group_defaults.security_group_use_name_prefix, true) + security_group_description = try(each.value.security_group_description, var.self_managed_node_group_defaults.security_group_description, "Self managed node group security group") + vpc_id = try(each.value.vpc_id, var.self_managed_node_group_defaults.vpc_id, var.vpc_id) + security_group_rules = try(each.value.security_group_rules, var.self_managed_node_group_defaults.security_group_rules, {}) + security_group_tags = try(each.value.security_group_tags, var.self_managed_node_group_defaults.security_group_tags, {}) + + tags = merge(var.tags, try(each.value.tags, var.self_managed_node_group_defaults.tags, {})) +} diff --git a/modules/aws-eks/outputs.tf b/modules/aws-eks/outputs.tf new file mode 100644 index 0000000..8ee139c --- /dev/null +++ b/modules/aws-eks/outputs.tf @@ -0,0 +1,223 @@ +################################################################################ +# Cluster +################################################################################ + +output "cluster_arn" { + description = "The Amazon Resource Name (ARN) of the cluster" + value = try(aws_eks_cluster.this[0].arn, "") +} + +output "cluster_certificate_authority_data" { + description = "Base64 encoded certificate data required to communicate with the cluster" + value = try(aws_eks_cluster.this[0].certificate_authority[0].data, "") +} + +output "cluster_endpoint" { + description = "Endpoint for your Kubernetes API server" + value = try(aws_eks_cluster.this[0].endpoint, "") +} + +output "cluster_id" { + description = "The name/id of the EKS cluster. Will block on cluster creation until the cluster is really ready" + value = try(aws_eks_cluster.this[0].id, "") +} + +output "cluster_oidc_issuer_url" { + description = "The URL on the EKS cluster for the OpenID Connect identity provider" + value = try(aws_eks_cluster.this[0].identity[0].oidc[0].issuer, "") +} + +output "cluster_version" { + description = "The Kubernetes version for the cluster" + value = try(aws_eks_cluster.this[0].version, "") +} + +output "cluster_platform_version" { + description = "Platform version for the cluster" + value = try(aws_eks_cluster.this[0].platform_version, "") +} + +output "cluster_status" { + description = "Status of the EKS cluster. One of `CREATING`, `ACTIVE`, `DELETING`, `FAILED`" + value = try(aws_eks_cluster.this[0].status, "") +} + +output "cluster_primary_security_group_id" { + description = "Cluster security group that was created by Amazon EKS for the cluster. Managed node groups use this security group for control-plane-to-data-plane communication. Referred to as 'Cluster security group' in the EKS console" + value = try(aws_eks_cluster.this[0].vpc_config[0].cluster_security_group_id, "") +} + +################################################################################ +# KMS Key +################################################################################ + +output "kms_key_arn" { + description = "The Amazon Resource Name (ARN) of the key" + value = module.kms.key_arn +} + +output "kms_key_id" { + description = "The globally unique identifier for the key" + value = module.kms.key_id +} + +output "kms_key_policy" { + description = "The IAM resource policy set on the key" + value = module.kms.key_policy +} + +################################################################################ +# Cluster Security Group +################################################################################ + +output "cluster_security_group_arn" { + description = "Amazon Resource Name (ARN) of the cluster security group" + value = try(aws_security_group.cluster[0].arn, "") +} + +output "cluster_security_group_id" { + description = "ID of the cluster security group" + value = try(aws_security_group.cluster[0].id, "") +} + +################################################################################ +# Node Security Group +################################################################################ + +output "node_security_group_arn" { + description = "Amazon Resource Name (ARN) of the node shared security group" + value = try(aws_security_group.node[0].arn, "") +} + +output "node_security_group_id" { + description = "ID of the node shared security group" + value = try(aws_security_group.node[0].id, "") +} + +################################################################################ +# IRSA +################################################################################ + +output "oidc_provider" { + description = "The OpenID Connect identity provider (issuer URL without leading `https://`)" + value = try(replace(aws_eks_cluster.this[0].identity[0].oidc[0].issuer, "https://", ""), "") +} + +output "oidc_provider_arn" { + description = "The ARN of the OIDC Provider if `enable_irsa = true`" + value = try(aws_iam_openid_connect_provider.oidc_provider[0].arn, "") +} + +################################################################################ +# IAM Role +################################################################################ + +output "cluster_iam_role_name" { + description = "IAM role name of the EKS cluster" + value = try(aws_iam_role.this[0].name, "") +} + +output "cluster_iam_role_arn" { + description = "IAM role ARN of the EKS cluster" + value = try(aws_iam_role.this[0].arn, "") +} + +output "cluster_iam_role_unique_id" { + description = "Stable and unique string identifying the IAM role" + value = try(aws_iam_role.this[0].unique_id, "") +} + +################################################################################ +# EKS Addons +################################################################################ + +output "cluster_addons" { + description = "Map of attribute maps for all EKS cluster addons enabled" + value = aws_eks_addon.this +} + +################################################################################ +# EKS Identity Provider +################################################################################ + +output "cluster_identity_providers" { + description = "Map of attribute maps for all EKS identity providers enabled" + value = aws_eks_identity_provider_config.this +} + +################################################################################ +# CloudWatch Log Group +################################################################################ + +output "cloudwatch_log_group_name" { + description = "Name of cloudwatch log group created" + value = try(aws_cloudwatch_log_group.this[0].name, "") +} + +output "cloudwatch_log_group_arn" { + description = "Arn of cloudwatch log group created" + value = try(aws_cloudwatch_log_group.this[0].arn, "") +} + +################################################################################ +# Fargate Profile +################################################################################ + +output "fargate_profiles" { + description = "Map of attribute maps for all EKS Fargate Profiles created" + value = module.fargate_profile +} + +################################################################################ +# EKS Managed Node Group +################################################################################ + +output "eks_managed_node_groups" { + description = "Map of attribute maps for all EKS managed node groups created" + value = module.eks_managed_node_group +} + +output "eks_managed_node_groups_iam_role_arn" { + description = "Map of attribute maps for all EKS managed node groups created" + value = module.eks_managed_node_group["linux"].iam_role_arn +} + +output "eks_managed_node_groups_autoscaling_group_names" { + description = "List of the autoscaling group names created by EKS managed node groups" + value = compact(flatten([for group in module.eks_managed_node_group : group.node_group_autoscaling_group_names])) +} + +################################################################################ +# Self Managed Node Group +################################################################################ + +output "self_managed_node_groups" { + description = "Map of attribute maps for all self managed node groups created" + value = module.self_managed_node_group +} + +output "self_managed_node_groups_autoscaling_group_names" { + description = "List of the autoscaling group names created by self-managed node groups" + value = compact([for group in module.self_managed_node_group : group.autoscaling_group_name]) +} + +################################################################################ +# Additional +################################################################################ + +output "aws_auth_configmap_yaml" { + description = "[DEPRECATED - use `var.manage_aws_auth_configmap`] Formatted yaml output for base aws-auth configmap containing roles used in cluster node groups/fargate profiles" + value = templatefile("${path.module}/templates/aws_auth_cm.tpl", + { + eks_managed_role_arns = distinct(compact([for group in module.eks_managed_node_group : group.iam_role_arn])) + self_managed_role_arns = distinct(compact([for group in module.self_managed_node_group : group.iam_role_arn if group.platform != "windows"])) + win32_self_managed_role_arns = distinct(compact([for group in module.self_managed_node_group : group.iam_role_arn if group.platform == "windows"])) + fargate_profile_pod_execution_role_arns = distinct(compact([for group in module.fargate_profile : group.fargate_profile_pod_execution_role_arn])) + } + ) +} + +output "cluster_name" { + description = "Name of the EKS cluster" + value = var.cluster_name +} \ No newline at end of file diff --git a/modules/aws-eks/templates/aws_auth_cm.tpl b/modules/aws-eks/templates/aws_auth_cm.tpl new file mode 100644 index 0000000..73a898e --- /dev/null +++ b/modules/aws-eks/templates/aws_auth_cm.tpl @@ -0,0 +1,37 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: aws-auth + namespace: kube-system +data: + mapRoles: | +%{ for role in eks_managed_role_arns ~} + - rolearn: ${role} + username: system:node:{{EC2PrivateDNSName}} + groups: + - system:bootstrappers + - system:nodes +%{ endfor ~} +%{ for role in self_managed_role_arns ~} + - rolearn: ${role} + username: system:node:{{EC2PrivateDNSName}} + groups: + - system:bootstrappers + - system:nodes +%{ endfor ~} +%{ for role in win32_self_managed_role_arns ~} + - rolearn: ${role} + username: system:node:{{EC2PrivateDNSName}} + groups: + - eks:kube-proxy-windows + - system:bootstrappers + - system:nodes +%{ endfor ~} +%{ for role in fargate_profile_pod_execution_role_arns ~} + - rolearn: ${role} + username: system:node:{{SessionName}} + groups: + - system:bootstrappers + - system:nodes + - system:node-proxier +%{ endfor ~} diff --git a/modules/aws-eks/templates/bottlerocket_user_data.tpl b/modules/aws-eks/templates/bottlerocket_user_data.tpl new file mode 100644 index 0000000..640c801 --- /dev/null +++ b/modules/aws-eks/templates/bottlerocket_user_data.tpl @@ -0,0 +1,7 @@ +%{ if enable_bootstrap_user_data ~} +[settings.kubernetes] +"cluster-name" = "${cluster_name}" +"api-server" = "${cluster_endpoint}" +"cluster-certificate" = "${cluster_auth_base64}" +%{ endif ~} +${bootstrap_extra_args ~} diff --git a/modules/aws-eks/templates/linux_user_data.tpl b/modules/aws-eks/templates/linux_user_data.tpl new file mode 100644 index 0000000..14acbd2 --- /dev/null +++ b/modules/aws-eks/templates/linux_user_data.tpl @@ -0,0 +1,14 @@ +%{ if enable_bootstrap_user_data ~} +#!/bin/bash +set -e +%{ endif ~} +${pre_bootstrap_user_data ~} +%{ if length(cluster_service_ipv4_cidr) > 0 ~} +export SERVICE_IPV4_CIDR=${cluster_service_ipv4_cidr} +%{ endif ~} +%{ if enable_bootstrap_user_data ~} +B64_CLUSTER_CA=${cluster_auth_base64} +API_SERVER_URL=${cluster_endpoint} +/etc/eks/bootstrap.sh ${cluster_name} ${bootstrap_extra_args} --b64-cluster-ca $B64_CLUSTER_CA --apiserver-endpoint $API_SERVER_URL +${post_bootstrap_user_data ~} +%{ endif ~} diff --git a/modules/aws-eks/templates/windows_user_data.tpl b/modules/aws-eks/templates/windows_user_data.tpl new file mode 100644 index 0000000..5000850 --- /dev/null +++ b/modules/aws-eks/templates/windows_user_data.tpl @@ -0,0 +1,9 @@ +
"http_endpoint": "enabled",
"http_put_response_hop_limit": 2,
"http_tokens": "required"
}
list(object({| `[]` | no | +| [maintenance\_window](#input\_maintenance\_window) | Specifies the weekly time range for when maintenance on the cache cluster is performed. | `string` | `""` | no | +| [multi\_az\_enabled](#input\_multi\_az\_enabled) | Specifies whether to enable Multi-AZ Support for the replication group. If true, `automatic_failover_enabled` must also be enabled. Defaults to false. | `string` | `false` | no | +| [name\_prefix](#input\_name\_prefix) | The replication group identifier. This parameter is stored as a lowercase string. | `string` | n/a | yes | +| [node\_type](#input\_node\_type) | The compute and memory capacity of the nodes in the node group. | `string` | n/a | yes | +| [notification\_topic\_arn](#input\_notification\_topic\_arn) | An Amazon Resource Name (ARN) of an SNS topic to send ElastiCache notifications to. Example: `arn:aws:sns:us-east-1:012345678999:my_sns_topic` | `string` | `""` | no | +| [num\_cache\_clusters](#input\_num\_cache\_clusters) | The number of cache clusters (primary and replicas) this replication group will have. If Multi-AZ is enabled, the value of this parameter must be at least 2. Updates will occur before other modifications. Conflicts with num\_node\_groups. | `number` | `1` | no | +| [num\_node\_groups](#input\_num\_node\_groups) | Specify the number of node groups (shards) for this Redis replication group. Changing this number will trigger an online resizing operation before other settings modifications. | `number` | `0` | no | +| [parameter](#input\_parameter) | A list of Redis parameters to apply. Note that parameters may differ from one Redis family to another |
destination_type = string
destination = string
log_format = string
log_type = string
}))
list(object({| `[]` | no | +| [port](#input\_port) | The port number on which each of the cache nodes will accept connections. | `number` | `6379` | no | +| [preferred\_cache\_cluster\_azs](#input\_preferred\_cache\_cluster\_azs) | A list of EC2 availability zones in which the replication group's cache clusters will be created. The order of the availability zones in the list is not important. | `list(string)` | `null` | no | +| [replicas\_per\_node\_group](#input\_replicas\_per\_node\_group) | Specify the number of replica nodes in each node group. Valid values are 0 to 5. Changing this number will trigger an online resizing operation before other settings modifications. | `number` | `0` | no | +| [security\_group\_ids](#input\_security\_group\_ids) | List of Security Groups. | `list(string)` | `[]` | no | +| [snapshot\_retention\_limit](#input\_snapshot\_retention\_limit) | The number of days for which ElastiCache will retain automatic cache cluster snapshots before deleting them. | `number` | `30` | no | +| [snapshot\_window](#input\_snapshot\_window) | The daily time range (in UTC) during which ElastiCache will begin taking a daily snapshot of your cache cluster. | `string` | `""` | no | +| [subnet\_ids](#input\_subnet\_ids) | List of VPC Subnet IDs for the cache subnet group. | `list(string)` | n/a | yes | +| [tags](#input\_tags) | A mapping of tags to assign to all resources. | `map(string)` | `{}` | no | +| [transit\_encryption\_enabled](#input\_transit\_encryption\_enabled) | Whether to enable encryption in transit. | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | VPC Id to associate with Redis ElastiCache. | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [elasticache\_auth\_token](#output\_elasticache\_auth\_token) | The Redis Auth Token. | +| [elasticache\_parameter\_group\_id](#output\_elasticache\_parameter\_group\_id) | The ElastiCache parameter group name. | +| [elasticache\_port](#output\_elasticache\_port) | The Redis port. | +| [elasticache\_replication\_group\_arn](#output\_elasticache\_replication\_group\_arn) | The Amazon Resource Name (ARN) of the created ElastiCache Replication Group. | +| [elasticache\_replication\_group\_id](#output\_elasticache\_replication\_group\_id) | The ID of the ElastiCache Replication Group. | +| [elasticache\_replication\_group\_member\_clusters](#output\_elasticache\_replication\_group\_member\_clusters) | The identifiers of all the nodes that are part of this replication group. | +| [elasticache\_replication\_group\_primary\_endpoint\_address](#output\_elasticache\_replication\_group\_primary\_endpoint\_address) | The address of the endpoint for the primary node in the replication group. | +| [elasticache\_replication\_group\_reader\_endpoint\_address](#output\_elasticache\_replication\_group\_reader\_endpoint\_address) | The address of the endpoint for the reader node in the replication group. | +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the Redis ElastiCache security group. | +| [security\_group\_description](#output\_security\_group\_description) | The description of the Redis ElastiCache security group. | +| [security\_group\_egress](#output\_security\_group\_egress) | The egress rules of the Redis ElastiCache security group. | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the Redis ElastiCache security group. | +| [security\_group\_ingress](#output\_security\_group\_ingress) | The ingress rules of the Redis ElastiCache security group. | +| [security\_group\_name](#output\_security\_group\_name) | The name of the Redis ElastiCache security group. | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID of the Redis ElastiCache security group. | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID of the Redis ElastiCache security group. | + + + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.0.11 | +| [aws](#requirement\_aws) | >= 4.8.0, < 5.0.0 | +| [random](#requirement\_random) | >= 3.3.2, < 4.0.0 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 4.8.0, < 5.0.0 | +| [random](#provider\_random) | >= 3.3.2, < 4.0.0 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_elasticache_parameter_group.redis](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/elasticache_parameter_group) | resource | +| [aws_elasticache_replication_group.redis](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/elasticache_replication_group) | resource | +| [aws_elasticache_subnet_group.redis](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/elasticache_subnet_group) | resource | +| [aws_security_group.redis](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource | +| [aws_security_group_rule.other_sg_ingress](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | +| [aws_security_group_rule.redis_egress](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | +| [aws_security_group_rule.redis_ingress_cidr_blocks](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | +| [aws_security_group_rule.redis_ingress_self](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | +| [random_id.redis_pg](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/id) | resource | +| [aws_subnet_ids.private_subnets_with_cache_tag](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnet_ids) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [allowed\_security\_groups](#input\_allowed\_security\_groups) | List of existing security groups that will be allowed ingress via the elaticache security group rules | `list(string)` | `[]` | no | +| [apply\_immediately](#input\_apply\_immediately) | Specifies whether any modifications are applied immediately, or during the next maintenance window. | `bool` | `false` | no | +| [at\_rest\_encryption\_enabled](#input\_at\_rest\_encryption\_enabled) | Whether to enable encryption at rest. | `bool` | `true` | no | +| [auth\_token](#input\_auth\_token) | The password used to access a password protected server. Can be specified only if `transit_encryption_enabled = true`. | `string` | `""` | no | +| [auto\_minor\_version\_upgrade](#input\_auto\_minor\_version\_upgrade) | n/a | `string` | `true` | no | +| [automatic\_failover\_enabled](#input\_automatic\_failover\_enabled) | Specifies whether a read-only replica will be automatically promoted to read/write primary if the existing primary fails. If enabled, number\_cache\_clusters must be greater than 1. Must be enabled for Redis (cluster mode enabled) replication groups. | `bool` | `true` | no | +| [cluster\_mode\_enabled](#input\_cluster\_mode\_enabled) | Enable creation of a native redis cluster. | `bool` | `false` | no | +| [data\_tiering\_enabled](#input\_data\_tiering\_enabled) | Enables data tiering. Data tiering is only supported for replication groups using the r6gd node type. This parameter must be set to true when using r6gd nodes. | `bool` | `false` | no | +| [description](#input\_description) | The description of the all resources. | `string` | `"Managed by Terraform"` | no | +| [engine\_version](#input\_engine\_version) | The version number of the cache engine to be used for the cache clusters in this replication group. | `string` | `"6.x"` | no | +| [family](#input\_family) | The family of the ElastiCache parameter group. | `string` | `"redis6.x"` | no | +| [final\_snapshot\_identifier](#input\_final\_snapshot\_identifier) | The name of your final node group (shard) snapshot. ElastiCache creates the snapshot from the primary node in the cluster. If omitted, no final snapshot will be made. | `string` | `null` | no | +| [global\_replication\_group\_id](#input\_global\_replication\_group\_id) | The ID of the global replication group to which this replication group should belong. | `string` | `null` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of Ingress CIDR blocks. | `list(string)` | `[]` | no | +| [ingress\_self](#input\_ingress\_self) | Specify whether the security group itself will be added as a source to the ingress rule. | `bool` | `false` | no | +| [kms\_key\_id](#input\_kms\_key\_id) | The ARN of the key that you wish to use if encrypting at rest. If not supplied, uses service managed encryption. Can be specified only if `at_rest_encryption_enabled = true` | `string` | `""` | no | +| [log\_delivery\_configuration](#input\_log\_delivery\_configuration) | Log Delivery configuration for the cluster. |
name = string
value = string
}))
list(object({| `[]` | no | +| [maintenance\_window](#input\_maintenance\_window) | Specifies the weekly time range for when maintenance on the cache cluster is performed. | `string` | `""` | no | +| [multi\_az\_enabled](#input\_multi\_az\_enabled) | Specifies whether to enable Multi-AZ Support for the replication group. If true, `automatic_failover_enabled` must also be enabled. Defaults to false. | `string` | `false` | no | +| [name\_prefix](#input\_name\_prefix) | The replication group identifier. This parameter is stored as a lowercase string. | `string` | n/a | yes | +| [node\_type](#input\_node\_type) | The compute and memory capacity of the nodes in the node group. | `string` | n/a | yes | +| [notification\_topic\_arn](#input\_notification\_topic\_arn) | An Amazon Resource Name (ARN) of an SNS topic to send ElastiCache notifications to. Example: `arn:aws:sns:us-east-1:012345678999:my_sns_topic` | `string` | `""` | no | +| [num\_cache\_clusters](#input\_num\_cache\_clusters) | The number of cache clusters (primary and replicas) this replication group will have. If Multi-AZ is enabled, the value of this parameter must be at least 2. Updates will occur before other modifications. Conflicts with num\_node\_groups. | `number` | `1` | no | +| [num\_node\_groups](#input\_num\_node\_groups) | Specify the number of node groups (shards) for this Redis replication group. Changing this number will trigger an online resizing operation before other settings modifications. | `number` | `0` | no | +| [parameter](#input\_parameter) | A list of Redis parameters to apply. Note that parameters may differ from one Redis family to another |
destination_type = string
destination = string
log_format = string
log_type = string
}))
list(object({| `[]` | no | +| [port](#input\_port) | The port number on which each of the cache nodes will accept connections. | `number` | `6379` | no | +| [preferred\_cache\_cluster\_azs](#input\_preferred\_cache\_cluster\_azs) | A list of EC2 availability zones in which the replication group's cache clusters will be created. The order of the availability zones in the list is not important. | `list(string)` | `null` | no | +| [replicas\_per\_node\_group](#input\_replicas\_per\_node\_group) | Specify the number of replica nodes in each node group. Valid values are 0 to 5. Changing this number will trigger an online resizing operation before other settings modifications. | `number` | `0` | no | +| [security\_group\_ids](#input\_security\_group\_ids) | List of Security Groups. | `list(string)` | `[]` | no | +| [snapshot\_retention\_limit](#input\_snapshot\_retention\_limit) | The number of days for which ElastiCache will retain automatic cache cluster snapshots before deleting them. | `number` | `30` | no | +| [snapshot\_window](#input\_snapshot\_window) | The daily time range (in UTC) during which ElastiCache will begin taking a daily snapshot of your cache cluster. | `string` | `""` | no | +| [subnet\_id\_names](#input\_subnet\_id\_names) | name of subnet ID's | `string` | `"*"` | no | +| [subnet\_ids](#input\_subnet\_ids) | List of VPC Subnet IDs for the cache subnet group. | `list(string)` | n/a | yes | +| [tags](#input\_tags) | A mapping of tags to assign to all resources. | `map(string)` | `{}` | no | +| [transit\_encryption\_enabled](#input\_transit\_encryption\_enabled) | Whether to enable encryption in transit. | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | VPC Id to associate with Redis ElastiCache. | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [elasticache\_auth\_token](#output\_elasticache\_auth\_token) | The Redis Auth Token. | +| [elasticache\_parameter\_group\_id](#output\_elasticache\_parameter\_group\_id) | The ElastiCache parameter group name. | +| [elasticache\_port](#output\_elasticache\_port) | The Redis port. | +| [elasticache\_replication\_group\_arn](#output\_elasticache\_replication\_group\_arn) | The Amazon Resource Name (ARN) of the created ElastiCache Replication Group. | +| [elasticache\_replication\_group\_id](#output\_elasticache\_replication\_group\_id) | The ID of the ElastiCache Replication Group. | +| [elasticache\_replication\_group\_member\_clusters](#output\_elasticache\_replication\_group\_member\_clusters) | The identifiers of all the nodes that are part of this replication group. | +| [elasticache\_replication\_group\_primary\_endpoint\_address](#output\_elasticache\_replication\_group\_primary\_endpoint\_address) | The address of the endpoint for the primary node in the replication group. | +| [elasticache\_replication\_group\_reader\_endpoint\_address](#output\_elasticache\_replication\_group\_reader\_endpoint\_address) | The address of the endpoint for the reader node in the replication group. | +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the Redis ElastiCache security group. | +| [security\_group\_description](#output\_security\_group\_description) | The description of the Redis ElastiCache security group. | +| [security\_group\_egress](#output\_security\_group\_egress) | The egress rules of the Redis ElastiCache security group. | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the Redis ElastiCache security group. | +| [security\_group\_ingress](#output\_security\_group\_ingress) | The ingress rules of the Redis ElastiCache security group. | +| [security\_group\_name](#output\_security\_group\_name) | The name of the Redis ElastiCache security group. | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID of the Redis ElastiCache security group. | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID of the Redis ElastiCache security group. | + \ No newline at end of file diff --git a/modules/aws-elasticache-redis/examples/redis-basic/README.md b/modules/aws-elasticache-redis/examples/redis-basic/README.md new file mode 100644 index 0000000..80cdc4d --- /dev/null +++ b/modules/aws-elasticache-redis/examples/redis-basic/README.md @@ -0,0 +1,8 @@ +## Example deployment flow + +```bash +terraform init +terraform validate +terraform plan +terraform apply --auto-approve +``` \ No newline at end of file diff --git a/modules/aws-elasticache-redis/examples/redis-basic/main.tf b/modules/aws-elasticache-redis/examples/redis-basic/main.tf new file mode 100644 index 0000000..9a35412 --- /dev/null +++ b/modules/aws-elasticache-redis/examples/redis-basic/main.tf @@ -0,0 +1,89 @@ +provider "aws" { + region = var.primary_region +} + +variable "primary_region" { + default = "eu-west-1" + type = string + description = "You can use as primary region for the AWS provider where this redis will be provisioned" +} + +data "aws_caller_identity" "current" {} +data "aws_region" "current" {} + +##### +# VPC and subnets +##### +data "aws_vpc" "default" { + default = true +} + +data "aws_subnets" "all" { + filter { + name = "vpc-id" + values = [data.aws_vpc.default.id] + } +} + +##### +# External Security Group +##### +resource "aws_security_group" "other_sg" { + vpc_id = data.aws_vpc.default.id +} + +##### +# Elasticache Redis +##### +module "redis" { + source = "../../" + + name_prefix = "redis-basic-example" + num_cache_clusters = 2 + node_type = "cache.t4g.small" + + engine_version = "6.x" + port = 6379 + maintenance_window = "mon:03:00-mon:04:00" + snapshot_window = "04:00-06:00" + snapshot_retention_limit = 7 + final_snapshot_identifier = "redis-final-snapshot-name" + + automatic_failover_enabled = true + multi_az_enabled = true + + at_rest_encryption_enabled = true + transit_encryption_enabled = true + auth_token = "1234567890asdfghjkl" + + apply_immediately = true + family = "redis6.x" + description = "Test elasticache redis." + + subnet_ids = data.aws_subnets.all.ids + vpc_id = data.aws_vpc.default.id + + allowed_security_groups = [aws_security_group.other_sg.id] + + ingress_cidr_blocks = ["0.0.0.0/0"] + + parameter = [ + { + name = "repl-backlog-size" + value = "16384" + } + ] + + log_delivery_configuration = [ + { + destination_type = "cloudwatch-logs" + destination = "aws_cloudwatch_log_group.henrique.name" + log_format = "json" + log_type = "engine-log" + } + ] + + tags = { + Project = "Test" + } +} diff --git a/modules/aws-elasticache-redis/examples/redis-clustered-mode/main.tf b/modules/aws-elasticache-redis/examples/redis-clustered-mode/main.tf new file mode 100644 index 0000000..92495c0 --- /dev/null +++ b/modules/aws-elasticache-redis/examples/redis-clustered-mode/main.tf @@ -0,0 +1,70 @@ +provider "aws" { + region = var.primary_region +} + +variable "primary_region" { + default = "eu-west-1" + type = string + description = "You can use as primary region for the AWS provider where this redis will be provisioned" +} +##### +# VPC and subnets +##### +data "aws_vpc" "default" { + default = true +} + +data "aws_subnets" "all" { + filter { + name = "vpc-id" + values = [data.aws_vpc.default.id] + } +} + +##### +# Elasticache Redis +##### +module "redis" { + source = "../../" + + name_prefix = "redis-clustered-example" + num_cache_clusters = 2 + node_type = "cache.m5.large" + + + cluster_mode_enabled = true + replicas_per_node_group = 1 + num_node_groups = 2 + + engine_version = "6.x" + port = 6379 + maintenance_window = "mon:03:00-mon:04:00" + snapshot_window = "04:00-06:00" + snapshot_retention_limit = 7 + + automatic_failover_enabled = true + + at_rest_encryption_enabled = true + transit_encryption_enabled = true + auth_token = "1234567890asdfghjkl" + + apply_immediately = true + family = "redis6.x" + description = "Test elasticache redis." + + subnet_ids = data.aws_subnets.all.ids + vpc_id = data.aws_vpc.default.id + + ingress_cidr_blocks = ["0.0.0.0/0"] + + parameter = [ + { + name = "repl-backlog-size" + value = "16384" + } + ] + + tags = { + Project = "Test" + } +} diff --git a/modules/aws-elasticache-redis/examples/redis-clustered-mode/outputs.tf b/modules/aws-elasticache-redis/examples/redis-clustered-mode/outputs.tf new file mode 100644 index 0000000..75385ca --- /dev/null +++ b/modules/aws-elasticache-redis/examples/redis-clustered-mode/outputs.tf @@ -0,0 +1,7 @@ +output "primary_endpoint" { + value = module.redis.elasticache_replication_group_primary_endpoint_address +} + +output "reader_endpoint" { + value = module.redis.elasticache_replication_group_reader_endpoint_address +} diff --git a/modules/aws-elasticache-redis/examples/redis-replication-group/main.tf b/modules/aws-elasticache-redis/examples/redis-replication-group/main.tf new file mode 100644 index 0000000..a3561b8 --- /dev/null +++ b/modules/aws-elasticache-redis/examples/redis-replication-group/main.tf @@ -0,0 +1,86 @@ +provider "aws" { + region = var.primary_region +} + +variable "primary_region" { + default = "eu-west-1" + type = string + description = "You can use as primary region for the AWS provider where this redis will be provisioned" +} + +provider "aws" { + region = var.secondary_region + alias = "replica" +} + +variable "secondary_region" { + default = "eu-west-2" + type = string + description = "You can use as primary region for the AWS provider where this redis will be provisioned" +} + +##### +# VPC and subnets +##### + +data "aws_vpc" "main" { + default = true +} + +data "aws_vpc" "replica" { + default = true + + provider = aws.replica +} + +data "aws_subnets" "main" { + filter { + name = "vpc-id" + values = [data.aws_vpc.main.id] + } +} + +data "aws_subnets" "replica" { + filter { + name = "vpc-id" + values = [data.aws_vpc.replica.id] + } + + provider = aws.replica +} +##### +# Elasticache Redis +##### + +module "redis_main" { + source = "../../" + + name_prefix = "redis-example-main" + num_cache_clusters = 2 + node_type = "cache.m5.large" + auth_token = "1234567890asdfghjkl" + + subnet_ids = data.aws_subnets.main.ids + vpc_id = data.aws_vpc.main.id +} + +resource "aws_elasticache_global_replication_group" "this" { + global_replication_group_id_suffix = "ha" + primary_replication_group_id = module.redis_main.elasticache_replication_group_id +} + +module "redis_replica" { + source = "../../" + + name_prefix = "redis-example-replica" + num_cache_clusters = 2 + node_type = "cache.m5.large" + auth_token = "1234567890asdfghjkl" + + subnet_ids = data.aws_subnets.replica.ids + vpc_id = data.aws_vpc.replica.id + + global_replication_group_id = aws_elasticache_global_replication_group.this.global_replication_group_id + + providers = { aws = aws.replica } +} diff --git a/modules/aws-elasticache-redis/main.tf b/modules/aws-elasticache-redis/main.tf new file mode 100644 index 0000000..3d86776 --- /dev/null +++ b/modules/aws-elasticache-redis/main.tf @@ -0,0 +1,159 @@ + +resource "aws_elasticache_replication_group" "redis" { + engine = var.global_replication_group_id == null ? "redis" : null + + parameter_group_name = var.global_replication_group_id == null ? aws_elasticache_parameter_group.redis.name : null + subnet_group_name = aws_elasticache_subnet_group.redis.name + security_group_ids = concat(var.security_group_ids, [aws_security_group.redis.id]) + + preferred_cache_cluster_azs = var.preferred_cache_cluster_azs + replication_group_id = var.global_replication_group_id == null ? "${var.name_prefix}-redis" : "${var.name_prefix}-redis-replica" + num_cache_clusters = var.cluster_mode_enabled ? null : var.num_cache_clusters + node_type = var.global_replication_group_id == null ? var.node_type : null + + engine_version = var.global_replication_group_id == null ? var.engine_version : null + port = var.port + + maintenance_window = var.maintenance_window + snapshot_window = var.snapshot_window + snapshot_retention_limit = var.snapshot_retention_limit + final_snapshot_identifier = var.final_snapshot_identifier + automatic_failover_enabled = var.automatic_failover_enabled && var.num_cache_clusters >= 2 ? true : false + auto_minor_version_upgrade = var.auto_minor_version_upgrade + multi_az_enabled = var.multi_az_enabled + + at_rest_encryption_enabled = var.global_replication_group_id == null && var.at_rest_encryption_enabled ? var.at_rest_encryption_enabled : null + transit_encryption_enabled = var.global_replication_group_id == null && var.transit_encryption_enabled ? var.transit_encryption_enabled : null + auth_token = var.auth_token != "" ? var.auth_token : null + kms_key_id = var.kms_key_id + global_replication_group_id = var.global_replication_group_id + + apply_immediately = var.apply_immediately + + description = var.description + + data_tiering_enabled = var.data_tiering_enabled + + notification_topic_arn = var.notification_topic_arn + + replicas_per_node_group = var.cluster_mode_enabled ? var.replicas_per_node_group : null + num_node_groups = var.cluster_mode_enabled ? var.num_node_groups : null + + dynamic "log_delivery_configuration" { + for_each = var.log_delivery_configuration + + content { + destination_type = log_delivery_configuration.value.destination_type + destination = log_delivery_configuration.value.destination + log_format = log_delivery_configuration.value.log_format + log_type = log_delivery_configuration.value.log_type + } + } + + tags = merge( + { + "Name" = "${var.name_prefix}-redis" + }, + var.tags, + ) +} + +resource "random_id" "redis_pg" { + keepers = { + family = var.family + } + + byte_length = 2 +} + +resource "aws_elasticache_parameter_group" "redis" { + name = "${var.name_prefix}-redis-${random_id.redis_pg.hex}" + family = var.family + description = var.description + + dynamic "parameter" { + for_each = var.num_node_groups > 0 ? concat([{ name = "cluster-enabled", value = "yes" }], var.parameter) : var.parameter + content { + name = parameter.value.name + value = parameter.value.value + } + } + + lifecycle { + create_before_destroy = true + } + + tags = var.tags +} + +data "aws_subnet_ids" "private_subnets_with_cache_tag" { + vpc_id = var.vpc_id + tags = { + Name = var.subnet_id_names + } +} + +resource "aws_elasticache_subnet_group" "redis" { + name = var.global_replication_group_id == null ? "${var.name_prefix}-redis-sg" : "${var.name_prefix}-redis-sg-replica" + subnet_ids = data.aws_subnet_ids.private_subnets_with_cache_tag.ids + description = var.description + + tags = var.tags +} + +resource "aws_security_group" "redis" { + name_prefix = "${var.name_prefix}-redis-" + vpc_id = var.vpc_id + + tags = merge( + { + "Name" = "${var.name_prefix}-redis" + }, + var.tags + ) + + lifecycle { + create_before_destroy = true + } +} + +resource "aws_security_group_rule" "redis_ingress_self" { + count = var.ingress_self ? 1 : 0 + + type = "ingress" + from_port = var.port + to_port = var.port + protocol = "tcp" + self = true + security_group_id = aws_security_group.redis.id +} + +resource "aws_security_group_rule" "redis_ingress_cidr_blocks" { + count = length(var.ingress_cidr_blocks) != 0 ? 1 : 0 + + type = "ingress" + from_port = var.port + to_port = var.port + protocol = "tcp" + cidr_blocks = var.ingress_cidr_blocks + security_group_id = aws_security_group.redis.id +} + +resource "aws_security_group_rule" "redis_egress" { + type = "egress" + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + security_group_id = aws_security_group.redis.id +} + +resource "aws_security_group_rule" "other_sg_ingress" { + count = length(var.allowed_security_groups) + type = "ingress" + from_port = var.port + to_port = var.port + protocol = "tcp" + source_security_group_id = element(var.allowed_security_groups, count.index) + security_group_id = aws_security_group.redis.id +} diff --git a/modules/aws-elasticache-redis/outputs.tf b/modules/aws-elasticache-redis/outputs.tf new file mode 100644 index 0000000..86652fa --- /dev/null +++ b/modules/aws-elasticache-redis/outputs.tf @@ -0,0 +1,85 @@ +output "elasticache_replication_group_arn" { + value = aws_elasticache_replication_group.redis.arn + description = "The Amazon Resource Name (ARN) of the created ElastiCache Replication Group." +} + +output "elasticache_replication_group_id" { + value = aws_elasticache_replication_group.redis.id + description = "The ID of the ElastiCache Replication Group." +} + +output "elasticache_replication_group_primary_endpoint_address" { + value = var.num_node_groups > 0 ? aws_elasticache_replication_group.redis.configuration_endpoint_address : aws_elasticache_replication_group.redis.primary_endpoint_address + description = "The address of the endpoint for the primary node in the replication group." +} + +output "elasticache_replication_group_reader_endpoint_address" { + value = var.num_node_groups > 0 ? aws_elasticache_replication_group.redis.configuration_endpoint_address : aws_elasticache_replication_group.redis.reader_endpoint_address + description = "The address of the endpoint for the reader node in the replication group." +} + +output "elasticache_configuration_endpoint_address" { + value = aws_elasticache_replication_group.redis.configuration_endpoint_address + description = "The address of the configuration endpoint" +} + +output "elasticache_replication_group_member_clusters" { + value = aws_elasticache_replication_group.redis.member_clusters + description = "The identifiers of all the nodes that are part of this replication group." +} + +output "elasticache_parameter_group_id" { + value = aws_elasticache_parameter_group.redis.id + description = "The ElastiCache parameter group name." +} + +output "security_group_id" { + value = aws_security_group.redis.id + description = "The ID of the Redis ElastiCache security group." +} + +output "security_group_arn" { + value = aws_security_group.redis.arn + description = "The ARN of the Redis ElastiCache security group." +} + +output "security_group_vpc_id" { + value = aws_security_group.redis.vpc_id + description = "The VPC ID of the Redis ElastiCache security group." +} + +output "security_group_owner_id" { + value = aws_security_group.redis.owner_id + description = "The owner ID of the Redis ElastiCache security group." +} + +output "security_group_name" { + value = aws_security_group.redis.name + description = "The name of the Redis ElastiCache security group." +} + +output "security_group_description" { + value = aws_security_group.redis.description + description = "The description of the Redis ElastiCache security group." +} + +output "security_group_ingress" { + value = aws_security_group.redis.ingress + description = "The ingress rules of the Redis ElastiCache security group." +} + +output "security_group_egress" { + value = aws_security_group.redis.egress + description = "The egress rules of the Redis ElastiCache security group." +} + +output "elasticache_auth_token" { + description = "The Redis Auth Token." + value = aws_elasticache_replication_group.redis.auth_token + sensitive = true +} + +output "elasticache_port" { + description = "The Redis port." + value = aws_elasticache_replication_group.redis.port +} diff --git a/modules/aws-elasticache-redis/variables.tf b/modules/aws-elasticache-redis/variables.tf new file mode 100644 index 0000000..58cb880 --- /dev/null +++ b/modules/aws-elasticache-redis/variables.tf @@ -0,0 +1,223 @@ +variable "name_prefix" { + type = string + description = "The replication group identifier. This parameter is stored as a lowercase string." +} + +variable "num_cache_clusters" { + type = number + default = 1 + description = "The number of cache clusters (primary and replicas) this replication group will have. If Multi-AZ is enabled, the value of this parameter must be at least 2. Updates will occur before other modifications. Conflicts with num_node_groups." +} + +variable "cluster_mode_enabled" { + type = bool + description = "Enable creation of a native redis cluster." + default = false +} + +variable "node_type" { + type = string + description = "The compute and memory capacity of the nodes in the node group." +} + +variable "subnet_id_names" { + description = "name of subnet ID's" + type = string + default = "*" +} + +variable "vpc_id" { + type = string + description = "VPC Id to associate with Redis ElastiCache." +} + +variable "ingress_cidr_blocks" { + type = list(string) + description = "List of Ingress CIDR blocks." + default = [] +} + +variable "ingress_self" { + type = bool + description = "Specify whether the security group itself will be added as a source to the ingress rule." + default = false +} + +variable "security_group_ids" { + type = list(string) + description = "List of Security Groups." + default = [] +} + +variable "engine_version" { + default = "6.x" + type = string + description = "The version number of the cache engine to be used for the cache clusters in this replication group." +} + +variable "port" { + default = 6379 + type = number + description = "The port number on which each of the cache nodes will accept connections." +} + +variable "maintenance_window" { + default = "" + type = string + description = "Specifies the weekly time range for when maintenance on the cache cluster is performed." +} + +variable "snapshot_window" { + default = "" + type = string + description = "The daily time range (in UTC) during which ElastiCache will begin taking a daily snapshot of your cache cluster." +} + +variable "snapshot_retention_limit" { + default = 30 + type = number + description = "The number of days for which ElastiCache will retain automatic cache cluster snapshots before deleting them." +} + +variable "auto_minor_version_upgrade" { + default = true + type = string +} + +variable "automatic_failover_enabled" { + default = true + type = bool + description = "Specifies whether a read-only replica will be automatically promoted to read/write primary if the existing primary fails. If enabled, number_cache_clusters must be greater than 1. Must be enabled for Redis (cluster mode enabled) replication groups." +} + +variable "at_rest_encryption_enabled" { + default = true + type = bool + description = "Whether to enable encryption at rest." +} + +variable "transit_encryption_enabled" { + default = true + type = bool + description = "Whether to enable encryption in transit." +} + +variable "apply_immediately" { + default = false + type = bool + description = "Specifies whether any modifications are applied immediately, or during the next maintenance window." +} + +variable "family" { + default = "redis6.x" + type = string + description = "The family of the ElastiCache parameter group." +} + +variable "description" { + default = "Managed by Terraform" + type = string + description = "The description of the all resources." +} + +variable "tags" { + default = {} + type = map(string) + description = "A mapping of tags to assign to all resources." +} + +variable "auth_token" { + type = string + description = "The password used to access a password protected server. Can be specified only if `transit_encryption_enabled = true`." + default = "" +} + +variable "kms_key_id" { + type = string + description = "The ARN of the key that you wish to use if encrypting at rest. If not supplied, uses service managed encryption. Can be specified only if `at_rest_encryption_enabled = true`" + default = "" +} + +variable "parameter" { + type = list(object({ + name = string + value = string + })) + default = [] + description = "A list of Redis parameters to apply. Note that parameters may differ from one Redis family to another" +} + +variable "notification_topic_arn" { + type = string + default = "" + description = "An Amazon Resource Name (ARN) of an SNS topic to send ElastiCache notifications to. Example: `arn:aws:sns:us-east-1:012345678999:my_sns_topic`" +} + +variable "replicas_per_node_group" { + type = number + default = 0 + description = "Specify the number of replica nodes in each node group. Valid values are 0 to 5. Changing this number will trigger an online resizing operation before other settings modifications." + + validation { + condition = var.replicas_per_node_group <= 5 + error_message = "The replicas_per_node_group value must be between 0 and 5." + } +} + +variable "num_node_groups" { + type = number + default = 0 + description = "Specify the number of node groups (shards) for this Redis replication group. Changing this number will trigger an online resizing operation before other settings modifications." +} + +variable "preferred_cache_cluster_azs" { + type = list(string) + description = "A list of EC2 availability zones in which the replication group's cache clusters will be created. The order of the availability zones in the list is not important." + default = null +} + +variable "multi_az_enabled" { + type = string + description = "Specifies whether to enable Multi-AZ Support for the replication group. If true, `automatic_failover_enabled` must also be enabled. Defaults to false." + default = false +} + +variable "final_snapshot_identifier" { + type = string + description = "The name of your final node group (shard) snapshot. ElastiCache creates the snapshot from the primary node in the cluster. If omitted, no final snapshot will be made." + default = null +} + +variable "global_replication_group_id" { + description = "The ID of the global replication group to which this replication group should belong." + type = string + default = null +} + +variable "log_delivery_configuration" { + type = list(object({ + destination_type = string + destination = string + log_format = string + log_type = string + })) + description = "Log Delivery configuration for the cluster." + default = [] + + validation { + condition = length(var.log_delivery_configuration) <= 2 + error_message = "You can set 2 targets at most for log delivery options." + } +} + +variable "allowed_security_groups" { + type = list(string) + description = "List of existing security groups that will be allowed ingress via the elaticache security group rules" + default = [] +} + +variable "data_tiering_enabled" { + type = bool + default = false + description = "Enables data tiering. Data tiering is only supported for replication groups using the r6gd node type. This parameter must be set to true when using r6gd nodes." +} diff --git a/modules/aws-elasticache-redis/versions.tf b/modules/aws-elasticache-redis/versions.tf new file mode 100644 index 0000000..8abb2a2 --- /dev/null +++ b/modules/aws-elasticache-redis/versions.tf @@ -0,0 +1,8 @@ +terraform { + required_version = ">= 1.0.11" + + required_providers { + aws = ">= 4.8.0, < 5.0.0" + random = ">= 3.3.2, < 4.0.0" + } +} diff --git a/modules/aws-elasticsearch/README.md b/modules/aws-elasticsearch/README.md new file mode 100644 index 0000000..b838dfb --- /dev/null +++ b/modules/aws-elasticsearch/README.md @@ -0,0 +1,187 @@ + + +# terraform-aws-elasticsearch + + + +Terraform module to provision an [`Elasticsearch`](https://aws.amazon.com/elasticsearch-service/) cluster with built-in integrations with [Kibana](https://aws.amazon.com/elasticsearch-service/kibana/) and [Logstash](https://aws.amazon.com/elasticsearch-service/logstash/). + + + +## Introduction + +This module will create: +- Elasticsearch cluster with the specified node count in the provided subnets in a VPC +- Elasticsearch domain policy that accepts a list of IAM role ARNs from which to permit management traffic to the cluster +- Security Group to control access to the Elasticsearch domain (inputs to the Security Group are other Security Groups or CIDRs blocks to be allowed to connect to the cluster) +- DNS hostname record for Elasticsearch cluster (if DNS Zone ID is provided) +- DNS hostname record for Kibana (if DNS Zone ID is provided) + +__NOTE:__ To enable [zone awareness](https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/es-managedomains.html#es-managedomains-zoneawareness) to deploy Elasticsearch nodes into two different Availability Zones, you need to set `zone_awareness_enabled` to `true` and provide two different subnets in `subnet_ids`. +If you enable zone awareness for your domain, Amazon ES places an endpoint into two subnets. +The subnets must be in different Availability Zones in the same region. +If you don't enable zone awareness, Amazon ES places an endpoint into only one subnet. You also need to set `availability_zone_count` to `1`. + + + +## Usage + + + + +```hcl +module "elasticsearch" { + + domain_name = "es" + security_groups = ["sg-XXXXXXXXX", "sg-YYYYYYYY"] + vpc_id = "vpc-XXXXXXXXX" + subnet_ids = ["subnet-XXXXXXXXX", "subnet-YYYYYYYY"] + zone_awareness_enabled = "true" + elasticsearch_version = "6.5" + instance_type = "t2.small.elasticsearch" + instance_count = 4 + ebs_volume_size = 10 + iam_role_arns = ["arn:aws:iam::XXXXXXXXX:role/ops", "arn:aws:iam::XXXXXXXXX:role/dev"] + iam_actions = ["es:ESHttpGet", "es:ESHttpPut", "es:ESHttpPost"] + encrypt_at_rest_enabled = true + kibana_subdomain_name = "kibana-es" + + advanced_options = { + "rest.action.multi.allow_explicit_index" = "true" + } +} +``` + + + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.0 | +| [aws](#requirement\_aws) | >= 3.35.0 | +| [null](#requirement\_null) | >= 2.0 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 3.35.0 | + + +## Resources + +| Name | Type | +|------|------| +| [aws_elasticsearch_domain.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/elasticsearch_domain) | resource | +| [aws_elasticsearch_domain_policy.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/elasticsearch_domain_policy) | resource | +| [aws_iam_role.elasticsearch_user](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | +| [aws_iam_service_linked_role.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_service_linked_role) | resource | +| [aws_security_group.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource | +| [aws_security_group_rule.egress](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | +| [aws_security_group_rule.ingress_cidr_blocks](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | +| [aws_security_group_rule.ingress_security_groups](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | +| [aws_iam_policy_document.assume_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [advanced\_options](#input\_advanced\_options) | Key-value string pairs to specify advanced configuration options | `map(string)` | `{}` | no | +| [advanced\_security\_options\_enabled](#input\_advanced\_security\_options\_enabled) | AWS Elasticsearch Kibana enchanced security plugin enabling (forces new resource) | `bool` | `false` | no | +| [advanced\_security\_options\_internal\_user\_database\_enabled](#input\_advanced\_security\_options\_internal\_user\_database\_enabled) | Whether to enable or not internal Kibana user database for ELK OpenDistro security plugin | `bool` | `false` | no | +| [advanced\_security\_options\_master\_user\_arn](#input\_advanced\_security\_options\_master\_user\_arn) | ARN of IAM user who is to be mapped to be Kibana master user (applicable if advanced\_security\_options\_internal\_user\_database\_enabled set to false) | `string` | `""` | no | +| [advanced\_security\_options\_master\_user\_name](#input\_advanced\_security\_options\_master\_user\_name) | Master user username (applicable if advanced\_security\_options\_internal\_user\_database\_enabled set to true) | `string` | `""` | no | +| [advanced\_security\_options\_master\_user\_password](#input\_advanced\_security\_options\_master\_user\_password) | Master user password (applicable if advanced\_security\_options\_internal\_user\_database\_enabled set to true) | `string` | `""` | no | +| [allowed\_cidr\_blocks](#input\_allowed\_cidr\_blocks) | List of CIDR blocks to be allowed to connect to the cluster | `list(string)` | `[]` | no | +| [automated\_snapshot\_start\_hour](#input\_automated\_snapshot\_start\_hour) | Hour at which automated snapshots are taken, in UTC | `number` | `0` | no | +| [availability\_zone\_count](#input\_availability\_zone\_count) | Number of Availability Zones for the domain to use. | `number` | `2` | no | +| [aws\_ec2\_service\_name](#input\_aws\_ec2\_service\_name) | AWS EC2 Service Name | `list(string)` |
name = string
value = string
}))
[| no | +| [cognito\_authentication\_enabled](#input\_cognito\_authentication\_enabled) | Whether to enable Amazon Cognito authentication with Kibana | `bool` | `false` | no | +| [cognito\_iam\_role\_arn](#input\_cognito\_iam\_role\_arn) | ARN of the IAM role that has the AmazonESCognitoAccess policy attached | `string` | `""` | no | +| [cognito\_identity\_pool\_id](#input\_cognito\_identity\_pool\_id) | The ID of the Cognito Identity Pool to use | `string` | `""` | no | +| [cognito\_user\_pool\_id](#input\_cognito\_user\_pool\_id) | The ID of the Cognito User Pool to use | `string` | `""` | no | +| [create\_iam\_service\_linked\_role](#input\_create\_iam\_service\_linked\_role) | Whether to create `AWSServiceRoleForAmazonElasticsearchService` service-linked role. Set it to `false` if you already have an ElasticSearch cluster created in the AWS account and AWSServiceRoleForAmazonElasticsearchService already exists. See https://github.com/terraform-providers/terraform-provider-aws/issues/5218 for more info | `bool` | `true` | no | +| [custom\_endpoint](#input\_custom\_endpoint) | Fully qualified domain for custom endpoint. | `string` | `""` | no | +| [custom\_endpoint\_certificate\_arn](#input\_custom\_endpoint\_certificate\_arn) | ACM certificate ARN for custom endpoint. | `string` | `""` | no | +| [custom\_endpoint\_enabled](#input\_custom\_endpoint\_enabled) | Whether to enable custom endpoint for the Elasticsearch domain. | `bool` | `false` | no | +| [dedicated\_master\_count](#input\_dedicated\_master\_count) | Number of dedicated master nodes in the cluster | `number` | `0` | no | +| [dedicated\_master\_enabled](#input\_dedicated\_master\_enabled) | Indicates whether dedicated master nodes are enabled for the cluster | `bool` | `false` | no | +| [dedicated\_master\_type](#input\_dedicated\_master\_type) | Instance type of the dedicated master nodes in the cluster | `string` | `"t2.small.elasticsearch"` | no | +| [dns\_zone\_id](#input\_dns\_zone\_id) | Route53 DNS Zone ID to add hostname records for Elasticsearch domain and Kibana | `string` | `""` | no | +| [domain\_endpoint\_options\_enforce\_https](#input\_domain\_endpoint\_options\_enforce\_https) | Whether or not to require HTTPS | `bool` | `true` | no | +| [domain\_endpoint\_options\_tls\_security\_policy](#input\_domain\_endpoint\_options\_tls\_security\_policy) | The name of the TLS security policy that needs to be applied to the HTTPS endpoint | `string` | `"Policy-Min-TLS-1-0-2019-07"` | no | +| [domain\_hostname\_enabled](#input\_domain\_hostname\_enabled) | Explicit flag to enable creating a DNS hostname for ES. If `true`, then `var.dns_zone_id` is required. | `bool` | `false` | no | +| [ebs\_iops](#input\_ebs\_iops) | The baseline input/output (I/O) performance of EBS volumes attached to data nodes. Applicable only for the Provisioned IOPS EBS volume type | `number` | `0` | no | +| [ebs\_volume\_size](#input\_ebs\_volume\_size) | EBS volumes for data storage in GB | `number` | `0` | no | +| [ebs\_volume\_type](#input\_ebs\_volume\_type) | Storage type of EBS volumes | `string` | `"gp2"` | no | +| [elasticsearch\_subdomain\_name](#input\_elasticsearch\_subdomain\_name) | The name of the subdomain for Elasticsearch in the DNS zone (\_e.g.\_ `elasticsearch`, `ui`, `ui-es`, `search-ui`) | `string` | `""` | no | +| [elasticsearch\_version](#input\_elasticsearch\_version) | Version of Elasticsearch to deploy (\_e.g.\_ `7.4`, `7.1`, `6.8`, `6.7`, `6.5`, `6.4`, `6.3`, `6.2`, `6.0`, `5.6`, `5.5`, `5.3`, `5.1`, `2.3`, `1.5` | `string` | `"7.4"` | no | +| [enabled](#input\_enabled) | Set to false to prevent the module from creating any resources | `bool` | `null` | no | +| [encrypt\_at\_rest\_enabled](#input\_encrypt\_at\_rest\_enabled) | Whether to enable encryption at rest | `bool` | `true` | no | +| [encrypt\_at\_rest\_kms\_key\_id](#input\_encrypt\_at\_rest\_kms\_key\_id) | The KMS key ID to encrypt the Elasticsearch domain with. If not specified, then it defaults to using the AWS/Elasticsearch service KMS key | `string` | `""` | no | +| [iam\_actions](#input\_iam\_actions) | List of actions to allow for the IAM roles, _e.g._ `es:ESHttpGet`, `es:ESHttpPut`, `es:ESHttpPost` | `list(string)` | `[]` | no | +| [iam\_authorizing\_role\_arns](#input\_iam\_authorizing\_role\_arns) | List of IAM role ARNs to permit to assume the Elasticsearch user role | `list(string)` | `[]` | no | +| [iam\_role\_arns](#input\_iam\_role\_arns) | List of IAM role ARNs to permit access to the Elasticsearch domain | `list(string)` | `[]` | no | +| [iam\_role\_max\_session\_duration](#input\_iam\_role\_max\_session\_duration) | The maximum session duration (in seconds) for the user role. Can have a value from 1 hour to 12 hours | `number` | `3600` | no | +| [iam\_role\_permissions\_boundary](#input\_iam\_role\_permissions\_boundary) | The ARN of the permissions boundary policy which will be attached to the Elasticsearch user role | `string` | `null` | no | +| [ingress\_port\_range\_end](#input\_ingress\_port\_range\_end) | End number for allowed port range. (e.g. `443`) | `number` | `65535` | no | +| [ingress\_port\_range\_start](#input\_ingress\_port\_range\_start) | Start number for allowed port range. (e.g. `443`) | `number` | `0` | no | +| [instance\_count](#input\_instance\_count) | Number of data nodes in the cluster | `number` | `4` | no | +| [instance\_type](#input\_instance\_type) | Elasticsearch instance type for data nodes in the cluster | `string` | `"t2.small.elasticsearch"` | no | +| [kibana\_hostname\_enabled](#input\_kibana\_hostname\_enabled) | Explicit flag to enable creating a DNS hostname for Kibana. If `true`, then `var.dns_zone_id` is required. | `bool` | `false` | no | +| [kibana\_subdomain\_name](#input\_kibana\_subdomain\_name) | The name of the subdomain for Kibana in the DNS zone (\_e.g.\_ `kibana`, `ui`, `ui-es`, `search-ui`, `kibana.elasticsearch`) | `string` | `""` | no | +| [log\_publishing\_application\_cloudwatch\_log\_group\_arn](#input\_log\_publishing\_application\_cloudwatch\_log\_group\_arn) | ARN of the CloudWatch log group to which log for ES\_APPLICATION\_LOGS needs to be published | `string` | `""` | no | +| [log\_publishing\_application\_enabled](#input\_log\_publishing\_application\_enabled) | Specifies whether log publishing option for ES\_APPLICATION\_LOGS is enabled or not | `bool` | `false` | no | +| [log\_publishing\_audit\_cloudwatch\_log\_group\_arn](#input\_log\_publishing\_audit\_cloudwatch\_log\_group\_arn) | ARN of the CloudWatch log group to which log for AUDIT\_LOGS needs to be published | `string` | `""` | no | +| [log\_publishing\_audit\_enabled](#input\_log\_publishing\_audit\_enabled) | Specifies whether log publishing option for AUDIT\_LOGS is enabled or not | `bool` | `false` | no | +| [log\_publishing\_index\_cloudwatch\_log\_group\_arn](#input\_log\_publishing\_index\_cloudwatch\_log\_group\_arn) | ARN of the CloudWatch log group to which log for INDEX\_SLOW\_LOGS needs to be published | `string` | `""` | no | +| [log\_publishing\_index\_enabled](#input\_log\_publishing\_index\_enabled) | Specifies whether log publishing option for INDEX\_SLOW\_LOGS is enabled or not | `bool` | `false` | no | +| [log\_publishing\_search\_cloudwatch\_log\_group\_arn](#input\_log\_publishing\_search\_cloudwatch\_log\_group\_arn) | ARN of the CloudWatch log group to which log for SEARCH\_SLOW\_LOGS needs to be published | `string` | `""` | no | +| [log\_publishing\_search\_enabled](#input\_log\_publishing\_search\_enabled) | Specifies whether log publishing option for SEARCH\_SLOW\_LOGS is enabled or not | `bool` | `false` | no | +| [node\_to\_node\_encryption\_enabled](#input\_node\_to\_node\_encryption\_enabled) | Whether to enable node-to-node encryption | `bool` | `false` | no | +| [security\_groups](#input\_security\_groups) | List of security group IDs to be allowed to connect to the cluster | `list(string)` | `[]` | no | +| [subnet\_ids](#input\_subnet\_ids) | VPC Subnet IDs | `list(string)` | `[]` | no | +| [tags](#input\_tags) | Additional tags (e.g. `{'BusinessUnit': 'XYZ'}`).
"ec2.amazonaws.com"
]
{| no | +| [create\_sns\_topic](#input\_create\_sns\_topic) | Flag to indicate whether an SNS topic should be created for notifications.
"additional_tag_map": {},
"attributes": [],
"delimiter": null,
"descriptor_formats": {},
"enabled": true,
"environment": null,
"id_length_limit": null,
"label_key_case": null,
"label_order": [],
"label_value_case": null,
"labels_as_tags": [
"unset"
],
"name": null,
"namespace": null,
"regex_replace_chars": null,
"stage": null,
"tags": {},
"tenant": null
}
[| no | +| [name](#input\_name) | ID element. Usually the component or solution name, e.g. 'app' or 'jenkins'.
"default"
]
map(object({| `{}` | no | +| [tags](#input\_tags) | Additional tags (e.g. `{'BusinessUnit': 'XYZ'}`).
protocol = string
endpoint = string
endpoint_auto_confirms = bool
raw_message_delivery = bool
}))
{| no | +| [create\_sns\_topic](#input\_create\_sns\_topic) | Flag to indicate whether an SNS topic should be created for notifications.
"additional_tag_map": {},
"attributes": [],
"delimiter": null,
"descriptor_formats": {},
"enabled": true,
"environment": null,
"id_length_limit": null,
"label_key_case": null,
"label_order": [],
"label_value_case": null,
"labels_as_tags": [
"unset"
],
"name": null,
"namespace": null,
"regex_replace_chars": null,
"stage": null,
"tags": {},
"tenant": null
}
[| no | +| [name](#input\_name) | ID element. Usually the component or solution name, e.g. 'app' or 'jenkins'.
"default"
]
map(object({| `{}` | no | +| [tags](#input\_tags) | Additional tags (e.g. `{'BusinessUnit': 'XYZ'}`).
protocol = string
endpoint = string
endpoint_auto_confirms = bool
raw_message_delivery = bool
}))
[| no | +| [trusted\_role\_arns](#input\_trusted\_role\_arns) | ARNs of AWS entities who can assume these roles | `list(string)` | `[]` | no | +| [trusted\_role\_services](#input\_trusted\_role\_services) | AWS Services that can assume these roles | `list(string)` | `[]` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [iam\_instance\_profile\_arn](#output\_iam\_instance\_profile\_arn) | ARN of IAM instance profile | +| [iam\_instance\_profile\_id](#output\_iam\_instance\_profile\_id) | IAM Instance profile's ID. | +| [iam\_instance\_profile\_name](#output\_iam\_instance\_profile\_name) | Name of IAM instance profile | +| [iam\_instance\_profile\_path](#output\_iam\_instance\_profile\_path) | Path of IAM instance profile | +| [iam\_role\_arn](#output\_iam\_role\_arn) | ARN of IAM role | +| [iam\_role\_name](#output\_iam\_role\_name) | Name of IAM role | +| [iam\_role\_path](#output\_iam\_role\_path) | Path of IAM role | +| [iam\_role\_unique\_id](#output\_iam\_role\_unique\_id) | Unique ID of IAM role | +| [role\_requires\_mfa](#output\_role\_requires\_mfa) | Whether IAM role requires MFA | +| [role\_sts\_externalid](#output\_role\_sts\_externalid) | STS ExternalId condition value to use with a role | diff --git a/modules/aws-iam/modules/iam-assumable-role/main.tf b/modules/aws-iam/modules/iam-assumable-role/main.tf new file mode 100644 index 0000000..6255dae --- /dev/null +++ b/modules/aws-iam/modules/iam-assumable-role/main.tf @@ -0,0 +1,141 @@ +locals { + role_sts_externalid = flatten([var.role_sts_externalid]) + role_sts_orgid = flatten([var.role_sts_orgid]) +} + +data "aws_iam_policy_document" "assume_role" { + count = var.custom_role_trust_policy == "" && var.role_requires_mfa ? 0 : 1 + + statement { + effect = "Allow" + + actions = var.trusted_role_actions + + principals { + type = "AWS" + identifiers = var.trusted_role_arns + } + + principals { + type = "Service" + identifiers = var.trusted_role_services + } + + dynamic "condition" { + for_each = length(local.role_sts_orgid) != 0 ? [true] : [] + content { + test = "StringEquals" + variable = "aws:PrincipalOrgID" + values = local.role_sts_orgid + } + } + + dynamic "condition" { + for_each = length(local.role_sts_externalid) != 0 ? [true] : [] + content { + test = "StringEquals" + variable = "sts:ExternalId" + values = local.role_sts_externalid + } + } + } +} + +data "aws_iam_policy_document" "assume_role_with_mfa" { + count = var.custom_role_trust_policy == "" && var.role_requires_mfa ? 1 : 0 + + statement { + effect = "Allow" + + actions = var.trusted_role_actions + + principals { + type = "AWS" + identifiers = var.trusted_role_arns + } + + principals { + type = "Service" + identifiers = var.trusted_role_services + } + + condition { + test = "Bool" + variable = "aws:MultiFactorAuthPresent" + values = ["true"] + } + + condition { + test = "NumericLessThan" + variable = "aws:MultiFactorAuthAge" + values = [var.mfa_age] + } + + dynamic "condition" { + for_each = length(local.role_sts_externalid) != 0 ? [true] : [] + content { + test = "StringEquals" + variable = "sts:ExternalId" + values = local.role_sts_externalid + } + } + } +} + +resource "aws_iam_role" "this" { + count = var.create_role ? 1 : 0 + + name = var.role_name + path = var.role_path + max_session_duration = var.max_session_duration + description = var.role_description + + force_detach_policies = var.force_detach_policies + permissions_boundary = var.role_permissions_boundary_arn + + assume_role_policy = coalesce( + var.custom_role_trust_policy, + try(data.aws_iam_policy_document.assume_role_with_mfa[0].json, + data.aws_iam_policy_document.assume_role[0].json + ) + ) + + tags = var.tags +} + +resource "aws_iam_role_policy_attachment" "custom" { + count = var.create_role ? coalesce(var.number_of_custom_role_policy_arns, length(var.custom_role_policy_arns)) : 0 + + role = aws_iam_role.this[0].name + policy_arn = element(var.custom_role_policy_arns, count.index) +} + +resource "aws_iam_role_policy_attachment" "admin" { + count = var.create_role && var.attach_admin_policy ? 1 : 0 + + role = aws_iam_role.this[0].name + policy_arn = var.admin_role_policy_arn +} + +resource "aws_iam_role_policy_attachment" "poweruser" { + count = var.create_role && var.attach_poweruser_policy ? 1 : 0 + + role = aws_iam_role.this[0].name + policy_arn = var.poweruser_role_policy_arn +} + +resource "aws_iam_role_policy_attachment" "readonly" { + count = var.create_role && var.attach_readonly_policy ? 1 : 0 + + role = aws_iam_role.this[0].name + policy_arn = var.readonly_role_policy_arn +} + +resource "aws_iam_instance_profile" "this" { + count = var.create_role && var.create_instance_profile ? 1 : 0 + name = var.role_name + path = var.role_path + role = aws_iam_role.this[0].name + + tags = var.tags +} diff --git a/modules/aws-iam/modules/iam-assumable-role/outputs.tf b/modules/aws-iam/modules/iam-assumable-role/outputs.tf new file mode 100644 index 0000000..117ff07 --- /dev/null +++ b/modules/aws-iam/modules/iam-assumable-role/outputs.tf @@ -0,0 +1,49 @@ +output "iam_role_arn" { + description = "ARN of IAM role" + value = try(aws_iam_role.this[0].arn, "") +} + +output "iam_role_name" { + description = "Name of IAM role" + value = try(aws_iam_role.this[0].name, "") +} + +output "iam_role_path" { + description = "Path of IAM role" + value = try(aws_iam_role.this[0].path, "") +} + +output "iam_role_unique_id" { + description = "Unique ID of IAM role" + value = try(aws_iam_role.this[0].unique_id, "") +} + +output "role_requires_mfa" { + description = "Whether IAM role requires MFA" + value = var.role_requires_mfa +} + +output "iam_instance_profile_arn" { + description = "ARN of IAM instance profile" + value = try(aws_iam_instance_profile.this[0].arn, "") +} + +output "iam_instance_profile_name" { + description = "Name of IAM instance profile" + value = try(aws_iam_instance_profile.this[0].name, "") +} + +output "iam_instance_profile_id" { + description = "IAM Instance profile's ID." + value = try(aws_iam_instance_profile.this[0].id, "") +} + +output "iam_instance_profile_path" { + description = "Path of IAM instance profile" + value = try(aws_iam_instance_profile.this[0].path, "") +} + +output "role_sts_externalid" { + description = "STS ExternalId condition value to use with a role" + value = var.role_sts_externalid +} diff --git a/modules/aws-iam/modules/iam-assumable-role/variables.tf b/modules/aws-iam/modules/iam-assumable-role/variables.tf new file mode 100644 index 0000000..747e5de --- /dev/null +++ b/modules/aws-iam/modules/iam-assumable-role/variables.tf @@ -0,0 +1,151 @@ +variable "trusted_role_actions" { + description = "Actions of STS" + type = list(string) + default = ["sts:AssumeRole"] +} + +variable "trusted_role_arns" { + description = "ARNs of AWS entities who can assume these roles" + type = list(string) + default = [] +} + +variable "trusted_role_services" { + description = "AWS Services that can assume these roles" + type = list(string) + default = [] +} + +variable "mfa_age" { + description = "Max age of valid MFA (in seconds) for roles which require MFA" + type = number + default = 86400 +} + +variable "max_session_duration" { + description = "Maximum CLI/API session duration in seconds between 3600 and 43200" + type = number + default = 3600 +} + +variable "create_role" { + description = "Whether to create a role" + type = bool + default = false +} + +variable "create_instance_profile" { + description = "Whether to create an instance profile" + type = bool + default = false +} + +variable "role_name" { + description = "IAM role name" + type = string + default = "" +} + +variable "role_path" { + description = "Path of IAM role" + type = string + default = "/" +} + +variable "role_requires_mfa" { + description = "Whether role requires MFA" + type = bool + default = true +} + +variable "role_permissions_boundary_arn" { + description = "Permissions boundary ARN to use for IAM role" + type = string + default = "" +} + +variable "tags" { + description = "A map of tags to add to IAM role resources" + type = map(string) + default = {} +} + +variable "custom_role_policy_arns" { + description = "List of ARNs of IAM policies to attach to IAM role" + type = list(string) + default = [] +} + +variable "custom_role_trust_policy" { + description = "A custom role trust policy" + type = string + default = "" +} + +variable "number_of_custom_role_policy_arns" { + description = "Number of IAM policies to attach to IAM role" + type = number + default = null +} + +# Pre-defined policies +variable "admin_role_policy_arn" { + description = "Policy ARN to use for admin role" + type = string + default = "arn:aws:iam::aws:policy/AdministratorAccess" +} + +variable "poweruser_role_policy_arn" { + description = "Policy ARN to use for poweruser role" + type = string + default = "arn:aws:iam::aws:policy/PowerUserAccess" +} + +variable "readonly_role_policy_arn" { + description = "Policy ARN to use for readonly role" + type = string + default = "arn:aws:iam::aws:policy/ReadOnlyAccess" +} + +variable "attach_admin_policy" { + description = "Whether to attach an admin policy to a role" + type = bool + default = false +} + +variable "attach_poweruser_policy" { + description = "Whether to attach a poweruser policy to a role" + type = bool + default = false +} + +variable "attach_readonly_policy" { + description = "Whether to attach a readonly policy to a role" + type = bool + default = false +} + +variable "force_detach_policies" { + description = "Whether policies should be detached from this role when destroying" + type = bool + default = false +} + +variable "role_description" { + description = "IAM Role description" + type = string + default = "" +} + +variable "role_sts_externalid" { + description = "STS ExternalId condition values to use with a role (when MFA is not required)" + type = any + default = [] +} + + +variable "role_sts_orgid" { + description = "STS Organization ID condition values to use with a role (when MFA is not required)" + type = any + default = [] +} \ No newline at end of file diff --git a/modules/aws-iam/modules/iam-assumable-role/versions.tf b/modules/aws-iam/modules/iam-assumable-role/versions.tf new file mode 100644 index 0000000..d8dd1a4 --- /dev/null +++ b/modules/aws-iam/modules/iam-assumable-role/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.0" + } + } +} diff --git a/modules/aws-iam/modules/iam-assumable-roles-with-saml/README.md b/modules/aws-iam/modules/iam-assumable-roles-with-saml/README.md new file mode 100644 index 0000000..c665f99 --- /dev/null +++ b/modules/aws-iam/modules/iam-assumable-roles-with-saml/README.md @@ -0,0 +1,82 @@ +# iam-assumable-roles-with-saml + +Creates predefined IAM roles (admin, poweruser and readonly) which can be assumed by trusted resources using SAML Federated Users. + + +[Creating IAM SAML Identity Providers](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_saml.html) +[Enabling SAML 2.0 Federated Users to Access the AWS Management Console](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_enable-console-saml.html) + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.0 | +| [aws](#requirement\_aws) | >= 4.0 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 4.0 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_iam_role.admin](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | +| [aws_iam_role.poweruser](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | +| [aws_iam_role.readonly](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | +| [aws_iam_role_policy_attachment.admin](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_iam_role_policy_attachment.poweruser](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_iam_role_policy_attachment.readonly](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_iam_policy_document.assume_role_with_saml](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [admin\_role\_name](#input\_admin\_role\_name) | IAM role with admin access | `string` | `"admin"` | no | +| [admin\_role\_path](#input\_admin\_role\_path) | Path of admin IAM role | `string` | `"/"` | no | +| [admin\_role\_permissions\_boundary\_arn](#input\_admin\_role\_permissions\_boundary\_arn) | Permissions boundary ARN to use for admin role | `string` | `""` | no | +| [admin\_role\_policy\_arns](#input\_admin\_role\_policy\_arns) | List of policy ARNs to use for admin role | `list(string)` |
"sts:AssumeRole"
]
[| no | +| [admin\_role\_tags](#input\_admin\_role\_tags) | A map of tags to add to admin role resource. | `map(string)` | `{}` | no | +| [aws\_saml\_endpoint](#input\_aws\_saml\_endpoint) | AWS SAML Endpoint | `string` | `"https://signin.aws.amazon.com/saml"` | no | +| [create\_admin\_role](#input\_create\_admin\_role) | Whether to create admin role | `bool` | `false` | no | +| [create\_poweruser\_role](#input\_create\_poweruser\_role) | Whether to create poweruser role | `bool` | `false` | no | +| [create\_readonly\_role](#input\_create\_readonly\_role) | Whether to create readonly role | `bool` | `false` | no | +| [force\_detach\_policies](#input\_force\_detach\_policies) | Whether policies should be detached from this role when destroying | `bool` | `false` | no | +| [max\_session\_duration](#input\_max\_session\_duration) | Maximum CLI/API session duration in seconds between 3600 and 43200 | `number` | `3600` | no | +| [poweruser\_role\_name](#input\_poweruser\_role\_name) | IAM role with poweruser access | `string` | `"poweruser"` | no | +| [poweruser\_role\_path](#input\_poweruser\_role\_path) | Path of poweruser IAM role | `string` | `"/"` | no | +| [poweruser\_role\_permissions\_boundary\_arn](#input\_poweruser\_role\_permissions\_boundary\_arn) | Permissions boundary ARN to use for poweruser role | `string` | `""` | no | +| [poweruser\_role\_policy\_arns](#input\_poweruser\_role\_policy\_arns) | List of policy ARNs to use for poweruser role | `list(string)` |
"arn:aws:iam::aws:policy/AdministratorAccess"
]
[| no | +| [poweruser\_role\_tags](#input\_poweruser\_role\_tags) | A map of tags to add to poweruser role resource. | `map(string)` | `{}` | no | +| [provider\_id](#input\_provider\_id) | ID of the SAML Provider. Use provider\_ids to specify several IDs. | `string` | `""` | no | +| [provider\_ids](#input\_provider\_ids) | List of SAML Provider IDs | `list(string)` | `[]` | no | +| [readonly\_role\_name](#input\_readonly\_role\_name) | IAM role with readonly access | `string` | `"readonly"` | no | +| [readonly\_role\_path](#input\_readonly\_role\_path) | Path of readonly IAM role | `string` | `"/"` | no | +| [readonly\_role\_permissions\_boundary\_arn](#input\_readonly\_role\_permissions\_boundary\_arn) | Permissions boundary ARN to use for readonly role | `string` | `""` | no | +| [readonly\_role\_policy\_arns](#input\_readonly\_role\_policy\_arns) | List of policy ARNs to use for readonly role | `list(string)` |
"arn:aws:iam::aws:policy/PowerUserAccess"
]
[| no | +| [readonly\_role\_tags](#input\_readonly\_role\_tags) | A map of tags to add to readonly role resource. | `map(string)` | `{}` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [admin\_iam\_role\_arn](#output\_admin\_iam\_role\_arn) | ARN of admin IAM role | +| [admin\_iam\_role\_name](#output\_admin\_iam\_role\_name) | Name of admin IAM role | +| [admin\_iam\_role\_path](#output\_admin\_iam\_role\_path) | Path of admin IAM role | +| [admin\_iam\_role\_unique\_id](#output\_admin\_iam\_role\_unique\_id) | Unique ID of IAM role | +| [poweruser\_iam\_role\_arn](#output\_poweruser\_iam\_role\_arn) | ARN of poweruser IAM role | +| [poweruser\_iam\_role\_name](#output\_poweruser\_iam\_role\_name) | Name of poweruser IAM role | +| [poweruser\_iam\_role\_path](#output\_poweruser\_iam\_role\_path) | Path of poweruser IAM role | +| [poweruser\_iam\_role\_unique\_id](#output\_poweruser\_iam\_role\_unique\_id) | Unique ID of IAM role | +| [readonly\_iam\_role\_arn](#output\_readonly\_iam\_role\_arn) | ARN of readonly IAM role | +| [readonly\_iam\_role\_name](#output\_readonly\_iam\_role\_name) | Name of readonly IAM role | +| [readonly\_iam\_role\_path](#output\_readonly\_iam\_role\_path) | Path of readonly IAM role | +| [readonly\_iam\_role\_unique\_id](#output\_readonly\_iam\_role\_unique\_id) | Unique ID of IAM role | diff --git a/modules/aws-iam/modules/iam-assumable-roles-with-saml/main.tf b/modules/aws-iam/modules/iam-assumable-roles-with-saml/main.tf new file mode 100644 index 0000000..fdfb687 --- /dev/null +++ b/modules/aws-iam/modules/iam-assumable-roles-with-saml/main.tf @@ -0,0 +1,92 @@ +locals { + identifiers = compact(distinct(concat(var.provider_ids, [var.provider_id]))) +} + +data "aws_iam_policy_document" "assume_role_with_saml" { + statement { + effect = "Allow" + + actions = ["sts:AssumeRoleWithSAML"] + + principals { + type = "Federated" + + identifiers = local.identifiers + } + + condition { + test = "StringEquals" + variable = "SAML:aud" + values = [var.aws_saml_endpoint] + } + } +} + +# Admin +resource "aws_iam_role" "admin" { + count = var.create_admin_role ? 1 : 0 + + name = var.admin_role_name + path = var.admin_role_path + max_session_duration = var.max_session_duration + + force_detach_policies = var.force_detach_policies + permissions_boundary = var.admin_role_permissions_boundary_arn + + assume_role_policy = data.aws_iam_policy_document.assume_role_with_saml.json + + tags = var.admin_role_tags +} + +resource "aws_iam_role_policy_attachment" "admin" { + count = var.create_admin_role ? length(var.admin_role_policy_arns) : 0 + + role = aws_iam_role.admin[0].name + policy_arn = element(var.admin_role_policy_arns, count.index) +} + +# Poweruser +resource "aws_iam_role" "poweruser" { + count = var.create_poweruser_role ? 1 : 0 + + name = var.poweruser_role_name + path = var.poweruser_role_path + max_session_duration = var.max_session_duration + + force_detach_policies = var.force_detach_policies + permissions_boundary = var.poweruser_role_permissions_boundary_arn + + assume_role_policy = data.aws_iam_policy_document.assume_role_with_saml.json + + tags = var.poweruser_role_tags +} + +resource "aws_iam_role_policy_attachment" "poweruser" { + count = var.create_poweruser_role ? length(var.poweruser_role_policy_arns) : 0 + + role = aws_iam_role.poweruser[0].name + policy_arn = element(var.poweruser_role_policy_arns, count.index) +} + +# Readonly +resource "aws_iam_role" "readonly" { + count = var.create_readonly_role ? 1 : 0 + + name = var.readonly_role_name + path = var.readonly_role_path + max_session_duration = var.max_session_duration + + force_detach_policies = var.force_detach_policies + permissions_boundary = var.readonly_role_permissions_boundary_arn + + assume_role_policy = data.aws_iam_policy_document.assume_role_with_saml.json + + tags = var.readonly_role_tags +} + +resource "aws_iam_role_policy_attachment" "readonly" { + count = var.create_readonly_role ? length(var.readonly_role_policy_arns) : 0 + + role = aws_iam_role.readonly[0].name + policy_arn = element(var.readonly_role_policy_arns, count.index) +} diff --git a/modules/aws-iam/modules/iam-assumable-roles-with-saml/outputs.tf b/modules/aws-iam/modules/iam-assumable-roles-with-saml/outputs.tf new file mode 100644 index 0000000..3b1c4d1 --- /dev/null +++ b/modules/aws-iam/modules/iam-assumable-roles-with-saml/outputs.tf @@ -0,0 +1,61 @@ +#Admin +output "admin_iam_role_arn" { + description = "ARN of admin IAM role" + value = try(aws_iam_role.admin[0].arn, "") +} + +output "admin_iam_role_name" { + description = "Name of admin IAM role" + value = try(aws_iam_role.admin[0].name, "") +} + +output "admin_iam_role_path" { + description = "Path of admin IAM role" + value = try(aws_iam_role.admin[0].path, "") +} + +output "admin_iam_role_unique_id" { + description = "Unique ID of IAM role" + value = try(aws_iam_role.admin[0].unique_id, "") +} + +output "poweruser_iam_role_arn" { + description = "ARN of poweruser IAM role" + value = try(aws_iam_role.poweruser[0].arn, "") +} + +output "poweruser_iam_role_name" { + description = "Name of poweruser IAM role" + value = try(aws_iam_role.poweruser[0].name, "") +} + +output "poweruser_iam_role_path" { + description = "Path of poweruser IAM role" + value = try(aws_iam_role.poweruser[0].path, "") +} + +output "poweruser_iam_role_unique_id" { + description = "Unique ID of IAM role" + value = try(aws_iam_role.poweruser[0].unique_id, "") +} + +# Readonly +output "readonly_iam_role_arn" { + description = "ARN of readonly IAM role" + value = try(aws_iam_role.readonly[0].arn, "") +} + +output "readonly_iam_role_name" { + description = "Name of readonly IAM role" + value = try(aws_iam_role.readonly[0].name, "") +} + +output "readonly_iam_role_path" { + description = "Path of readonly IAM role" + value = try(aws_iam_role.readonly[0].path, "") +} + +output "readonly_iam_role_unique_id" { + description = "Unique ID of IAM role" + value = try(aws_iam_role.readonly[0].unique_id, "") +} diff --git a/modules/aws-iam/modules/iam-assumable-roles-with-saml/variables.tf b/modules/aws-iam/modules/iam-assumable-roles-with-saml/variables.tf new file mode 100644 index 0000000..4f2af0f --- /dev/null +++ b/modules/aws-iam/modules/iam-assumable-roles-with-saml/variables.tf @@ -0,0 +1,140 @@ +variable "provider_id" { + description = "ID of the SAML Provider. Use provider_ids to specify several IDs." + type = string + default = "" +} + +variable "provider_ids" { + description = "List of SAML Provider IDs" + type = list(string) + default = [] +} + +variable "aws_saml_endpoint" { + description = "AWS SAML Endpoint" + default = "https://signin.aws.amazon.com/saml" + type = string +} + +# Admin +variable "create_admin_role" { + description = "Whether to create admin role" + type = bool + default = false +} + +variable "admin_role_name" { + description = "IAM role with admin access" + type = string + default = "admin" +} + +variable "admin_role_path" { + description = "Path of admin IAM role" + type = string + default = "/" +} + +variable "admin_role_policy_arns" { + description = "List of policy ARNs to use for admin role" + type = list(string) + default = ["arn:aws:iam::aws:policy/AdministratorAccess"] +} + +variable "admin_role_permissions_boundary_arn" { + description = "Permissions boundary ARN to use for admin role" + type = string + default = "" +} + +variable "admin_role_tags" { + description = "A map of tags to add to admin role resource." + type = map(string) + default = {} +} + +# Poweruser +variable "create_poweruser_role" { + description = "Whether to create poweruser role" + type = bool + default = false +} + +variable "poweruser_role_name" { + description = "IAM role with poweruser access" + type = string + default = "poweruser" +} + +variable "poweruser_role_path" { + description = "Path of poweruser IAM role" + type = string + default = "/" +} + +variable "poweruser_role_policy_arns" { + description = "List of policy ARNs to use for poweruser role" + type = list(string) + default = ["arn:aws:iam::aws:policy/PowerUserAccess"] +} + +variable "poweruser_role_permissions_boundary_arn" { + description = "Permissions boundary ARN to use for poweruser role" + type = string + default = "" +} + +variable "poweruser_role_tags" { + description = "A map of tags to add to poweruser role resource." + type = map(string) + default = {} +} + +# Readonly +variable "create_readonly_role" { + description = "Whether to create readonly role" + type = bool + default = false +} + +variable "readonly_role_name" { + description = "IAM role with readonly access" + type = string + default = "readonly" +} + +variable "readonly_role_path" { + description = "Path of readonly IAM role" + type = string + default = "/" +} + +variable "readonly_role_policy_arns" { + description = "List of policy ARNs to use for readonly role" + type = list(string) + default = ["arn:aws:iam::aws:policy/ReadOnlyAccess"] +} + +variable "readonly_role_permissions_boundary_arn" { + description = "Permissions boundary ARN to use for readonly role" + type = string + default = "" +} + +variable "readonly_role_tags" { + description = "A map of tags to add to readonly role resource." + type = map(string) + default = {} +} + +variable "max_session_duration" { + description = "Maximum CLI/API session duration in seconds between 3600 and 43200" + type = number + default = 3600 +} + +variable "force_detach_policies" { + description = "Whether policies should be detached from this role when destroying" + type = bool + default = false +} diff --git a/modules/aws-iam/modules/iam-assumable-roles-with-saml/versions.tf b/modules/aws-iam/modules/iam-assumable-roles-with-saml/versions.tf new file mode 100644 index 0000000..d8dd1a4 --- /dev/null +++ b/modules/aws-iam/modules/iam-assumable-roles-with-saml/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.0" + } + } +} diff --git a/modules/aws-iam/modules/iam-assumable-roles/README.md b/modules/aws-iam/modules/iam-assumable-roles/README.md new file mode 100644 index 0000000..5facdd0 --- /dev/null +++ b/modules/aws-iam/modules/iam-assumable-roles/README.md @@ -0,0 +1,87 @@ +# iam-assumable-roles + +Creates predefined IAM roles (admin, poweruser and readonly) which can be assumed by trusted resources. + +Trusted resources can be any [IAM ARNs](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html#identifiers-arns) - typically, AWS accounts and users. + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.0 | +| [aws](#requirement\_aws) | >= 4.0 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 4.0 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_iam_role.admin](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | +| [aws_iam_role.poweruser](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | +| [aws_iam_role.readonly](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | +| [aws_iam_role_policy_attachment.admin](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_iam_role_policy_attachment.poweruser](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_iam_role_policy_attachment.readonly](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_iam_policy_document.assume_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.assume_role_with_mfa](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [admin\_role\_name](#input\_admin\_role\_name) | IAM role with admin access | `string` | `"admin"` | no | +| [admin\_role\_path](#input\_admin\_role\_path) | Path of admin IAM role | `string` | `"/"` | no | +| [admin\_role\_permissions\_boundary\_arn](#input\_admin\_role\_permissions\_boundary\_arn) | Permissions boundary ARN to use for admin role | `string` | `""` | no | +| [admin\_role\_policy\_arns](#input\_admin\_role\_policy\_arns) | List of policy ARNs to use for admin role | `list(string)` |
"arn:aws:iam::aws:policy/ReadOnlyAccess"
]
[| no | +| [admin\_role\_requires\_mfa](#input\_admin\_role\_requires\_mfa) | Whether admin role requires MFA | `bool` | `true` | no | +| [admin\_role\_tags](#input\_admin\_role\_tags) | A map of tags to add to admin role resource. | `map(string)` | `{}` | no | +| [create\_admin\_role](#input\_create\_admin\_role) | Whether to create admin role | `bool` | `false` | no | +| [create\_poweruser\_role](#input\_create\_poweruser\_role) | Whether to create poweruser role | `bool` | `false` | no | +| [create\_readonly\_role](#input\_create\_readonly\_role) | Whether to create readonly role | `bool` | `false` | no | +| [force\_detach\_policies](#input\_force\_detach\_policies) | Whether policies should be detached from this role when destroying | `bool` | `false` | no | +| [max\_session\_duration](#input\_max\_session\_duration) | Maximum CLI/API session duration in seconds between 3600 and 43200 | `number` | `3600` | no | +| [mfa\_age](#input\_mfa\_age) | Max age of valid MFA (in seconds) for roles which require MFA | `number` | `86400` | no | +| [poweruser\_role\_name](#input\_poweruser\_role\_name) | IAM role with poweruser access | `string` | `"poweruser"` | no | +| [poweruser\_role\_path](#input\_poweruser\_role\_path) | Path of poweruser IAM role | `string` | `"/"` | no | +| [poweruser\_role\_permissions\_boundary\_arn](#input\_poweruser\_role\_permissions\_boundary\_arn) | Permissions boundary ARN to use for poweruser role | `string` | `""` | no | +| [poweruser\_role\_policy\_arns](#input\_poweruser\_role\_policy\_arns) | List of policy ARNs to use for poweruser role | `list(string)` |
"arn:aws:iam::aws:policy/AdministratorAccess"
]
[| no | +| [poweruser\_role\_requires\_mfa](#input\_poweruser\_role\_requires\_mfa) | Whether poweruser role requires MFA | `bool` | `true` | no | +| [poweruser\_role\_tags](#input\_poweruser\_role\_tags) | A map of tags to add to poweruser role resource. | `map(string)` | `{}` | no | +| [readonly\_role\_name](#input\_readonly\_role\_name) | IAM role with readonly access | `string` | `"readonly"` | no | +| [readonly\_role\_path](#input\_readonly\_role\_path) | Path of readonly IAM role | `string` | `"/"` | no | +| [readonly\_role\_permissions\_boundary\_arn](#input\_readonly\_role\_permissions\_boundary\_arn) | Permissions boundary ARN to use for readonly role | `string` | `""` | no | +| [readonly\_role\_policy\_arns](#input\_readonly\_role\_policy\_arns) | List of policy ARNs to use for readonly role | `list(string)` |
"arn:aws:iam::aws:policy/PowerUserAccess"
]
[| no | +| [readonly\_role\_requires\_mfa](#input\_readonly\_role\_requires\_mfa) | Whether readonly role requires MFA | `bool` | `true` | no | +| [readonly\_role\_tags](#input\_readonly\_role\_tags) | A map of tags to add to readonly role resource. | `map(string)` | `{}` | no | +| [trusted\_role\_arns](#input\_trusted\_role\_arns) | ARNs of AWS entities who can assume these roles | `list(string)` | `[]` | no | +| [trusted\_role\_services](#input\_trusted\_role\_services) | AWS Services that can assume these roles | `list(string)` | `[]` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [admin\_iam\_role\_arn](#output\_admin\_iam\_role\_arn) | ARN of admin IAM role | +| [admin\_iam\_role\_name](#output\_admin\_iam\_role\_name) | Name of admin IAM role | +| [admin\_iam\_role\_path](#output\_admin\_iam\_role\_path) | Path of admin IAM role | +| [admin\_iam\_role\_requires\_mfa](#output\_admin\_iam\_role\_requires\_mfa) | Whether admin IAM role requires MFA | +| [admin\_iam\_role\_unique\_id](#output\_admin\_iam\_role\_unique\_id) | Unique ID of IAM role | +| [poweruser\_iam\_role\_arn](#output\_poweruser\_iam\_role\_arn) | ARN of poweruser IAM role | +| [poweruser\_iam\_role\_name](#output\_poweruser\_iam\_role\_name) | Name of poweruser IAM role | +| [poweruser\_iam\_role\_path](#output\_poweruser\_iam\_role\_path) | Path of poweruser IAM role | +| [poweruser\_iam\_role\_requires\_mfa](#output\_poweruser\_iam\_role\_requires\_mfa) | Whether poweruser IAM role requires MFA | +| [poweruser\_iam\_role\_unique\_id](#output\_poweruser\_iam\_role\_unique\_id) | Unique ID of IAM role | +| [readonly\_iam\_role\_arn](#output\_readonly\_iam\_role\_arn) | ARN of readonly IAM role | +| [readonly\_iam\_role\_name](#output\_readonly\_iam\_role\_name) | Name of readonly IAM role | +| [readonly\_iam\_role\_path](#output\_readonly\_iam\_role\_path) | Path of readonly IAM role | +| [readonly\_iam\_role\_requires\_mfa](#output\_readonly\_iam\_role\_requires\_mfa) | Whether readonly IAM role requires MFA | +| [readonly\_iam\_role\_unique\_id](#output\_readonly\_iam\_role\_unique\_id) | Unique ID of IAM role | diff --git a/modules/aws-iam/modules/iam-assumable-roles/main.tf b/modules/aws-iam/modules/iam-assumable-roles/main.tf new file mode 100644 index 0000000..c0d935d --- /dev/null +++ b/modules/aws-iam/modules/iam-assumable-roles/main.tf @@ -0,0 +1,116 @@ +data "aws_iam_policy_document" "assume_role" { + statement { + effect = "Allow" + + actions = ["sts:AssumeRole"] + + principals { + type = "AWS" + identifiers = var.trusted_role_arns + } + + principals { + type = "Service" + identifiers = var.trusted_role_services + } + } +} + +data "aws_iam_policy_document" "assume_role_with_mfa" { + statement { + effect = "Allow" + + actions = ["sts:AssumeRole"] + + principals { + type = "AWS" + identifiers = var.trusted_role_arns + } + + principals { + type = "Service" + identifiers = var.trusted_role_services + } + + condition { + test = "Bool" + variable = "aws:MultiFactorAuthPresent" + values = ["true"] + } + + condition { + test = "NumericLessThan" + variable = "aws:MultiFactorAuthAge" + values = [var.mfa_age] + } + } +} + +# Admin +resource "aws_iam_role" "admin" { + count = var.create_admin_role ? 1 : 0 + + name = var.admin_role_name + path = var.admin_role_path + max_session_duration = var.max_session_duration + + force_detach_policies = var.force_detach_policies + permissions_boundary = var.admin_role_permissions_boundary_arn + + assume_role_policy = var.admin_role_requires_mfa ? data.aws_iam_policy_document.assume_role_with_mfa.json : data.aws_iam_policy_document.assume_role.json + + tags = var.admin_role_tags +} + +resource "aws_iam_role_policy_attachment" "admin" { + count = var.create_admin_role ? length(var.admin_role_policy_arns) : 0 + + role = aws_iam_role.admin[0].name + policy_arn = element(var.admin_role_policy_arns, count.index) +} + +# Poweruser +resource "aws_iam_role" "poweruser" { + count = var.create_poweruser_role ? 1 : 0 + + name = var.poweruser_role_name + path = var.poweruser_role_path + max_session_duration = var.max_session_duration + + force_detach_policies = var.force_detach_policies + permissions_boundary = var.poweruser_role_permissions_boundary_arn + + assume_role_policy = var.poweruser_role_requires_mfa ? data.aws_iam_policy_document.assume_role_with_mfa.json : data.aws_iam_policy_document.assume_role.json + + tags = var.poweruser_role_tags +} + +resource "aws_iam_role_policy_attachment" "poweruser" { + count = var.create_poweruser_role ? length(var.poweruser_role_policy_arns) : 0 + + role = aws_iam_role.poweruser[0].name + policy_arn = element(var.poweruser_role_policy_arns, count.index) +} + +# Readonly +resource "aws_iam_role" "readonly" { + count = var.create_readonly_role ? 1 : 0 + + name = var.readonly_role_name + path = var.readonly_role_path + max_session_duration = var.max_session_duration + + force_detach_policies = var.force_detach_policies + permissions_boundary = var.readonly_role_permissions_boundary_arn + + assume_role_policy = var.readonly_role_requires_mfa ? data.aws_iam_policy_document.assume_role_with_mfa.json : data.aws_iam_policy_document.assume_role.json + + tags = var.readonly_role_tags +} + +resource "aws_iam_role_policy_attachment" "readonly" { + count = var.create_readonly_role ? length(var.readonly_role_policy_arns) : 0 + + role = aws_iam_role.readonly[0].name + policy_arn = element(var.readonly_role_policy_arns, count.index) +} diff --git a/modules/aws-iam/modules/iam-assumable-roles/outputs.tf b/modules/aws-iam/modules/iam-assumable-roles/outputs.tf new file mode 100644 index 0000000..5918ba4 --- /dev/null +++ b/modules/aws-iam/modules/iam-assumable-roles/outputs.tf @@ -0,0 +1,77 @@ +#Admin +output "admin_iam_role_arn" { + description = "ARN of admin IAM role" + value = try(aws_iam_role.admin[0].arn, "") +} + +output "admin_iam_role_name" { + description = "Name of admin IAM role" + value = try(aws_iam_role.admin[0].name, "") +} + +output "admin_iam_role_path" { + description = "Path of admin IAM role" + value = try(aws_iam_role.admin[0].path, "") +} + +output "admin_iam_role_unique_id" { + description = "Unique ID of IAM role" + value = try(aws_iam_role.admin[0].unique_id, "") +} + +output "admin_iam_role_requires_mfa" { + description = "Whether admin IAM role requires MFA" + value = var.admin_role_requires_mfa +} + +# Poweruser +output "poweruser_iam_role_arn" { + description = "ARN of poweruser IAM role" + value = try(aws_iam_role.poweruser[0].arn, "") +} + +output "poweruser_iam_role_name" { + description = "Name of poweruser IAM role" + value = try(aws_iam_role.poweruser[0].name, "") +} + +output "poweruser_iam_role_path" { + description = "Path of poweruser IAM role" + value = try(aws_iam_role.poweruser[0].path, "") +} + +output "poweruser_iam_role_unique_id" { + description = "Unique ID of IAM role" + value = try(aws_iam_role.poweruser[0].unique_id, "") +} + +output "poweruser_iam_role_requires_mfa" { + description = "Whether poweruser IAM role requires MFA" + value = var.poweruser_role_requires_mfa +} + +# Readonly +output "readonly_iam_role_arn" { + description = "ARN of readonly IAM role" + value = try(aws_iam_role.readonly[0].arn, "") +} + +output "readonly_iam_role_name" { + description = "Name of readonly IAM role" + value = try(aws_iam_role.readonly[0].name, "") +} + +output "readonly_iam_role_path" { + description = "Path of readonly IAM role" + value = try(aws_iam_role.readonly[0].path, "") +} + +output "readonly_iam_role_unique_id" { + description = "Unique ID of IAM role" + value = try(aws_iam_role.readonly[0].unique_id, "") +} + +output "readonly_iam_role_requires_mfa" { + description = "Whether readonly IAM role requires MFA" + value = var.readonly_role_requires_mfa +} diff --git a/modules/aws-iam/modules/iam-assumable-roles/variables.tf b/modules/aws-iam/modules/iam-assumable-roles/variables.tf new file mode 100644 index 0000000..f824502 --- /dev/null +++ b/modules/aws-iam/modules/iam-assumable-roles/variables.tf @@ -0,0 +1,158 @@ +variable "trusted_role_arns" { + description = "ARNs of AWS entities who can assume these roles" + type = list(string) + default = [] +} + +variable "trusted_role_services" { + description = "AWS Services that can assume these roles" + type = list(string) + default = [] +} + +variable "mfa_age" { + description = "Max age of valid MFA (in seconds) for roles which require MFA" + type = number + default = 86400 +} + +# Admin +variable "create_admin_role" { + description = "Whether to create admin role" + type = bool + default = false +} + +variable "admin_role_name" { + description = "IAM role with admin access" + type = string + default = "admin" +} + +variable "admin_role_path" { + description = "Path of admin IAM role" + type = string + default = "/" +} + +variable "admin_role_requires_mfa" { + description = "Whether admin role requires MFA" + type = bool + default = true +} + +variable "admin_role_policy_arns" { + description = "List of policy ARNs to use for admin role" + type = list(string) + default = ["arn:aws:iam::aws:policy/AdministratorAccess"] +} + +variable "admin_role_permissions_boundary_arn" { + description = "Permissions boundary ARN to use for admin role" + type = string + default = "" +} + +variable "admin_role_tags" { + description = "A map of tags to add to admin role resource." + type = map(string) + default = {} +} + +# Poweruser +variable "create_poweruser_role" { + description = "Whether to create poweruser role" + type = bool + default = false +} + +variable "poweruser_role_name" { + description = "IAM role with poweruser access" + type = string + default = "poweruser" +} + +variable "poweruser_role_path" { + description = "Path of poweruser IAM role" + type = string + default = "/" +} + +variable "poweruser_role_requires_mfa" { + description = "Whether poweruser role requires MFA" + type = bool + default = true +} + +variable "poweruser_role_policy_arns" { + description = "List of policy ARNs to use for poweruser role" + type = list(string) + default = ["arn:aws:iam::aws:policy/PowerUserAccess"] +} + +variable "poweruser_role_permissions_boundary_arn" { + description = "Permissions boundary ARN to use for poweruser role" + type = string + default = "" +} + +variable "poweruser_role_tags" { + description = "A map of tags to add to poweruser role resource." + type = map(string) + default = {} +} + +# Readonly +variable "create_readonly_role" { + description = "Whether to create readonly role" + type = bool + default = false +} + +variable "readonly_role_name" { + description = "IAM role with readonly access" + type = string + default = "readonly" +} + +variable "readonly_role_path" { + description = "Path of readonly IAM role" + type = string + default = "/" +} + +variable "readonly_role_requires_mfa" { + description = "Whether readonly role requires MFA" + type = bool + default = true +} + +variable "readonly_role_policy_arns" { + description = "List of policy ARNs to use for readonly role" + type = list(string) + default = ["arn:aws:iam::aws:policy/ReadOnlyAccess"] +} + +variable "readonly_role_permissions_boundary_arn" { + description = "Permissions boundary ARN to use for readonly role" + type = string + default = "" +} + +variable "readonly_role_tags" { + description = "A map of tags to add to readonly role resource." + type = map(string) + default = {} +} + +variable "max_session_duration" { + description = "Maximum CLI/API session duration in seconds between 3600 and 43200" + type = number + default = 3600 +} + +variable "force_detach_policies" { + description = "Whether policies should be detached from this role when destroying" + type = bool + default = false +} diff --git a/modules/aws-iam/modules/iam-assumable-roles/versions.tf b/modules/aws-iam/modules/iam-assumable-roles/versions.tf new file mode 100644 index 0000000..d8dd1a4 --- /dev/null +++ b/modules/aws-iam/modules/iam-assumable-roles/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.0" + } + } +} diff --git a/modules/aws-iam/modules/iam-eks-role/README.md b/modules/aws-iam/modules/iam-eks-role/README.md new file mode 100644 index 0000000..1e0a22f --- /dev/null +++ b/modules/aws-iam/modules/iam-eks-role/README.md @@ -0,0 +1,129 @@ +# iam-eks-role + +Creates an IAM role that can be assumed by one or more EKS `ServiceAccount` in one or more EKS clusters. Unlike [iam-assumable-role-with-oidc](https://github.com/kloia/platform-modules/tree/main/terraform-aws-iam/modules/iam-assumable-role-with-oidc/), this module: + +- Does not require any knowledge of cluster OIDC information as `data` resources are used +- Supports assuming the role from multiple EKS clusters, for example used in DR or when a workload is spread across clusters +- Support multiple `ServiceAccount` in the same cluster, for example when a workload runs in multiple namespaces +- More suitable for non-cluster admins as implementation is simpler +- More suitable for when the IAM role and cluster resources are in separate Terraform configurations + +This module is for use with AWS EKS. For details of how a `ServiceAccount` in EKS can assume an IAM role, see the [EKS documentation](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html). + +Implementation notes: + +- The EKS cluster needs to exist first, in the current AWS account and region +- The key in the `cluster_service_accounts` is the exact name of the EKS cluster + +## Basic example + +To create an IAM role named `my-app` that can be assumed in EKS cluster `cluster1` by a `ServiceAccount` called `my-serviceaccount` in the `default` namespace: + +```hcl +module "iam_eks_role" { + source = "terraform-aws-modules/iam/aws//modules/iam-eks-role" + + role_name = "my-app" + + cluster_service_accounts = { + "cluster1" = ["default:my-serviceaccount"] + } +} +``` + +## Multi cluster example: + +To create an IAM role named `my-app` that can be assumed from: + +- EKS cluster `staging-main-1`, namespace `default`, `ServiceAccount` called `my-app-staging` +- EKS cluster `staging-backup-1`, namespace `default`, `ServiceAccount` called `my-app-staging` + +```hcl +module "iam_eks_role" { + source = "terraform-aws-modules/iam/aws//modules/iam-eks-role" + + role_name = "my-app" + + cluster_service_accounts = { + "staging-main-1" = ["default:my-app-staging"] + "staging-backup-1" = ["default:my-app-staging"] + } +} +``` + +## Multi `ServiceAccount` example + +To create an IAM role named `cloudwatch-exporter` that can be assumed in EKS cluster `production-main-1` from: + +- namespace `kube-system`, `ServiceAccount` called `cloudwatch-exporter` +- namespace `app1`, `ServiceAccount` called `cloudwatch-exporter` + +```hcl +module "iam_eks_role" { + source = "terraform-aws-modules/iam/aws//modules/iam-eks-role" + + role_name = "my-app" + + cluster_service_accounts = { + "production-main-1" = [ + "kube-system:cloudwatch-exporter", + "app1:cloudwatch-exporter", + ] + } +} +``` + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.0 | +| [aws](#requirement\_aws) | >= 4.0 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 4.0 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_iam_role.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | +| [aws_iam_role_policy_attachment.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source | +| [aws_eks_cluster.main](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/eks_cluster) | data source | +| [aws_iam_policy_document.assume_role_with_oidc](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_partition.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/partition) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [cluster\_service\_accounts](#input\_cluster\_service\_accounts) | EKS cluster and k8s ServiceAccount pairs. Each EKS cluster can have multiple k8s ServiceAccount. See README for details | `map(list(string))` | `{}` | no | +| [create\_role](#input\_create\_role) | Whether to create a role | `bool` | `true` | no | +| [force\_detach\_policies](#input\_force\_detach\_policies) | Whether policies should be detached from this role when destroying | `bool` | `false` | no | +| [max\_session\_duration](#input\_max\_session\_duration) | Maximum CLI/API session duration in seconds between 3600 and 43200 | `number` | `43200` | no | +| [role\_description](#input\_role\_description) | IAM Role description | `string` | `""` | no | +| [role\_name](#input\_role\_name) | Name of IAM role | `string` | `null` | no | +| [role\_name\_prefix](#input\_role\_name\_prefix) | IAM role name prefix | `string` | `null` | no | +| [role\_path](#input\_role\_path) | Path of IAM role | `string` | `"/"` | no | +| [role\_permissions\_boundary\_arn](#input\_role\_permissions\_boundary\_arn) | Permissions boundary ARN to use for IAM role | `string` | `""` | no | +| [role\_policy\_arns](#input\_role\_policy\_arns) | ARNs of any policies to attach to the IAM role | `map(string)` | `{}` | no | +| [tags](#input\_tags) | A map of tags to add the the IAM role | `map(any)` | `{}` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [iam\_role\_arn](#output\_iam\_role\_arn) | ARN of IAM role | +| [iam\_role\_name](#output\_iam\_role\_name) | Name of IAM role | +| [iam\_role\_path](#output\_iam\_role\_path) | Path of IAM role | +| [iam\_role\_unique\_id](#output\_iam\_role\_unique\_id) | Unique ID of IAM role | + diff --git a/modules/aws-iam/modules/iam-eks-role/main.tf b/modules/aws-iam/modules/iam-eks-role/main.tf new file mode 100644 index 0000000..31dac45 --- /dev/null +++ b/modules/aws-iam/modules/iam-eks-role/main.tf @@ -0,0 +1,56 @@ +data "aws_caller_identity" "current" {} + +data "aws_partition" "current" {} + +data "aws_eks_cluster" "main" { + for_each = var.cluster_service_accounts + + name = each.key +} + +data "aws_iam_policy_document" "assume_role_with_oidc" { + dynamic "statement" { + for_each = var.cluster_service_accounts + + content { + effect = "Allow" + + actions = ["sts:AssumeRoleWithWebIdentity"] + + principals { + type = "Federated" + + identifiers = [ + "arn:${data.aws_partition.current.partition}:iam::${data.aws_caller_identity.current.account_id}:oidc-provider/${replace(data.aws_eks_cluster.main[statement.key].identity[0].oidc[0].issuer, "https://", "")}" + ] + } + + condition { + test = "StringEquals" + variable = "${replace(data.aws_eks_cluster.main[statement.key].identity[0].oidc[0].issuer, "https://", "")}:sub" + values = [for s in statement.value : "system:serviceaccount:${s}"] + } + } + } +} + +resource "aws_iam_role" "this" { + count = var.create_role ? 1 : 0 + + assume_role_policy = data.aws_iam_policy_document.assume_role_with_oidc.json + description = var.role_description + force_detach_policies = var.force_detach_policies + max_session_duration = var.max_session_duration + name = var.role_name + name_prefix = var.role_name_prefix + path = var.role_path + permissions_boundary = var.role_permissions_boundary_arn + tags = var.tags +} + +resource "aws_iam_role_policy_attachment" "this" { + for_each = { for k, v in var.role_policy_arns : k => v if var.create_role } + + role = aws_iam_role.this[0].name + policy_arn = each.value +} diff --git a/modules/aws-iam/modules/iam-eks-role/outputs.tf b/modules/aws-iam/modules/iam-eks-role/outputs.tf new file mode 100644 index 0000000..a680531 --- /dev/null +++ b/modules/aws-iam/modules/iam-eks-role/outputs.tf @@ -0,0 +1,19 @@ +output "iam_role_arn" { + description = "ARN of IAM role" + value = try(aws_iam_role.this[0].arn, "") +} + +output "iam_role_name" { + description = "Name of IAM role" + value = try(aws_iam_role.this[0].name, "") +} + +output "iam_role_path" { + description = "Path of IAM role" + value = try(aws_iam_role.this[0].path, "") +} + +output "iam_role_unique_id" { + description = "Unique ID of IAM role" + value = try(aws_iam_role.this[0].unique_id, "") +} diff --git a/modules/aws-iam/modules/iam-eks-role/variables.tf b/modules/aws-iam/modules/iam-eks-role/variables.tf new file mode 100644 index 0000000..5f69d75 --- /dev/null +++ b/modules/aws-iam/modules/iam-eks-role/variables.tf @@ -0,0 +1,65 @@ +variable "create_role" { + description = "Whether to create a role" + type = bool + default = true +} + +variable "role_name" { + description = "Name of IAM role" + type = string + default = null +} + +variable "role_path" { + description = "Path of IAM role" + type = string + default = "/" +} + +variable "role_permissions_boundary_arn" { + description = "Permissions boundary ARN to use for IAM role" + type = string + default = "" +} + +variable "role_description" { + description = "IAM Role description" + type = string + default = "" +} + +variable "role_name_prefix" { + description = "IAM role name prefix" + type = string + default = null +} + +variable "role_policy_arns" { + description = "ARNs of any policies to attach to the IAM role" + type = map(string) + default = {} +} + +variable "cluster_service_accounts" { + description = "EKS cluster and k8s ServiceAccount pairs. Each EKS cluster can have multiple k8s ServiceAccount. See README for details" + type = map(list(string)) + default = {} +} + +variable "tags" { + description = "A map of tags to add the the IAM role" + type = map(any) + default = {} +} + +variable "force_detach_policies" { + description = "Whether policies should be detached from this role when destroying" + type = bool + default = false +} + +variable "max_session_duration" { + description = "Maximum CLI/API session duration in seconds between 3600 and 43200" + type = number + default = 43200 +} diff --git a/modules/aws-iam/modules/iam-eks-role/versions.tf b/modules/aws-iam/modules/iam-eks-role/versions.tf new file mode 100644 index 0000000..d8dd1a4 --- /dev/null +++ b/modules/aws-iam/modules/iam-eks-role/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.0" + } + } +} diff --git a/modules/aws-iam/modules/iam-group-with-assumable-roles-policy/README.md b/modules/aws-iam/modules/iam-group-with-assumable-roles-policy/README.md new file mode 100644 index 0000000..fecc7a5 --- /dev/null +++ b/modules/aws-iam/modules/iam-group-with-assumable-roles-policy/README.md @@ -0,0 +1,51 @@ +# iam-group-with-assumable-roles-policy + +Creates IAM group with users who are allowed to assume IAM roles. This is typically done in resource AWS account where IAM users can jump into from IAM AWS account. + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.0 | +| [aws](#requirement\_aws) | >= 4.0 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 4.0 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_iam_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_group) | resource | +| [aws_iam_group_membership.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_group_membership) | resource | +| [aws_iam_group_policy_attachment.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_group_policy_attachment) | resource | +| [aws_iam_policy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | +| [aws_iam_policy_document.assume_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [assumable\_roles](#input\_assumable\_roles) | List of IAM roles ARNs which can be assumed by the group | `list(string)` | `[]` | no | +| [group\_users](#input\_group\_users) | List of IAM users to have in an IAM group which can assume the role | `list(string)` | `[]` | no | +| [name](#input\_name) | Name of IAM policy and IAM group | `string` | n/a | yes | +| [tags](#input\_tags) | A map of tags to add to all resources. | `map(string)` | `{}` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [assumable\_roles](#output\_assumable\_roles) | List of ARNs of IAM roles which members of IAM group can assume | +| [group\_arn](#output\_group\_arn) | IAM group arn | +| [group\_name](#output\_group\_name) | IAM group name | +| [group\_users](#output\_group\_users) | List of IAM users in IAM group | +| [policy\_arn](#output\_policy\_arn) | Assume role policy ARN of IAM group | + diff --git a/modules/aws-iam/modules/iam-group-with-assumable-roles-policy/main.tf b/modules/aws-iam/modules/iam-group-with-assumable-roles-policy/main.tf new file mode 100644 index 0000000..f17e738 --- /dev/null +++ b/modules/aws-iam/modules/iam-group-with-assumable-roles-policy/main.tf @@ -0,0 +1,32 @@ +data "aws_iam_policy_document" "assume_role" { + statement { + effect = "Allow" + actions = ["sts:AssumeRole"] + resources = var.assumable_roles + } +} + +resource "aws_iam_policy" "this" { + name = var.name + description = "Allows to assume role in another AWS account" + policy = data.aws_iam_policy_document.assume_role.json + + tags = var.tags +} + +resource "aws_iam_group" "this" { + name = var.name +} + +resource "aws_iam_group_policy_attachment" "this" { + group = aws_iam_group.this.id + policy_arn = aws_iam_policy.this.id +} + +resource "aws_iam_group_membership" "this" { + count = length(var.group_users) > 0 ? 1 : 0 + + group = aws_iam_group.this.id + name = var.name + users = var.group_users +} diff --git a/modules/aws-iam/modules/iam-group-with-assumable-roles-policy/outputs.tf b/modules/aws-iam/modules/iam-group-with-assumable-roles-policy/outputs.tf new file mode 100644 index 0000000..a172a66 --- /dev/null +++ b/modules/aws-iam/modules/iam-group-with-assumable-roles-policy/outputs.tf @@ -0,0 +1,24 @@ +output "group_users" { + description = "List of IAM users in IAM group" + value = flatten(aws_iam_group_membership.this[*].users) +} + +output "assumable_roles" { + description = "List of ARNs of IAM roles which members of IAM group can assume" + value = var.assumable_roles +} + +output "policy_arn" { + description = "Assume role policy ARN of IAM group" + value = aws_iam_policy.this.arn +} + +output "group_name" { + description = "IAM group name" + value = aws_iam_group.this.name +} + +output "group_arn" { + description = "IAM group arn" + value = aws_iam_group.this.arn +} diff --git a/modules/aws-iam/modules/iam-group-with-assumable-roles-policy/variables.tf b/modules/aws-iam/modules/iam-group-with-assumable-roles-policy/variables.tf new file mode 100644 index 0000000..3cc3a6d --- /dev/null +++ b/modules/aws-iam/modules/iam-group-with-assumable-roles-policy/variables.tf @@ -0,0 +1,22 @@ +variable "name" { + description = "Name of IAM policy and IAM group" + type = string +} + +variable "assumable_roles" { + description = "List of IAM roles ARNs which can be assumed by the group" + type = list(string) + default = [] +} + +variable "group_users" { + description = "List of IAM users to have in an IAM group which can assume the role" + type = list(string) + default = [] +} + +variable "tags" { + description = "A map of tags to add to all resources." + type = map(string) + default = {} +} diff --git a/modules/aws-iam/modules/iam-group-with-assumable-roles-policy/versions.tf b/modules/aws-iam/modules/iam-group-with-assumable-roles-policy/versions.tf new file mode 100644 index 0000000..d8dd1a4 --- /dev/null +++ b/modules/aws-iam/modules/iam-group-with-assumable-roles-policy/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.0" + } + } +} diff --git a/modules/aws-iam/modules/iam-group-with-policies/README.md b/modules/aws-iam/modules/iam-group-with-policies/README.md new file mode 100644 index 0000000..683f11d --- /dev/null +++ b/modules/aws-iam/modules/iam-group-with-policies/README.md @@ -0,0 +1,60 @@ +# iam-group-with-policies + +Creates IAM group with specified IAM policies, and add users into a group. + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.0 | +| [aws](#requirement\_aws) | >= 4.0 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 4.0 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_iam_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_group) | resource | +| [aws_iam_group_membership.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_group_membership) | resource | +| [aws_iam_group_policy_attachment.custom](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_group_policy_attachment) | resource | +| [aws_iam_group_policy_attachment.custom_arns](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_group_policy_attachment) | resource | +| [aws_iam_group_policy_attachment.iam_self_management](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_group_policy_attachment) | resource | +| [aws_iam_policy.custom](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | +| [aws_iam_policy.iam_self_management](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | +| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source | +| [aws_iam_policy_document.iam_self_management](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_partition.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/partition) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [attach\_iam\_self\_management\_policy](#input\_attach\_iam\_self\_management\_policy) | Whether to attach IAM policy which allows IAM users to manage their credentials and MFA | `bool` | `true` | no | +| [aws\_account\_id](#input\_aws\_account\_id) | AWS account id to use inside IAM policies. If empty, current AWS account ID will be used. | `string` | `""` | no | +| [create\_group](#input\_create\_group) | Whether to create IAM group | `bool` | `true` | no | +| [custom\_group\_policies](#input\_custom\_group\_policies) | List of maps of inline IAM policies to attach to IAM group. Should have `name` and `policy` keys in each element. | `list(map(string))` | `[]` | no | +| [custom\_group\_policy\_arns](#input\_custom\_group\_policy\_arns) | List of IAM policies ARNs to attach to IAM group | `list(string)` | `[]` | no | +| [group\_users](#input\_group\_users) | List of IAM users to have in an IAM group which can assume the role | `list(string)` | `[]` | no | +| [iam\_self\_management\_policy\_name\_prefix](#input\_iam\_self\_management\_policy\_name\_prefix) | Name prefix for IAM policy to create with IAM self-management permissions | `string` | `"IAMSelfManagement-"` | no | +| [name](#input\_name) | Name of IAM group | `string` | `""` | no | +| [tags](#input\_tags) | A map of tags to add to all resources. | `map(string)` | `{}` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [aws\_account\_id](#output\_aws\_account\_id) | IAM AWS account id | +| [group\_arn](#output\_group\_arn) | IAM group arn | +| [group\_name](#output\_group\_name) | IAM group name | +| [group\_users](#output\_group\_users) | List of IAM users in IAM group | + diff --git a/modules/aws-iam/modules/iam-group-with-policies/main.tf b/modules/aws-iam/modules/iam-group-with-policies/main.tf new file mode 100644 index 0000000..00571a9 --- /dev/null +++ b/modules/aws-iam/modules/iam-group-with-policies/main.tf @@ -0,0 +1,63 @@ +locals { + group_name = element(concat(aws_iam_group.this.*.id, [var.name]), 0) +} + +resource "aws_iam_group" "this" { + count = var.create_group ? 1 : 0 + + name = var.name +} + +resource "aws_iam_group_membership" "this" { + count = length(var.group_users) > 0 ? 1 : 0 + + group = local.group_name + name = var.name + users = var.group_users +} + +################################ +# IAM group policy attachements +################################ +resource "aws_iam_group_policy_attachment" "iam_self_management" { + count = var.attach_iam_self_management_policy ? 1 : 0 + + group = local.group_name + policy_arn = aws_iam_policy.iam_self_management[0].arn +} + +resource "aws_iam_group_policy_attachment" "custom_arns" { + count = length(var.custom_group_policy_arns) + + group = local.group_name + policy_arn = element(var.custom_group_policy_arns, count.index) +} + +resource "aws_iam_group_policy_attachment" "custom" { + count = length(var.custom_group_policies) + + group = local.group_name + policy_arn = element(aws_iam_policy.custom.*.arn, count.index) +} + +############### +# IAM policies +############### +resource "aws_iam_policy" "iam_self_management" { + count = var.attach_iam_self_management_policy ? 1 : 0 + + name_prefix = var.iam_self_management_policy_name_prefix + policy = data.aws_iam_policy_document.iam_self_management.json + + tags = var.tags +} + +resource "aws_iam_policy" "custom" { + count = length(var.custom_group_policies) + + name = var.custom_group_policies[count.index]["name"] + policy = var.custom_group_policies[count.index]["policy"] + description = lookup(var.custom_group_policies[count.index], "description", null) + + tags = var.tags +} diff --git a/modules/aws-iam/modules/iam-group-with-policies/outputs.tf b/modules/aws-iam/modules/iam-group-with-policies/outputs.tf new file mode 100644 index 0000000..ee0835c --- /dev/null +++ b/modules/aws-iam/modules/iam-group-with-policies/outputs.tf @@ -0,0 +1,19 @@ +output "aws_account_id" { + description = "IAM AWS account id" + value = local.aws_account_id +} + +output "group_arn" { + description = "IAM group arn" + value = try(aws_iam_group.this[0].arn, "") +} + +output "group_users" { + description = "List of IAM users in IAM group" + value = flatten(aws_iam_group_membership.this[*].users) +} + +output "group_name" { + description = "IAM group name" + value = try(aws_iam_group.this[0].name, var.name) +} diff --git a/modules/aws-iam/modules/iam-group-with-policies/policies.tf b/modules/aws-iam/modules/iam-group-with-policies/policies.tf new file mode 100644 index 0000000..537b19c --- /dev/null +++ b/modules/aws-iam/modules/iam-group-with-policies/policies.tf @@ -0,0 +1,93 @@ +data "aws_caller_identity" "current" { + count = var.aws_account_id == "" ? 1 : 0 +} + +data "aws_partition" "current" {} + +locals { + aws_account_id = element( + concat( + data.aws_caller_identity.current.*.account_id, + [var.aws_account_id], + ), + 0, + ) +} + +data "aws_iam_policy_document" "iam_self_management" { + statement { + sid = "AllowSelfManagement" + + effect = "Allow" + + actions = [ + "iam:ChangePassword", + "iam:CreateAccessKey", + "iam:CreateLoginProfile", + "iam:CreateVirtualMFADevice", + "iam:DeleteAccessKey", + "iam:DeleteLoginProfile", + "iam:DeleteVirtualMFADevice", + "iam:EnableMFADevice", + "iam:GenerateCredentialReport", + "iam:GenerateServiceLastAccessedDetails", + "iam:Get*", + "iam:List*", + "iam:ResyncMFADevice", + "iam:UpdateAccessKey", + "iam:UpdateLoginProfile", + "iam:UpdateUser", + "iam:UploadSigningCertificate", + "iam:UploadSSHPublicKey", + ] + + # Allow for both users with "path" and without it + resources = [ + "arn:${data.aws_partition.current.partition}:iam::${local.aws_account_id}:user/*/$${aws:username}", + "arn:${data.aws_partition.current.partition}:iam::${local.aws_account_id}:user/$${aws:username}", + "arn:${data.aws_partition.current.partition}:iam::${local.aws_account_id}:mfa/$${aws:username}", + ] + } + + statement { + sid = "AllowIAMReadOnly" + + actions = [ + "iam:Get*", + "iam:List*", + ] + + resources = ["*"] + effect = "Allow" + } + + # Allow to deactivate MFA only when logging in with MFA + statement { + sid = "AllowDeactivateMFADevice" + + effect = "Allow" + + actions = [ + "iam:DeactivateMFADevice", + ] + + # Allow for both users with "path" and without it + resources = [ + "arn:${data.aws_partition.current.partition}:iam::${local.aws_account_id}:user/*/$${aws:username}", + "arn:${data.aws_partition.current.partition}:iam::${local.aws_account_id}:user/$${aws:username}", + "arn:${data.aws_partition.current.partition}:iam::${local.aws_account_id}:mfa/$${aws:username}", + ] + + condition { + test = "Bool" + variable = "aws:MultiFactorAuthPresent" + values = ["true"] + } + + condition { + test = "NumericLessThan" + variable = "aws:MultiFactorAuthAge" + values = ["3600"] + } + } +} diff --git a/modules/aws-iam/modules/iam-group-with-policies/variables.tf b/modules/aws-iam/modules/iam-group-with-policies/variables.tf new file mode 100644 index 0000000..7c5d764 --- /dev/null +++ b/modules/aws-iam/modules/iam-group-with-policies/variables.tf @@ -0,0 +1,53 @@ +variable "create_group" { + description = "Whether to create IAM group" + type = bool + default = true +} + +variable "name" { + description = "Name of IAM group" + type = string + default = "" +} + +variable "group_users" { + description = "List of IAM users to have in an IAM group which can assume the role" + type = list(string) + default = [] +} + +variable "custom_group_policy_arns" { + description = "List of IAM policies ARNs to attach to IAM group" + type = list(string) + default = [] +} + +variable "custom_group_policies" { + description = "List of maps of inline IAM policies to attach to IAM group. Should have `name` and `policy` keys in each element." + type = list(map(string)) + default = [] +} + +variable "attach_iam_self_management_policy" { + description = "Whether to attach IAM policy which allows IAM users to manage their credentials and MFA" + type = bool + default = true +} + +variable "iam_self_management_policy_name_prefix" { + description = "Name prefix for IAM policy to create with IAM self-management permissions" + type = string + default = "IAMSelfManagement-" +} + +variable "aws_account_id" { + description = "AWS account id to use inside IAM policies. If empty, current AWS account ID will be used." + type = string + default = "" +} + +variable "tags" { + description = "A map of tags to add to all resources." + type = map(string) + default = {} +} diff --git a/modules/aws-iam/modules/iam-group-with-policies/versions.tf b/modules/aws-iam/modules/iam-group-with-policies/versions.tf new file mode 100644 index 0000000..d8dd1a4 --- /dev/null +++ b/modules/aws-iam/modules/iam-group-with-policies/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.0" + } + } +} diff --git a/modules/aws-iam/modules/iam-policy/README.md b/modules/aws-iam/modules/iam-policy/README.md new file mode 100644 index 0000000..482a49b --- /dev/null +++ b/modules/aws-iam/modules/iam-policy/README.md @@ -0,0 +1,50 @@ +# iam-policy + +Creates IAM policy. + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.0 | +| [aws](#requirement\_aws) | >= 4.0 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 4.0 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_iam_policy.policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [create\_policy](#input\_create\_policy) | Whether to create the IAM policy | `bool` | `true` | no | +| [description](#input\_description) | The description of the policy | `string` | `"IAM Policy"` | no | +| [name](#input\_name) | The name of the policy | `string` | `""` | no | +| [path](#input\_path) | The path of the policy in IAM | `string` | `"/"` | no | +| [policy](#input\_policy) | The path of the policy in IAM (tpl file) | `string` | `""` | no | +| [tags](#input\_tags) | A map of tags to add to all resources. | `map(string)` | `{}` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [arn](#output\_arn) | The ARN assigned by AWS to this policy | +| [description](#output\_description) | The description of the policy | +| [id](#output\_id) | The policy's ID | +| [name](#output\_name) | The name of the policy | +| [path](#output\_path) | The path of the policy in IAM | +| [policy](#output\_policy) | The policy document | + diff --git a/modules/aws-iam/modules/iam-policy/main.tf b/modules/aws-iam/modules/iam-policy/main.tf new file mode 100644 index 0000000..01ced98 --- /dev/null +++ b/modules/aws-iam/modules/iam-policy/main.tf @@ -0,0 +1,11 @@ +resource "aws_iam_policy" "policy" { + count = var.create_policy ? 1 : 0 + + name = var.name + path = var.path + description = var.description + + policy = var.policy + + tags = var.tags +} diff --git a/modules/aws-iam/modules/iam-policy/outputs.tf b/modules/aws-iam/modules/iam-policy/outputs.tf new file mode 100644 index 0000000..d890080 --- /dev/null +++ b/modules/aws-iam/modules/iam-policy/outputs.tf @@ -0,0 +1,29 @@ +output "id" { + description = "The policy's ID" + value = try(aws_iam_policy.policy[0].id, "") +} + +output "arn" { + description = "The ARN assigned by AWS to this policy" + value = try(aws_iam_policy.policy[0].arn, "") +} + +output "description" { + description = "The description of the policy" + value = try(aws_iam_policy.policy[0].description, "") +} + +output "name" { + description = "The name of the policy" + value = try(aws_iam_policy.policy[0].name, "") +} + +output "path" { + description = "The path of the policy in IAM" + value = try(aws_iam_policy.policy[0].path, "") +} + +output "policy" { + description = "The policy document" + value = try(aws_iam_policy.policy[0].policy, "") +} diff --git a/modules/aws-iam/modules/iam-policy/variables.tf b/modules/aws-iam/modules/iam-policy/variables.tf new file mode 100644 index 0000000..f01443c --- /dev/null +++ b/modules/aws-iam/modules/iam-policy/variables.tf @@ -0,0 +1,35 @@ +variable "create_policy" { + description = "Whether to create the IAM policy" + type = bool + default = true +} + +variable "name" { + description = "The name of the policy" + type = string + default = "" +} + +variable "path" { + description = "The path of the policy in IAM" + type = string + default = "/" +} + +variable "description" { + description = "The description of the policy" + type = string + default = "IAM Policy" +} + +variable "policy" { + description = "The path of the policy in IAM (tpl file)" + type = string + default = "" +} + +variable "tags" { + description = "A map of tags to add to all resources." + type = map(string) + default = {} +} diff --git a/modules/aws-iam/modules/iam-policy/versions.tf b/modules/aws-iam/modules/iam-policy/versions.tf new file mode 100644 index 0000000..d8dd1a4 --- /dev/null +++ b/modules/aws-iam/modules/iam-policy/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.0" + } + } +} diff --git a/modules/aws-iam/modules/iam-read-only-policy/README.md b/modules/aws-iam/modules/iam-read-only-policy/README.md new file mode 100644 index 0000000..9f97ee7 --- /dev/null +++ b/modules/aws-iam/modules/iam-read-only-policy/README.md @@ -0,0 +1,62 @@ +# iam-read-only-policy + +Creates IAM read-only policy for specified services. Default AWS read-only policies (arn:aws:iam::aws:policy/job-function/ViewOnlyAccess, arn:aws:iam::aws:policy/ReadOnlyAccess), being a one-size-fits-all type of policies, have a lot of things missing as well as something that you might not need. Also, AWS default policies are known for having [security issues](https://securityboulevard.com/2020/12/the-aws-managed-policies-trap/) +Thus this module is an attempt to build a better base for a customizable usable read-only policy. + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.0 | +| [aws](#requirement\_aws) | >= 4.0 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 4.0 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_iam_policy.policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | +| [aws_iam_policy_document.allowed_services](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.combined](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.console_services](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.logs_query](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.sts](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [additional\_policy\_json](#input\_additional\_policy\_json) | JSON policy document if you want to add custom actions | `string` | `"{}"` | no | +| [allow\_cloudwatch\_logs\_query](#input\_allow\_cloudwatch\_logs\_query) | Allows StartQuery/StopQuery/FilterLogEvents CloudWatch actions | `bool` | `true` | no | +| [allow\_predefined\_sts\_actions](#input\_allow\_predefined\_sts\_actions) | Allows GetCallerIdentity/GetSessionToken/GetAccessKeyInfo sts actions | `bool` | `true` | no | +| [allow\_web\_console\_services](#input\_allow\_web\_console\_services) | Allows List/Get/Describe/View actions for services used when browsing AWS console (e.g. resource-groups, tag, health services) | `bool` | `true` | no | +| [allowed\_services](#input\_allowed\_services) | List of services to allow Get/List/Describe/View options. Service name should be the same as corresponding service IAM prefix. See what it is for each service here https://docs.aws.amazon.com/service-authorization/latest/reference/reference_policies_actions-resources-contextkeys.html | `list(string)` | n/a | yes | +| [create\_policy](#input\_create\_policy) | Whether to create the IAM policy | `bool` | `true` | no | +| [description](#input\_description) | The description of the policy | `string` | `"IAM Policy"` | no | +| [name](#input\_name) | The name of the policy | `string` | `""` | no | +| [path](#input\_path) | The path of the policy in IAM | `string` | `"/"` | no | +| [tags](#input\_tags) | A map of tags to add to all resources. | `map(string)` | `{}` | no | +| [web\_console\_services](#input\_web\_console\_services) | List of web console services to allow | `list(string)` |
"arn:aws:iam::aws:policy/ReadOnlyAccess"
]
[| no | + +## Outputs + +| Name | Description | +|------|-------------| +| [arn](#output\_arn) | The ARN assigned by AWS to this policy | +| [description](#output\_description) | The description of the policy | +| [id](#output\_id) | The policy's ID | +| [name](#output\_name) | The name of the policy | +| [path](#output\_path) | The path of the policy in IAM | +| [policy](#output\_policy) | The policy document | +| [policy\_json](#output\_policy\_json) | Policy document as json. Useful if you need document but do not want to create IAM policy itself. For example for SSO Permission Set inline policies | + diff --git a/modules/aws-iam/modules/iam-read-only-policy/main.tf b/modules/aws-iam/modules/iam-read-only-policy/main.tf new file mode 100644 index 0000000..455c15e --- /dev/null +++ b/modules/aws-iam/modules/iam-read-only-policy/main.tf @@ -0,0 +1,90 @@ +resource "aws_iam_policy" "policy" { + count = var.create_policy ? 1 : 0 + + name = var.name + path = var.path + description = var.description + + policy = data.aws_iam_policy_document.combined.json + + tags = var.tags +} + +locals { + allowed_services = distinct(var.allowed_services) +} + +data "aws_iam_policy_document" "allowed_services" { + + dynamic "statement" { + for_each = toset(local.allowed_services) + content { + sid = replace(statement.value, "-", "") + + actions = [ + "${statement.value}:List*", + "${statement.value}:Get*", + "${statement.value}:Describe*", + "${statement.value}:View*", + ] + resources = ["*"] + } + } +} + +data "aws_iam_policy_document" "console_services" { + count = var.allow_web_console_services ? 1 : 0 + + dynamic "statement" { + for_each = toset(var.web_console_services) + content { + sid = replace(statement.value, "-", "") + + actions = [ + "${statement.value}:List*", + "${statement.value}:Get*", + "${statement.value}:Describe*", + "${statement.value}:View*", + ] + resources = ["*"] + } + } +} + +data "aws_iam_policy_document" "sts" { + count = var.allow_predefined_sts_actions ? 1 : 0 + + statement { + sid = "STS" + actions = [ + "sts:GetAccessKeyInfo", + "sts:GetCallerIdentity", + "sts:GetSessionToken", + ] + resources = ["*"] + } +} + +data "aws_iam_policy_document" "logs_query" { + count = var.allow_cloudwatch_logs_query ? 1 : 0 + + statement { + sid = "AllowLogsQuery" + actions = [ + "logs:StartQuery", + "logs:StopQuery", + "logs:FilterLogEvents" + ] + resources = ["*"] + } +} + +data "aws_iam_policy_document" "combined" { + source_policy_documents = concat( + [data.aws_iam_policy_document.allowed_services.json], + data.aws_iam_policy_document.console_services.*.json, + data.aws_iam_policy_document.sts.*.json, + data.aws_iam_policy_document.logs_query.*.json, + [var.additional_policy_json] + ) +} diff --git a/modules/aws-iam/modules/iam-read-only-policy/outputs.tf b/modules/aws-iam/modules/iam-read-only-policy/outputs.tf new file mode 100644 index 0000000..c18731d --- /dev/null +++ b/modules/aws-iam/modules/iam-read-only-policy/outputs.tf @@ -0,0 +1,34 @@ +output "policy_json" { + description = "Policy document as json. Useful if you need document but do not want to create IAM policy itself. For example for SSO Permission Set inline policies" + value = data.aws_iam_policy_document.combined.json +} + +output "id" { + description = "The policy's ID" + value = try(aws_iam_policy.policy[0].id, "") +} + +output "arn" { + description = "The ARN assigned by AWS to this policy" + value = try(aws_iam_policy.policy[0].arn, "") +} + +output "description" { + description = "The description of the policy" + value = try(aws_iam_policy.policy[0].description, "") +} + +output "name" { + description = "The name of the policy" + value = try(aws_iam_policy.policy[0].name, "") +} + +output "path" { + description = "The path of the policy in IAM" + value = try(aws_iam_policy.policy[0].path, "") +} + +output "policy" { + description = "The policy document" + value = try(aws_iam_policy.policy[0].policy, "") +} diff --git a/modules/aws-iam/modules/iam-read-only-policy/variables.tf b/modules/aws-iam/modules/iam-read-only-policy/variables.tf new file mode 100644 index 0000000..822b4bd --- /dev/null +++ b/modules/aws-iam/modules/iam-read-only-policy/variables.tf @@ -0,0 +1,64 @@ +variable "create_policy" { + description = "Whether to create the IAM policy" + type = bool + default = true +} + +variable "name" { + description = "The name of the policy" + type = string + default = "" +} + +variable "path" { + description = "The path of the policy in IAM" + type = string + default = "/" +} + +variable "description" { + description = "The description of the policy" + type = string + default = "IAM Policy" +} + +variable "allowed_services" { + description = "List of services to allow Get/List/Describe/View options. Service name should be the same as corresponding service IAM prefix. See what it is for each service here https://docs.aws.amazon.com/service-authorization/latest/reference/reference_policies_actions-resources-contextkeys.html" + type = list(string) +} + +variable "additional_policy_json" { + description = "JSON policy document if you want to add custom actions" + type = string + default = "{}" +} + +variable "tags" { + description = "A map of tags to add to all resources." + type = map(string) + default = {} +} + +variable "allow_cloudwatch_logs_query" { + description = "Allows StartQuery/StopQuery/FilterLogEvents CloudWatch actions" + type = bool + default = true +} + +variable "allow_predefined_sts_actions" { + description = "Allows GetCallerIdentity/GetSessionToken/GetAccessKeyInfo sts actions" + type = bool + default = true +} + +variable "allow_web_console_services" { + description = "Allows List/Get/Describe/View actions for services used when browsing AWS console (e.g. resource-groups, tag, health services)" + type = bool + default = true +} + +variable "web_console_services" { + description = "List of web console services to allow" + type = list(string) + default = ["resource-groups", "tag", "health", "ce"] +} diff --git a/modules/aws-iam/modules/iam-read-only-policy/versions.tf b/modules/aws-iam/modules/iam-read-only-policy/versions.tf new file mode 100644 index 0000000..d8dd1a4 --- /dev/null +++ b/modules/aws-iam/modules/iam-read-only-policy/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.0" + } + } +} diff --git a/modules/aws-iam/modules/iam-role-for-service-accounts-eks/README.md b/modules/aws-iam/modules/iam-role-for-service-accounts-eks/README.md new file mode 100644 index 0000000..6e9d502 --- /dev/null +++ b/modules/aws-iam/modules/iam-role-for-service-accounts-eks/README.md @@ -0,0 +1,231 @@ +# IAM Role for Service Accounts in EKS + +Creates an IAM role which can be assumed by AWS EKS `ServiceAccount`s with optional policies for commonly used controllers/custom resources within EKS. The optional policies supported include: +- [Cert-Manager](https://cert-manager.io/docs/configuration/acme/dns01/route53/#set-up-an-iam-role) +- [Cluster Autoscaler](https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/aws/README.md) +- [EBS CSI Driver](https://github.com/kubernetes-sigs/aws-ebs-csi-driver/blob/master/docs/example-iam-policy.json) +- [EFS CSI Driver](https://github.com/kubernetes-sigs/aws-efs-csi-driver/blob/master/docs/iam-policy-example.json) +- [External DNS](https://github.com/kubernetes-sigs/external-dns/blob/master/docs/tutorials/aws.md#iam-policy) +- [External Secrets](https://github.com/external-secrets/kubernetes-external-secrets#add-a-secret) +- [FSx for Lustre CSI Driver](https://github.com/kubernetes-sigs/aws-fsx-csi-driver/blob/master/docs/README.md) +- [Karpenter](https://github.com/aws/karpenter/blob/main/website/content/en/preview/getting-started/cloudformation.yaml) +- [Load Balancer Controller](https://github.com/kubernetes-sigs/aws-load-balancer-controller/blob/main/docs/install/iam_policy.json) + - [Load Balancer Controller Target Group Binding Only](https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.4/deploy/installation/#iam-permission-subset-for-those-who-use-targetgroupbinding-only-and-dont-plan-to-use-the-aws-load-balancer-controller-to-manage-security-group-rules) +- [App Mesh Controller](https://github.com/aws/aws-app-mesh-controller-for-k8s/blob/master/config/iam/controller-iam-policy.json) + - [App Mesh Envoy Proxy](https://raw.githubusercontent.com/aws/aws-app-mesh-controller-for-k8s/master/config/iam/envoy-iam-policy.json) +- [Managed Service for Prometheus](https://docs.aws.amazon.com/prometheus/latest/userguide/set-up-irsa.html) +- [Node Termination Handler](https://github.com/aws/aws-node-termination-handler#5-create-an-iam-role-for-the-pods) +- [Velero](https://github.com/vmware-tanzu/velero-plugin-for-aws#option-1-set-permissions-with-an-iam-user) +- [VPC CNI](https://docs.aws.amazon.com/eks/latest/userguide/cni-iam-role.html) + +This module is intended to be used with AWS EKS. For details of how a `ServiceAccount` in EKS can assume an IAM role, see the [EKS documentation](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html). + +This module supports multiple `ServiceAccount`s across multiple clusters and/or namespaces. This allows for a single IAM role to be used when an application may span multiple clusters (e.g. for DR) or multiple namespaces (e.g. for canary deployments). For example, to create an IAM role named `my-app` that can be assumed from the `ServiceAccount` named `my-app-staging` in the namespace `default` and `canary` in a cluster in `us-east-1`; and also the `ServiceAccount` name `my-app-staging` in the namespace `default` in a cluster in `ap-southeast-1`, the configuration would be: + +```hcl +module "iam_eks_role" { + source = "terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts-eks" + role_name = "my-app" + + oidc_providers = { + one = { + provider_arn = "arn:aws:iam::111111111111:oidc-provider/oidc.eks.us-east-1.amazonaws.com/id/5C54DDF35ER19312844C7333374CC09D" + namespace_service_accounts = ["default:my-app-staging", "canary:my-app-staging"] + } + two = { + provider_arn = "arn:aws:iam::111111111111:oidc-provider/oidc.eks.ap-southeast-1.amazonaws.com/id/5C54DDF35ER54476848E7333374FF09G" + namespace_service_accounts = ["default:my-app-staging"] + } + } +} +``` + +This module can be used in conjunction with the [`terraform-aws-eks`](https://github.com/kloia/platform-modules/tree/main/terraform-aws-eks/examples) module to easily integrate with it: + +```hcl +module "vpc_cni_irsa_role" { + source = "terraform-modules/iam/aws//modules/iam-role-for-service-accounts-eks" + + role_name = "vpc-cni" + + attach_vpc_cni_policy = true + vpc_cni_enable_ipv4 = true + + oidc_providers = { + main = { + provider_arn = module.eks.oidc_provider_arn + namespace_service_accounts = ["default:my-app", "canary:my-app"] + } + } +} + +module "karpenter_irsa_role" { + source = "terraform-modules/iam/aws//modules/iam-role-for-service-accounts-eks" + + role_name = "karpenter_controller" + attach_karpenter_controller_policy = true + + karpenter_controller_cluster_id = module.eks.cluster_id + karpenter_controller_node_iam_role_arns = [module.eks.eks_managed_node_groups["default"].iam_role_arn] + + attach_vpc_cni_policy = true + vpc_cni_enable_ipv4 = true + + oidc_providers = { + main = { + provider_arn = module.eks.oidc_provider_arn + namespace_service_accounts = ["default:my-app", "canary:my-app"] + } + } +} + +module "eks" { + source = "terraform-modules/eks/aws" + version = "~> 18.6" + + cluster_name = "my-cluster" + cluster_version = "1.21" + + vpc_id = module.vpc.vpc_id + subnet_ids = module.vpc.private_subnets + + eks_managed_node_groups = { + default = {} + } +} +``` + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.0 | +| [aws](#requirement\_aws) | >= 4.0 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 4.0 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_iam_policy.amazon_managed_service_prometheus](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | +| [aws_iam_policy.appmesh_controller](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | +| [aws_iam_policy.appmesh_envoy_proxy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | +| [aws_iam_policy.cert_manager](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | +| [aws_iam_policy.cluster_autoscaler](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | +| [aws_iam_policy.ebs_csi](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | +| [aws_iam_policy.efs_csi](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | +| [aws_iam_policy.external_dns](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | +| [aws_iam_policy.external_secrets](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | +| [aws_iam_policy.fsx_lustre_csi](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | +| [aws_iam_policy.karpenter_controller](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | +| [aws_iam_policy.load_balancer_controller](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | +| [aws_iam_policy.load_balancer_controller_targetgroup_only](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | +| [aws_iam_policy.node_termination_handler](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | +| [aws_iam_policy.velero](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | +| [aws_iam_policy.vpc_cni](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | +| [aws_iam_role.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | +| [aws_iam_role_policy_attachment.amazon_managed_service_prometheus](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_iam_role_policy_attachment.appmesh_controller](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_iam_role_policy_attachment.appmesh_envoy_proxy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_iam_role_policy_attachment.cert_manager](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_iam_role_policy_attachment.cluster_autoscaler](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_iam_role_policy_attachment.ebs_csi](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_iam_role_policy_attachment.efs_csi](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_iam_role_policy_attachment.external_dns](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_iam_role_policy_attachment.external_secrets](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_iam_role_policy_attachment.fsx_lustre_csi](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_iam_role_policy_attachment.karpenter_controller](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_iam_role_policy_attachment.load_balancer_controller](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_iam_role_policy_attachment.load_balancer_controller_targetgroup_only](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_iam_role_policy_attachment.node_termination_handler](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_iam_role_policy_attachment.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_iam_role_policy_attachment.velero](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_iam_role_policy_attachment.vpc_cni](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source | +| [aws_iam_policy_document.amazon_managed_service_prometheus](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.appmesh_controller](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.appmesh_envoy_proxy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.cert_manager](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.cluster_autoscaler](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.ebs_csi](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.efs_csi](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.external_dns](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.external_secrets](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.fsx_lustre_csi](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.karpenter_controller](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.load_balancer_controller](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.load_balancer_controller_targetgroup_only](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.node_termination_handler](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.velero](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.vpc_cni](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_partition.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/partition) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [amazon\_managed\_service\_prometheus\_workspace\_arns](#input\_amazon\_managed\_service\_prometheus\_workspace\_arns) | List of AMP Workspace ARNs to read and write metrics | `list(string)` |
"resource-groups",
"tag",
"health",
"ce"
]
[| no | +| [assume\_role\_condition\_test](#input\_assume\_role\_condition\_test) | Name of the [IAM condition operator](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html) to evaluate when assuming the role | `string` | `"StringEquals"` | no | +| [attach\_amazon\_managed\_service\_prometheus\_policy](#input\_attach\_amazon\_managed\_service\_prometheus\_policy) | Determines whether to attach the Amazon Managed Service for Prometheus IAM policy to the role | `bool` | `false` | no | +| [attach\_appmesh\_controller\_policy](#input\_attach\_appmesh\_controller\_policy) | Determines whether to attach the Appmesh Controller policy to the role | `bool` | `false` | no | +| [attach\_appmesh\_envoy\_proxy\_policy](#input\_attach\_appmesh\_envoy\_proxy\_policy) | Determines whether to attach the Appmesh envoy proxy policy to the role | `bool` | `false` | no | +| [attach\_cert\_manager\_policy](#input\_attach\_cert\_manager\_policy) | Determines whether to attach the Cert Manager IAM policy to the role | `bool` | `false` | no | +| [attach\_cluster\_autoscaler\_policy](#input\_attach\_cluster\_autoscaler\_policy) | Determines whether to attach the Cluster Autoscaler IAM policy to the role | `bool` | `false` | no | +| [attach\_ebs\_csi\_policy](#input\_attach\_ebs\_csi\_policy) | Determines whether to attach the EBS CSI IAM policy to the role | `bool` | `false` | no | +| [attach\_efs\_csi\_policy](#input\_attach\_efs\_csi\_policy) | Determines whether to attach the EFS CSI IAM policy to the role | `bool` | `false` | no | +| [attach\_external\_dns\_policy](#input\_attach\_external\_dns\_policy) | Determines whether to attach the External DNS IAM policy to the role | `bool` | `false` | no | +| [attach\_external\_secrets\_policy](#input\_attach\_external\_secrets\_policy) | Determines whether to attach the External Secrets policy to the role | `bool` | `false` | no | +| [attach\_fsx\_lustre\_csi\_policy](#input\_attach\_fsx\_lustre\_csi\_policy) | Determines whether to attach the FSx for Lustre CSI Driver IAM policy to the role | `bool` | `false` | no | +| [attach\_karpenter\_controller\_policy](#input\_attach\_karpenter\_controller\_policy) | Determines whether to attach the Karpenter Controller policy to the role | `bool` | `false` | no | +| [attach\_load\_balancer\_controller\_policy](#input\_attach\_load\_balancer\_controller\_policy) | Determines whether to attach the Load Balancer Controller policy to the role | `bool` | `false` | no | +| [attach\_load\_balancer\_controller\_targetgroup\_binding\_only\_policy](#input\_attach\_load\_balancer\_controller\_targetgroup\_binding\_only\_policy) | Determines whether to attach the Load Balancer Controller policy for the TargetGroupBinding only | `bool` | `false` | no | +| [attach\_node\_termination\_handler\_policy](#input\_attach\_node\_termination\_handler\_policy) | Determines whether to attach the Node Termination Handler policy to the role | `bool` | `false` | no | +| [attach\_velero\_policy](#input\_attach\_velero\_policy) | Determines whether to attach the Velero IAM policy to the role | `bool` | `false` | no | +| [attach\_vpc\_cni\_policy](#input\_attach\_vpc\_cni\_policy) | Determines whether to attach the VPC CNI IAM policy to the role | `bool` | `false` | no | +| [cert\_manager\_hosted\_zone\_arns](#input\_cert\_manager\_hosted\_zone\_arns) | Route53 hosted zone ARNs to allow Cert manager to manage records | `list(string)` |
"*"
]
[| no | +| [cluster\_autoscaler\_cluster\_ids](#input\_cluster\_autoscaler\_cluster\_ids) | List of cluster IDs to appropriately scope permissions within the Cluster Autoscaler IAM policy | `list(string)` | `[]` | no | +| [create\_role](#input\_create\_role) | Whether to create a role | `bool` | `true` | no | +| [ebs\_csi\_kms\_cmk\_ids](#input\_ebs\_csi\_kms\_cmk\_ids) | KMS CMK IDs to allow EBS CSI to manage encrypted volumes | `list(string)` | `[]` | no | +| [external\_dns\_hosted\_zone\_arns](#input\_external\_dns\_hosted\_zone\_arns) | Route53 hosted zone ARNs to allow External DNS to manage records | `list(string)` |
"arn:aws:route53:::hostedzone/*"
]
[| no | +| [external\_secrets\_secrets\_manager\_arns](#input\_external\_secrets\_secrets\_manager\_arns) | List of Secrets Manager ARNs that contain secrets to mount using External Secrets | `list(string)` |
"arn:aws:route53:::hostedzone/*"
]
[| no | +| [external\_secrets\_ssm\_parameter\_arns](#input\_external\_secrets\_ssm\_parameter\_arns) | List of Systems Manager Parameter ARNs that contain secrets to mount using External Secrets | `list(string)` |
"arn:aws:secretsmanager:*:*:secret:*"
]
[| no | +| [force\_detach\_policies](#input\_force\_detach\_policies) | Whether policies should be detached from this role when destroying | `bool` | `true` | no | +| [fsx\_lustre\_csi\_service\_role\_arns](#input\_fsx\_lustre\_csi\_service\_role\_arns) | Service role ARNs to allow FSx for Lustre CSI create and manage FSX for Lustre service linked roles | `list(string)` |
"arn:aws:ssm:*:*:parameter/*"
]
[| no | +| [karpenter\_controller\_cluster\_id](#input\_karpenter\_controller\_cluster\_id) | Cluster ID where the Karpenter controller is provisioned/managing | `string` | `"*"` | no | +| [karpenter\_controller\_node\_iam\_role\_arns](#input\_karpenter\_controller\_node\_iam\_role\_arns) | List of node IAM role ARNs Karpenter can use to launch nodes | `list(string)` |
"arn:aws:iam::*:role/aws-service-role/s3.data-source.lustre.fsx.amazonaws.com/*"
]
[| no | +| [karpenter\_controller\_ssm\_parameter\_arns](#input\_karpenter\_controller\_ssm\_parameter\_arns) | List of SSM Parameter ARNs that contain AMI IDs launched by Karpenter | `list(string)` |
"*"
]
[| no | +| [karpenter\_subnet\_account\_id](#input\_karpenter\_subnet\_account\_id) | Account ID of where the subnets Karpenter will utilize resides. Used when subnets are shared from another account | `string` | `""` | no | +| [karpenter\_tag\_key](#input\_karpenter\_tag\_key) | Tag key (`{key = value}`) applied to resources launched by Karpenter through the Karpenter provisioner | `string` | `"karpenter.sh/discovery"` | no | +| [max\_session\_duration](#input\_max\_session\_duration) | Maximum CLI/API session duration in seconds between 3600 and 43200 | `number` | `null` | no | +| [node\_termination\_handler\_sqs\_queue\_arns](#input\_node\_termination\_handler\_sqs\_queue\_arns) | List of SQS ARNs that contain node termination events | `list(string)` |
"arn:aws:ssm:*:*:parameter/aws/service/*"
]
[| no | +| [oidc\_providers](#input\_oidc\_providers) | Map of OIDC providers where each provider map should contain the `provider`, `provider_arn`, and `namespace_service_accounts` | `any` | `{}` | no | +| [policy\_name\_prefix](#input\_policy\_name\_prefix) | IAM policy name prefix | `string` | `"AmazonEKS_"` | no | +| [role\_description](#input\_role\_description) | IAM Role description | `string` | `null` | no | +| [role\_name](#input\_role\_name) | Name of IAM role | `string` | `null` | no | +| [role\_name\_prefix](#input\_role\_name\_prefix) | IAM role name prefix | `string` | `null` | no | +| [role\_path](#input\_role\_path) | Path of IAM role | `string` | `null` | no | +| [role\_permissions\_boundary\_arn](#input\_role\_permissions\_boundary\_arn) | Permissions boundary ARN to use for IAM role | `string` | `null` | no | +| [role\_policy\_arns](#input\_role\_policy\_arns) | ARNs of any policies to attach to the IAM role | `map(string)` | `{}` | no | +| [tags](#input\_tags) | A map of tags to add the the IAM role | `map(any)` | `{}` | no | +| [velero\_s3\_bucket\_arns](#input\_velero\_s3\_bucket\_arns) | List of S3 Bucket ARNs that Velero needs access to in order to backup and restore cluster resources | `list(string)` |
"*"
]
[| no | +| [vpc\_cni\_enable\_ipv4](#input\_vpc\_cni\_enable\_ipv4) | Determines whether to enable IPv4 permissions for VPC CNI policy | `bool` | `false` | no | +| [vpc\_cni\_enable\_ipv6](#input\_vpc\_cni\_enable\_ipv6) | Determines whether to enable IPv6 permissions for VPC CNI policy | `bool` | `false` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [iam\_role\_arn](#output\_iam\_role\_arn) | ARN of IAM role | +| [iam\_role\_name](#output\_iam\_role\_name) | Name of IAM role | +| [iam\_role\_path](#output\_iam\_role\_path) | Path of IAM role | +| [iam\_role\_unique\_id](#output\_iam\_role\_unique\_id) | Unique ID of IAM role | diff --git a/modules/aws-iam/modules/iam-role-for-service-accounts-eks/main.tf b/modules/aws-iam/modules/iam-role-for-service-accounts-eks/main.tf new file mode 100644 index 0000000..5b99694 --- /dev/null +++ b/modules/aws-iam/modules/iam-role-for-service-accounts-eks/main.tf @@ -0,0 +1,55 @@ +data "aws_iam_policy_document" "this" { + count = var.create_role ? 1 : 0 + + dynamic "statement" { + for_each = var.oidc_providers + + content { + effect = "Allow" + actions = ["sts:AssumeRoleWithWebIdentity"] + + principals { + type = "Federated" + identifiers = [statement.value.provider_arn] + } + + condition { + test = var.assume_role_condition_test + variable = "${replace(statement.value.provider_arn, "/^(.*provider/)/", "")}:sub" + values = [for sa in statement.value.namespace_service_accounts : "system:serviceaccount:${sa}"] + } + + # https://aws.amazon.com/premiumsupport/knowledge-center/eks-troubleshoot-oidc-and-irsa/?nc1=h_ls + condition { + test = var.assume_role_condition_test + variable = "${replace(statement.value.provider_arn, "/^(.*provider/)/", "")}:aud" + values = ["sts.amazonaws.com"] + } + + } + } +} + +resource "aws_iam_role" "this" { + count = var.create_role ? 1 : 0 + + name = var.role_name + name_prefix = var.role_name_prefix + path = var.role_path + description = var.role_description + + assume_role_policy = data.aws_iam_policy_document.this[0].json + # assume_role_policy = "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"Federated\":\"arn:aws:iam::111111111111:oidc-provider/oidc.eks.eu-west-1.amazonaws.com/id/xxxxxxxx\"},\"Action\":\"sts:AssumeRole\",\"Condition\":{}}]}" + max_session_duration = var.max_session_duration + permissions_boundary = var.role_permissions_boundary_arn + force_detach_policies = var.force_detach_policies + + tags = var.tags +} + +resource "aws_iam_role_policy_attachment" "this" { + for_each = { for k, v in var.role_policy_arns : k => v if var.create_role } + + role = aws_iam_role.this[0].name + policy_arn = each.value +} diff --git a/modules/aws-iam/modules/iam-role-for-service-accounts-eks/outputs.tf b/modules/aws-iam/modules/iam-role-for-service-accounts-eks/outputs.tf new file mode 100644 index 0000000..a680531 --- /dev/null +++ b/modules/aws-iam/modules/iam-role-for-service-accounts-eks/outputs.tf @@ -0,0 +1,19 @@ +output "iam_role_arn" { + description = "ARN of IAM role" + value = try(aws_iam_role.this[0].arn, "") +} + +output "iam_role_name" { + description = "Name of IAM role" + value = try(aws_iam_role.this[0].name, "") +} + +output "iam_role_path" { + description = "Path of IAM role" + value = try(aws_iam_role.this[0].path, "") +} + +output "iam_role_unique_id" { + description = "Unique ID of IAM role" + value = try(aws_iam_role.this[0].unique_id, "") +} diff --git a/modules/aws-iam/modules/iam-role-for-service-accounts-eks/policies.tf b/modules/aws-iam/modules/iam-role-for-service-accounts-eks/policies.tf new file mode 100644 index 0000000..7821a9a --- /dev/null +++ b/modules/aws-iam/modules/iam-role-for-service-accounts-eks/policies.tf @@ -0,0 +1,1275 @@ +data "aws_partition" "current" {} +data "aws_caller_identity" "current" {} + +locals { + account_id = data.aws_caller_identity.current.account_id + partition = data.aws_partition.current.partition + dns_suffix = data.aws_partition.current.dns_suffix +} + +################################################################################ +# Cert Manager Policy +################################################################################ + +# https://cert-manager.io/docs/configuration/acme/dns01/route53/#set-up-an-iam-role +data "aws_iam_policy_document" "cert_manager" { + count = var.create_role && var.attach_cert_manager_policy ? 1 : 0 + + statement { + actions = ["route53:GetChange"] + resources = ["arn:${local.partition}:route53:::change/*"] + } + + statement { + actions = [ + "route53:ChangeResourceRecordSets", + "route53:ListResourceRecordSets" + ] + + resources = var.cert_manager_hosted_zone_arns + } + + statement { + actions = ["route53:ListHostedZonesByName"] + resources = ["*"] + } +} + +resource "aws_iam_policy" "cert_manager" { + count = var.create_role && var.attach_cert_manager_policy ? 1 : 0 + + name_prefix = "${var.policy_name_prefix}Cert_Manager_Policy-" + path = var.role_path + description = "Cert Manager policy to allow management of Route53 hosted zone records" + policy = data.aws_iam_policy_document.cert_manager[0].json + + tags = var.tags +} + +resource "aws_iam_role_policy_attachment" "cert_manager" { + count = var.create_role && var.attach_cert_manager_policy ? 1 : 0 + + role = aws_iam_role.this[0].name + policy_arn = aws_iam_policy.cert_manager[0].arn +} + +################################################################################ +# Cluster Autoscaler Policy +################################################################################ + +# https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/aws/README.md +data "aws_iam_policy_document" "cluster_autoscaler" { + count = var.create_role && var.attach_cluster_autoscaler_policy ? 1 : 0 + + statement { + actions = [ + "autoscaling:DescribeAutoScalingGroups", + "autoscaling:DescribeAutoScalingInstances", + "autoscaling:DescribeLaunchConfigurations", + "autoscaling:DescribeScalingActivities", + "autoscaling:DescribeTags", + "ec2:DescribeLaunchTemplateVersions", + "ec2:DescribeInstanceTypes", + "eks:DescribeNodegroup", + ] + + resources = ["*"] + } + + dynamic "statement" { + for_each = toset(var.cluster_autoscaler_cluster_ids) + content { + actions = [ + "autoscaling:SetDesiredCapacity", + "autoscaling:TerminateInstanceInAutoScalingGroup", + "autoscaling:UpdateAutoScalingGroup", + ] + + resources = ["*"] + + condition { + test = "StringEquals" + variable = "autoscaling:ResourceTag/kubernetes.io/cluster/${statement.value}" + values = ["owned"] + } + } + } +} + +resource "aws_iam_policy" "cluster_autoscaler" { + count = var.create_role && var.attach_cluster_autoscaler_policy ? 1 : 0 + + name_prefix = "${var.policy_name_prefix}Cluster_Autoscaler_Policy-" + path = var.role_path + description = "Cluster autoscaler policy to allow examination and modification of EC2 Auto Scaling Groups" + policy = data.aws_iam_policy_document.cluster_autoscaler[0].json + + tags = var.tags +} + +resource "aws_iam_role_policy_attachment" "cluster_autoscaler" { + count = var.create_role && var.attach_cluster_autoscaler_policy ? 1 : 0 + + role = aws_iam_role.this[0].name + policy_arn = aws_iam_policy.cluster_autoscaler[0].arn +} + +################################################################################ +# EBS CSI Policy +################################################################################ + +# https://github.com/kubernetes-sigs/aws-ebs-csi-driver/blob/master/docs/example-iam-policy.json +data "aws_iam_policy_document" "ebs_csi" { + count = var.create_role && var.attach_ebs_csi_policy ? 1 : 0 + + statement { + actions = [ + "ec2:CreateSnapshot", + "ec2:AttachVolume", + "ec2:DetachVolume", + "ec2:ModifyVolume", + "ec2:DescribeAvailabilityZones", + "ec2:DescribeInstances", + "ec2:DescribeSnapshots", + "ec2:DescribeTags", + "ec2:DescribeVolumes", + "ec2:DescribeVolumesModifications", + ] + + resources = ["*"] + } + + statement { + actions = ["ec2:CreateTags"] + + resources = [ + "arn:${local.partition}:ec2:*:*:volume/*", + "arn:${local.partition}:ec2:*:*:snapshot/*", + ] + + condition { + test = "StringEquals" + variable = "ec2:CreateAction" + values = [ + "CreateVolume", + "CreateSnapshot", + ] + } + } + + statement { + actions = ["ec2:DeleteTags"] + + resources = [ + "arn:${local.partition}:ec2:*:*:volume/*", + "arn:${local.partition}:ec2:*:*:snapshot/*", + ] + } + + statement { + actions = ["ec2:CreateVolume"] + resources = ["*"] + + condition { + test = "StringLike" + variable = "aws:RequestTag/ebs.csi.aws.com/cluster" + values = [ + true + ] + } + } + + statement { + actions = ["ec2:CreateVolume"] + resources = ["*"] + + condition { + test = "StringLike" + variable = "aws:RequestTag/CSIVolumeName" + values = ["*"] + } + } + + statement { + actions = ["ec2:CreateVolume"] + resources = ["*"] + + condition { + test = "StringLike" + variable = "aws:RequestTag/kubernetes.io/cluster/*" + values = ["owned"] + } + } + + statement { + actions = ["ec2:DeleteVolume"] + resources = ["*"] + + condition { + test = "StringLike" + variable = "ec2:ResourceTag/ebs.csi.aws.com/cluster" + values = [true] + } + } + + statement { + actions = ["ec2:DeleteVolume"] + resources = ["*"] + + condition { + test = "StringLike" + variable = "ec2:ResourceTag/CSIVolumeName" + values = ["*"] + } + } + + statement { + actions = ["ec2:DeleteVolume"] + resources = ["*"] + + condition { + test = "StringLike" + variable = "ec2:ResourceTag/kubernetes.io/cluster/*" + values = ["owned"] + } + } + + statement { + actions = ["ec2:DeleteSnapshot"] + resources = ["*"] + + condition { + test = "StringLike" + variable = "ec2:ResourceTag/CSIVolumeSnapshotName" + values = ["*"] + } + } + + statement { + actions = ["ec2:DeleteSnapshot"] + resources = ["*"] + + condition { + test = "StringLike" + variable = "ec2:ResourceTag/ebs.csi.aws.com/cluster" + values = [true] + } + } + + dynamic "statement" { + for_each = length(var.ebs_csi_kms_cmk_ids) > 0 ? [1] : [] + content { + actions = [ + "kms:CreateGrant", + "kms:ListGrants", + "kms:RevokeGrant", + ] + + resources = var.ebs_csi_kms_cmk_ids + + condition { + test = "Bool" + variable = "kms:GrantIsForAWSResource" + values = [true] + } + } + } + + dynamic "statement" { + for_each = length(var.ebs_csi_kms_cmk_ids) > 0 ? [1] : [] + content { + actions = [ + "kms:Encrypt", + "kms:Decrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*", + "kms:DescribeKey", + ] + + resources = var.ebs_csi_kms_cmk_ids + } + } +} + +resource "aws_iam_policy" "ebs_csi" { + count = var.create_role && var.attach_ebs_csi_policy ? 1 : 0 + + name_prefix = "${var.policy_name_prefix}EBS_CSI_Policy-" + path = var.role_path + description = "Provides permissions to manage EBS volumes via the container storage interface driver" + policy = data.aws_iam_policy_document.ebs_csi[0].json + + tags = var.tags +} + +resource "aws_iam_role_policy_attachment" "ebs_csi" { + count = var.create_role && var.attach_ebs_csi_policy ? 1 : 0 + + role = aws_iam_role.this[0].name + policy_arn = aws_iam_policy.ebs_csi[0].arn +} + +################################################################################ +# EFS CSI Driver Policy +################################################################################ + +# https://github.com/kubernetes-sigs/aws-efs-csi-driver/blob/master/docs/iam-policy-example.json +data "aws_iam_policy_document" "efs_csi" { + count = var.create_role && var.attach_efs_csi_policy ? 1 : 0 + + statement { + actions = [ + "ec2:DescribeAvailabilityZones", + "elasticfilesystem:DescribeAccessPoints", + "elasticfilesystem:DescribeFileSystems", + "elasticfilesystem:DescribeMountTargets", + ] + + resources = ["*"] + } + + statement { + actions = ["elasticfilesystem:CreateAccessPoint"] + resources = ["*"] + + condition { + test = "StringLike" + variable = "aws:RequestTag/efs.csi.aws.com/cluster" + values = ["true"] + } + } + + statement { + actions = ["elasticfilesystem:DeleteAccessPoint"] + resources = ["*"] + + condition { + test = "StringEquals" + variable = "aws:ResourceTag/efs.csi.aws.com/cluster" + values = ["true"] + } + } +} + +resource "aws_iam_policy" "efs_csi" { + count = var.create_role && var.attach_efs_csi_policy ? 1 : 0 + + name_prefix = "${var.policy_name_prefix}EFS_CSI_Policy-" + path = var.role_path + description = "Provides permissions to manage EFS volumes via the container storage interface driver" + policy = data.aws_iam_policy_document.efs_csi[0].json + + tags = var.tags +} + +resource "aws_iam_role_policy_attachment" "efs_csi" { + count = var.create_role && var.attach_efs_csi_policy ? 1 : 0 + + role = aws_iam_role.this[0].name + policy_arn = aws_iam_policy.efs_csi[0].arn +} + +################################################################################ +# External DNS Policy +################################################################################ + +# https://github.com/kubernetes-sigs/external-dns/blob/master/docs/tutorials/aws.md#iam-policy +data "aws_iam_policy_document" "external_dns" { + count = var.create_role && var.attach_external_dns_policy ? 1 : 0 + + statement { + actions = ["route53:ChangeResourceRecordSets"] + resources = var.external_dns_hosted_zone_arns + } + + statement { + actions = [ + "route53:ListHostedZones", + "route53:ListResourceRecordSets", + ] + + resources = ["*"] + } +} + +resource "aws_iam_policy" "external_dns" { + count = var.create_role && var.attach_external_dns_policy ? 1 : 0 + + name_prefix = "${var.policy_name_prefix}External_DNS_Policy-" + path = var.role_path + description = "External DNS policy to allow management of Route53 hosted zone records" + policy = data.aws_iam_policy_document.external_dns[0].json + + tags = var.tags +} + +resource "aws_iam_role_policy_attachment" "external_dns" { + count = var.create_role && var.attach_external_dns_policy ? 1 : 0 + + role = aws_iam_role.this[0].name + policy_arn = aws_iam_policy.external_dns[0].arn +} + +################################################################################ +# External Secrets Policy +################################################################################ + +# https://github.com/external-secrets/kubernetes-external-secrets#add-a-secret +data "aws_iam_policy_document" "external_secrets" { + count = var.create_role && var.attach_external_secrets_policy ? 1 : 0 + + statement { + actions = ["ssm:GetParameter"] + resources = var.external_secrets_ssm_parameter_arns + } + + statement { + actions = [ + "secretsmanager:GetResourcePolicy", + "secretsmanager:GetSecretValue", + "secretsmanager:DescribeSecret", + "secretsmanager:ListSecretVersionIds", + ] + resources = var.external_secrets_secrets_manager_arns + } +} + +resource "aws_iam_policy" "external_secrets" { + count = var.create_role && var.attach_external_secrets_policy ? 1 : 0 + + name_prefix = "${var.policy_name_prefix}External_Secrets_Policy-" + path = var.role_path + description = "Provides permissions to for External Secrets to retrieve secrets from AWS SSM and AWS Secrets Manager" + policy = data.aws_iam_policy_document.external_secrets[0].json + + tags = var.tags +} + +resource "aws_iam_role_policy_attachment" "external_secrets" { + count = var.create_role && var.attach_external_secrets_policy ? 1 : 0 + + role = aws_iam_role.this[0].name + policy_arn = aws_iam_policy.external_secrets[0].arn +} + +################################################################################ +# FSx for Lustre CSI Driver Policy +################################################################################ + +# https://github.com/kubernetes-sigs/aws-fsx-csi-driver/blob/master/docs/README.md +data "aws_iam_policy_document" "fsx_lustre_csi" { + count = var.create_role && var.attach_fsx_lustre_csi_policy ? 1 : 0 + + statement { + actions = [ + "iam:CreateServiceLinkedRole", + "iam:AttachRolePolicy", + "iam:PutRolePolicy" + ] + resources = var.fsx_lustre_csi_service_role_arns + } + + statement { + actions = ["iam:CreateServiceLinkedRole"] + resources = ["*"] + condition { + test = "StringLike" + variable = "iam:AWSServiceName" + values = ["fsx.${local.dns_suffix}"] + } + } + + statement { + actions = [ + "s3:ListBucket", + "fsx:CreateFileSystem", + "fsx:DeleteFileSystem", + "fsx:DescribeFileSystems", + "fsx:TagResource", + ] + resources = ["*"] + } +} + +resource "aws_iam_policy" "fsx_lustre_csi" { + count = var.create_role && var.attach_fsx_lustre_csi_policy ? 1 : 0 + + name_prefix = "${var.policy_name_prefix}FSx_Lustre_CSI_Policy-" + path = var.role_path + description = "Provides permissions to manage FSx Lustre volumes via the container storage interface driver" + policy = data.aws_iam_policy_document.fsx_lustre_csi[0].json + + tags = var.tags +} + +resource "aws_iam_role_policy_attachment" "fsx_lustre_csi" { + count = var.create_role && var.attach_fsx_lustre_csi_policy ? 1 : 0 + + role = aws_iam_role.this[0].name + policy_arn = aws_iam_policy.fsx_lustre_csi[0].arn +} + +################################################################################ +# Karpenter Controller Policy +################################################################################ + +# curl -fsSL https://karpenter.sh/v0.6.1/getting-started/cloudformation.yaml +data "aws_iam_policy_document" "karpenter_controller" { + count = var.create_role && var.attach_karpenter_controller_policy ? 1 : 0 + + statement { + actions = [ + "ec2:CreateLaunchTemplate", + "ec2:CreateFleet", + "ec2:CreateTags", + "ec2:DescribeLaunchTemplates", + "ec2:DescribeImages", + "ec2:DescribeInstances", + "ec2:DescribeSecurityGroups", + "ec2:DescribeSubnets", + "ec2:DescribeInstanceTypes", + "ec2:DescribeInstanceTypeOfferings", + "ec2:DescribeAvailabilityZones", + "ec2:DescribeSpotPriceHistory", + "pricing:GetProducts", + ] + + resources = ["*"] + } + + statement { + actions = [ + "ec2:TerminateInstances", + "ec2:DeleteLaunchTemplate", + ] + + resources = ["*"] + + condition { + test = "StringEquals" + variable = "ec2:ResourceTag/${var.karpenter_tag_key}" + values = [var.karpenter_controller_cluster_id] + } + } + + statement { + actions = ["ec2:RunInstances"] + resources = [ + "arn:${local.partition}:ec2:*:${local.account_id}:launch-template/*", + "arn:${local.partition}:ec2:*:${local.account_id}:security-group/*", + ] + + condition { + test = "StringEquals" + variable = "ec2:ResourceTag/${var.karpenter_tag_key}" + values = [var.karpenter_controller_cluster_id] + } + } + + statement { + actions = ["ec2:RunInstances"] + resources = [ + "arn:${local.partition}:ec2:*::image/*", + "arn:${local.partition}:ec2:*:${local.account_id}:instance/*", + "arn:${local.partition}:ec2:*:${local.account_id}:spot-instances-request/*", + "arn:${local.partition}:ec2:*:${local.account_id}:volume/*", + "arn:${local.partition}:ec2:*:${local.account_id}:network-interface/*", + "arn:${local.partition}:ec2:*:${coalesce(var.karpenter_subnet_account_id, local.account_id)}:subnet/*", + ] + } + + statement { + actions = ["ssm:GetParameter"] + resources = var.karpenter_controller_ssm_parameter_arns + } + + statement { + actions = ["iam:PassRole"] + resources = var.karpenter_controller_node_iam_role_arns + } +} + +resource "aws_iam_policy" "karpenter_controller" { + count = var.create_role && var.attach_karpenter_controller_policy ? 1 : 0 + + name_prefix = "${var.policy_name_prefix}Karpenter_Controller_Policy-" + path = var.role_path + description = "Provides permissions to handle node termination events via the Node Termination Handler" + policy = data.aws_iam_policy_document.karpenter_controller[0].json + + tags = var.tags +} + +resource "aws_iam_role_policy_attachment" "karpenter_controller" { + count = var.create_role && var.attach_karpenter_controller_policy ? 1 : 0 + + role = aws_iam_role.this[0].name + policy_arn = aws_iam_policy.karpenter_controller[0].arn +} + +################################################################################ +# AWS Load Balancer Controller Policy +################################################################################ + +# https://github.com/kubernetes-sigs/aws-load-balancer-controller/blob/main/docs/install/iam_policy.json +data "aws_iam_policy_document" "load_balancer_controller" { + count = var.create_role && var.attach_load_balancer_controller_policy ? 1 : 0 + + statement { + actions = ["iam:CreateServiceLinkedRole"] + resources = ["*"] + + condition { + test = "StringEquals" + variable = "iam:AWSServiceName" + values = ["elasticloadbalancing.${local.dns_suffix}"] + } + } + + statement { + actions = [ + "ec2:DescribeAccountAttributes", + "ec2:DescribeAddresses", + "ec2:DescribeAvailabilityZones", + "ec2:DescribeInternetGateways", + "ec2:DescribeVpcs", + "ec2:DescribeVpcPeeringConnections", + "ec2:DescribeSubnets", + "ec2:DescribeSecurityGroups", + "ec2:DescribeInstances", + "ec2:DescribeNetworkInterfaces", + "ec2:DescribeTags", + "ec2:GetCoipPoolUsage", + "ec2:DescribeCoipPools", + "elasticloadbalancing:DescribeLoadBalancers", + "elasticloadbalancing:DescribeLoadBalancerAttributes", + "elasticloadbalancing:DescribeListeners", + "elasticloadbalancing:DescribeListenerCertificates", + "elasticloadbalancing:DescribeSSLPolicies", + "elasticloadbalancing:DescribeRules", + "elasticloadbalancing:DescribeTargetGroups", + "elasticloadbalancing:DescribeTargetGroupAttributes", + "elasticloadbalancing:DescribeTargetHealth", + "elasticloadbalancing:DescribeTags", + "elasticloadbalancing:AddTags", + ] + resources = ["*"] + } + + statement { + actions = [ + "cognito-idp:DescribeUserPoolClient", + "acm:ListCertificates", + "acm:DescribeCertificate", + "iam:ListServerCertificates", + "iam:GetServerCertificate", + "waf-regional:GetWebACL", + "waf-regional:GetWebACLForResource", + "waf-regional:AssociateWebACL", + "waf-regional:DisassociateWebACL", + "wafv2:GetWebACL", + "wafv2:GetWebACLForResource", + "wafv2:AssociateWebACL", + "wafv2:DisassociateWebACL", + "shield:GetSubscriptionState", + "shield:DescribeProtection", + "shield:CreateProtection", + "shield:DeleteProtection", + ] + resources = ["*"] + } + + statement { + actions = [ + "ec2:AuthorizeSecurityGroupIngress", + "ec2:RevokeSecurityGroupIngress", + "ec2:CreateSecurityGroup", + ] + resources = ["*"] + } + + statement { + actions = ["ec2:CreateTags"] + resources = ["arn:${local.partition}:ec2:*:*:security-group/*"] + + condition { + test = "StringEquals" + variable = "ec2:CreateAction" + values = ["CreateSecurityGroup"] + } + + condition { + test = "Null" + variable = "aws:RequestTag/elbv2.k8s.aws/cluster" + values = ["false"] + } + } + + statement { + actions = [ + "ec2:CreateTags", + "ec2:DeleteTags", + ] + resources = ["arn:${local.partition}:ec2:*:*:security-group/*"] + + condition { + test = "Null" + variable = "aws:RequestTag/elbv2.k8s.aws/cluster" + values = ["true"] + } + + condition { + test = "Null" + variable = "aws:ResourceTag/elbv2.k8s.aws/cluster" + values = ["false"] + } + } + + statement { + actions = [ + "ec2:AuthorizeSecurityGroupIngress", + "ec2:RevokeSecurityGroupIngress", + "ec2:DeleteSecurityGroup", + ] + resources = ["*"] + + condition { + test = "Null" + variable = "aws:ResourceTag/elbv2.k8s.aws/cluster" + values = ["false"] + } + } + + statement { + actions = [ + "elasticloadbalancing:CreateLoadBalancer", + "elasticloadbalancing:CreateTargetGroup", + ] + resources = ["*"] + + condition { + test = "Null" + variable = "aws:RequestTag/elbv2.k8s.aws/cluster" + values = ["false"] + } + } + + statement { + actions = [ + "elasticloadbalancing:CreateListener", + "elasticloadbalancing:DeleteListener", + "elasticloadbalancing:CreateRule", + "elasticloadbalancing:DeleteRule", + ] + resources = ["*"] + } + + statement { + actions = [ + "elasticloadbalancing:AddTags", + "elasticloadbalancing:RemoveTags", + ] + resources = [ + "arn:${local.partition}:elasticloadbalancing:*:*:targetgroup/*/*", + "arn:${local.partition}:elasticloadbalancing:*:*:loadbalancer/net/*/*", + "arn:${local.partition}:elasticloadbalancing:*:*:loadbalancer/app/*/*", + ] + + condition { + test = "Null" + variable = "aws:RequestTag/elbv2.k8s.aws/cluster" + values = ["true"] + } + + condition { + test = "Null" + variable = "aws:ResourceTag/elbv2.k8s.aws/cluster" + values = ["false"] + } + } + + statement { + actions = [ + "elasticloadbalancing:AddTags", + "elasticloadbalancing:RemoveTags", + ] + resources = [ + "arn:${local.partition}:elasticloadbalancing:*:*:listener/net/*/*/*", + "arn:${local.partition}:elasticloadbalancing:*:*:listener/app/*/*/*", + "arn:${local.partition}:elasticloadbalancing:*:*:listener-rule/net/*/*/*", + "arn:${local.partition}:elasticloadbalancing:*:*:listener-rule/app/*/*/*", + ] + } + + statement { + actions = [ + "elasticloadbalancing:ModifyLoadBalancerAttributes", + "elasticloadbalancing:SetIpAddressType", + "elasticloadbalancing:SetSecurityGroups", + "elasticloadbalancing:SetSubnets", + "elasticloadbalancing:DeleteLoadBalancer", + "elasticloadbalancing:ModifyTargetGroup", + "elasticloadbalancing:ModifyTargetGroupAttributes", + "elasticloadbalancing:DeleteTargetGroup", + ] + resources = ["*"] + + condition { + test = "Null" + variable = "aws:ResourceTag/elbv2.k8s.aws/cluster" + values = ["false"] + } + } + + statement { + actions = [ + "elasticloadbalancing:RegisterTargets", + "elasticloadbalancing:DeregisterTargets", + ] + resources = ["arn:${local.partition}:elasticloadbalancing:*:*:targetgroup/*/*"] + } + + statement { + actions = [ + "elasticloadbalancing:SetWebAcl", + "elasticloadbalancing:ModifyListener", + "elasticloadbalancing:AddListenerCertificates", + "elasticloadbalancing:RemoveListenerCertificates", + "elasticloadbalancing:ModifyRule", + ] + resources = ["*"] + } +} + +resource "aws_iam_policy" "load_balancer_controller" { + count = var.create_role && var.attach_load_balancer_controller_policy ? 1 : 0 + + name_prefix = "${var.policy_name_prefix}AWS_Load_Balancer_Controller-" + path = var.role_path + description = "Provides permissions for AWS Load Balancer Controller addon" + policy = data.aws_iam_policy_document.load_balancer_controller[0].json + + tags = var.tags +} + +resource "aws_iam_role_policy_attachment" "load_balancer_controller" { + count = var.create_role && var.attach_load_balancer_controller_policy ? 1 : 0 + + role = aws_iam_role.this[0].name + policy_arn = aws_iam_policy.load_balancer_controller[0].arn +} + +################################################################################ +# AWS Load Balancer Controller TargetGroup Binding Only Policy +################################################################################ + +# https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.4/guide/targetgroupbinding/targetgroupbinding/#reference +# https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.4/deploy/installation/#setup-iam-manually +data "aws_iam_policy_document" "load_balancer_controller_targetgroup_only" { + count = var.create_role && var.attach_load_balancer_controller_targetgroup_binding_only_policy ? 1 : 0 + + statement { + actions = [ + "ec2:DescribeSecurityGroups", + "ec2:DescribeInstances", + "ec2:DescribeVpcs", + "elasticloadbalancing:DescribeTargetGroups", + "elasticloadbalancing:DescribeTargetHealth", + "elasticloadbalancing:ModifyTargetGroup", + "elasticloadbalancing:ModifyTargetGroupAttributes", + "elasticloadbalancing:RegisterTargets", + "elasticloadbalancing:DeregisterTargets" + ] + + resources = ["*"] + } +} + +resource "aws_iam_policy" "load_balancer_controller_targetgroup_only" { + count = var.create_role && var.attach_load_balancer_controller_targetgroup_binding_only_policy ? 1 : 0 + + name_prefix = "${var.policy_name_prefix}AWS_Load_Balancer_Controller_TargetGroup_Only-" + path = var.role_path + description = "Provides permissions for AWS Load Balancer Controller addon in TargetGroup binding only scenario" + policy = data.aws_iam_policy_document.load_balancer_controller_targetgroup_only[0].json + + tags = var.tags +} + +resource "aws_iam_role_policy_attachment" "load_balancer_controller_targetgroup_only" { + count = var.create_role && var.attach_load_balancer_controller_targetgroup_binding_only_policy ? 1 : 0 + + role = aws_iam_role.this[0].name + policy_arn = aws_iam_policy.load_balancer_controller_targetgroup_only[0].arn +} + +################################################################################ +# Appmesh Controller +################################################################################ +# https://github.com/aws/eks-charts/tree/master/stable/appmesh-controller#prerequisites +# https://raw.githubusercontent.com/aws/aws-app-mesh-controller-for-k8s/master/config/iam/controller-iam-policy.json +data "aws_iam_policy_document" "appmesh_controller" { + count = var.create_role && var.attach_appmesh_controller_policy ? 1 : 0 + + statement { + actions = [ + "appmesh:ListVirtualRouters", + "appmesh:ListVirtualServices", + "appmesh:ListRoutes", + "appmesh:ListGatewayRoutes", + "appmesh:ListMeshes", + "appmesh:ListVirtualNodes", + "appmesh:ListVirtualGateways", + "appmesh:DescribeMesh", + "appmesh:DescribeVirtualRouter", + "appmesh:DescribeRoute", + "appmesh:DescribeVirtualNode", + "appmesh:DescribeVirtualGateway", + "appmesh:DescribeGatewayRoute", + "appmesh:DescribeVirtualService", + "appmesh:CreateMesh", + "appmesh:CreateVirtualRouter", + "appmesh:CreateVirtualGateway", + "appmesh:CreateVirtualService", + "appmesh:CreateGatewayRoute", + "appmesh:CreateRoute", + "appmesh:CreateVirtualNode", + "appmesh:UpdateMesh", + "appmesh:UpdateRoute", + "appmesh:UpdateVirtualGateway", + "appmesh:UpdateVirtualRouter", + "appmesh:UpdateGatewayRoute", + "appmesh:UpdateVirtualService", + "appmesh:UpdateVirtualNode", + "appmesh:DeleteMesh", + "appmesh:DeleteRoute", + "appmesh:DeleteVirtualRouter", + "appmesh:DeleteGatewayRoute", + "appmesh:DeleteVirtualService", + "appmesh:DeleteVirtualNode", + "appmesh:DeleteVirtualGateway" + ] + resources = ["*"] + } + + statement { + actions = [ + "iam:CreateServiceLinkedRole" + ] + resources = ["arn:${local.partition}:iam::*:role/aws-service-role/appmesh.${local.dns_suffix}/AWSServiceRoleForAppMesh"] + condition { + test = "StringLike" + variable = "iam:AWSServiceName" + values = ["appmesh.${local.dns_suffix}"] + } + } + + statement { + actions = [ + "acm:ListCertificates", + "acm:DescribeCertificate", + "acm-pca:DescribeCertificateAuthority", + "acm-pca:ListCertificateAuthorities" + ] + resources = ["*"] + } + + statement { + actions = [ + "servicediscovery:CreateService", + "servicediscovery:DeleteService", + "servicediscovery:GetService", + "servicediscovery:GetInstance", + "servicediscovery:RegisterInstance", + "servicediscovery:DeregisterInstance", + "servicediscovery:ListInstances", + "servicediscovery:ListNamespaces", + "servicediscovery:ListServices", + "servicediscovery:GetInstancesHealthStatus", + "servicediscovery:UpdateInstanceCustomHealthStatus", + "servicediscovery:GetOperation", + "route53:GetHealthCheck", + "route53:CreateHealthCheck", + "route53:UpdateHealthCheck", + "route53:ChangeResourceRecordSets", + "route53:DeleteHealthCheck" + ] + resources = ["*"] + } +} + +resource "aws_iam_policy" "appmesh_controller" { + count = var.create_role && var.attach_appmesh_controller_policy ? 1 : 0 + + name_prefix = "${var.policy_name_prefix}Appmesh_Controller-" + path = var.role_path + description = "Provides permissions to for appmesh controller" + policy = data.aws_iam_policy_document.appmesh_controller[0].json + + tags = var.tags +} + +resource "aws_iam_role_policy_attachment" "appmesh_controller" { + count = var.create_role && var.attach_appmesh_controller_policy ? 1 : 0 + + role = aws_iam_role.this[0].name + policy_arn = aws_iam_policy.appmesh_controller[0].arn +} + +################################################################################ +# Appmesh envoy proxy +################################################################################ +# https://github.com/aws/aws-app-mesh-controller-for-k8s/blob/f4a551399c4a4428d31692d0e6d944c2b78f2753/config/helm/appmesh-controller/README.md#with-irsa +# https://raw.githubusercontent.com/aws/aws-app-mesh-controller-for-k8s/master/config/iam/envoy-iam-policy.json +data "aws_iam_policy_document" "appmesh_envoy_proxy" { + count = var.create_role && var.attach_appmesh_envoy_proxy_policy ? 1 : 0 + + statement { + actions = [ + "appmesh:StreamAggregatedResources" + ] + resources = ["*"] + } + + statement { + actions = [ + "acm:ExportCertificate", + "acm-pca:GetCertificateAuthorityCertificate" + ] + resources = ["*"] + } +} + +resource "aws_iam_policy" "appmesh_envoy_proxy" { + count = var.create_role && var.attach_appmesh_envoy_proxy_policy ? 1 : 0 + + name_prefix = "${var.policy_name_prefix}Appmesh_Envoy_Proxy-" + path = var.role_path + description = "Provides permissions to for appmesh envoy proxy" + policy = data.aws_iam_policy_document.appmesh_envoy_proxy[0].json + + tags = var.tags +} + +resource "aws_iam_role_policy_attachment" "appmesh_envoy_proxy" { + count = var.create_role && var.attach_appmesh_envoy_proxy_policy ? 1 : 0 + + role = aws_iam_role.this[0].name + policy_arn = aws_iam_policy.appmesh_envoy_proxy[0].arn +} + +################################################################################ +# Amazon Managed Service for Prometheus Policy +################################################################################ + +# https://docs.aws.amazon.com/prometheus/latest/userguide/set-up-irsa.html +data "aws_iam_policy_document" "amazon_managed_service_prometheus" { + count = var.create_role && var.attach_amazon_managed_service_prometheus_policy ? 1 : 0 + + statement { + actions = [ + "aps:RemoteWrite", + "aps:QueryMetrics", + "aps:GetSeries", + "aps:GetLabels", + "aps:GetMetricMetadata", + ] + + resources = var.amazon_managed_service_prometheus_workspace_arns + } +} + +resource "aws_iam_policy" "amazon_managed_service_prometheus" { + count = var.create_role && var.attach_amazon_managed_service_prometheus_policy ? 1 : 0 + + name_prefix = "${var.policy_name_prefix}Managed_Service_Prometheus_Policy-" + path = var.role_path + description = "Provides permissions to for Amazon Managed Service for Prometheus" + policy = data.aws_iam_policy_document.amazon_managed_service_prometheus[0].json + + tags = var.tags +} + +resource "aws_iam_role_policy_attachment" "amazon_managed_service_prometheus" { + count = var.create_role && var.attach_amazon_managed_service_prometheus_policy ? 1 : 0 + + role = aws_iam_role.this[0].name + policy_arn = aws_iam_policy.amazon_managed_service_prometheus[0].arn +} + +################################################################################ +# Node Termination Handler Policy +################################################################################ + +# https://github.com/aws/aws-node-termination-handler#5-create-an-iam-role-for-the-pods +data "aws_iam_policy_document" "node_termination_handler" { + count = var.create_role && var.attach_node_termination_handler_policy ? 1 : 0 + + statement { + actions = [ + "autoscaling:CompleteLifecycleAction", + "autoscaling:DescribeAutoScalingInstances", + "autoscaling:DescribeTags", + "ec2:DescribeInstances", + ] + + resources = ["*"] + } + + statement { + actions = [ + "sqs:DeleteMessage", + "sqs:ReceiveMessage", + ] + + resources = var.node_termination_handler_sqs_queue_arns + } +} + +resource "aws_iam_policy" "node_termination_handler" { + count = var.create_role && var.attach_node_termination_handler_policy ? 1 : 0 + + name_prefix = "${var.policy_name_prefix}Node_Termination_Handler_Policy-" + path = var.role_path + description = "Provides permissions to handle node termination events via the Node Termination Handler" + policy = data.aws_iam_policy_document.node_termination_handler[0].json + + tags = var.tags +} + +resource "aws_iam_role_policy_attachment" "node_termination_handler" { + count = var.create_role && var.attach_node_termination_handler_policy ? 1 : 0 + + role = aws_iam_role.this[0].name + policy_arn = aws_iam_policy.node_termination_handler[0].arn +} + +################################################################################ +# Velero Policy +################################################################################ + +# https://github.com/vmware-tanzu/velero-plugin-for-aws#set-permissions-for-velero +data "aws_iam_policy_document" "velero" { + count = var.create_role && var.attach_velero_policy ? 1 : 0 + + statement { + sid = "Ec2ReadWrite" + actions = [ + "ec2:DescribeVolumes", + "ec2:DescribeSnapshots", + "ec2:CreateTags", + "ec2:CreateVolume", + "ec2:CreateSnapshot", + "ec2:DeleteSnapshot", + ] + resources = ["*"] + } + + statement { + sid = "S3ReadWrite" + actions = [ + "s3:GetObject", + "s3:DeleteObject", + "s3:PutObject", + "s3:AbortMultipartUpload", + "s3:ListMultipartUploadParts", + ] + resources = [for bucket in var.velero_s3_bucket_arns : "${bucket}/*"] + } + + statement { + sid = "S3List" + actions = [ + "s3:ListBucket", + ] + resources = var.velero_s3_bucket_arns + } +} + +resource "aws_iam_policy" "velero" { + count = var.create_role && var.attach_velero_policy ? 1 : 0 + + name_prefix = "${var.policy_name_prefix}Velero_Policy-" + path = var.role_path + description = "Provides Velero permissions to backup and restore cluster resources" + policy = data.aws_iam_policy_document.velero[0].json + + tags = var.tags +} + +resource "aws_iam_role_policy_attachment" "velero" { + count = var.create_role && var.attach_velero_policy ? 1 : 0 + + role = aws_iam_role.this[0].name + policy_arn = aws_iam_policy.velero[0].arn +} + +################################################################################ +# VPC CNI Policy +################################################################################ + +data "aws_iam_policy_document" "vpc_cni" { + count = var.create_role && var.attach_vpc_cni_policy ? 1 : 0 + + # arn:${local.partition}:iam::aws:policy/AmazonEKS_CNI_Policy + dynamic "statement" { + for_each = var.vpc_cni_enable_ipv4 ? [1] : [] + content { + sid = "IPV4" + actions = [ + "ec2:AssignPrivateIpAddresses", + "ec2:AttachNetworkInterface", + "ec2:CreateNetworkInterface", + "ec2:DeleteNetworkInterface", + "ec2:DescribeInstances", + "ec2:DescribeTags", + "ec2:DescribeNetworkInterfaces", + "ec2:DescribeInstanceTypes", + "ec2:DetachNetworkInterface", + "ec2:ModifyNetworkInterfaceAttribute", + "ec2:UnassignPrivateIpAddresses", + ] + resources = ["*"] + } + } + + # https://docs.aws.amazon.com/eks/latest/userguide/cni-iam-role.html#cni-iam-role-create-ipv6-policy + dynamic "statement" { + for_each = var.vpc_cni_enable_ipv6 ? [1] : [] + content { + sid = "IPV6" + actions = [ + "ec2:AssignIpv6Addresses", + "ec2:DescribeInstances", + "ec2:DescribeTags", + "ec2:DescribeNetworkInterfaces", + "ec2:DescribeInstanceTypes", + ] + resources = ["*"] + } + } + + statement { + sid = "CreateTags" + actions = ["ec2:CreateTags"] + resources = ["arn:${local.partition}:ec2:*:*:network-interface/*"] + } +} + +resource "aws_iam_policy" "vpc_cni" { + count = var.create_role && var.attach_vpc_cni_policy ? 1 : 0 + + name_prefix = "${var.policy_name_prefix}CNI_Policy-" + path = var.role_path + description = "Provides the Amazon VPC CNI Plugin (amazon-vpc-cni-k8s) the permissions it requires to modify the IPv4/IPv6 address configuration on your EKS worker nodes" + policy = data.aws_iam_policy_document.vpc_cni[0].json + + tags = var.tags +} + +resource "aws_iam_role_policy_attachment" "vpc_cni" { + count = var.create_role && var.attach_vpc_cni_policy ? 1 : 0 + + role = aws_iam_role.this[0].name + policy_arn = aws_iam_policy.vpc_cni[0].arn +} diff --git a/modules/aws-iam/modules/iam-role-for-service-accounts-eks/variables.tf b/modules/aws-iam/modules/iam-role-for-service-accounts-eks/variables.tf new file mode 100644 index 0000000..3d9504f --- /dev/null +++ b/modules/aws-iam/modules/iam-role-for-service-accounts-eks/variables.tf @@ -0,0 +1,297 @@ +variable "create_role" { + description = "Whether to create a role" + type = bool + default = true +} + +variable "role_name" { + description = "Name of IAM role" + type = string + default = null +} + +variable "role_path" { + description = "Path of IAM role" + type = string + default = null +} + +variable "role_permissions_boundary_arn" { + description = "Permissions boundary ARN to use for IAM role" + type = string + default = null +} + +variable "role_description" { + description = "IAM Role description" + type = string + default = null +} + +variable "role_name_prefix" { + description = "IAM role name prefix" + type = string + default = null +} + +variable "policy_name_prefix" { + description = "IAM policy name prefix" + type = string + default = "AmazonEKS_" +} + +variable "role_policy_arns" { + description = "ARNs of any policies to attach to the IAM role" + type = map(string) + default = {} +} + +variable "oidc_providers" { + description = "Map of OIDC providers where each provider map should contain the `provider`, `provider_arn`, and `namespace_service_accounts`" + type = any + default = {} +} + +variable "tags" { + description = "A map of tags to add the the IAM role" + type = map(any) + default = {} +} + +variable "force_detach_policies" { + description = "Whether policies should be detached from this role when destroying" + type = bool + default = true +} + +variable "max_session_duration" { + description = "Maximum CLI/API session duration in seconds between 3600 and 43200" + type = number + default = null +} + +variable "assume_role_condition_test" { + description = "Name of the [IAM condition operator](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html) to evaluate when assuming the role" + type = string + default = "StringEquals" +} + +################################################################################ +# Policies +################################################################################ + +# Cert Manager +variable "attach_cert_manager_policy" { + description = "Determines whether to attach the Cert Manager IAM policy to the role" + type = bool + default = false +} + +variable "cert_manager_hosted_zone_arns" { + description = "Route53 hosted zone ARNs to allow Cert manager to manage records" + type = list(string) + default = ["arn:aws:route53:::hostedzone/*"] +} + +# Cluster autoscaler +variable "attach_cluster_autoscaler_policy" { + description = "Determines whether to attach the Cluster Autoscaler IAM policy to the role" + type = bool + default = false +} + +variable "cluster_autoscaler_cluster_ids" { + description = "List of cluster IDs to appropriately scope permissions within the Cluster Autoscaler IAM policy" + type = list(string) + default = [] +} + +# EBS CSI +variable "attach_ebs_csi_policy" { + description = "Determines whether to attach the EBS CSI IAM policy to the role" + type = bool + default = false +} + +variable "ebs_csi_kms_cmk_ids" { + description = "KMS CMK IDs to allow EBS CSI to manage encrypted volumes" + type = list(string) + default = [] +} + +# EFS CSI +variable "attach_efs_csi_policy" { + description = "Determines whether to attach the EFS CSI IAM policy to the role" + type = bool + default = false +} + +# External DNS +variable "attach_external_dns_policy" { + description = "Determines whether to attach the External DNS IAM policy to the role" + type = bool + default = false +} + +variable "external_dns_hosted_zone_arns" { + description = "Route53 hosted zone ARNs to allow External DNS to manage records" + type = list(string) + default = ["arn:aws:route53:::hostedzone/*"] +} + +# External Secrets +variable "attach_external_secrets_policy" { + description = "Determines whether to attach the External Secrets policy to the role" + type = bool + default = false +} + +variable "external_secrets_ssm_parameter_arns" { + description = "List of Systems Manager Parameter ARNs that contain secrets to mount using External Secrets" + type = list(string) + default = ["arn:aws:ssm:*:*:parameter/*"] +} + +variable "external_secrets_secrets_manager_arns" { + description = "List of Secrets Manager ARNs that contain secrets to mount using External Secrets" + type = list(string) + default = ["arn:aws:secretsmanager:*:*:secret:*"] +} + +# FSx Lustre CSI +variable "attach_fsx_lustre_csi_policy" { + description = "Determines whether to attach the FSx for Lustre CSI Driver IAM policy to the role" + type = bool + default = false +} + +variable "fsx_lustre_csi_service_role_arns" { + description = "Service role ARNs to allow FSx for Lustre CSI create and manage FSX for Lustre service linked roles" + type = list(string) + default = ["arn:aws:iam::*:role/aws-service-role/s3.data-source.lustre.fsx.amazonaws.com/*"] +} + +# Karpenter controller +variable "attach_karpenter_controller_policy" { + description = "Determines whether to attach the Karpenter Controller policy to the role" + type = bool + default = false +} + +variable "karpenter_controller_cluster_id" { + description = "Cluster ID where the Karpenter controller is provisioned/managing" + type = string + default = "*" +} + +variable "karpenter_tag_key" { + description = "Tag key (`{key = value}`) applied to resources launched by Karpenter through the Karpenter provisioner" + type = string + default = "karpenter.sh/discovery" +} + +variable "karpenter_controller_ssm_parameter_arns" { + description = "List of SSM Parameter ARNs that contain AMI IDs launched by Karpenter" + type = list(string) + # https://github.com/aws/karpenter/blob/ed9473a9863ca949b61b9846c8b9f33f35b86dbd/pkg/cloudprovider/aws/ami.go#L105-L123 + default = ["arn:aws:ssm:*:*:parameter/aws/service/*"] +} + +variable "karpenter_controller_node_iam_role_arns" { + description = "List of node IAM role ARNs Karpenter can use to launch nodes" + type = list(string) + default = ["*"] +} + +variable "karpenter_subnet_account_id" { + description = "Account ID of where the subnets Karpenter will utilize resides. Used when subnets are shared from another account" + type = string + default = "" +} + +# AWS Load Balancer Controller +variable "attach_load_balancer_controller_policy" { + description = "Determines whether to attach the Load Balancer Controller policy to the role" + type = bool + default = false +} + +# https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.4/guide/targetgroupbinding/targetgroupbinding/#reference +# https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.4/deploy/installation/#setup-iam-manually +variable "attach_load_balancer_controller_targetgroup_binding_only_policy" { + description = "Determines whether to attach the Load Balancer Controller policy for the TargetGroupBinding only" + type = bool + default = false +} + +# AWS Appmesh Controller +variable "attach_appmesh_controller_policy" { + description = "Determines whether to attach the Appmesh Controller policy to the role" + type = bool + default = false +} + +# AWS Appmesh envoy proxy +variable "attach_appmesh_envoy_proxy_policy" { + description = "Determines whether to attach the Appmesh envoy proxy policy to the role" + type = bool + default = false +} + +# Amazon Managed Service for Prometheus +variable "attach_amazon_managed_service_prometheus_policy" { + description = "Determines whether to attach the Amazon Managed Service for Prometheus IAM policy to the role" + type = bool + default = false +} + +variable "amazon_managed_service_prometheus_workspace_arns" { + description = "List of AMP Workspace ARNs to read and write metrics" + type = list(string) + default = ["*"] +} + +# Velero +variable "attach_velero_policy" { + description = "Determines whether to attach the Velero IAM policy to the role" + type = bool + default = false +} + +variable "velero_s3_bucket_arns" { + description = "List of S3 Bucket ARNs that Velero needs access to in order to backup and restore cluster resources" + type = list(string) + default = ["*"] +} + +# VPC CNI +variable "attach_vpc_cni_policy" { + description = "Determines whether to attach the VPC CNI IAM policy to the role" + type = bool + default = false +} + +variable "vpc_cni_enable_ipv4" { + description = "Determines whether to enable IPv4 permissions for VPC CNI policy" + type = bool + default = false +} + +variable "vpc_cni_enable_ipv6" { + description = "Determines whether to enable IPv6 permissions for VPC CNI policy" + type = bool + default = false +} + +# Node termination handler +variable "attach_node_termination_handler_policy" { + description = "Determines whether to attach the Node Termination Handler policy to the role" + type = bool + default = false +} + +variable "node_termination_handler_sqs_queue_arns" { + description = "List of SQS ARNs that contain node termination events" + type = list(string) + default = ["*"] +} diff --git a/modules/aws-iam/modules/iam-role-for-service-accounts-eks/versions.tf b/modules/aws-iam/modules/iam-role-for-service-accounts-eks/versions.tf new file mode 100644 index 0000000..d8dd1a4 --- /dev/null +++ b/modules/aws-iam/modules/iam-role-for-service-accounts-eks/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.0" + } + } +} diff --git a/modules/aws-iam/modules/iam-user/README.md b/modules/aws-iam/modules/iam-user/README.md new file mode 100644 index 0000000..15925ff --- /dev/null +++ b/modules/aws-iam/modules/iam-user/README.md @@ -0,0 +1,94 @@ +# iam-user + +Creates IAM user, IAM login profile, IAM access key and uploads IAM SSH user public key. All of these are optional resources. + +## Notes for keybase users + +**If possible, always use PGP encryption to prevent Terraform from keeping unencrypted password and access secret key in state file.** + +### Keybase pre-requisits + +When `pgp_key` is specified as `keybase:username`, make sure that that user has already uploaded public key to keybase.io. For example, user with username `test` has done it properly and you can [verify it here](https://keybase.io/test/pgp_keys.asc). + +### How to decrypt user's encrypted password and secret key + +This module outputs commands and PGP messages which can be decrypted either using [keybase.io web-site](https://keybase.io/decrypt) or using command line to get user's password and user's secret key: +- `keybase_password_decrypt_command` +- `keybase_secret_key_decrypt_command` +- `keybase_ses_smtp_password_v4_decrypt_command` +- `keybase_password_pgp_message` +- `keybase_secret_key_pgp_message` +- `keybase_ses_smtp_password_v4_pgp_message` + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.0 | +| [aws](#requirement\_aws) | >= 4.0 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 4.0 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_iam_access_key.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_access_key) | resource | +| [aws_iam_access_key.this_no_pgp](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_access_key) | resource | +| [aws_iam_user.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_user) | resource | +| [aws_iam_user_login_profile.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_user_login_profile) | resource | +| [aws_iam_user_ssh_key.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_user_ssh_key) | resource | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [create\_iam\_access\_key](#input\_create\_iam\_access\_key) | Whether to create IAM access key | `bool` | `true` | no | +| [create\_iam\_user\_login\_profile](#input\_create\_iam\_user\_login\_profile) | Whether to create IAM user login profile | `bool` | `true` | no | +| [create\_user](#input\_create\_user) | Whether to create the IAM user | `bool` | `true` | no | +| [force\_destroy](#input\_force\_destroy) | When destroying this user, destroy even if it has non-Terraform-managed IAM access keys, login profile or MFA devices. Without force\_destroy a user with non-Terraform-managed access keys and login profile will fail to be destroyed. | `bool` | `false` | no | +| [name](#input\_name) | Desired name for the IAM user | `string` | n/a | yes | +| [password\_length](#input\_password\_length) | The length of the generated password | `number` | `20` | no | +| [password\_reset\_required](#input\_password\_reset\_required) | Whether the user should be forced to reset the generated password on first login. | `bool` | `true` | no | +| [path](#input\_path) | Desired path for the IAM user | `string` | `"/"` | no | +| [permissions\_boundary](#input\_permissions\_boundary) | The ARN of the policy that is used to set the permissions boundary for the user. | `string` | `""` | no | +| [pgp\_key](#input\_pgp\_key) | Either a base-64 encoded PGP public key, or a keybase username in the form `keybase:username`. Used to encrypt password and access key. | `string` | `""` | no | +| [ssh\_key\_encoding](#input\_ssh\_key\_encoding) | Specifies the public key encoding format to use in the response. To retrieve the public key in ssh-rsa format, use SSH. To retrieve the public key in PEM format, use PEM | `string` | `"SSH"` | no | +| [ssh\_public\_key](#input\_ssh\_public\_key) | The SSH public key. The public key must be encoded in ssh-rsa format or PEM format | `string` | `""` | no | +| [tags](#input\_tags) | A map of tags to add to all resources. | `map(string)` | `{}` | no | +| [upload\_iam\_user\_ssh\_key](#input\_upload\_iam\_user\_ssh\_key) | Whether to upload a public ssh key to the IAM user | `bool` | `false` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [iam\_access\_key\_encrypted\_secret](#output\_iam\_access\_key\_encrypted\_secret) | The encrypted secret, base64 encoded | +| [iam\_access\_key\_encrypted\_ses\_smtp\_password\_v4](#output\_iam\_access\_key\_encrypted\_ses\_smtp\_password\_v4) | The encrypted secret access key converted into an SES SMTP password by applying AWS's Sigv4 conversion algorithm | +| [iam\_access\_key\_id](#output\_iam\_access\_key\_id) | The access key ID | +| [iam\_access\_key\_key\_fingerprint](#output\_iam\_access\_key\_key\_fingerprint) | The fingerprint of the PGP key used to encrypt the secret | +| [iam\_access\_key\_secret](#output\_iam\_access\_key\_secret) | The access key secret | +| [iam\_access\_key\_ses\_smtp\_password\_v4](#output\_iam\_access\_key\_ses\_smtp\_password\_v4) | The secret access key converted into an SES SMTP password by applying AWS's Sigv4 conversion algorithm | +| [iam\_access\_key\_status](#output\_iam\_access\_key\_status) | Active or Inactive. Keys are initially active, but can be made inactive by other means. | +| [iam\_user\_arn](#output\_iam\_user\_arn) | The ARN assigned by AWS for this user | +| [iam\_user\_login\_profile\_encrypted\_password](#output\_iam\_user\_login\_profile\_encrypted\_password) | The encrypted password, base64 encoded | +| [iam\_user\_login\_profile\_key\_fingerprint](#output\_iam\_user\_login\_profile\_key\_fingerprint) | The fingerprint of the PGP key used to encrypt the password | +| [iam\_user\_login\_profile\_password](#output\_iam\_user\_login\_profile\_password) | The user password | +| [iam\_user\_name](#output\_iam\_user\_name) | The user's name | +| [iam\_user\_ssh\_key\_fingerprint](#output\_iam\_user\_ssh\_key\_fingerprint) | The MD5 message digest of the SSH public key | +| [iam\_user\_ssh\_key\_ssh\_public\_key\_id](#output\_iam\_user\_ssh\_key\_ssh\_public\_key\_id) | The unique identifier for the SSH public key | +| [iam\_user\_unique\_id](#output\_iam\_user\_unique\_id) | The unique ID assigned by AWS | +| [keybase\_password\_decrypt\_command](#output\_keybase\_password\_decrypt\_command) | Decrypt user password command | +| [keybase\_password\_pgp\_message](#output\_keybase\_password\_pgp\_message) | Encrypted password | +| [keybase\_secret\_key\_decrypt\_command](#output\_keybase\_secret\_key\_decrypt\_command) | Decrypt access secret key command | +| [keybase\_secret\_key\_pgp\_message](#output\_keybase\_secret\_key\_pgp\_message) | Encrypted access secret key | +| [keybase\_ses\_smtp\_password\_v4\_decrypt\_command](#output\_keybase\_ses\_smtp\_password\_v4\_decrypt\_command) | Decrypt SES SMTP password command | +| [keybase\_ses\_smtp\_password\_v4\_pgp\_message](#output\_keybase\_ses\_smtp\_password\_v4\_pgp\_message) | Encrypted SES SMTP password | +| [pgp\_key](#output\_pgp\_key) | PGP key used to encrypt sensitive data for this user (if empty - secrets are not encrypted) | diff --git a/modules/aws-iam/modules/iam-user/main.tf b/modules/aws-iam/modules/iam-user/main.tf new file mode 100644 index 0000000..792de76 --- /dev/null +++ b/modules/aws-iam/modules/iam-user/main.tf @@ -0,0 +1,45 @@ +resource "aws_iam_user" "this" { + count = var.create_user ? 1 : 0 + + name = var.name + path = var.path + force_destroy = var.force_destroy + permissions_boundary = var.permissions_boundary + + tags = var.tags +} + +resource "aws_iam_user_login_profile" "this" { + count = var.create_user && var.create_iam_user_login_profile ? 1 : 0 + + user = aws_iam_user.this[0].name + pgp_key = var.pgp_key + password_length = var.password_length + password_reset_required = var.password_reset_required + + # TODO: Remove once https://github.com/hashicorp/terraform-provider-aws/issues/23567 is resolved + lifecycle { + ignore_changes = [password_reset_required] + } +} + +resource "aws_iam_access_key" "this" { + count = var.create_user && var.create_iam_access_key && var.pgp_key != "" ? 1 : 0 + + user = aws_iam_user.this[0].name + pgp_key = var.pgp_key +} + +resource "aws_iam_access_key" "this_no_pgp" { + count = var.create_user && var.create_iam_access_key && var.pgp_key == "" ? 1 : 0 + + user = aws_iam_user.this[0].name +} + +resource "aws_iam_user_ssh_key" "this" { + count = var.create_user && var.upload_iam_user_ssh_key ? 1 : 0 + + username = aws_iam_user.this[0].name + encoding = var.ssh_key_encoding + public_key = var.ssh_public_key +} diff --git a/modules/aws-iam/modules/iam-user/outputs.tf b/modules/aws-iam/modules/iam-user/outputs.tf new file mode 100644 index 0000000..98dadef --- /dev/null +++ b/modules/aws-iam/modules/iam-user/outputs.tf @@ -0,0 +1,151 @@ +locals { + has_encrypted_password = length(compact(aws_iam_user_login_profile.this[*].encrypted_password)) > 0 + has_encrypted_secret = length(compact(aws_iam_access_key.this[*].encrypted_secret)) > 0 + has_encrypted_ses_smtp_password_v4 = length(compact(aws_iam_access_key.this[*].encrypted_ses_smtp_password_v4)) > 0 +} + +output "iam_user_name" { + description = "The user's name" + value = try(aws_iam_user.this[0].name, "") +} + +output "iam_user_arn" { + description = "The ARN assigned by AWS for this user" + value = try(aws_iam_user.this[0].arn, "") +} + +output "iam_user_unique_id" { + description = "The unique ID assigned by AWS" + value = try(aws_iam_user.this[0].unique_id, "") +} + +output "iam_user_login_profile_key_fingerprint" { + description = "The fingerprint of the PGP key used to encrypt the password" + value = try(aws_iam_user_login_profile.this[0].key_fingerprint, "") +} + +output "iam_user_login_profile_encrypted_password" { + description = "The encrypted password, base64 encoded" + value = try(aws_iam_user_login_profile.this[0].encrypted_password, "") +} + +output "iam_user_login_profile_password" { + description = "The user password" + value = lookup(try(aws_iam_user_login_profile.this[0], {}), "password", sensitive("")) + sensitive = true +} + +output "iam_access_key_id" { + description = "The access key ID" + value = try(aws_iam_access_key.this[0].id, aws_iam_access_key.this_no_pgp[0].id, "") +} + +output "iam_access_key_secret" { + description = "The access key secret" + value = try(aws_iam_access_key.this_no_pgp[0].secret, "") + sensitive = true +} + +output "iam_access_key_key_fingerprint" { + description = "The fingerprint of the PGP key used to encrypt the secret" + value = try(aws_iam_access_key.this[0].key_fingerprint, "") +} + +output "iam_access_key_encrypted_secret" { + description = "The encrypted secret, base64 encoded" + value = try(aws_iam_access_key.this[0].encrypted_secret, "") +} + +output "iam_access_key_ses_smtp_password_v4" { + description = "The secret access key converted into an SES SMTP password by applying AWS's Sigv4 conversion algorithm" + value = try(aws_iam_access_key.this_no_pgp[0].ses_smtp_password_v4, "") + sensitive = true +} + +output "iam_access_key_encrypted_ses_smtp_password_v4" { + description = "The encrypted secret access key converted into an SES SMTP password by applying AWS's Sigv4 conversion algorithm" + value = try(aws_iam_access_key.this[0].encrypted_ses_smtp_password_v4, "") +} + +output "iam_access_key_status" { + description = "Active or Inactive. Keys are initially active, but can be made inactive by other means." + value = try(aws_iam_access_key.this[0].status, aws_iam_access_key.this_no_pgp[0].status, "") +} + +output "pgp_key" { + description = "PGP key used to encrypt sensitive data for this user (if empty - secrets are not encrypted)" + value = var.pgp_key +} + +output "keybase_password_decrypt_command" { + description = "Decrypt user password command" + value = !local.has_encrypted_password ? null : <
"*"
]
[| no | +| [aws\_cli\_command](#input\_aws\_cli\_command) | Command to run as AWS CLI. May include extra arguments like region and profile. | `string` | `"aws"` | no | +| [before\_allow\_traffic\_hook\_arn](#input\_before\_allow\_traffic\_hook\_arn) | ARN of Lambda function to execute before allow traffic during deployment. This function should be named CodeDeployHook\_, to match the managed AWSCodeDeployForLambda policy, unless you're using a custom role | `string` | `""` | no | +| [codedeploy\_principals](#input\_codedeploy\_principals) | List of CodeDeploy service principals to allow. The list can include global or regional endpoints. | `list(string)` |
"DEPLOYMENT_STOP_ON_ALARM"
]
[| no | +| [codedeploy\_role\_name](#input\_codedeploy\_role\_name) | IAM role name to create or use by CodeDeploy | `string` | `""` | no | +| [create](#input\_create) | Controls whether resources should be created | `bool` | `true` | no | +| [create\_app](#input\_create\_app) | Whether to create new AWS CodeDeploy app | `bool` | `false` | no | +| [create\_codedeploy\_role](#input\_create\_codedeploy\_role) | Whether to create new AWS CodeDeploy IAM role | `bool` | `true` | no | +| [create\_deployment](#input\_create\_deployment) | Create the AWS resources and script for CodeDeploy | `bool` | `false` | no | +| [create\_deployment\_group](#input\_create\_deployment\_group) | Whether to create new AWS CodeDeploy Deployment Group | `bool` | `false` | no | +| [current\_version](#input\_current\_version) | Current version of Lambda function version to deploy (can't be $LATEST) | `string` | `""` | no | +| [deployment\_config\_name](#input\_deployment\_config\_name) | Name of deployment config to use | `string` | `"CodeDeployDefault.LambdaAllAtOnce"` | no | +| [deployment\_group\_name](#input\_deployment\_group\_name) | Name of deployment group to use | `string` | `""` | no | +| [description](#input\_description) | Description to use for the deployment | `string` | `""` | no | +| [force\_deploy](#input\_force\_deploy) | Force deployment every time (even when nothing changes) | `bool` | `false` | no | +| [function\_name](#input\_function\_name) | The name of the Lambda function to deploy | `string` | `""` | no | +| [get\_deployment\_sleep\_timer](#input\_get\_deployment\_sleep\_timer) | Adds additional sleep time to get-deployment command to avoid the service throttling | `number` | `5` | no | +| [interpreter](#input\_interpreter) | List of interpreter arguments used to execute deploy script, first arg is path | `list(string)` |
"codedeploy.amazonaws.com"
]
[| no | +| [run\_deployment](#input\_run\_deployment) | Run AWS CLI command to start the deployment | `bool` | `false` | no | +| [save\_deploy\_script](#input\_save\_deploy\_script) | Save deploy script locally | `bool` | `false` | no | +| [tags](#input\_tags) | A map of tags to assign to resources. | `map(string)` | `{}` | no | +| [target\_version](#input\_target\_version) | Target version of Lambda function version to deploy | `string` | `""` | no | +| [triggers](#input\_triggers) | Map of triggers which will be notified when event happens. Valid options for event types are DeploymentStart, DeploymentSuccess, DeploymentFailure, DeploymentStop, DeploymentRollback, DeploymentReady (Applies only to replacement instances in a blue/green deployment), InstanceStart, InstanceSuccess, InstanceFailure, InstanceReady. Note that not all are applicable for Lambda deployments. | `map(any)` | `{}` | no | +| [use\_existing\_app](#input\_use\_existing\_app) | Whether to use existing AWS CodeDeploy app | `bool` | `false` | no | +| [use\_existing\_deployment\_group](#input\_use\_existing\_deployment\_group) | Whether to use existing AWS CodeDeploy Deployment Group | `bool` | `false` | no | +| [wait\_deployment\_completion](#input\_wait\_deployment\_completion) | Wait until deployment completes. It can take a lot of time and your terraform process may lock execution for long time. | `bool` | `false` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [appspec](#output\_appspec) | Appspec data as HCL | +| [appspec\_content](#output\_appspec\_content) | Appspec data as valid JSON | +| [appspec\_sha256](#output\_appspec\_sha256) | SHA256 of Appspec JSON | +| [codedeploy\_app\_name](#output\_codedeploy\_app\_name) | Name of CodeDeploy application | +| [codedeploy\_deployment\_group\_id](#output\_codedeploy\_deployment\_group\_id) | CodeDeploy deployment group id | +| [codedeploy\_deployment\_group\_name](#output\_codedeploy\_deployment\_group\_name) | CodeDeploy deployment group name | +| [codedeploy\_iam\_role\_name](#output\_codedeploy\_iam\_role\_name) | Name of IAM role used by CodeDeploy | +| [deploy\_script](#output\_deploy\_script) | Path to a deployment script | +| [script](#output\_script) | Deployment script | + + +## Authors + +Module managed by [Anton Babenko](https://github.com/antonbabenko). Check out [serverless.tf](https://serverless.tf) to learn more about doing serverless with Terraform. + +Please reach out to [Betajob](https://www.betajob.com/) if you are looking for commercial support for your Terraform, AWS, or serverless project. + + +## License + +Apache 2 Licensed. See LICENSE for full details. diff --git a/modules/aws-lambda/modules/deploy/main.tf b/modules/aws-lambda/modules/deploy/main.tf new file mode 100644 index 0000000..f82ca37 --- /dev/null +++ b/modules/aws-lambda/modules/deploy/main.tf @@ -0,0 +1,286 @@ +locals { + # AWS CodeDeploy can't deploy when CurrentVersion is "$LATEST" + qualifier = try(data.aws_lambda_function.this[0].qualifier, "") + current_version = local.qualifier == "$LATEST" ? 1 : local.qualifier + + app_name = try(aws_codedeploy_app.this[0].name, var.app_name) + deployment_group_name = try(aws_codedeploy_deployment_group.this[0].deployment_group_name, var.deployment_group_name) + + appspec = merge({ + version = "0.0" + Resources = [ + { + MyFunction = { + Type = "AWS::Lambda::Function" + Properties = { + Name = var.function_name + Alias = var.alias_name + CurrentVersion = var.current_version != "" ? var.current_version : local.current_version + TargetVersion : var.target_version + } + } + } + ] + }, var.before_allow_traffic_hook_arn != "" || var.after_allow_traffic_hook_arn != "" ? { + Hooks = [for k, v in zipmap(["BeforeAllowTraffic", "AfterAllowTraffic"], [ + var.before_allow_traffic_hook_arn != "" ? var.before_allow_traffic_hook_arn : null, + var.after_allow_traffic_hook_arn != "" ? var.after_allow_traffic_hook_arn : null + ]) : tomap({ (k) = v }) if v != null] + } : {}) + + appspec_content = replace(jsonencode(local.appspec), "\"", "\\\"") + appspec_sha256 = sha256(jsonencode(local.appspec)) + + script = <
"/bin/bash",
"-c"
]
{| no | +| [create\_security\_group](#input\_create\_security\_group) | Set `true` to create and configure a new security group. If false, `associated_security_group_ids` must be provided. | `bool` | `true` | no | +| [delimiter](#input\_delimiter) | Delimiter to be used between ID elements.
"additional_tag_map": {},
"attributes": [],
"delimiter": null,
"descriptor_formats": {},
"enabled": true,
"environment": null,
"id_length_limit": null,
"label_key_case": null,
"label_order": [],
"label_value_case": null,
"labels_as_tags": [
"unset"
],
"name": null,
"namespace": null,
"regex_replace_chars": null,
"stage": null,
"tags": {},
"tenant": null
}
[| no | +| [maintenance\_day\_of\_week](#input\_maintenance\_day\_of\_week) | The maintenance day of the week. e.g. MONDAY, TUESDAY, or WEDNESDAY | `string` | `"SUNDAY"` | no | +| [maintenance\_time\_of\_day](#input\_maintenance\_time\_of\_day) | The maintenance time, in 24-hour format. e.g. 02:00 | `string` | `"03:00"` | no | +| [maintenance\_time\_zone](#input\_maintenance\_time\_zone) | The maintenance time zone, in either the Country/City format, or the UTC offset format. e.g. CET | `string` | `"UTC"` | no | +| [mq\_admin\_password](#input\_mq\_admin\_password) | Admin password | `list(string)` | `[]` | no | +| [mq\_admin\_password\_ssm\_parameter\_name](#input\_mq\_admin\_password\_ssm\_parameter\_name) | SSM parameter name for Admin password | `string` | `"mq_admin_password"` | no | +| [mq\_admin\_user](#input\_mq\_admin\_user) | Admin username | `list(string)` | `[]` | no | +| [mq\_admin\_user\_ssm\_parameter\_name](#input\_mq\_admin\_user\_ssm\_parameter\_name) | SSM parameter name for Admin username | `string` | `"mq_admin_username"` | no | +| [mq\_application\_password](#input\_mq\_application\_password) | Application password | `list(string)` | `[]` | no | +| [mq\_application\_password\_ssm\_parameter\_name](#input\_mq\_application\_password\_ssm\_parameter\_name) | SSM parameter name for Application password | `string` | `"mq_application_password"` | no | +| [mq\_application\_user](#input\_mq\_application\_user) | Application username | `list(string)` | `[]` | no | +| [mq\_application\_user\_ssm\_parameter\_name](#input\_mq\_application\_user\_ssm\_parameter\_name) | SSM parameter name for Application username | `string` | `"mq_application_username"` | no | +| [name](#input\_name) | ID element. Usually the component or solution name, e.g. 'app' or 'jenkins'.
"default"
]
{| no | +| [create\_security\_group](#input\_create\_security\_group) | Set `true` to create and configure a new security group. If false, `associated_security_group_ids` must be provided. | `bool` | `true` | no | +| [delimiter](#input\_delimiter) | Delimiter to be used between ID elements.
"additional_tag_map": {},
"attributes": [],
"delimiter": null,
"descriptor_formats": {},
"enabled": true,
"environment": null,
"id_length_limit": null,
"label_key_case": null,
"label_order": [],
"label_value_case": null,
"labels_as_tags": [
"unset"
],
"name": null,
"namespace": null,
"regex_replace_chars": null,
"stage": null,
"tags": {},
"tenant": null
}
[| no | +| [name](#input\_name) | ID element. Usually the component or solution name, e.g. 'app' or 'jenkins'.
"default"
]
[| no | +| [request\_interval](#input\_request\_interval) | Request Interval (must be 10 or 30) | `string` | `"30"` | no | + +## Outputs + +No outputs. + diff --git a/modules/aws-route53-health-check-main/main.tf b/modules/aws-route53-health-check-main/main.tf new file mode 100644 index 0000000..5e48c65 --- /dev/null +++ b/modules/aws-route53-health-check-main/main.tf @@ -0,0 +1,140 @@ +locals { + http_enabled = !var.disable && contains(var.health_check_type, "HTTP") + https_enabled = !var.disable && contains(var.health_check_type, "HTTPS") + tcp_enabled = !var.disable && contains(var.health_check_type, "TCP") +} + + +resource "aws_route53_health_check" "http" { + fqdn = var.dns_name + port = 80 + type = "HTTP" + resource_path = var.health_check_path + failure_threshold = var.failure_threshold + request_interval = var.request_interval + regions = var.health_check_regions + measure_latency = true + count = local.http_enabled ? 1 : 0 + + tags = { + Name = "${var.dns_name}-http" + Environment = var.environment + Automation = "Terraform" + } +} + +resource "aws_route53_health_check" "https" { + fqdn = var.dns_name + port = 443 + type = "HTTPS" + resource_path = var.health_check_path + failure_threshold = var.failure_threshold + request_interval = var.request_interval + regions = var.health_check_regions + measure_latency = true + count = local.https_enabled ? 1 : 0 + + tags = { + Name = "${var.dns_name}-https" + Environment = var.environment + Automation = "Terraform" + } +} + +resource "aws_route53_health_check" "tcp" { + fqdn = var.dns_name + port = var.port + type = "TCP" + resource_path = var.health_check_path + failure_threshold = var.failure_threshold + request_interval = var.request_interval + regions = var.health_check_regions + measure_latency = true + count = local.tcp_enabled ? 1 : 0 + + tags = { + Name = "${var.dns_name}-tcp" + Environment = var.environment + Automation = "Terraform" + } +} + +resource "aws_cloudwatch_metric_alarm" "http" { + provider = aws.us-east-1 + + alarm_name = "${var.dns_name}-status-http${var.alarm_name_suffix}" + alarm_description = "Route53 health check status for ${var.dns_name}" + count = (local.http_enabled && var.enable_cloudwatch_alarm) ? 1 : 0 + + + namespace = "AWS/Route53" + metric_name = "HealthCheckStatus" + + dimensions = { + HealthCheckId = aws_route53_health_check.http[0].id + } + + comparison_operator = "LessThanThreshold" + statistic = "Minimum" + threshold = "1" + + evaluation_periods = "1" + period = "60" + + alarm_actions = var.alarm_actions + ok_actions = var.alarm_actions + insufficient_data_actions = var.alarm_actions +} + +resource "aws_cloudwatch_metric_alarm" "https" { + provider = aws.us-east-1 + + alarm_name = "${var.dns_name}-status-https${var.alarm_name_suffix}" + alarm_description = "Route53 health check status for ${var.dns_name}" + count = (local.https_enabled && var.enable_cloudwatch_alarm) ? 1 : 0 + + namespace = "AWS/Route53" + metric_name = "HealthCheckStatus" + + dimensions = { + HealthCheckId = aws_route53_health_check.https[0].id + } + + comparison_operator = "LessThanThreshold" + statistic = "Minimum" + threshold = "1" + + evaluation_periods = "1" + period = "60" + + alarm_actions = var.alarm_actions + ok_actions = var.alarm_actions + insufficient_data_actions = var.alarm_actions +} + +resource "aws_cloudwatch_metric_alarm" "tcp" { + provider = aws.us-east-1 + + alarm_name = "${var.dns_name}-status-tcp${var.alarm_name_suffix}" + alarm_description = "Route53 health check status for ${var.dns_name}" + count = (local.tcp_enabled && var.enable_cloudwatch_alarm) ? 1 : 0 + + namespace = "AWS/Route53" + metric_name = "HealthCheckStatus" + + dimensions = { + HealthCheckId = aws_route53_health_check.tcp[0].id + } + + comparison_operator = "LessThanThreshold" + statistic = "Minimum" + threshold = "1" + + evaluation_periods = "1" + period = "60" + + alarm_actions = var.alarm_actions + ok_actions = var.alarm_actions + insufficient_data_actions = var.alarm_actions +} + diff --git a/modules/aws-route53-health-check-main/outputs.tf b/modules/aws-route53-health-check-main/outputs.tf new file mode 100644 index 0000000..bf29f90 --- /dev/null +++ b/modules/aws-route53-health-check-main/outputs.tf @@ -0,0 +1,17 @@ +output "health_check_ids" { + description = "The health check ID" + value = compact([ + try(aws_route53_health_check.http[0].id, ""), + try(aws_route53_health_check.https[0].id, ""), + try(aws_route53_health_check.tcp[0].id, ""), + ]) +} + +output "health_check_arns" { + description = "The health check ARN" + value = compact([ + try(aws_route53_health_check.http[0].arn, ""), + try(aws_route53_health_check.https[0].arn, ""), + try(aws_route53_health_check.tcp[0].arn, ""), + ]) +} diff --git a/modules/aws-route53-health-check-main/providers.tf b/modules/aws-route53-health-check-main/providers.tf new file mode 100644 index 0000000..edafcb7 --- /dev/null +++ b/modules/aws-route53-health-check-main/providers.tf @@ -0,0 +1,4 @@ +provider "aws" { + alias = "us-east-1" +} + diff --git a/modules/aws-route53-health-check-main/variables.tf b/modules/aws-route53-health-check-main/variables.tf new file mode 100644 index 0000000..9a217f6 --- /dev/null +++ b/modules/aws-route53-health-check-main/variables.tf @@ -0,0 +1,79 @@ +variable "environment" { + description = "Environment tag (e.g. prod)." + type = string +} + +variable "dns_name" { + description = "Fully-qualified domain name (FQDN) to create." + type = string +} + +variable "alarm_name_suffix" { + description = "Suffix for cloudwatch alarm name to ensure uniqueness." + type = string + default = "" +} + +variable "alarm_actions" { + description = "Actions to execute when this alarm transitions." + type = list(string) + default = [] +} + +variable "health_check_regions" { + description = "AWS Regions for health check" + type = list(string) + default = ["us-east-1", "eu-west-1", "ap-southeast-1"] +} + +variable "health_check_path" { + description = "Resource Path to check" + type = string + default = "" +} + +variable "failure_threshold" { + description = "Failure Threshold (must be less than or equal to 10)" + type = string + default = "3" +} + +variable "request_interval" { + description = "Request Interval (must be 10 or 30)" + type = string + default = "30" +} + +variable "disable" { + description = "Disable health checks" + type = bool + default = false +} + +variable "port" { + description = "Port for TCP (between 0 to 65535)" + type = number + default = 443 +} + +variable "enable_cloudwatch_alarm" { + description = "Enable cloudwatch alarm" + type = bool + default = true +} + +variable "health_check_type" { + description = <<-EOT + The health check type to use. + The value specified can either be `HTTP`, `HTTPS`, + and/or `TCP`. + + Defaults to `HTTP` and `HTTPS`. + EOT + type = set(string) + default = ["HTTP", "HTTPS"] + validation { + condition = length(setintersection(["HTTP", "HTTPS", "TCP"], var.health_check_type)) > 0 + error_message = "Health check type must be one be one of: HTTP, HTTPS, TCP." + } +} diff --git a/modules/aws-route53-health-check-main/versions.tf b/modules/aws-route53-health-check-main/versions.tf new file mode 100644 index 0000000..9fdbc79 --- /dev/null +++ b/modules/aws-route53-health-check-main/versions.tf @@ -0,0 +1,7 @@ +terraform { + required_version = ">= 0.13.0" + + required_providers { + aws = ">= 3.0" + } +} diff --git a/modules/aws-route53-records/README.md b/modules/aws-route53-records/README.md new file mode 100644 index 0000000..d76a21e --- /dev/null +++ b/modules/aws-route53-records/README.md @@ -0,0 +1,105 @@ +# Route53 Records + +This module creates DNS records in Route53 zone. + +## Usage + +```hcl +module "records" { + source = "../terraform-aws-route53-records" + version = "~> 2.0" + + zone_name = "
"us-east-1",
"us-west-1",
"us-west-2"
]
{| no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [create\_sg](#input\_create\_sg) | Whether to create security group | `bool` | `true` | no | +| [create\_timeout](#input\_create\_timeout) | Time to wait for a security group to be created | `string` | `"10m"` | no | +| [delete\_timeout](#input\_delete\_timeout) | Time to wait for a security group to be deleted | `string` | `"15m"` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"activemq": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"activemq-5671-tcp",
"activemq-8883-tcp",
"activemq-61614-tcp",
"activemq-61617-tcp",
"activemq-61619-tcp"
],
"ingress_with_self": [
"all-all"
]
},
"alertmanager": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"alertmanager-9093-tcp",
"alertmanager-9094-tcp"
],
"ingress_with_self": [
"all-all"
]
},
"carbon-relay-ng": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"carbon-line-in-tcp",
"carbon-line-in-udp",
"carbon-pickle-tcp",
"carbon-pickle-udp",
"carbon-gui-udp"
],
"ingress_with_self": [
"all-all"
]
},
"cassandra": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"cassandra-clients-tcp",
"cassandra-thrift-clients-tcp",
"cassandra-jmx-tcp"
],
"ingress_with_self": [
"all-all"
]
},
"consul": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"consul-tcp",
"consul-grpc-tcp",
"consul-webui-http-tcp",
"consul-webui-https-tcp",
"consul-dns-tcp",
"consul-dns-udp",
"consul-serf-lan-tcp",
"consul-serf-lan-udp",
"consul-serf-wan-tcp",
"consul-serf-wan-udp"
],
"ingress_with_self": [
"all-all"
]
},
"docker-swarm": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"docker-swarm-mngmt-tcp",
"docker-swarm-node-tcp",
"docker-swarm-node-udp",
"docker-swarm-overlay-udp"
],
"ingress_with_self": [
"all-all"
]
},
"elasticsearch": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"elasticsearch-rest-tcp",
"elasticsearch-java-tcp"
],
"ingress_with_self": [
"all-all"
]
},
"etcd": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"etcd-client-tcp",
"etcd-peer-tcp"
],
"ingress_with_self": [
"all-all"
]
},
"grafana": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"grafana-tcp"
],
"ingress_with_self": [
"all-all"
]
},
"graphite-statsd": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"graphite-webui",
"graphite-2003-tcp",
"graphite-2004-tcp",
"graphite-2023-tcp",
"graphite-2024-tcp",
"graphite-8080-tcp",
"graphite-8125-tcp",
"graphite-8125-udp",
"graphite-8126-tcp"
],
"ingress_with_self": [
"all-all"
]
},
"http-80": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"http-80-tcp"
],
"ingress_with_self": [
"all-all"
]
},
"http-8080": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"http-8080-tcp"
],
"ingress_with_self": [
"all-all"
]
},
"https-443": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"https-443-tcp"
],
"ingress_with_self": [
"all-all"
]
},
"https-8443": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"https-8443-tcp"
],
"ingress_with_self": [
"all-all"
]
},
"ipsec-4500": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"ipsec-4500-udp"
],
"ingress_with_self": [
"all-all"
]
},
"ipsec-500": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"ipsec-500-udp"
],
"ingress_with_self": [
"all-all"
]
},
"kafka": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"kafka-broker-tcp",
"kafka-broker-tls-tcp",
"kafka-broker-tls-public-tcp",
"kafka-broker-sasl-scram-tcp",
"kafka-broker-sasl-scram-tcp",
"kafka-broker-sasl-iam-tcp",
"kafka-broker-sasl-iam-public-tcp",
"kafka-jmx-exporter-tcp",
"kafka-node-exporter-tcp"
],
"ingress_with_self": [
"all-all"
]
},
"kibana": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"kibana-tcp"
],
"ingress_with_self": [
"all-all"
]
},
"kubernetes-api": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"kubernetes-api-tcp"
],
"ingress_with_self": [
"all-all"
]
},
"ldap": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"ldap-tcp"
],
"ingress_with_self": [
"all-all"
]
},
"ldaps": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"ldaps-tcp"
],
"ingress_with_self": [
"all-all"
]
},
"logstash": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"logstash-tcp"
],
"ingress_with_self": [
"all-all"
]
},
"memcached": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"memcached-tcp"
],
"ingress_with_self": [
"all-all"
]
},
"minio": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"minio-tcp"
],
"ingress_with_self": [
"all-all"
]
},
"mongodb": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"mongodb-27017-tcp",
"mongodb-27018-tcp",
"mongodb-27019-tcp"
],
"ingress_with_self": [
"all-all"
]
},
"mssql": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"mssql-tcp",
"mssql-udp",
"mssql-analytics-tcp",
"mssql-broker-tcp"
],
"ingress_with_self": [
"all-all"
]
},
"mysql": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"mysql-tcp"
],
"ingress_with_self": [
"all-all"
]
},
"nfs": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"nfs-tcp"
],
"ingress_with_self": [
"all-all"
]
},
"nomad": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"nomad-http-tcp",
"nomad-rpc-tcp",
"nomad-serf-tcp",
"nomad-serf-udp"
],
"ingress_with_self": [
"all-all"
]
},
"ntp": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"ntp-udp"
],
"ingress_with_self": [
"all-all"
]
},
"openvpn": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"openvpn-udp",
"openvpn-tcp",
"openvpn-https-tcp"
],
"ingress_with_self": [
"all-all"
]
},
"oracle-db": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"oracle-db-tcp"
],
"ingress_with_self": [
"all-all"
]
},
"postgresql": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"postgresql-tcp"
],
"ingress_with_self": [
"all-all"
]
},
"prometheus": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"prometheus-http-tcp",
"prometheus-pushgateway-http-tcp"
],
"ingress_with_self": [
"all-all"
]
},
"puppet": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"puppet-tcp",
"puppetdb-tcp"
],
"ingress_with_self": [
"all-all"
]
},
"rabbitmq": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"rabbitmq-4369-tcp",
"rabbitmq-5671-tcp",
"rabbitmq-5672-tcp",
"rabbitmq-15672-tcp",
"rabbitmq-25672-tcp"
],
"ingress_with_self": [
"all-all"
]
},
"rdp": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"rdp-tcp",
"rdp-udp"
],
"ingress_with_self": [
"all-all"
]
},
"redis": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"redis-tcp"
],
"ingress_with_self": [
"all-all"
]
},
"redshift": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"redshift-tcp"
],
"ingress_with_self": [
"all-all"
]
},
"smtp": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"smtp-tcp"
],
"ingress_with_self": [
"all-all"
]
},
"smtp-submission": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"smtp-submission-587-tcp",
"smtp-submission-2587-tcp"
],
"ingress_with_self": [
"all-all"
]
},
"smtps": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"smtps-465-tcp",
"smtps-2465-tcp"
],
"ingress_with_self": [
"all-all"
]
},
"solr": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"solr-tcp"
],
"ingress_with_self": [
"all-all"
]
},
"splunk": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"splunk-indexer-tcp",
"splunk-clients-tcp",
"splunk-splunkd-tcp",
"splunk-hec-tcp"
],
"ingress_with_self": [
"all-all"
]
},
"squid": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"squid-proxy-tcp"
],
"ingress_with_self": [
"all-all"
]
},
"ssh": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"ssh-tcp"
],
"ingress_with_self": [
"all-all"
]
},
"storm": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"storm-nimbus-tcp",
"storm-ui-tcp",
"storm-supervisor-tcp"
],
"ingress_with_self": [
"all-all"
]
},
"wazuh": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"wazuh-server-agent-connection-tcp",
"wazuh-server-agent-connection-udp",
"wazuh-server-agent-enrollment",
"wazuh-server-agent-cluster-daemon",
"wazuh-server-syslog-collector-tcp",
"wazuh-server-syslog-collector-udp",
"wazuh-server-restful-api",
"wazuh-indexer-restful-api",
"wazuh-dashboard"
],
"ingress_with_self": [
"all-all"
]
},
"web": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"http-80-tcp",
"http-8080-tcp",
"https-443-tcp",
"web-jmx-tcp"
],
"ingress_with_self": [
"all-all"
]
},
"winrm": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"winrm-http-tcp",
"winrm-https-tcp"
],
"ingress_with_self": [
"all-all"
]
},
"zabbix": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"zabbix-server",
"zabbix-proxy",
"zabbix-agent"
],
"ingress_with_self": [
"all-all"
]
},
"zipkin": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"zipkin-admin-tcp",
"zipkin-admin-query-tcp",
"zipkin-admin-web-tcp",
"zipkin-query-tcp",
"zipkin-web-tcp"
],
"ingress_with_self": [
"all-all"
]
},
"zookeeper": {
"egress_rules": [
"all-all"
],
"ingress_rules": [
"zookeeper-2181-tcp",
"zookeeper-2182-tls-tcp",
"zookeeper-2888-tcp",
"zookeeper-3888-tcp",
"zookeeper-jmx-tcp"
],
"ingress_with_self": [
"all-all"
]
}
}
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group - not required if create\_sg is false | `string` | `null` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [rules](#input\_rules) | Map of known security group rules (define as 'name' = ['from port', 'to port', 'protocol', 'description']) | `map(list(any))` |
"::/0"
]
{| no | +| [security\_group\_id](#input\_security\_group\_id) | ID of existing security group whose rules we will manage | `string` | `null` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | `null` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + + + + + + + diff --git a/modules/aws-security-group/main.tf b/modules/aws-security-group/main.tf new file mode 100644 index 0000000..8b75822 --- /dev/null +++ b/modules/aws-security-group/main.tf @@ -0,0 +1,812 @@ +################################## +# Get ID of created Security Group +################################## +locals { + create = var.create + + this_sg_id = var.create_sg ? concat(aws_security_group.this.*.id, aws_security_group.this_name_prefix.*.id, [""])[0] : var.security_group_id +} + +########################## +# Security group with name +########################## +resource "aws_security_group" "this" { + count = local.create && var.create_sg && !var.use_name_prefix ? 1 : 0 + + name = var.name + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + + tags = merge( + { + "Name" = format("%s", var.name) + }, + var.tags, + ) + + timeouts { + create = var.create_timeout + delete = var.delete_timeout + } +} + +################################# +# Security group with name_prefix +################################# +resource "aws_security_group" "this_name_prefix" { + count = local.create && var.create_sg && var.use_name_prefix ? 1 : 0 + + name_prefix = "${var.name}-" + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + + tags = merge( + { + "Name" = format("%s", var.name) + }, + var.tags, + ) + + lifecycle { + create_before_destroy = true + } + + timeouts { + create = var.create_timeout + delete = var.delete_timeout + } +} + +################################### +# Ingress - List of rules (simple) +################################### +# Security group rules with "cidr_blocks" and it uses list of rules names +resource "aws_security_group_rule" "ingress_rules" { + count = local.create ? length(var.ingress_rules) : 0 + + security_group_id = local.this_sg_id + type = "ingress" + + cidr_blocks = var.ingress_cidr_blocks + ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + prefix_list_ids = var.ingress_prefix_list_ids + description = var.rules[var.ingress_rules[count.index]][3] + + from_port = var.rules[var.ingress_rules[count.index]][0] + to_port = var.rules[var.ingress_rules[count.index]][1] + protocol = var.rules[var.ingress_rules[count.index]][2] +} + +# Computed - Security group rules with "cidr_blocks" and it uses list of rules names +resource "aws_security_group_rule" "computed_ingress_rules" { + count = local.create ? var.number_of_computed_ingress_rules : 0 + + security_group_id = local.this_sg_id + type = "ingress" + + cidr_blocks = var.ingress_cidr_blocks + ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + prefix_list_ids = var.ingress_prefix_list_ids + description = var.rules[var.computed_ingress_rules[count.index]][3] + + from_port = var.rules[var.computed_ingress_rules[count.index]][0] + to_port = var.rules[var.computed_ingress_rules[count.index]][1] + protocol = var.rules[var.computed_ingress_rules[count.index]][2] +} + +########################## +# Ingress - Maps of rules +########################## +# Security group rules with "source_security_group_id", but without "cidr_blocks" and "self" +resource "aws_security_group_rule" "ingress_with_source_security_group_id" { + count = local.create ? length(var.ingress_with_source_security_group_id) : 0 + + security_group_id = local.this_sg_id + type = "ingress" + + source_security_group_id = var.ingress_with_source_security_group_id[count.index]["source_security_group_id"] + prefix_list_ids = var.ingress_prefix_list_ids + description = lookup( + var.ingress_with_source_security_group_id[count.index], + "description", + "Ingress Rule", + ) + + from_port = lookup( + var.ingress_with_source_security_group_id[count.index], + "from_port", + var.rules[lookup( + var.ingress_with_source_security_group_id[count.index], + "rule", + "_", + )][0], + ) + to_port = lookup( + var.ingress_with_source_security_group_id[count.index], + "to_port", + var.rules[lookup( + var.ingress_with_source_security_group_id[count.index], + "rule", + "_", + )][1], + ) + protocol = lookup( + var.ingress_with_source_security_group_id[count.index], + "protocol", + var.rules[lookup( + var.ingress_with_source_security_group_id[count.index], + "rule", + "_", + )][2], + ) +} + +# Computed - Security group rules with "source_security_group_id", but without "cidr_blocks" and "self" +resource "aws_security_group_rule" "computed_ingress_with_source_security_group_id" { + count = local.create ? var.number_of_computed_ingress_with_source_security_group_id : 0 + + security_group_id = local.this_sg_id + type = "ingress" + + source_security_group_id = var.computed_ingress_with_source_security_group_id[count.index]["source_security_group_id"] + prefix_list_ids = var.ingress_prefix_list_ids + description = lookup( + var.computed_ingress_with_source_security_group_id[count.index], + "description", + "Ingress Rule", + ) + + from_port = lookup( + var.computed_ingress_with_source_security_group_id[count.index], + "from_port", + var.rules[lookup( + var.computed_ingress_with_source_security_group_id[count.index], + "rule", + "_", + )][0], + ) + to_port = lookup( + var.computed_ingress_with_source_security_group_id[count.index], + "to_port", + var.rules[lookup( + var.computed_ingress_with_source_security_group_id[count.index], + "rule", + "_", + )][1], + ) + protocol = lookup( + var.computed_ingress_with_source_security_group_id[count.index], + "protocol", + var.rules[lookup( + var.computed_ingress_with_source_security_group_id[count.index], + "rule", + "_", + )][2], + ) +} + +# Security group rules with "cidr_blocks", but without "ipv6_cidr_blocks", "source_security_group_id" and "self" +resource "aws_security_group_rule" "ingress_with_cidr_blocks" { + count = local.create ? length(var.ingress_with_cidr_blocks) : 0 + + security_group_id = local.this_sg_id + type = "ingress" + + cidr_blocks = split( + ",", + lookup( + var.ingress_with_cidr_blocks[count.index], + "cidr_blocks", + join(",", var.ingress_cidr_blocks), + ), + ) + prefix_list_ids = var.ingress_prefix_list_ids + description = lookup( + var.ingress_with_cidr_blocks[count.index], + "description", + "Ingress Rule", + ) + + from_port = lookup( + var.ingress_with_cidr_blocks[count.index], + "from_port", + var.rules[lookup(var.ingress_with_cidr_blocks[count.index], "rule", "_")][0], + ) + to_port = lookup( + var.ingress_with_cidr_blocks[count.index], + "to_port", + var.rules[lookup(var.ingress_with_cidr_blocks[count.index], "rule", "_")][1], + ) + protocol = lookup( + var.ingress_with_cidr_blocks[count.index], + "protocol", + var.rules[lookup(var.ingress_with_cidr_blocks[count.index], "rule", "_")][2], + ) +} + +# Computed - Security group rules with "cidr_blocks", but without "ipv6_cidr_blocks", "source_security_group_id" and "self" +resource "aws_security_group_rule" "computed_ingress_with_cidr_blocks" { + count = local.create ? var.number_of_computed_ingress_with_cidr_blocks : 0 + + security_group_id = local.this_sg_id + type = "ingress" + + cidr_blocks = split( + ",", + lookup( + var.computed_ingress_with_cidr_blocks[count.index], + "cidr_blocks", + join(",", var.ingress_cidr_blocks), + ), + ) + prefix_list_ids = var.ingress_prefix_list_ids + description = lookup( + var.computed_ingress_with_cidr_blocks[count.index], + "description", + "Ingress Rule", + ) + + from_port = lookup( + var.computed_ingress_with_cidr_blocks[count.index], + "from_port", + var.rules[lookup( + var.computed_ingress_with_cidr_blocks[count.index], + "rule", + "_", + )][0], + ) + to_port = lookup( + var.computed_ingress_with_cidr_blocks[count.index], + "to_port", + var.rules[lookup( + var.computed_ingress_with_cidr_blocks[count.index], + "rule", + "_", + )][1], + ) + protocol = lookup( + var.computed_ingress_with_cidr_blocks[count.index], + "protocol", + var.rules[lookup( + var.computed_ingress_with_cidr_blocks[count.index], + "rule", + "_", + )][2], + ) +} + +# Security group rules with "ipv6_cidr_blocks", but without "cidr_blocks", "source_security_group_id" and "self" +resource "aws_security_group_rule" "ingress_with_ipv6_cidr_blocks" { + count = local.create ? length(var.ingress_with_ipv6_cidr_blocks) : 0 + + security_group_id = local.this_sg_id + type = "ingress" + + ipv6_cidr_blocks = split( + ",", + lookup( + var.ingress_with_ipv6_cidr_blocks[count.index], + "ipv6_cidr_blocks", + join(",", var.ingress_ipv6_cidr_blocks), + ), + ) + prefix_list_ids = var.ingress_prefix_list_ids + description = lookup( + var.ingress_with_ipv6_cidr_blocks[count.index], + "description", + "Ingress Rule", + ) + + from_port = lookup( + var.ingress_with_ipv6_cidr_blocks[count.index], + "from_port", + var.rules[lookup(var.ingress_with_ipv6_cidr_blocks[count.index], "rule", "_")][0], + ) + to_port = lookup( + var.ingress_with_ipv6_cidr_blocks[count.index], + "to_port", + var.rules[lookup(var.ingress_with_ipv6_cidr_blocks[count.index], "rule", "_")][1], + ) + protocol = lookup( + var.ingress_with_ipv6_cidr_blocks[count.index], + "protocol", + var.rules[lookup(var.ingress_with_ipv6_cidr_blocks[count.index], "rule", "_")][2], + ) +} + +# Computed - Security group rules with "ipv6_cidr_blocks", but without "cidr_blocks", "source_security_group_id" and "self" +resource "aws_security_group_rule" "computed_ingress_with_ipv6_cidr_blocks" { + count = local.create ? var.number_of_computed_ingress_with_ipv6_cidr_blocks : 0 + + security_group_id = local.this_sg_id + type = "ingress" + + ipv6_cidr_blocks = split( + ",", + lookup( + var.computed_ingress_with_ipv6_cidr_blocks[count.index], + "ipv6_cidr_blocks", + join(",", var.ingress_ipv6_cidr_blocks), + ), + ) + prefix_list_ids = var.ingress_prefix_list_ids + description = lookup( + var.computed_ingress_with_ipv6_cidr_blocks[count.index], + "description", + "Ingress Rule", + ) + + from_port = lookup( + var.computed_ingress_with_ipv6_cidr_blocks[count.index], + "from_port", + var.rules[lookup( + var.computed_ingress_with_ipv6_cidr_blocks[count.index], + "rule", + "_", + )][0], + ) + to_port = lookup( + var.computed_ingress_with_ipv6_cidr_blocks[count.index], + "to_port", + var.rules[lookup( + var.computed_ingress_with_ipv6_cidr_blocks[count.index], + "rule", + "_", + )][1], + ) + protocol = lookup( + var.computed_ingress_with_ipv6_cidr_blocks[count.index], + "protocol", + var.rules[lookup( + var.computed_ingress_with_ipv6_cidr_blocks[count.index], + "rule", + "_", + )][2], + ) +} + +# Security group rules with "self", but without "cidr_blocks" and "source_security_group_id" +resource "aws_security_group_rule" "ingress_with_self" { + count = local.create ? length(var.ingress_with_self) : 0 + + security_group_id = local.this_sg_id + type = "ingress" + + self = lookup(var.ingress_with_self[count.index], "self", true) + prefix_list_ids = var.ingress_prefix_list_ids + description = lookup( + var.ingress_with_self[count.index], + "description", + "Ingress Rule", + ) + + from_port = lookup( + var.ingress_with_self[count.index], + "from_port", + var.rules[lookup(var.ingress_with_self[count.index], "rule", "_")][0], + ) + to_port = lookup( + var.ingress_with_self[count.index], + "to_port", + var.rules[lookup(var.ingress_with_self[count.index], "rule", "_")][1], + ) + protocol = lookup( + var.ingress_with_self[count.index], + "protocol", + var.rules[lookup(var.ingress_with_self[count.index], "rule", "_")][2], + ) +} + +# Computed - Security group rules with "self", but without "cidr_blocks" and "source_security_group_id" +resource "aws_security_group_rule" "computed_ingress_with_self" { + count = local.create ? var.number_of_computed_ingress_with_self : 0 + + security_group_id = local.this_sg_id + type = "ingress" + + self = lookup(var.computed_ingress_with_self[count.index], "self", true) + prefix_list_ids = var.ingress_prefix_list_ids + description = lookup( + var.computed_ingress_with_self[count.index], + "description", + "Ingress Rule", + ) + + from_port = lookup( + var.computed_ingress_with_self[count.index], + "from_port", + var.rules[lookup(var.computed_ingress_with_self[count.index], "rule", "_")][0], + ) + to_port = lookup( + var.computed_ingress_with_self[count.index], + "to_port", + var.rules[lookup(var.computed_ingress_with_self[count.index], "rule", "_")][1], + ) + protocol = lookup( + var.computed_ingress_with_self[count.index], + "protocol", + var.rules[lookup(var.computed_ingress_with_self[count.index], "rule", "_")][2], + ) +} + +################# +# End of ingress +################# + +################################## +# Egress - List of rules (simple) +################################## +# Security group rules with "cidr_blocks" and it uses list of rules names +resource "aws_security_group_rule" "egress_rules" { + count = local.create ? length(var.egress_rules) : 0 + + security_group_id = local.this_sg_id + type = "egress" + + cidr_blocks = var.egress_cidr_blocks + ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + prefix_list_ids = var.egress_prefix_list_ids + description = var.rules[var.egress_rules[count.index]][3] + + from_port = var.rules[var.egress_rules[count.index]][0] + to_port = var.rules[var.egress_rules[count.index]][1] + protocol = var.rules[var.egress_rules[count.index]][2] +} + +# Computed - Security group rules with "cidr_blocks" and it uses list of rules names +resource "aws_security_group_rule" "computed_egress_rules" { + count = local.create ? var.number_of_computed_egress_rules : 0 + + security_group_id = local.this_sg_id + type = "egress" + + cidr_blocks = var.egress_cidr_blocks + ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + prefix_list_ids = var.egress_prefix_list_ids + description = var.rules[var.computed_egress_rules[count.index]][3] + + from_port = var.rules[var.computed_egress_rules[count.index]][0] + to_port = var.rules[var.computed_egress_rules[count.index]][1] + protocol = var.rules[var.computed_egress_rules[count.index]][2] +} + +######################### +# Egress - Maps of rules +######################### +# Security group rules with "source_security_group_id", but without "cidr_blocks" and "self" +resource "aws_security_group_rule" "egress_with_source_security_group_id" { + count = local.create ? length(var.egress_with_source_security_group_id) : 0 + + security_group_id = local.this_sg_id + type = "egress" + + source_security_group_id = var.egress_with_source_security_group_id[count.index]["source_security_group_id"] + prefix_list_ids = var.egress_prefix_list_ids + description = lookup( + var.egress_with_source_security_group_id[count.index], + "description", + "Egress Rule", + ) + + from_port = lookup( + var.egress_with_source_security_group_id[count.index], + "from_port", + var.rules[lookup( + var.egress_with_source_security_group_id[count.index], + "rule", + "_", + )][0], + ) + to_port = lookup( + var.egress_with_source_security_group_id[count.index], + "to_port", + var.rules[lookup( + var.egress_with_source_security_group_id[count.index], + "rule", + "_", + )][1], + ) + protocol = lookup( + var.egress_with_source_security_group_id[count.index], + "protocol", + var.rules[lookup( + var.egress_with_source_security_group_id[count.index], + "rule", + "_", + )][2], + ) +} + +# Computed - Security group rules with "source_security_group_id", but without "cidr_blocks" and "self" +resource "aws_security_group_rule" "computed_egress_with_source_security_group_id" { + count = local.create ? var.number_of_computed_egress_with_source_security_group_id : 0 + + security_group_id = local.this_sg_id + type = "egress" + + source_security_group_id = var.computed_egress_with_source_security_group_id[count.index]["source_security_group_id"] + prefix_list_ids = var.egress_prefix_list_ids + description = lookup( + var.computed_egress_with_source_security_group_id[count.index], + "description", + "Egress Rule", + ) + + from_port = lookup( + var.computed_egress_with_source_security_group_id[count.index], + "from_port", + var.rules[lookup( + var.computed_egress_with_source_security_group_id[count.index], + "rule", + "_", + )][0], + ) + to_port = lookup( + var.computed_egress_with_source_security_group_id[count.index], + "to_port", + var.rules[lookup( + var.computed_egress_with_source_security_group_id[count.index], + "rule", + "_", + )][1], + ) + protocol = lookup( + var.computed_egress_with_source_security_group_id[count.index], + "protocol", + var.rules[lookup( + var.computed_egress_with_source_security_group_id[count.index], + "rule", + "_", + )][2], + ) +} + +# Security group rules with "cidr_blocks", but without "ipv6_cidr_blocks", "source_security_group_id" and "self" +resource "aws_security_group_rule" "egress_with_cidr_blocks" { + count = local.create ? length(var.egress_with_cidr_blocks) : 0 + + security_group_id = local.this_sg_id + type = "egress" + + cidr_blocks = split( + ",", + lookup( + var.egress_with_cidr_blocks[count.index], + "cidr_blocks", + join(",", var.egress_cidr_blocks), + ), + ) + prefix_list_ids = var.egress_prefix_list_ids + description = lookup( + var.egress_with_cidr_blocks[count.index], + "description", + "Egress Rule", + ) + + from_port = lookup( + var.egress_with_cidr_blocks[count.index], + "from_port", + var.rules[lookup(var.egress_with_cidr_blocks[count.index], "rule", "_")][0], + ) + to_port = lookup( + var.egress_with_cidr_blocks[count.index], + "to_port", + var.rules[lookup(var.egress_with_cidr_blocks[count.index], "rule", "_")][1], + ) + protocol = lookup( + var.egress_with_cidr_blocks[count.index], + "protocol", + var.rules[lookup(var.egress_with_cidr_blocks[count.index], "rule", "_")][2], + ) +} + +# Computed - Security group rules with "cidr_blocks", but without "ipv6_cidr_blocks", "source_security_group_id" and "self" +resource "aws_security_group_rule" "computed_egress_with_cidr_blocks" { + count = local.create ? var.number_of_computed_egress_with_cidr_blocks : 0 + + security_group_id = local.this_sg_id + type = "egress" + + cidr_blocks = split( + ",", + lookup( + var.computed_egress_with_cidr_blocks[count.index], + "cidr_blocks", + join(",", var.egress_cidr_blocks), + ), + ) + prefix_list_ids = var.egress_prefix_list_ids + description = lookup( + var.computed_egress_with_cidr_blocks[count.index], + "description", + "Egress Rule", + ) + + from_port = lookup( + var.computed_egress_with_cidr_blocks[count.index], + "from_port", + var.rules[lookup( + var.computed_egress_with_cidr_blocks[count.index], + "rule", + "_", + )][0], + ) + to_port = lookup( + var.computed_egress_with_cidr_blocks[count.index], + "to_port", + var.rules[lookup( + var.computed_egress_with_cidr_blocks[count.index], + "rule", + "_", + )][1], + ) + protocol = lookup( + var.computed_egress_with_cidr_blocks[count.index], + "protocol", + var.rules[lookup( + var.computed_egress_with_cidr_blocks[count.index], + "rule", + "_", + )][2], + ) +} + +# Security group rules with "ipv6_cidr_blocks", but without "cidr_blocks", "source_security_group_id" and "self" +resource "aws_security_group_rule" "egress_with_ipv6_cidr_blocks" { + count = local.create ? length(var.egress_with_ipv6_cidr_blocks) : 0 + + security_group_id = local.this_sg_id + type = "egress" + + ipv6_cidr_blocks = split( + ",", + lookup( + var.egress_with_ipv6_cidr_blocks[count.index], + "ipv6_cidr_blocks", + join(",", var.egress_ipv6_cidr_blocks), + ), + ) + prefix_list_ids = var.egress_prefix_list_ids + description = lookup( + var.egress_with_ipv6_cidr_blocks[count.index], + "description", + "Egress Rule", + ) + + from_port = lookup( + var.egress_with_ipv6_cidr_blocks[count.index], + "from_port", + var.rules[lookup(var.egress_with_ipv6_cidr_blocks[count.index], "rule", "_")][0], + ) + to_port = lookup( + var.egress_with_ipv6_cidr_blocks[count.index], + "to_port", + var.rules[lookup(var.egress_with_ipv6_cidr_blocks[count.index], "rule", "_")][1], + ) + protocol = lookup( + var.egress_with_ipv6_cidr_blocks[count.index], + "protocol", + var.rules[lookup(var.egress_with_ipv6_cidr_blocks[count.index], "rule", "_")][2], + ) +} + +# Computed - Security group rules with "ipv6_cidr_blocks", but without "cidr_blocks", "source_security_group_id" and "self" +resource "aws_security_group_rule" "computed_egress_with_ipv6_cidr_blocks" { + count = local.create ? var.number_of_computed_egress_with_ipv6_cidr_blocks : 0 + + security_group_id = local.this_sg_id + type = "egress" + + ipv6_cidr_blocks = split( + ",", + lookup( + var.computed_egress_with_ipv6_cidr_blocks[count.index], + "ipv6_cidr_blocks", + join(",", var.egress_ipv6_cidr_blocks), + ), + ) + prefix_list_ids = var.egress_prefix_list_ids + description = lookup( + var.computed_egress_with_ipv6_cidr_blocks[count.index], + "description", + "Egress Rule", + ) + + from_port = lookup( + var.computed_egress_with_ipv6_cidr_blocks[count.index], + "from_port", + var.rules[lookup( + var.computed_egress_with_ipv6_cidr_blocks[count.index], + "rule", + "_", + )][0], + ) + to_port = lookup( + var.computed_egress_with_ipv6_cidr_blocks[count.index], + "to_port", + var.rules[lookup( + var.computed_egress_with_ipv6_cidr_blocks[count.index], + "rule", + "_", + )][1], + ) + protocol = lookup( + var.computed_egress_with_ipv6_cidr_blocks[count.index], + "protocol", + var.rules[lookup( + var.computed_egress_with_ipv6_cidr_blocks[count.index], + "rule", + "_", + )][2], + ) +} + +# Security group rules with "self", but without "cidr_blocks" and "source_security_group_id" +resource "aws_security_group_rule" "egress_with_self" { + count = local.create ? length(var.egress_with_self) : 0 + + security_group_id = local.this_sg_id + type = "egress" + + self = lookup(var.egress_with_self[count.index], "self", true) + prefix_list_ids = var.egress_prefix_list_ids + description = lookup( + var.egress_with_self[count.index], + "description", + "Egress Rule", + ) + + from_port = lookup( + var.egress_with_self[count.index], + "from_port", + var.rules[lookup(var.egress_with_self[count.index], "rule", "_")][0], + ) + to_port = lookup( + var.egress_with_self[count.index], + "to_port", + var.rules[lookup(var.egress_with_self[count.index], "rule", "_")][1], + ) + protocol = lookup( + var.egress_with_self[count.index], + "protocol", + var.rules[lookup(var.egress_with_self[count.index], "rule", "_")][2], + ) +} + +# Computed - Security group rules with "self", but without "cidr_blocks" and "source_security_group_id" +resource "aws_security_group_rule" "computed_egress_with_self" { + count = local.create ? var.number_of_computed_egress_with_self : 0 + + security_group_id = local.this_sg_id + type = "egress" + + self = lookup(var.computed_egress_with_self[count.index], "self", true) + prefix_list_ids = var.egress_prefix_list_ids + description = lookup( + var.computed_egress_with_self[count.index], + "description", + "Egress Rule", + ) + + from_port = lookup( + var.computed_egress_with_self[count.index], + "from_port", + var.rules[lookup(var.computed_egress_with_self[count.index], "rule", "_")][0], + ) + to_port = lookup( + var.computed_egress_with_self[count.index], + "to_port", + var.rules[lookup(var.computed_egress_with_self[count.index], "rule", "_")][1], + ) + protocol = lookup( + var.computed_egress_with_self[count.index], + "protocol", + var.rules[lookup(var.computed_egress_with_self[count.index], "rule", "_")][2], + ) +} + +################ +# End of egress +################ diff --git a/modules/aws-security-group/modules/README.md b/modules/aws-security-group/modules/README.md new file mode 100644 index 0000000..fbfc411 --- /dev/null +++ b/modules/aws-security-group/modules/README.md @@ -0,0 +1,58 @@ +List of Security Groups implemented as Terraform modules +======================================================== + + +* [activemq](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/activemq) +* [alertmanager](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/alertmanager) +* [carbon-relay-ng](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/carbon-relay-ng) +* [cassandra](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/cassandra) +* [consul](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/consul) +* [docker-swarm](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/docker-swarm) +* [elasticsearch](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/elasticsearch) +* [etcd](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/etcd) +* [grafana](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/grafana) +* [graphite-statsd](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/graphite-statsd) +* [http-80](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/http-80) +* [http-8080](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/http-8080) +* [https-443](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/https-443) +* [https-8443](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/https-8443) +* [ipsec-4500](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/ipsec-4500) +* [ipsec-500](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/ipsec-500) +* [kafka](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/kafka) +* [kibana](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/kibana) +* [kubernetes-api](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/kubernetes-api) +* [ldap](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/ldap) +* [ldaps](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/ldaps) +* [logstash](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/logstash) +* [memcached](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/memcached) +* [minio](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/minio) +* [mongodb](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/mongodb) +* [mssql](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/mssql) +* [mysql](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/mysql) +* [nfs](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/nfs) +* [nomad](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/nomad) +* [ntp](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/ntp) +* [openvpn](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/openvpn) +* [oracle-db](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/oracle-db) +* [postgresql](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/postgresql) +* [prometheus](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/prometheus) +* [puppet](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/puppet) +* [rabbitmq](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/rabbitmq) +* [rdp](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/rdp) +* [redis](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/redis) +* [redshift](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/redshift) +* [smtp](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/smtp) +* [smtp-submission](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/smtp-submission) +* [smtps](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/smtps) +* [solr](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/solr) +* [splunk](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/splunk) +* [squid](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/squid) +* [ssh](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/ssh) +* [storm](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/storm) +* [wazuh](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/wazuh) +* [web](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/web) +* [winrm](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/winrm) +* [zabbix](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/zabbix) +* [zipkin](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/zipkin) +* [zookeeper](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/zookeeper) +* [_templates](https://github.com/kloia/terraform-modules/terraform-aws-security-group/tree/main/modules/_templates) - Source templates for all other modules. Change carefully, test thoughtfully! diff --git a/modules/aws-security-group/modules/_templates/main.tf b/modules/aws-security-group/modules/_templates/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/_templates/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/_templates/outputs.tf b/modules/aws-security-group/modules/_templates/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/_templates/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/_templates/variables.tf b/modules/aws-security-group/modules/_templates/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/_templates/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/_templates/versions.tf b/modules/aws-security-group/modules/_templates/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/_templates/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/activemq/README.md b/modules/aws-security-group/modules/activemq/README.md new file mode 100644 index 0000000..e98f4e7 --- /dev/null +++ b/modules/aws-security-group/modules/activemq/README.md @@ -0,0 +1,120 @@ +# activemq - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "activemq_security_group" { + source = "terraform-modules/security-group/aws//modules/activemq" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **activemq module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/activemq/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"_": [
"",
"",
""
],
"activemq-5671-tcp": [
5671,
5671,
"tcp",
"ActiveMQ AMQP"
],
"activemq-61614-tcp": [
61614,
61614,
"tcp",
"ActiveMQ STOMP"
],
"activemq-61617-tcp": [
61617,
61617,
"tcp",
"ActiveMQ OpenWire"
],
"activemq-61619-tcp": [
61619,
61619,
"tcp",
"ActiveMQ WebSocket"
],
"activemq-8883-tcp": [
8883,
8883,
"tcp",
"ActiveMQ MQTT"
],
"alertmanager-9093-tcp": [
9093,
9093,
"tcp",
"Alert Manager"
],
"alertmanager-9094-tcp": [
9094,
9094,
"tcp",
"Alert Manager Cluster"
],
"all-all": [
-1,
-1,
"-1",
"All protocols"
],
"all-icmp": [
-1,
-1,
"icmp",
"All IPV4 ICMP"
],
"all-ipv6-icmp": [
-1,
-1,
58,
"All IPV6 ICMP"
],
"all-tcp": [
0,
65535,
"tcp",
"All TCP ports"
],
"all-udp": [
0,
65535,
"udp",
"All UDP ports"
],
"carbon-admin-tcp": [
2004,
2004,
"tcp",
"Carbon admin"
],
"carbon-gui-udp": [
8081,
8081,
"tcp",
"Carbon GUI"
],
"carbon-line-in-tcp": [
2003,
2003,
"tcp",
"Carbon line-in"
],
"carbon-line-in-udp": [
2003,
2003,
"udp",
"Carbon line-in"
],
"carbon-pickle-tcp": [
2013,
2013,
"tcp",
"Carbon pickle"
],
"carbon-pickle-udp": [
2013,
2013,
"udp",
"Carbon pickle"
],
"cassandra-clients-tcp": [
9042,
9042,
"tcp",
"Cassandra clients"
],
"cassandra-jmx-tcp": [
7199,
7199,
"tcp",
"JMX"
],
"cassandra-thrift-clients-tcp": [
9160,
9160,
"tcp",
"Cassandra Thrift clients"
],
"consul-dns-tcp": [
8600,
8600,
"tcp",
"Consul DNS"
],
"consul-dns-udp": [
8600,
8600,
"udp",
"Consul DNS"
],
"consul-grpc-tcp": [
8502,
8502,
"tcp",
"Consul gRPC"
],
"consul-serf-lan-tcp": [
8301,
8301,
"tcp",
"Serf LAN"
],
"consul-serf-lan-udp": [
8301,
8301,
"udp",
"Serf LAN"
],
"consul-serf-wan-tcp": [
8302,
8302,
"tcp",
"Serf WAN"
],
"consul-serf-wan-udp": [
8302,
8302,
"udp",
"Serf WAN"
],
"consul-tcp": [
8300,
8300,
"tcp",
"Consul server"
],
"consul-webui-http-tcp": [
8500,
8500,
"tcp",
"Consul web UI HTTP"
],
"consul-webui-https-tcp": [
8501,
8501,
"tcp",
"Consul web UI HTTPS"
],
"dns-tcp": [
53,
53,
"tcp",
"DNS"
],
"dns-udp": [
53,
53,
"udp",
"DNS"
],
"docker-swarm-mngmt-tcp": [
2377,
2377,
"tcp",
"Docker Swarm cluster management"
],
"docker-swarm-node-tcp": [
7946,
7946,
"tcp",
"Docker Swarm node"
],
"docker-swarm-node-udp": [
7946,
7946,
"udp",
"Docker Swarm node"
],
"docker-swarm-overlay-udp": [
4789,
4789,
"udp",
"Docker Swarm Overlay Network Traffic"
],
"elasticsearch-java-tcp": [
9300,
9300,
"tcp",
"Elasticsearch Java interface"
],
"elasticsearch-rest-tcp": [
9200,
9200,
"tcp",
"Elasticsearch REST interface"
],
"etcd-client-tcp": [
2379,
2379,
"tcp",
"Etcd Client"
],
"etcd-peer-tcp": [
2380,
2380,
"tcp",
"Etcd Peer"
],
"grafana-tcp": [
3000,
3000,
"tcp",
"Grafana Dashboard"
],
"graphite-2003-tcp": [
2003,
2003,
"tcp",
"Carbon receiver plain text"
],
"graphite-2004-tcp": [
2004,
2004,
"tcp",
"Carbon receiver pickle"
],
"graphite-2023-tcp": [
2023,
2023,
"tcp",
"Carbon aggregator plaintext"
],
"graphite-2024-tcp": [
2024,
2024,
"tcp",
"Carbon aggregator pickle"
],
"graphite-8080-tcp": [
8080,
8080,
"tcp",
"Graphite gunicorn port"
],
"graphite-8125-tcp": [
8125,
8125,
"tcp",
"Statsd TCP"
],
"graphite-8125-udp": [
8125,
8125,
"udp",
"Statsd UDP default"
],
"graphite-8126-tcp": [
8126,
8126,
"tcp",
"Statsd admin"
],
"graphite-webui": [
80,
80,
"tcp",
"Graphite admin interface"
],
"http-80-tcp": [
80,
80,
"tcp",
"HTTP"
],
"http-8080-tcp": [
8080,
8080,
"tcp",
"HTTP"
],
"https-443-tcp": [
443,
443,
"tcp",
"HTTPS"
],
"https-8443-tcp": [
8443,
8443,
"tcp",
"HTTPS"
],
"ipsec-4500-udp": [
4500,
4500,
"udp",
"IPSEC NAT-T"
],
"ipsec-500-udp": [
500,
500,
"udp",
"IPSEC ISAKMP"
],
"kafka-broker-sasl-iam-public-tcp": [
9198,
9198,
"tcp",
"Kafka SASL/IAM Public access control enabled (MSK specific)"
],
"kafka-broker-sasl-iam-tcp": [
9098,
9098,
"tcp",
"Kafka SASL/IAM access control enabled (MSK specific)"
],
"kafka-broker-sasl-scram-public-tcp": [
9196,
9196,
"tcp",
"Kafka SASL/SCRAM Public enabled broker (MSK specific)"
],
"kafka-broker-sasl-scram-tcp": [
9096,
9096,
"tcp",
"Kafka SASL/SCRAM enabled broker (MSK specific)"
],
"kafka-broker-tcp": [
9092,
9092,
"tcp",
"Kafka PLAINTEXT enable broker 0.8.2+"
],
"kafka-broker-tls-public-tcp": [
9194,
9194,
"tcp",
"Kafka TLS Public enabled broker 0.8.2+ (MSK specific)"
],
"kafka-broker-tls-tcp": [
9094,
9094,
"tcp",
"Kafka TLS enabled broker 0.8.2+"
],
"kafka-jmx-exporter-tcp": [
11001,
11001,
"tcp",
"Kafka JMX Exporter"
],
"kafka-node-exporter-tcp": [
11002,
11002,
"tcp",
"Kafka Node Exporter"
],
"kibana-tcp": [
5601,
5601,
"tcp",
"Kibana Web Interface"
],
"kubernetes-api-tcp": [
6443,
6443,
"tcp",
"Kubernetes API Server"
],
"ldap-tcp": [
389,
389,
"tcp",
"LDAP"
],
"ldaps-tcp": [
636,
636,
"tcp",
"LDAPS"
],
"logstash-tcp": [
5044,
5044,
"tcp",
"Logstash"
],
"memcached-tcp": [
11211,
11211,
"tcp",
"Memcached"
],
"minio-tcp": [
9000,
9000,
"tcp",
"MinIO"
],
"mongodb-27017-tcp": [
27017,
27017,
"tcp",
"MongoDB"
],
"mongodb-27018-tcp": [
27018,
27018,
"tcp",
"MongoDB shard"
],
"mongodb-27019-tcp": [
27019,
27019,
"tcp",
"MongoDB config server"
],
"mssql-analytics-tcp": [
2383,
2383,
"tcp",
"MSSQL Analytics"
],
"mssql-broker-tcp": [
4022,
4022,
"tcp",
"MSSQL Broker"
],
"mssql-tcp": [
1433,
1433,
"tcp",
"MSSQL Server"
],
"mssql-udp": [
1434,
1434,
"udp",
"MSSQL Browser"
],
"mysql-tcp": [
3306,
3306,
"tcp",
"MySQL/Aurora"
],
"nfs-tcp": [
2049,
2049,
"tcp",
"NFS/EFS"
],
"nomad-http-tcp": [
4646,
4646,
"tcp",
"Nomad HTTP"
],
"nomad-rpc-tcp": [
4647,
4647,
"tcp",
"Nomad RPC"
],
"nomad-serf-tcp": [
4648,
4648,
"tcp",
"Serf"
],
"nomad-serf-udp": [
4648,
4648,
"udp",
"Serf"
],
"ntp-udp": [
123,
123,
"udp",
"NTP"
],
"octopus-tentacle-tcp": [
10933,
10933,
"tcp",
"Octopus Tentacle"
],
"openvpn-https-tcp": [
443,
443,
"tcp",
"OpenVPN"
],
"openvpn-tcp": [
943,
943,
"tcp",
"OpenVPN"
],
"openvpn-udp": [
1194,
1194,
"udp",
"OpenVPN"
],
"oracle-db-tcp": [
1521,
1521,
"tcp",
"Oracle"
],
"postgresql-tcp": [
5432,
5432,
"tcp",
"PostgreSQL"
],
"prometheus-http-tcp": [
9090,
9090,
"tcp",
"Prometheus"
],
"prometheus-pushgateway-http-tcp": [
9091,
9091,
"tcp",
"Prometheus Pushgateway"
],
"puppet-tcp": [
8140,
8140,
"tcp",
"Puppet"
],
"puppetdb-tcp": [
8081,
8081,
"tcp",
"PuppetDB"
],
"rabbitmq-15672-tcp": [
15672,
15672,
"tcp",
"RabbitMQ"
],
"rabbitmq-25672-tcp": [
25672,
25672,
"tcp",
"RabbitMQ"
],
"rabbitmq-4369-tcp": [
4369,
4369,
"tcp",
"RabbitMQ epmd"
],
"rabbitmq-5671-tcp": [
5671,
5671,
"tcp",
"RabbitMQ"
],
"rabbitmq-5672-tcp": [
5672,
5672,
"tcp",
"RabbitMQ"
],
"rdp-tcp": [
3389,
3389,
"tcp",
"Remote Desktop"
],
"rdp-udp": [
3389,
3389,
"udp",
"Remote Desktop"
],
"redis-tcp": [
6379,
6379,
"tcp",
"Redis"
],
"redshift-tcp": [
5439,
5439,
"tcp",
"Redshift"
],
"saltstack-tcp": [
4505,
4506,
"tcp",
"SaltStack"
],
"smtp-submission-2587-tcp": [
2587,
2587,
"tcp",
"SMTP Submission"
],
"smtp-submission-587-tcp": [
587,
587,
"tcp",
"SMTP Submission"
],
"smtp-tcp": [
25,
25,
"tcp",
"SMTP"
],
"smtps-2456-tcp": [
2465,
2465,
"tcp",
"SMTPS"
],
"smtps-465-tcp": [
465,
465,
"tcp",
"SMTPS"
],
"solr-tcp": [
8983,
8987,
"tcp",
"Solr"
],
"splunk-hec-tcp": [
8088,
8088,
"tcp",
"Splunk HEC"
],
"splunk-indexer-tcp": [
9997,
9997,
"tcp",
"Splunk indexer"
],
"splunk-splunkd-tcp": [
8089,
8089,
"tcp",
"Splunkd"
],
"splunk-web-tcp": [
8000,
8000,
"tcp",
"Splunk Web"
],
"squid-proxy-tcp": [
3128,
3128,
"tcp",
"Squid default proxy"
],
"ssh-tcp": [
22,
22,
"tcp",
"SSH"
],
"storm-nimbus-tcp": [
6627,
6627,
"tcp",
"Nimbus"
],
"storm-supervisor-tcp": [
6700,
6703,
"tcp",
"Supervisor"
],
"storm-ui-tcp": [
8080,
8080,
"tcp",
"Storm UI"
],
"wazuh-dashboard": [
443,
443,
"tcp",
"Wazuh web user interface"
],
"wazuh-indexer-restful-api": [
9200,
9200,
"tcp",
"Wazuh indexer RESTful API"
],
"wazuh-server-agent-cluster-daemon": [
1516,
1516,
"tcp",
"Wazuh cluster daemon"
],
"wazuh-server-agent-connection-tcp": [
1514,
1514,
"tcp",
"Agent connection service(TCP)"
],
"wazuh-server-agent-connection-udp": [
1514,
1514,
"udp",
"Agent connection service(UDP)"
],
"wazuh-server-agent-enrollment": [
1515,
1515,
"tcp",
"Agent enrollment service"
],
"wazuh-server-restful-api": [
55000,
55000,
"tcp",
"Wazuh server RESTful API"
],
"wazuh-server-syslog-collector-tcp": [
514,
514,
"tcp",
"Wazuh Syslog collector(TCP)"
],
"wazuh-server-syslog-collector-udp": [
514,
514,
"udp",
"Wazuh Syslog collector(UDP)"
],
"web-jmx-tcp": [
1099,
1099,
"tcp",
"JMX"
],
"winrm-http-tcp": [
5985,
5985,
"tcp",
"WinRM HTTP"
],
"winrm-https-tcp": [
5986,
5986,
"tcp",
"WinRM HTTPS"
],
"zabbix-agent": [
10050,
10050,
"tcp",
"Zabbix Agent"
],
"zabbix-proxy": [
10051,
10051,
"tcp",
"Zabbix Proxy"
],
"zabbix-server": [
10051,
10051,
"tcp",
"Zabbix Server"
],
"zipkin-admin-query-tcp": [
9901,
9901,
"tcp",
"Zipkin Admin port query"
],
"zipkin-admin-tcp": [
9990,
9990,
"tcp",
"Zipkin Admin port collector"
],
"zipkin-admin-web-tcp": [
9991,
9991,
"tcp",
"Zipkin Admin port web"
],
"zipkin-query-tcp": [
9411,
9411,
"tcp",
"Zipkin query port"
],
"zipkin-web-tcp": [
8080,
8080,
"tcp",
"Zipkin web port"
],
"zookeeper-2181-tcp": [
2181,
2181,
"tcp",
"Zookeeper"
],
"zookeeper-2182-tls-tcp": [
2182,
2182,
"tcp",
"Zookeeper TLS (MSK specific)"
],
"zookeeper-2888-tcp": [
2888,
2888,
"tcp",
"Zookeeper"
],
"zookeeper-3888-tcp": [
3888,
3888,
"tcp",
"Zookeeper"
],
"zookeeper-jmx-tcp": [
7199,
7199,
"tcp",
"JMX"
]
}
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"activemq-5671-tcp",
"activemq-8883-tcp",
"activemq-61614-tcp",
"activemq-61617-tcp",
"activemq-61619-tcp"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/activemq/auto_values.tf b/modules/aws-security-group/modules/activemq/auto_values.tf new file mode 100644 index 0000000..f125c23 --- /dev/null +++ b/modules/aws-security-group/modules/activemq/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["activemq-5671-tcp", "activemq-8883-tcp", "activemq-61614-tcp", "activemq-61617-tcp", "activemq-61619-tcp"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/activemq/main.tf b/modules/aws-security-group/modules/activemq/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/activemq/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/activemq/outputs.tf b/modules/aws-security-group/modules/activemq/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/activemq/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/activemq/variables.tf b/modules/aws-security-group/modules/activemq/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/activemq/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/activemq/versions.tf b/modules/aws-security-group/modules/activemq/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/activemq/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/alertmanager/README.md b/modules/aws-security-group/modules/alertmanager/README.md new file mode 100644 index 0000000..94554d0 --- /dev/null +++ b/modules/aws-security-group/modules/alertmanager/README.md @@ -0,0 +1,120 @@ +# alertmanager - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "alertmanager_security_group" { + source = "terraform-modules/security-group/aws//modules/alertmanager" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **alertmanager module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/alertmanager/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"alertmanager-9093-tcp",
"alertmanager-9094-tcp"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/alertmanager/auto_values.tf b/modules/aws-security-group/modules/alertmanager/auto_values.tf new file mode 100644 index 0000000..f73768c --- /dev/null +++ b/modules/aws-security-group/modules/alertmanager/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["alertmanager-9093-tcp", "alertmanager-9094-tcp"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/alertmanager/main.tf b/modules/aws-security-group/modules/alertmanager/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/alertmanager/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/alertmanager/outputs.tf b/modules/aws-security-group/modules/alertmanager/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/alertmanager/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/alertmanager/variables.tf b/modules/aws-security-group/modules/alertmanager/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/alertmanager/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/alertmanager/versions.tf b/modules/aws-security-group/modules/alertmanager/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/alertmanager/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/carbon-relay-ng/README.md b/modules/aws-security-group/modules/carbon-relay-ng/README.md new file mode 100644 index 0000000..80a5a85 --- /dev/null +++ b/modules/aws-security-group/modules/carbon-relay-ng/README.md @@ -0,0 +1,120 @@ +# carbon-relay-ng - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "carbon_relay-ng_security_group" { + source = "terraform-modules/security-group/aws//modules/carbon-relay-ng" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **carbon-relay-ng module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/carbon-relay-ng/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"carbon-line-in-tcp",
"carbon-line-in-udp",
"carbon-pickle-tcp",
"carbon-pickle-udp",
"carbon-gui-udp"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/carbon-relay-ng/auto_values.tf b/modules/aws-security-group/modules/carbon-relay-ng/auto_values.tf new file mode 100644 index 0000000..6d04463 --- /dev/null +++ b/modules/aws-security-group/modules/carbon-relay-ng/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["carbon-line-in-tcp", "carbon-line-in-udp", "carbon-pickle-tcp", "carbon-pickle-udp", "carbon-gui-udp"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/carbon-relay-ng/main.tf b/modules/aws-security-group/modules/carbon-relay-ng/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/carbon-relay-ng/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/carbon-relay-ng/outputs.tf b/modules/aws-security-group/modules/carbon-relay-ng/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/carbon-relay-ng/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/carbon-relay-ng/variables.tf b/modules/aws-security-group/modules/carbon-relay-ng/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/carbon-relay-ng/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/carbon-relay-ng/versions.tf b/modules/aws-security-group/modules/carbon-relay-ng/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/carbon-relay-ng/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/cassandra/README.md b/modules/aws-security-group/modules/cassandra/README.md new file mode 100644 index 0000000..d6d6aee --- /dev/null +++ b/modules/aws-security-group/modules/cassandra/README.md @@ -0,0 +1,120 @@ +# cassandra - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "cassandra_security_group" { + source = "terraform-modules/security-group/aws//modules/cassandra" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **cassandra module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/cassandra/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"cassandra-clients-tcp",
"cassandra-thrift-clients-tcp",
"cassandra-jmx-tcp"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/cassandra/auto_values.tf b/modules/aws-security-group/modules/cassandra/auto_values.tf new file mode 100644 index 0000000..cf41218 --- /dev/null +++ b/modules/aws-security-group/modules/cassandra/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["cassandra-clients-tcp", "cassandra-thrift-clients-tcp", "cassandra-jmx-tcp"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/cassandra/main.tf b/modules/aws-security-group/modules/cassandra/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/cassandra/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/cassandra/outputs.tf b/modules/aws-security-group/modules/cassandra/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/cassandra/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/cassandra/variables.tf b/modules/aws-security-group/modules/cassandra/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/cassandra/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/cassandra/versions.tf b/modules/aws-security-group/modules/cassandra/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/cassandra/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/consul/README.md b/modules/aws-security-group/modules/consul/README.md new file mode 100644 index 0000000..868f554 --- /dev/null +++ b/modules/aws-security-group/modules/consul/README.md @@ -0,0 +1,120 @@ +# consul - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "consul_security_group" { + source = "terraform-modules/security-group/aws//modules/consul" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **consul module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/consul/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"consul-tcp",
"consul-grpc-tcp",
"consul-webui-http-tcp",
"consul-webui-https-tcp",
"consul-dns-tcp",
"consul-dns-udp",
"consul-serf-lan-tcp",
"consul-serf-lan-udp",
"consul-serf-wan-tcp",
"consul-serf-wan-udp"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/consul/auto_values.tf b/modules/aws-security-group/modules/consul/auto_values.tf new file mode 100644 index 0000000..e3385db --- /dev/null +++ b/modules/aws-security-group/modules/consul/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["consul-tcp", "consul-grpc-tcp", "consul-webui-http-tcp", "consul-webui-https-tcp", "consul-dns-tcp", "consul-dns-udp", "consul-serf-lan-tcp", "consul-serf-lan-udp", "consul-serf-wan-tcp", "consul-serf-wan-udp"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/consul/main.tf b/modules/aws-security-group/modules/consul/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/consul/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/consul/outputs.tf b/modules/aws-security-group/modules/consul/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/consul/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/consul/variables.tf b/modules/aws-security-group/modules/consul/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/consul/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/consul/versions.tf b/modules/aws-security-group/modules/consul/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/consul/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/docker-swarm/README.md b/modules/aws-security-group/modules/docker-swarm/README.md new file mode 100644 index 0000000..3ba25e6 --- /dev/null +++ b/modules/aws-security-group/modules/docker-swarm/README.md @@ -0,0 +1,120 @@ +# docker-swarm - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "docker_swarm_security_group" { + source = "terraform-modules/security-group/aws//modules/docker-swarm" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **docker-swarm module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/docker-swarm/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"docker-swarm-mngmt-tcp",
"docker-swarm-node-tcp",
"docker-swarm-node-udp",
"docker-swarm-overlay-udp"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/docker-swarm/auto_values.tf b/modules/aws-security-group/modules/docker-swarm/auto_values.tf new file mode 100644 index 0000000..eedae24 --- /dev/null +++ b/modules/aws-security-group/modules/docker-swarm/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["docker-swarm-mngmt-tcp", "docker-swarm-node-tcp", "docker-swarm-node-udp", "docker-swarm-overlay-udp"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/docker-swarm/main.tf b/modules/aws-security-group/modules/docker-swarm/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/docker-swarm/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/docker-swarm/outputs.tf b/modules/aws-security-group/modules/docker-swarm/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/docker-swarm/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/docker-swarm/variables.tf b/modules/aws-security-group/modules/docker-swarm/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/docker-swarm/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/docker-swarm/versions.tf b/modules/aws-security-group/modules/docker-swarm/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/docker-swarm/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/elasticsearch/README.md b/modules/aws-security-group/modules/elasticsearch/README.md new file mode 100644 index 0000000..59dcc5e --- /dev/null +++ b/modules/aws-security-group/modules/elasticsearch/README.md @@ -0,0 +1,120 @@ +# elasticsearch - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "elasticsearch_security_group" { + source = "terraform-modules/security-group/aws//modules/elasticsearch" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **elasticsearch module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/elasticsearch/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"elasticsearch-rest-tcp",
"elasticsearch-java-tcp"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/elasticsearch/auto_values.tf b/modules/aws-security-group/modules/elasticsearch/auto_values.tf new file mode 100644 index 0000000..e8c9275 --- /dev/null +++ b/modules/aws-security-group/modules/elasticsearch/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["elasticsearch-rest-tcp", "elasticsearch-java-tcp"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/elasticsearch/main.tf b/modules/aws-security-group/modules/elasticsearch/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/elasticsearch/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/elasticsearch/outputs.tf b/modules/aws-security-group/modules/elasticsearch/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/elasticsearch/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/elasticsearch/variables.tf b/modules/aws-security-group/modules/elasticsearch/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/elasticsearch/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/elasticsearch/versions.tf b/modules/aws-security-group/modules/elasticsearch/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/elasticsearch/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/etcd/README.md b/modules/aws-security-group/modules/etcd/README.md new file mode 100644 index 0000000..ae45681 --- /dev/null +++ b/modules/aws-security-group/modules/etcd/README.md @@ -0,0 +1,120 @@ +# etcd - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "etcd_security_group" { + source = "terraform-modules/security-group/aws//modules/etcd" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **etcd module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/etcd/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"etcd-client-tcp",
"etcd-peer-tcp"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/etcd/auto_values.tf b/modules/aws-security-group/modules/etcd/auto_values.tf new file mode 100644 index 0000000..e8c0412 --- /dev/null +++ b/modules/aws-security-group/modules/etcd/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["etcd-client-tcp", "etcd-peer-tcp"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/etcd/main.tf b/modules/aws-security-group/modules/etcd/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/etcd/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/etcd/outputs.tf b/modules/aws-security-group/modules/etcd/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/etcd/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/etcd/variables.tf b/modules/aws-security-group/modules/etcd/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/etcd/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/etcd/versions.tf b/modules/aws-security-group/modules/etcd/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/etcd/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/grafana/README.md b/modules/aws-security-group/modules/grafana/README.md new file mode 100644 index 0000000..1ea3d9e --- /dev/null +++ b/modules/aws-security-group/modules/grafana/README.md @@ -0,0 +1,120 @@ +# grafana - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "grafana_security_group" { + source = "terraform-modules/security-group/aws//modules/grafana" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **grafana module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/grafana/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"grafana-tcp"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/grafana/auto_values.tf b/modules/aws-security-group/modules/grafana/auto_values.tf new file mode 100644 index 0000000..ee39b60 --- /dev/null +++ b/modules/aws-security-group/modules/grafana/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["grafana-tcp"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/grafana/main.tf b/modules/aws-security-group/modules/grafana/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/grafana/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/grafana/outputs.tf b/modules/aws-security-group/modules/grafana/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/grafana/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/grafana/variables.tf b/modules/aws-security-group/modules/grafana/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/grafana/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/grafana/versions.tf b/modules/aws-security-group/modules/grafana/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/grafana/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/graphite-statsd/README.md b/modules/aws-security-group/modules/graphite-statsd/README.md new file mode 100644 index 0000000..6a951f0 --- /dev/null +++ b/modules/aws-security-group/modules/graphite-statsd/README.md @@ -0,0 +1,120 @@ +# graphite-statsd - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "graphite_statsd_security_group" { + source = "terraform-modules/security-group/aws//modules/graphite-statsd" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **graphite-statsd module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/graphite-statsd/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"graphite-webui",
"graphite-2003-tcp",
"graphite-2004-tcp",
"graphite-2023-tcp",
"graphite-2024-tcp",
"graphite-8080-tcp",
"graphite-8125-tcp",
"graphite-8125-udp",
"graphite-8126-tcp"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/graphite-statsd/auto_values.tf b/modules/aws-security-group/modules/graphite-statsd/auto_values.tf new file mode 100644 index 0000000..04167ba --- /dev/null +++ b/modules/aws-security-group/modules/graphite-statsd/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["graphite-webui", "graphite-2003-tcp", "graphite-2004-tcp", "graphite-2023-tcp", "graphite-2024-tcp", "graphite-8080-tcp", "graphite-8125-tcp", "graphite-8125-udp", "graphite-8126-tcp"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/graphite-statsd/main.tf b/modules/aws-security-group/modules/graphite-statsd/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/graphite-statsd/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/graphite-statsd/outputs.tf b/modules/aws-security-group/modules/graphite-statsd/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/graphite-statsd/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/graphite-statsd/variables.tf b/modules/aws-security-group/modules/graphite-statsd/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/graphite-statsd/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/graphite-statsd/versions.tf b/modules/aws-security-group/modules/graphite-statsd/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/graphite-statsd/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/http-80/README.md b/modules/aws-security-group/modules/http-80/README.md new file mode 100644 index 0000000..d45e5b4 --- /dev/null +++ b/modules/aws-security-group/modules/http-80/README.md @@ -0,0 +1,120 @@ +# http-80 - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "http_80_security_group" { + source = "terraform-modules/security-group/aws//modules/http-80" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **http-80 module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/http-80/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"http-80-tcp"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/http-80/auto_values.tf b/modules/aws-security-group/modules/http-80/auto_values.tf new file mode 100644 index 0000000..0fee81d --- /dev/null +++ b/modules/aws-security-group/modules/http-80/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["http-80-tcp"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/http-80/main.tf b/modules/aws-security-group/modules/http-80/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/http-80/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/http-80/outputs.tf b/modules/aws-security-group/modules/http-80/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/http-80/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/http-80/variables.tf b/modules/aws-security-group/modules/http-80/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/http-80/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/http-80/versions.tf b/modules/aws-security-group/modules/http-80/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/http-80/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/http-8080/README.md b/modules/aws-security-group/modules/http-8080/README.md new file mode 100644 index 0000000..5215df0 --- /dev/null +++ b/modules/aws-security-group/modules/http-8080/README.md @@ -0,0 +1,120 @@ +# http-8080 - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "http_8080_security_group" { + source = "terraform-modules/security-group/aws//modules/http-8080" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **http-8080 module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/http-8080/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"http-8080-tcp"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/http-8080/auto_values.tf b/modules/aws-security-group/modules/http-8080/auto_values.tf new file mode 100644 index 0000000..9577559 --- /dev/null +++ b/modules/aws-security-group/modules/http-8080/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["http-8080-tcp"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/http-8080/main.tf b/modules/aws-security-group/modules/http-8080/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/http-8080/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/http-8080/outputs.tf b/modules/aws-security-group/modules/http-8080/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/http-8080/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/http-8080/variables.tf b/modules/aws-security-group/modules/http-8080/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/http-8080/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/http-8080/versions.tf b/modules/aws-security-group/modules/http-8080/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/http-8080/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/https-443/README.md b/modules/aws-security-group/modules/https-443/README.md new file mode 100644 index 0000000..f10c04e --- /dev/null +++ b/modules/aws-security-group/modules/https-443/README.md @@ -0,0 +1,120 @@ +# https-443 - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "https_443_security_group" { + source = "terraform-modules/security-group/aws//modules/https-443" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **https-443 module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/https-443/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"https-443-tcp"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/https-443/auto_values.tf b/modules/aws-security-group/modules/https-443/auto_values.tf new file mode 100644 index 0000000..3bd14e0 --- /dev/null +++ b/modules/aws-security-group/modules/https-443/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["https-443-tcp"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/https-443/main.tf b/modules/aws-security-group/modules/https-443/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/https-443/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/https-443/outputs.tf b/modules/aws-security-group/modules/https-443/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/https-443/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/https-443/variables.tf b/modules/aws-security-group/modules/https-443/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/https-443/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/https-443/versions.tf b/modules/aws-security-group/modules/https-443/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/https-443/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/https-8443/README.md b/modules/aws-security-group/modules/https-8443/README.md new file mode 100644 index 0000000..274b7b8 --- /dev/null +++ b/modules/aws-security-group/modules/https-8443/README.md @@ -0,0 +1,120 @@ +# https-8443 - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "https_8443_security_group" { + source = "terraform-modules/security-group/aws//modules/https-8443" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **https-8443 module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/https-8443/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"https-8443-tcp"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/https-8443/auto_values.tf b/modules/aws-security-group/modules/https-8443/auto_values.tf new file mode 100644 index 0000000..1ca3d58 --- /dev/null +++ b/modules/aws-security-group/modules/https-8443/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["https-8443-tcp"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/https-8443/main.tf b/modules/aws-security-group/modules/https-8443/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/https-8443/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/https-8443/outputs.tf b/modules/aws-security-group/modules/https-8443/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/https-8443/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/https-8443/variables.tf b/modules/aws-security-group/modules/https-8443/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/https-8443/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/https-8443/versions.tf b/modules/aws-security-group/modules/https-8443/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/https-8443/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/ipsec-4500/README.md b/modules/aws-security-group/modules/ipsec-4500/README.md new file mode 100644 index 0000000..df517bd --- /dev/null +++ b/modules/aws-security-group/modules/ipsec-4500/README.md @@ -0,0 +1,120 @@ +# ipsec-4500 - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "ipsec_4500_security_group" { + source = "terraform-modules/security-group/aws//modules/ipsec-4500" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **ipsec-4500 module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/ipsec-4500/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"ipsec-4500-udp"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/ipsec-4500/auto_values.tf b/modules/aws-security-group/modules/ipsec-4500/auto_values.tf new file mode 100644 index 0000000..1b4cad0 --- /dev/null +++ b/modules/aws-security-group/modules/ipsec-4500/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["ipsec-4500-udp"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/ipsec-4500/main.tf b/modules/aws-security-group/modules/ipsec-4500/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/ipsec-4500/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/ipsec-4500/outputs.tf b/modules/aws-security-group/modules/ipsec-4500/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/ipsec-4500/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/ipsec-4500/variables.tf b/modules/aws-security-group/modules/ipsec-4500/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/ipsec-4500/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/ipsec-4500/versions.tf b/modules/aws-security-group/modules/ipsec-4500/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/ipsec-4500/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/ipsec-500/README.md b/modules/aws-security-group/modules/ipsec-500/README.md new file mode 100644 index 0000000..980f43d --- /dev/null +++ b/modules/aws-security-group/modules/ipsec-500/README.md @@ -0,0 +1,120 @@ +# ipsec-500 - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "ipsec_500_security_group" { + source = "terraform-modules/security-group/aws//modules/ipsec-500" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **ipsec-500 module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/ipsec-500/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"ipsec-500-udp"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/ipsec-500/auto_values.tf b/modules/aws-security-group/modules/ipsec-500/auto_values.tf new file mode 100644 index 0000000..1d276c8 --- /dev/null +++ b/modules/aws-security-group/modules/ipsec-500/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["ipsec-500-udp"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/ipsec-500/main.tf b/modules/aws-security-group/modules/ipsec-500/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/ipsec-500/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/ipsec-500/outputs.tf b/modules/aws-security-group/modules/ipsec-500/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/ipsec-500/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/ipsec-500/variables.tf b/modules/aws-security-group/modules/ipsec-500/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/ipsec-500/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/ipsec-500/versions.tf b/modules/aws-security-group/modules/ipsec-500/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/ipsec-500/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/kafka/README.md b/modules/aws-security-group/modules/kafka/README.md new file mode 100644 index 0000000..a21e962 --- /dev/null +++ b/modules/aws-security-group/modules/kafka/README.md @@ -0,0 +1,120 @@ +# kafka - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "kafka_security_group" { + source = "terraform-modules/security-group/aws//modules/kafka" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **kafka module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/kafka/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"kafka-broker-tcp",
"kafka-broker-tls-tcp",
"kafka-broker-tls-public-tcp",
"kafka-broker-sasl-scram-tcp",
"kafka-broker-sasl-scram-tcp",
"kafka-broker-sasl-iam-tcp",
"kafka-broker-sasl-iam-public-tcp",
"kafka-jmx-exporter-tcp",
"kafka-node-exporter-tcp"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/kafka/auto_values.tf b/modules/aws-security-group/modules/kafka/auto_values.tf new file mode 100644 index 0000000..181bbb8 --- /dev/null +++ b/modules/aws-security-group/modules/kafka/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["kafka-broker-tcp", "kafka-broker-tls-tcp", "kafka-broker-tls-public-tcp", "kafka-broker-sasl-scram-tcp", "kafka-broker-sasl-scram-tcp", "kafka-broker-sasl-iam-tcp", "kafka-broker-sasl-iam-public-tcp", "kafka-jmx-exporter-tcp", "kafka-node-exporter-tcp"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/kafka/main.tf b/modules/aws-security-group/modules/kafka/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/kafka/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/kafka/outputs.tf b/modules/aws-security-group/modules/kafka/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/kafka/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/kafka/variables.tf b/modules/aws-security-group/modules/kafka/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/kafka/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/kafka/versions.tf b/modules/aws-security-group/modules/kafka/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/kafka/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/kibana/README.md b/modules/aws-security-group/modules/kibana/README.md new file mode 100644 index 0000000..7db6774 --- /dev/null +++ b/modules/aws-security-group/modules/kibana/README.md @@ -0,0 +1,120 @@ +# kibana - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "kibana_security_group" { + source = "terraform-modules/security-group/aws//modules/kibana" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **kibana module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/kibana/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"kibana-tcp"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/kibana/auto_values.tf b/modules/aws-security-group/modules/kibana/auto_values.tf new file mode 100644 index 0000000..fc6d8e2 --- /dev/null +++ b/modules/aws-security-group/modules/kibana/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["kibana-tcp"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/kibana/main.tf b/modules/aws-security-group/modules/kibana/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/kibana/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/kibana/outputs.tf b/modules/aws-security-group/modules/kibana/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/kibana/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/kibana/variables.tf b/modules/aws-security-group/modules/kibana/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/kibana/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/kibana/versions.tf b/modules/aws-security-group/modules/kibana/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/kibana/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/kubernetes-api/README.md b/modules/aws-security-group/modules/kubernetes-api/README.md new file mode 100644 index 0000000..20419b8 --- /dev/null +++ b/modules/aws-security-group/modules/kubernetes-api/README.md @@ -0,0 +1,120 @@ +# kubernetes-api - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "kubernetes_api_security_group" { + source = "terraform-modules/security-group/aws//modules/kubernetes-api" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **kubernetes-api module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/kubernetes-api/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"kubernetes-api-tcp"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/kubernetes-api/auto_values.tf b/modules/aws-security-group/modules/kubernetes-api/auto_values.tf new file mode 100644 index 0000000..0cd8c9b --- /dev/null +++ b/modules/aws-security-group/modules/kubernetes-api/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["kubernetes-api-tcp"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/kubernetes-api/main.tf b/modules/aws-security-group/modules/kubernetes-api/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/kubernetes-api/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/kubernetes-api/outputs.tf b/modules/aws-security-group/modules/kubernetes-api/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/kubernetes-api/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/kubernetes-api/variables.tf b/modules/aws-security-group/modules/kubernetes-api/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/kubernetes-api/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/kubernetes-api/versions.tf b/modules/aws-security-group/modules/kubernetes-api/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/kubernetes-api/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/ldap/README.md b/modules/aws-security-group/modules/ldap/README.md new file mode 100644 index 0000000..483bab2 --- /dev/null +++ b/modules/aws-security-group/modules/ldap/README.md @@ -0,0 +1,120 @@ +# ldap - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "ldap_security_group" { + source = "terraform-modules/security-group/aws//modules/ldap" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **ldap module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/ldap/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"ldap-tcp"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/ldap/auto_values.tf b/modules/aws-security-group/modules/ldap/auto_values.tf new file mode 100644 index 0000000..c437562 --- /dev/null +++ b/modules/aws-security-group/modules/ldap/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["ldap-tcp"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/ldap/main.tf b/modules/aws-security-group/modules/ldap/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/ldap/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/ldap/outputs.tf b/modules/aws-security-group/modules/ldap/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/ldap/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/ldap/variables.tf b/modules/aws-security-group/modules/ldap/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/ldap/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/ldap/versions.tf b/modules/aws-security-group/modules/ldap/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/ldap/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/ldaps/README.md b/modules/aws-security-group/modules/ldaps/README.md new file mode 100644 index 0000000..d1317eb --- /dev/null +++ b/modules/aws-security-group/modules/ldaps/README.md @@ -0,0 +1,120 @@ +# ldaps - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "ldaps_security_group" { + source = "terraform-modules/security-group/aws//modules/ldaps" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **ldaps module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/ldaps/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"ldaps-tcp"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/ldaps/auto_values.tf b/modules/aws-security-group/modules/ldaps/auto_values.tf new file mode 100644 index 0000000..451b538 --- /dev/null +++ b/modules/aws-security-group/modules/ldaps/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["ldaps-tcp"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/ldaps/main.tf b/modules/aws-security-group/modules/ldaps/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/ldaps/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/ldaps/outputs.tf b/modules/aws-security-group/modules/ldaps/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/ldaps/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/ldaps/variables.tf b/modules/aws-security-group/modules/ldaps/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/ldaps/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/ldaps/versions.tf b/modules/aws-security-group/modules/ldaps/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/ldaps/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/logstash/README.md b/modules/aws-security-group/modules/logstash/README.md new file mode 100644 index 0000000..ac69998 --- /dev/null +++ b/modules/aws-security-group/modules/logstash/README.md @@ -0,0 +1,120 @@ +# logstash - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "logstash_security_group" { + source = "terraform-modules/security-group/aws//modules/logstash" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **logstash module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/logstash/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"logstash-tcp"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/logstash/auto_values.tf b/modules/aws-security-group/modules/logstash/auto_values.tf new file mode 100644 index 0000000..10e573d --- /dev/null +++ b/modules/aws-security-group/modules/logstash/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["logstash-tcp"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/logstash/main.tf b/modules/aws-security-group/modules/logstash/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/logstash/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/logstash/outputs.tf b/modules/aws-security-group/modules/logstash/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/logstash/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/logstash/variables.tf b/modules/aws-security-group/modules/logstash/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/logstash/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/logstash/versions.tf b/modules/aws-security-group/modules/logstash/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/logstash/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/memcached/README.md b/modules/aws-security-group/modules/memcached/README.md new file mode 100644 index 0000000..443e6ac --- /dev/null +++ b/modules/aws-security-group/modules/memcached/README.md @@ -0,0 +1,120 @@ +# memcached - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "memcached_security_group" { + source = "terraform-modules/security-group/aws//modules/memcached" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **memcached module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/memcached/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"memcached-tcp"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/memcached/auto_values.tf b/modules/aws-security-group/modules/memcached/auto_values.tf new file mode 100644 index 0000000..bdf4e45 --- /dev/null +++ b/modules/aws-security-group/modules/memcached/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["memcached-tcp"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/memcached/main.tf b/modules/aws-security-group/modules/memcached/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/memcached/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/memcached/outputs.tf b/modules/aws-security-group/modules/memcached/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/memcached/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/memcached/variables.tf b/modules/aws-security-group/modules/memcached/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/memcached/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/memcached/versions.tf b/modules/aws-security-group/modules/memcached/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/memcached/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/minio/README.md b/modules/aws-security-group/modules/minio/README.md new file mode 100644 index 0000000..8f530cb --- /dev/null +++ b/modules/aws-security-group/modules/minio/README.md @@ -0,0 +1,120 @@ +# minio - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "minio_security_group" { + source = "terraform-modules/security-group/aws//modules/minio" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **minio module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/minio/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"minio-tcp"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/minio/auto_values.tf b/modules/aws-security-group/modules/minio/auto_values.tf new file mode 100644 index 0000000..3afb82e --- /dev/null +++ b/modules/aws-security-group/modules/minio/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["minio-tcp"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/minio/main.tf b/modules/aws-security-group/modules/minio/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/minio/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/minio/outputs.tf b/modules/aws-security-group/modules/minio/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/minio/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/minio/variables.tf b/modules/aws-security-group/modules/minio/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/minio/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/minio/versions.tf b/modules/aws-security-group/modules/minio/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/minio/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/mongodb/README.md b/modules/aws-security-group/modules/mongodb/README.md new file mode 100644 index 0000000..8f252e8 --- /dev/null +++ b/modules/aws-security-group/modules/mongodb/README.md @@ -0,0 +1,120 @@ +# mongodb - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "mongodb_security_group" { + source = "terraform-modules/security-group/aws//modules/mongodb" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **mongodb module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/mongodb/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"mongodb-27017-tcp",
"mongodb-27018-tcp",
"mongodb-27019-tcp"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/mongodb/auto_values.tf b/modules/aws-security-group/modules/mongodb/auto_values.tf new file mode 100644 index 0000000..b6d2436 --- /dev/null +++ b/modules/aws-security-group/modules/mongodb/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["mongodb-27017-tcp", "mongodb-27018-tcp", "mongodb-27019-tcp"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/mongodb/main.tf b/modules/aws-security-group/modules/mongodb/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/mongodb/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/mongodb/outputs.tf b/modules/aws-security-group/modules/mongodb/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/mongodb/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/mongodb/variables.tf b/modules/aws-security-group/modules/mongodb/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/mongodb/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/mongodb/versions.tf b/modules/aws-security-group/modules/mongodb/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/mongodb/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/mssql/README.md b/modules/aws-security-group/modules/mssql/README.md new file mode 100644 index 0000000..fb47633 --- /dev/null +++ b/modules/aws-security-group/modules/mssql/README.md @@ -0,0 +1,120 @@ +# mssql - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "mssql_security_group" { + source = "terraform-modules/security-group/aws//modules/mssql" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **mssql module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/mssql/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"mssql-tcp",
"mssql-udp",
"mssql-analytics-tcp",
"mssql-broker-tcp"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/mssql/auto_values.tf b/modules/aws-security-group/modules/mssql/auto_values.tf new file mode 100644 index 0000000..af370a5 --- /dev/null +++ b/modules/aws-security-group/modules/mssql/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["mssql-tcp", "mssql-udp", "mssql-analytics-tcp", "mssql-broker-tcp"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/mssql/main.tf b/modules/aws-security-group/modules/mssql/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/mssql/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/mssql/outputs.tf b/modules/aws-security-group/modules/mssql/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/mssql/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/mssql/variables.tf b/modules/aws-security-group/modules/mssql/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/mssql/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/mssql/versions.tf b/modules/aws-security-group/modules/mssql/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/mssql/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/mysql/README.md b/modules/aws-security-group/modules/mysql/README.md new file mode 100644 index 0000000..cba81eb --- /dev/null +++ b/modules/aws-security-group/modules/mysql/README.md @@ -0,0 +1,120 @@ +# mysql - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "mysql_security_group" { + source = "terraform-modules/security-group/aws//modules/mysql" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **mysql module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/mysql/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"mysql-tcp"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/mysql/auto_values.tf b/modules/aws-security-group/modules/mysql/auto_values.tf new file mode 100644 index 0000000..ad231a8 --- /dev/null +++ b/modules/aws-security-group/modules/mysql/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["mysql-tcp"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/mysql/main.tf b/modules/aws-security-group/modules/mysql/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/mysql/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/mysql/outputs.tf b/modules/aws-security-group/modules/mysql/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/mysql/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/mysql/variables.tf b/modules/aws-security-group/modules/mysql/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/mysql/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/mysql/versions.tf b/modules/aws-security-group/modules/mysql/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/mysql/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/nfs/README.md b/modules/aws-security-group/modules/nfs/README.md new file mode 100644 index 0000000..1df5b24 --- /dev/null +++ b/modules/aws-security-group/modules/nfs/README.md @@ -0,0 +1,120 @@ +# nfs - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "nfs_security_group" { + source = "terraform-modules/security-group/aws//modules/nfs" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **nfs module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/nfs/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"nfs-tcp"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/nfs/auto_values.tf b/modules/aws-security-group/modules/nfs/auto_values.tf new file mode 100644 index 0000000..fb87606 --- /dev/null +++ b/modules/aws-security-group/modules/nfs/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["nfs-tcp"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/nfs/main.tf b/modules/aws-security-group/modules/nfs/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/nfs/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/nfs/outputs.tf b/modules/aws-security-group/modules/nfs/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/nfs/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/nfs/variables.tf b/modules/aws-security-group/modules/nfs/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/nfs/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/nfs/versions.tf b/modules/aws-security-group/modules/nfs/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/nfs/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/nomad/README.md b/modules/aws-security-group/modules/nomad/README.md new file mode 100644 index 0000000..fef0fa2 --- /dev/null +++ b/modules/aws-security-group/modules/nomad/README.md @@ -0,0 +1,120 @@ +# nomad - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "nomad_security_group" { + source = "terraform-modules/security-group/aws//modules/nomad" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **nomad module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/nomad/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"nomad-http-tcp",
"nomad-rpc-tcp",
"nomad-serf-tcp",
"nomad-serf-udp"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/nomad/auto_values.tf b/modules/aws-security-group/modules/nomad/auto_values.tf new file mode 100644 index 0000000..08df67f --- /dev/null +++ b/modules/aws-security-group/modules/nomad/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["nomad-http-tcp", "nomad-rpc-tcp", "nomad-serf-tcp", "nomad-serf-udp"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/nomad/main.tf b/modules/aws-security-group/modules/nomad/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/nomad/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/nomad/outputs.tf b/modules/aws-security-group/modules/nomad/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/nomad/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/nomad/variables.tf b/modules/aws-security-group/modules/nomad/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/nomad/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/nomad/versions.tf b/modules/aws-security-group/modules/nomad/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/nomad/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/ntp/README.md b/modules/aws-security-group/modules/ntp/README.md new file mode 100644 index 0000000..2769103 --- /dev/null +++ b/modules/aws-security-group/modules/ntp/README.md @@ -0,0 +1,120 @@ +# ntp - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "ntp_security_group" { + source = "terraform-modules/security-group/aws//modules/ntp" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **ntp module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/ntp/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"ntp-udp"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/ntp/auto_values.tf b/modules/aws-security-group/modules/ntp/auto_values.tf new file mode 100644 index 0000000..cf4b735 --- /dev/null +++ b/modules/aws-security-group/modules/ntp/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["ntp-udp"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/ntp/main.tf b/modules/aws-security-group/modules/ntp/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/ntp/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/ntp/outputs.tf b/modules/aws-security-group/modules/ntp/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/ntp/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/ntp/variables.tf b/modules/aws-security-group/modules/ntp/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/ntp/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/ntp/versions.tf b/modules/aws-security-group/modules/ntp/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/ntp/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/openvpn/README.md b/modules/aws-security-group/modules/openvpn/README.md new file mode 100644 index 0000000..3c217aa --- /dev/null +++ b/modules/aws-security-group/modules/openvpn/README.md @@ -0,0 +1,120 @@ +# openvpn - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "openvpn_security_group" { + source = "terraform-modules/security-group/aws//modules/openvpn" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **openvpn module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/openvpn/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"openvpn-udp",
"openvpn-tcp",
"openvpn-https-tcp"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/openvpn/auto_values.tf b/modules/aws-security-group/modules/openvpn/auto_values.tf new file mode 100644 index 0000000..d6f7bdc --- /dev/null +++ b/modules/aws-security-group/modules/openvpn/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["openvpn-udp", "openvpn-tcp", "openvpn-https-tcp"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/openvpn/main.tf b/modules/aws-security-group/modules/openvpn/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/openvpn/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/openvpn/outputs.tf b/modules/aws-security-group/modules/openvpn/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/openvpn/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/openvpn/variables.tf b/modules/aws-security-group/modules/openvpn/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/openvpn/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/openvpn/versions.tf b/modules/aws-security-group/modules/openvpn/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/openvpn/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/oracle-db/README.md b/modules/aws-security-group/modules/oracle-db/README.md new file mode 100644 index 0000000..4dbde5f --- /dev/null +++ b/modules/aws-security-group/modules/oracle-db/README.md @@ -0,0 +1,120 @@ +# oracle-db - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "oracle_db_security_group" { + source = "terraform-modules/security-group/aws//modules/oracle-db" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **oracle-db module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/oracle-db/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"oracle-db-tcp"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/oracle-db/auto_values.tf b/modules/aws-security-group/modules/oracle-db/auto_values.tf new file mode 100644 index 0000000..b74c717 --- /dev/null +++ b/modules/aws-security-group/modules/oracle-db/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["oracle-db-tcp"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/oracle-db/main.tf b/modules/aws-security-group/modules/oracle-db/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/oracle-db/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/oracle-db/outputs.tf b/modules/aws-security-group/modules/oracle-db/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/oracle-db/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/oracle-db/variables.tf b/modules/aws-security-group/modules/oracle-db/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/oracle-db/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/oracle-db/versions.tf b/modules/aws-security-group/modules/oracle-db/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/oracle-db/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/postgresql/README.md b/modules/aws-security-group/modules/postgresql/README.md new file mode 100644 index 0000000..43fef67 --- /dev/null +++ b/modules/aws-security-group/modules/postgresql/README.md @@ -0,0 +1,120 @@ +# postgresql - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "postgresql_security_group" { + source = "terraform-modules/security-group/aws//modules/postgresql" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **postgresql module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/postgresql/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"postgresql-tcp"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/postgresql/auto_values.tf b/modules/aws-security-group/modules/postgresql/auto_values.tf new file mode 100644 index 0000000..338998e --- /dev/null +++ b/modules/aws-security-group/modules/postgresql/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["postgresql-tcp"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/postgresql/main.tf b/modules/aws-security-group/modules/postgresql/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/postgresql/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/postgresql/outputs.tf b/modules/aws-security-group/modules/postgresql/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/postgresql/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/postgresql/variables.tf b/modules/aws-security-group/modules/postgresql/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/postgresql/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/postgresql/versions.tf b/modules/aws-security-group/modules/postgresql/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/postgresql/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/prometheus/README.md b/modules/aws-security-group/modules/prometheus/README.md new file mode 100644 index 0000000..2f529c3 --- /dev/null +++ b/modules/aws-security-group/modules/prometheus/README.md @@ -0,0 +1,120 @@ +# prometheus - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "prometheus_security_group" { + source = "terraform-modules/security-group/aws//modules/prometheus" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **prometheus module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/prometheus/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"prometheus-http-tcp",
"prometheus-pushgateway-http-tcp"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/prometheus/auto_values.tf b/modules/aws-security-group/modules/prometheus/auto_values.tf new file mode 100644 index 0000000..89ebe86 --- /dev/null +++ b/modules/aws-security-group/modules/prometheus/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["prometheus-http-tcp", "prometheus-pushgateway-http-tcp"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/prometheus/main.tf b/modules/aws-security-group/modules/prometheus/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/prometheus/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/prometheus/outputs.tf b/modules/aws-security-group/modules/prometheus/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/prometheus/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/prometheus/variables.tf b/modules/aws-security-group/modules/prometheus/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/prometheus/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/prometheus/versions.tf b/modules/aws-security-group/modules/prometheus/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/prometheus/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/puppet/README.md b/modules/aws-security-group/modules/puppet/README.md new file mode 100644 index 0000000..0c11d40 --- /dev/null +++ b/modules/aws-security-group/modules/puppet/README.md @@ -0,0 +1,120 @@ +# puppet - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "puppet_security_group" { + source = "terraform-modules/security-group/aws//modules/puppet" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **puppet module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/puppet/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"puppet-tcp",
"puppetdb-tcp"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/puppet/auto_values.tf b/modules/aws-security-group/modules/puppet/auto_values.tf new file mode 100644 index 0000000..afe6d4d --- /dev/null +++ b/modules/aws-security-group/modules/puppet/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["puppet-tcp", "puppetdb-tcp"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/puppet/main.tf b/modules/aws-security-group/modules/puppet/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/puppet/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/puppet/outputs.tf b/modules/aws-security-group/modules/puppet/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/puppet/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/puppet/variables.tf b/modules/aws-security-group/modules/puppet/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/puppet/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/puppet/versions.tf b/modules/aws-security-group/modules/puppet/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/puppet/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/rabbitmq/README.md b/modules/aws-security-group/modules/rabbitmq/README.md new file mode 100644 index 0000000..6bcd846 --- /dev/null +++ b/modules/aws-security-group/modules/rabbitmq/README.md @@ -0,0 +1,120 @@ +# rabbitmq - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "rabbitmq_security_group" { + source = "terraform-modules/security-group/aws//modules/rabbitmq" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **rabbitmq module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/rabbitmq/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"rabbitmq-4369-tcp",
"rabbitmq-5671-tcp",
"rabbitmq-5672-tcp",
"rabbitmq-15672-tcp",
"rabbitmq-25672-tcp"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/rabbitmq/auto_values.tf b/modules/aws-security-group/modules/rabbitmq/auto_values.tf new file mode 100644 index 0000000..30a7676 --- /dev/null +++ b/modules/aws-security-group/modules/rabbitmq/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["rabbitmq-4369-tcp", "rabbitmq-5671-tcp", "rabbitmq-5672-tcp", "rabbitmq-15672-tcp", "rabbitmq-25672-tcp"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/rabbitmq/main.tf b/modules/aws-security-group/modules/rabbitmq/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/rabbitmq/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/rabbitmq/outputs.tf b/modules/aws-security-group/modules/rabbitmq/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/rabbitmq/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/rabbitmq/variables.tf b/modules/aws-security-group/modules/rabbitmq/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/rabbitmq/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/rabbitmq/versions.tf b/modules/aws-security-group/modules/rabbitmq/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/rabbitmq/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/rdp/README.md b/modules/aws-security-group/modules/rdp/README.md new file mode 100644 index 0000000..e2dee66 --- /dev/null +++ b/modules/aws-security-group/modules/rdp/README.md @@ -0,0 +1,120 @@ +# rdp - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "rdp_security_group" { + source = "terraform-modules/security-group/aws//modules/rdp" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **rdp module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/rdp/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"rdp-tcp",
"rdp-udp"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/rdp/auto_values.tf b/modules/aws-security-group/modules/rdp/auto_values.tf new file mode 100644 index 0000000..dc55929 --- /dev/null +++ b/modules/aws-security-group/modules/rdp/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["rdp-tcp", "rdp-udp"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/rdp/main.tf b/modules/aws-security-group/modules/rdp/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/rdp/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/rdp/outputs.tf b/modules/aws-security-group/modules/rdp/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/rdp/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/rdp/variables.tf b/modules/aws-security-group/modules/rdp/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/rdp/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/rdp/versions.tf b/modules/aws-security-group/modules/rdp/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/rdp/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/redis/README.md b/modules/aws-security-group/modules/redis/README.md new file mode 100644 index 0000000..56486c5 --- /dev/null +++ b/modules/aws-security-group/modules/redis/README.md @@ -0,0 +1,120 @@ +# redis - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "redis_security_group" { + source = "terraform-modules/security-group/aws//modules/redis" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **redis module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/redis/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"redis-tcp"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/redis/auto_values.tf b/modules/aws-security-group/modules/redis/auto_values.tf new file mode 100644 index 0000000..8563abf --- /dev/null +++ b/modules/aws-security-group/modules/redis/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["redis-tcp"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/redis/main.tf b/modules/aws-security-group/modules/redis/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/redis/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/redis/outputs.tf b/modules/aws-security-group/modules/redis/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/redis/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/redis/variables.tf b/modules/aws-security-group/modules/redis/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/redis/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/redis/versions.tf b/modules/aws-security-group/modules/redis/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/redis/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/redshift/README.md b/modules/aws-security-group/modules/redshift/README.md new file mode 100644 index 0000000..e25a86c --- /dev/null +++ b/modules/aws-security-group/modules/redshift/README.md @@ -0,0 +1,120 @@ +# redshift - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "redshift_security_group" { + source = "terraform-modules/security-group/aws//modules/redshift" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **redshift module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/redshift/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"redshift-tcp"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/redshift/auto_values.tf b/modules/aws-security-group/modules/redshift/auto_values.tf new file mode 100644 index 0000000..c4d26e7 --- /dev/null +++ b/modules/aws-security-group/modules/redshift/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["redshift-tcp"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/redshift/main.tf b/modules/aws-security-group/modules/redshift/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/redshift/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/redshift/outputs.tf b/modules/aws-security-group/modules/redshift/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/redshift/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/redshift/variables.tf b/modules/aws-security-group/modules/redshift/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/redshift/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/redshift/versions.tf b/modules/aws-security-group/modules/redshift/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/redshift/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/smtp-submission/README.md b/modules/aws-security-group/modules/smtp-submission/README.md new file mode 100644 index 0000000..d8cd856 --- /dev/null +++ b/modules/aws-security-group/modules/smtp-submission/README.md @@ -0,0 +1,120 @@ +# smtp-submission - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "smtp_submission_security_group" { + source = "terraform-modules/security-group/aws//modules/smtp-submission" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **smtp-submission module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/smtp-submission/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"smtp-submission-587-tcp",
"smtp-submission-2587-tcp"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/smtp-submission/auto_values.tf b/modules/aws-security-group/modules/smtp-submission/auto_values.tf new file mode 100644 index 0000000..1b4902f --- /dev/null +++ b/modules/aws-security-group/modules/smtp-submission/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["smtp-submission-587-tcp", "smtp-submission-2587-tcp"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/smtp-submission/main.tf b/modules/aws-security-group/modules/smtp-submission/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/smtp-submission/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/smtp-submission/outputs.tf b/modules/aws-security-group/modules/smtp-submission/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/smtp-submission/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/smtp-submission/variables.tf b/modules/aws-security-group/modules/smtp-submission/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/smtp-submission/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/smtp-submission/versions.tf b/modules/aws-security-group/modules/smtp-submission/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/smtp-submission/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/smtp/README.md b/modules/aws-security-group/modules/smtp/README.md new file mode 100644 index 0000000..c25fbc1 --- /dev/null +++ b/modules/aws-security-group/modules/smtp/README.md @@ -0,0 +1,120 @@ +# smtp - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "smtp_security_group" { + source = "terraform-modules/security-group/aws//modules/smtp" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **smtp module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/smtp/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"smtp-tcp"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/smtp/auto_values.tf b/modules/aws-security-group/modules/smtp/auto_values.tf new file mode 100644 index 0000000..59fe543 --- /dev/null +++ b/modules/aws-security-group/modules/smtp/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["smtp-tcp"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/smtp/main.tf b/modules/aws-security-group/modules/smtp/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/smtp/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/smtp/outputs.tf b/modules/aws-security-group/modules/smtp/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/smtp/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/smtp/variables.tf b/modules/aws-security-group/modules/smtp/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/smtp/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/smtp/versions.tf b/modules/aws-security-group/modules/smtp/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/smtp/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/smtps/README.md b/modules/aws-security-group/modules/smtps/README.md new file mode 100644 index 0000000..04e544c --- /dev/null +++ b/modules/aws-security-group/modules/smtps/README.md @@ -0,0 +1,120 @@ +# smtps - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "smtps_security_group" { + source = "terraform-modules/security-group/aws//modules/smtps" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **smtps module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/smtps/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"smtps-465-tcp",
"smtps-2465-tcp"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/smtps/auto_values.tf b/modules/aws-security-group/modules/smtps/auto_values.tf new file mode 100644 index 0000000..5c43085 --- /dev/null +++ b/modules/aws-security-group/modules/smtps/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["smtps-465-tcp", "smtps-2465-tcp"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/smtps/main.tf b/modules/aws-security-group/modules/smtps/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/smtps/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/smtps/outputs.tf b/modules/aws-security-group/modules/smtps/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/smtps/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/smtps/variables.tf b/modules/aws-security-group/modules/smtps/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/smtps/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/smtps/versions.tf b/modules/aws-security-group/modules/smtps/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/smtps/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/solr/README.md b/modules/aws-security-group/modules/solr/README.md new file mode 100644 index 0000000..9221b7d --- /dev/null +++ b/modules/aws-security-group/modules/solr/README.md @@ -0,0 +1,120 @@ +# solr - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "solr_security_group" { + source = "terraform-modules/security-group/aws//modules/solr" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **solr module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/solr/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"solr-tcp"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/solr/auto_values.tf b/modules/aws-security-group/modules/solr/auto_values.tf new file mode 100644 index 0000000..78c11b4 --- /dev/null +++ b/modules/aws-security-group/modules/solr/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["solr-tcp"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/solr/main.tf b/modules/aws-security-group/modules/solr/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/solr/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/solr/outputs.tf b/modules/aws-security-group/modules/solr/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/solr/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/solr/variables.tf b/modules/aws-security-group/modules/solr/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/solr/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/solr/versions.tf b/modules/aws-security-group/modules/solr/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/solr/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/splunk/README.md b/modules/aws-security-group/modules/splunk/README.md new file mode 100644 index 0000000..2993c01 --- /dev/null +++ b/modules/aws-security-group/modules/splunk/README.md @@ -0,0 +1,120 @@ +# splunk - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "splunk_security_group" { + source = "terraform-modules/security-group/aws//modules/splunk" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **splunk module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/splunk/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"splunk-indexer-tcp",
"splunk-clients-tcp",
"splunk-splunkd-tcp",
"splunk-hec-tcp"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/splunk/auto_values.tf b/modules/aws-security-group/modules/splunk/auto_values.tf new file mode 100644 index 0000000..8c6468b --- /dev/null +++ b/modules/aws-security-group/modules/splunk/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["splunk-indexer-tcp", "splunk-clients-tcp", "splunk-splunkd-tcp", "splunk-hec-tcp"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/splunk/main.tf b/modules/aws-security-group/modules/splunk/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/splunk/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/splunk/outputs.tf b/modules/aws-security-group/modules/splunk/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/splunk/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/splunk/variables.tf b/modules/aws-security-group/modules/splunk/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/splunk/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/splunk/versions.tf b/modules/aws-security-group/modules/splunk/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/splunk/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/squid/README.md b/modules/aws-security-group/modules/squid/README.md new file mode 100644 index 0000000..e740eaf --- /dev/null +++ b/modules/aws-security-group/modules/squid/README.md @@ -0,0 +1,120 @@ +# squid - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "squid_security_group" { + source = "terraform-modules/security-group/aws//modules/squid" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **squid module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/squid/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"squid-proxy-tcp"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/squid/auto_values.tf b/modules/aws-security-group/modules/squid/auto_values.tf new file mode 100644 index 0000000..fa95425 --- /dev/null +++ b/modules/aws-security-group/modules/squid/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["squid-proxy-tcp"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/squid/main.tf b/modules/aws-security-group/modules/squid/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/squid/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/squid/outputs.tf b/modules/aws-security-group/modules/squid/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/squid/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/squid/variables.tf b/modules/aws-security-group/modules/squid/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/squid/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/squid/versions.tf b/modules/aws-security-group/modules/squid/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/squid/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/ssh/README.md b/modules/aws-security-group/modules/ssh/README.md new file mode 100644 index 0000000..b2fbfb5 --- /dev/null +++ b/modules/aws-security-group/modules/ssh/README.md @@ -0,0 +1,120 @@ +# ssh - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "ssh_security_group" { + source = "terraform-modules/security-group/aws//modules/ssh" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **ssh module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/ssh/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"ssh-tcp"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/ssh/auto_values.tf b/modules/aws-security-group/modules/ssh/auto_values.tf new file mode 100644 index 0000000..da270c3 --- /dev/null +++ b/modules/aws-security-group/modules/ssh/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["ssh-tcp"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/ssh/main.tf b/modules/aws-security-group/modules/ssh/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/ssh/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/ssh/outputs.tf b/modules/aws-security-group/modules/ssh/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/ssh/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/ssh/variables.tf b/modules/aws-security-group/modules/ssh/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/ssh/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/ssh/versions.tf b/modules/aws-security-group/modules/ssh/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/ssh/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/storm/README.md b/modules/aws-security-group/modules/storm/README.md new file mode 100644 index 0000000..0155a5c --- /dev/null +++ b/modules/aws-security-group/modules/storm/README.md @@ -0,0 +1,120 @@ +# storm - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "storm_security_group" { + source = "terraform-modules/security-group/aws//modules/storm" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **storm module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/storm/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"storm-nimbus-tcp",
"storm-ui-tcp",
"storm-supervisor-tcp"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/storm/auto_values.tf b/modules/aws-security-group/modules/storm/auto_values.tf new file mode 100644 index 0000000..7a049c6 --- /dev/null +++ b/modules/aws-security-group/modules/storm/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["storm-nimbus-tcp", "storm-ui-tcp", "storm-supervisor-tcp"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/storm/main.tf b/modules/aws-security-group/modules/storm/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/storm/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/storm/outputs.tf b/modules/aws-security-group/modules/storm/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/storm/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/storm/variables.tf b/modules/aws-security-group/modules/storm/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/storm/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/storm/versions.tf b/modules/aws-security-group/modules/storm/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/storm/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/wazuh/README.md b/modules/aws-security-group/modules/wazuh/README.md new file mode 100644 index 0000000..8a8f75e --- /dev/null +++ b/modules/aws-security-group/modules/wazuh/README.md @@ -0,0 +1,120 @@ +# wazuh - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "wazuh_security_group" { + source = "terraform-modules/security-group/aws//modules/wazuh" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **wazuh module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/wazuh/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"wazuh-server-agent-connection-tcp",
"wazuh-server-agent-connection-udp",
"wazuh-server-agent-enrollment",
"wazuh-server-agent-cluster-daemon",
"wazuh-server-syslog-collector-tcp",
"wazuh-server-syslog-collector-udp",
"wazuh-server-restful-api",
"wazuh-indexer-restful-api",
"wazuh-dashboard"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/wazuh/auto_values.tf b/modules/aws-security-group/modules/wazuh/auto_values.tf new file mode 100644 index 0000000..56dbf96 --- /dev/null +++ b/modules/aws-security-group/modules/wazuh/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["wazuh-server-agent-connection-tcp", "wazuh-server-agent-connection-udp", "wazuh-server-agent-enrollment", "wazuh-server-agent-cluster-daemon", "wazuh-server-syslog-collector-tcp", "wazuh-server-syslog-collector-udp", "wazuh-server-restful-api", "wazuh-indexer-restful-api", "wazuh-dashboard"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/wazuh/main.tf b/modules/aws-security-group/modules/wazuh/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/wazuh/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/wazuh/outputs.tf b/modules/aws-security-group/modules/wazuh/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/wazuh/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/wazuh/variables.tf b/modules/aws-security-group/modules/wazuh/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/wazuh/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/wazuh/versions.tf b/modules/aws-security-group/modules/wazuh/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/wazuh/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/web/README.md b/modules/aws-security-group/modules/web/README.md new file mode 100644 index 0000000..738e9b9 --- /dev/null +++ b/modules/aws-security-group/modules/web/README.md @@ -0,0 +1,120 @@ +# web - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "web_security_group" { + source = "terraform-modules/security-group/aws//modules/web" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **web module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/web/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"http-80-tcp",
"http-8080-tcp",
"https-443-tcp",
"web-jmx-tcp"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/web/auto_values.tf b/modules/aws-security-group/modules/web/auto_values.tf new file mode 100644 index 0000000..03bdb52 --- /dev/null +++ b/modules/aws-security-group/modules/web/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["http-80-tcp", "http-8080-tcp", "https-443-tcp", "web-jmx-tcp"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/web/main.tf b/modules/aws-security-group/modules/web/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/web/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/web/outputs.tf b/modules/aws-security-group/modules/web/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/web/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/web/variables.tf b/modules/aws-security-group/modules/web/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/web/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/web/versions.tf b/modules/aws-security-group/modules/web/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/web/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/winrm/README.md b/modules/aws-security-group/modules/winrm/README.md new file mode 100644 index 0000000..d17d90a --- /dev/null +++ b/modules/aws-security-group/modules/winrm/README.md @@ -0,0 +1,120 @@ +# winrm - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "winrm_security_group" { + source = "terraform-modules/security-group/aws//modules/winrm" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **winrm module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/winrm/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"winrm-http-tcp",
"winrm-https-tcp"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/winrm/auto_values.tf b/modules/aws-security-group/modules/winrm/auto_values.tf new file mode 100644 index 0000000..8ea1ff5 --- /dev/null +++ b/modules/aws-security-group/modules/winrm/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["winrm-http-tcp", "winrm-https-tcp"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/winrm/main.tf b/modules/aws-security-group/modules/winrm/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/winrm/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/winrm/outputs.tf b/modules/aws-security-group/modules/winrm/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/winrm/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/winrm/variables.tf b/modules/aws-security-group/modules/winrm/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/winrm/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/winrm/versions.tf b/modules/aws-security-group/modules/winrm/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/winrm/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/zabbix/README.md b/modules/aws-security-group/modules/zabbix/README.md new file mode 100644 index 0000000..ef17da5 --- /dev/null +++ b/modules/aws-security-group/modules/zabbix/README.md @@ -0,0 +1,120 @@ +# zabbix - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "zabbix_security_group" { + source = "terraform-modules/security-group/aws//modules/zabbix" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **zabbix module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/zabbix/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"zabbix-server",
"zabbix-proxy",
"zabbix-agent"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/zabbix/auto_values.tf b/modules/aws-security-group/modules/zabbix/auto_values.tf new file mode 100644 index 0000000..0869c7a --- /dev/null +++ b/modules/aws-security-group/modules/zabbix/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["zabbix-server", "zabbix-proxy", "zabbix-agent"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/zabbix/main.tf b/modules/aws-security-group/modules/zabbix/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/zabbix/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/zabbix/outputs.tf b/modules/aws-security-group/modules/zabbix/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/zabbix/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/zabbix/variables.tf b/modules/aws-security-group/modules/zabbix/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/zabbix/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/zabbix/versions.tf b/modules/aws-security-group/modules/zabbix/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/zabbix/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/zipkin/README.md b/modules/aws-security-group/modules/zipkin/README.md new file mode 100644 index 0000000..188deaf --- /dev/null +++ b/modules/aws-security-group/modules/zipkin/README.md @@ -0,0 +1,120 @@ +# zipkin - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "zipkin_security_group" { + source = "terraform-modules/security-group/aws//modules/zipkin" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **zipkin module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/zipkin/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"zipkin-admin-tcp",
"zipkin-admin-query-tcp",
"zipkin-admin-web-tcp",
"zipkin-query-tcp",
"zipkin-web-tcp"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/zipkin/auto_values.tf b/modules/aws-security-group/modules/zipkin/auto_values.tf new file mode 100644 index 0000000..d5abf3e --- /dev/null +++ b/modules/aws-security-group/modules/zipkin/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["zipkin-admin-tcp", "zipkin-admin-query-tcp", "zipkin-admin-web-tcp", "zipkin-query-tcp", "zipkin-web-tcp"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/zipkin/main.tf b/modules/aws-security-group/modules/zipkin/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/zipkin/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/zipkin/outputs.tf b/modules/aws-security-group/modules/zipkin/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/zipkin/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/zipkin/variables.tf b/modules/aws-security-group/modules/zipkin/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/zipkin/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/zipkin/versions.tf b/modules/aws-security-group/modules/zipkin/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/zipkin/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/modules/zookeeper/README.md b/modules/aws-security-group/modules/zookeeper/README.md new file mode 100644 index 0000000..fdd12cc --- /dev/null +++ b/modules/aws-security-group/modules/zookeeper/README.md @@ -0,0 +1,120 @@ +# zookeeper - AWS EC2-VPC Security Group Terraform module + +## Usage + +```hcl +module "zookeeper_security_group" { + source = "terraform-modules/security-group/aws//modules/zookeeper" + version = "~> 4.0" + + # omitted... +} +``` + +All automatic values **zookeeper module** is using are available [here](https://github.com/kloia/terraform-modules/terraform-aws-security-group/blob/main/modules/zookeeper/auto_values.tf). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.29 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [sg](#module\_sg) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auto\_computed\_egress\_rules](#input\_auto\_computed\_egress\_rules) | List of computed egress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_egress\_with\_self](#input\_auto\_computed\_egress\_with\_self) | List of maps defining computed egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_computed\_ingress\_rules](#input\_auto\_computed\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` | `[]` | no | +| [auto\_computed\_ingress\_with\_self](#input\_auto\_computed\_ingress\_with\_self) | List of maps defining computed ingress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_egress\_rules](#input\_auto\_egress\_rules) | List of egress rules to add automatically | `list(string)` |
"::/0"
]
[| no | +| [auto\_egress\_with\_self](#input\_auto\_egress\_with\_self) | List of maps defining egress rules with self to add automatically | `list(map(string))` | `[]` | no | +| [auto\_ingress\_rules](#input\_auto\_ingress\_rules) | List of ingress rules to add automatically | `list(string)` |
"all-all"
]
[| no | +| [auto\_ingress\_with\_self](#input\_auto\_ingress\_with\_self) | List of maps defining ingress rules with self to add automatically | `list(map(string))` |
"zookeeper-2181-tcp",
"zookeeper-2182-tls-tcp",
"zookeeper-2888-tcp",
"zookeeper-3888-tcp",
"zookeeper-jmx-tcp"
]
[| no | +| [auto\_number\_of\_computed\_egress\_rules](#input\_auto\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_egress\_with\_self](#input\_auto\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_rules](#input\_auto\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [auto\_number\_of\_computed\_ingress\_with\_self](#input\_auto\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [computed\_egress\_cidr\_blocks](#input\_computed\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed egress rules | `list(string)` |
{
"rule": "all-all"
}
]
[| no | +| [computed\_egress\_ipv6\_cidr\_blocks](#input\_computed\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [computed\_egress\_prefix\_list\_ids](#input\_computed\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `list(string)` | `[]` | no | +| [computed\_egress\_rules](#input\_computed\_egress\_rules) | List of computed egress rules to create by name | `list(string)` | `[]` | no | +| [computed\_egress\_with\_cidr\_blocks](#input\_computed\_egress\_with\_cidr\_blocks) | List of computed egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_computed\_egress\_with\_ipv6\_cidr\_blocks) | List of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_self](#input\_computed\_egress\_with\_self) | List of computed egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_egress\_with\_source\_security\_group\_id](#input\_computed\_egress\_with\_source\_security\_group\_id) | List of computed egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_cidr\_blocks](#input\_computed\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_prefix\_list\_ids](#input\_computed\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `list(string)` | `[]` | no | +| [computed\_ingress\_rules](#input\_computed\_ingress\_rules) | List of computed ingress rules to create by name | `list(string)` | `[]` | no | +| [computed\_ingress\_with\_cidr\_blocks](#input\_computed\_ingress\_with\_cidr\_blocks) | List of computed ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | List of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_self](#input\_computed\_ingress\_with\_self) | List of computed ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [computed\_ingress\_with\_source\_security\_group\_id](#input\_computed\_ingress\_with\_source\_security\_group\_id) | List of computed ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [create](#input\_create) | Whether to create security group and all rules | `bool` | `true` | no | +| [description](#input\_description) | Description of security group | `string` | `"Security Group managed by Terraform"` | no | +| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all egress rules | `list(string)` |
"::/0"
]
[| no | +| [egress\_ipv6\_cidr\_blocks](#input\_egress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all egress rules | `list(string)` |
"0.0.0.0/0"
]
[| no | +| [egress\_prefix\_list\_ids](#input\_egress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules | `list(string)` | `[]` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules to create by name | `list(string)` | `[]` | no | +| [egress\_with\_cidr\_blocks](#input\_egress\_with\_cidr\_blocks) | List of egress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_ipv6\_cidr\_blocks](#input\_egress\_with\_ipv6\_cidr\_blocks) | List of egress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [egress\_with\_self](#input\_egress\_with\_self) | List of egress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [egress\_with\_source\_security\_group\_id](#input\_egress\_with\_source\_security\_group\_id) | List of egress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [ingress\_cidr\_blocks](#input\_ingress\_cidr\_blocks) | List of IPv4 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_ipv6\_cidr\_blocks](#input\_ingress\_ipv6\_cidr\_blocks) | List of IPv6 CIDR ranges to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_prefix\_list\_ids](#input\_ingress\_prefix\_list\_ids) | List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules | `list(string)` | `[]` | no | +| [ingress\_rules](#input\_ingress\_rules) | List of ingress rules to create by name | `list(string)` | `[]` | no | +| [ingress\_with\_cidr\_blocks](#input\_ingress\_with\_cidr\_blocks) | List of ingress rules to create where 'cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_ipv6\_cidr\_blocks](#input\_ingress\_with\_ipv6\_cidr\_blocks) | List of ingress rules to create where 'ipv6\_cidr\_blocks' is used | `list(map(string))` | `[]` | no | +| [ingress\_with\_self](#input\_ingress\_with\_self) | List of ingress rules to create where 'self' is defined | `list(map(string))` | `[]` | no | +| [ingress\_with\_source\_security\_group\_id](#input\_ingress\_with\_source\_security\_group\_id) | List of ingress rules to create where 'source\_security\_group\_id' is used | `list(map(string))` | `[]` | no | +| [name](#input\_name) | Name of security group | `string` | n/a | yes | +| [number\_of\_computed\_egress\_cidr\_blocks](#input\_number\_of\_computed\_egress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_prefix\_list\_ids](#input\_number\_of\_computed\_egress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules | `number` | `0` | no | +| [number\_of\_computed\_egress\_rules](#input\_number\_of\_computed\_egress\_rules) | Number of computed egress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_cidr\_blocks) | Number of computed egress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_egress\_with\_ipv6\_cidr\_blocks) | Number of computed egress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_self](#input\_number\_of\_computed\_egress\_with\_self) | Number of computed egress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_egress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_egress\_with\_source\_security\_group\_id) | Number of computed egress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_cidr\_blocks) | Number of IPv4 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_ipv6\_cidr\_blocks) | Number of IPv6 CIDR ranges to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_prefix\_list\_ids](#input\_number\_of\_computed\_ingress\_prefix\_list\_ids) | Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules | `number` | `0` | no | +| [number\_of\_computed\_ingress\_rules](#input\_number\_of\_computed\_ingress\_rules) | Number of computed ingress rules to create by name | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_cidr\_blocks) | Number of computed ingress rules to create where 'cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks](#input\_number\_of\_computed\_ingress\_with\_ipv6\_cidr\_blocks) | Number of computed ingress rules to create where 'ipv6\_cidr\_blocks' is used | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_self](#input\_number\_of\_computed\_ingress\_with\_self) | Number of computed ingress rules to create where 'self' is defined | `number` | `0` | no | +| [number\_of\_computed\_ingress\_with\_source\_security\_group\_id](#input\_number\_of\_computed\_ingress\_with\_source\_security\_group\_id) | Number of computed ingress rules to create where 'source\_security\_group\_id' is used | `number` | `0` | no | +| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR. | `bool` | `false` | no | +| [tags](#input\_tags) | A mapping of tags to assign to security group | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Whether to use name\_prefix or fixed name. Should be true to able to update security group name after initial creation | `bool` | `true` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group | +| [security\_group\_description](#output\_security\_group\_description) | The description of the security group | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group | +| [security\_group\_name](#output\_security\_group\_name) | The name of the security group | +| [security\_group\_owner\_id](#output\_security\_group\_owner\_id) | The owner ID | +| [security\_group\_vpc\_id](#output\_security\_group\_vpc\_id) | The VPC ID | + diff --git a/modules/aws-security-group/modules/zookeeper/auto_values.tf b/modules/aws-security-group/modules/zookeeper/auto_values.tf new file mode 100644 index 0000000..fad05d7 --- /dev/null +++ b/modules/aws-security-group/modules/zookeeper/auto_values.tf @@ -0,0 +1,78 @@ +# This file was generated from values defined in rules.tf using update_groups.sh. +################################### +# DO NOT CHANGE THIS FILE MANUALLY +################################### + +variable "auto_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = ["zookeeper-2181-tcp", "zookeeper-2182-tls-tcp", "zookeeper-2888-tcp", "zookeeper-3888-tcp", "zookeeper-jmx-tcp"] +} + +variable "auto_ingress_with_self" { + description = "List of maps defining ingress rules with self to add automatically" + type = list(map(string)) + default = [{ "rule" = "all-all" }] +} + +variable "auto_egress_rules" { + description = "List of egress rules to add automatically" + type = list(string) + default = ["all-all"] +} + +variable "auto_egress_with_self" { + description = "List of maps defining egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Computed +variable "auto_computed_ingress_rules" { + description = "List of ingress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_ingress_with_self" { + description = "List of maps defining computed ingress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +variable "auto_computed_egress_rules" { + description = "List of computed egress rules to add automatically" + type = list(string) + default = [] +} + +variable "auto_computed_egress_with_self" { + description = "List of maps defining computed egress rules with self to add automatically" + type = list(map(string)) + default = [] +} + +# Number of computed rules +variable "auto_number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "auto_number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/zookeeper/main.tf b/modules/aws-security-group/modules/zookeeper/main.tf new file mode 100644 index 0000000..758bb7b --- /dev/null +++ b/modules/aws-security-group/modules/zookeeper/main.tf @@ -0,0 +1,115 @@ +module "sg" { + source = "../../" + + create = var.create + name = var.name + use_name_prefix = var.use_name_prefix + description = var.description + vpc_id = var.vpc_id + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags + + ########## + # Ingress + ########## + # Rules by names - open for default CIDR + ingress_rules = sort(compact(distinct(concat(var.auto_ingress_rules, var.ingress_rules, [""])))) + + # Open for self + ingress_with_self = concat(var.auto_ingress_with_self, var.ingress_with_self) + + # Open to IPv4 cidr blocks + ingress_with_cidr_blocks = var.ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + ingress_with_ipv6_cidr_blocks = var.ingress_with_ipv6_cidr_blocks + + # Open for security group id + ingress_with_source_security_group_id = var.ingress_with_source_security_group_id + + # Default ingress CIDR blocks + ingress_cidr_blocks = var.ingress_cidr_blocks + ingress_ipv6_cidr_blocks = var.ingress_ipv6_cidr_blocks + + # Default prefix list ids + ingress_prefix_list_ids = var.ingress_prefix_list_ids + + ################### + # Computed Ingress + ################### + # Rules by names - open for default CIDR + computed_ingress_rules = sort(compact(distinct(concat(var.auto_computed_ingress_rules, var.computed_ingress_rules, [""])))) + + # Open for self + computed_ingress_with_self = concat(var.auto_computed_ingress_with_self, var.computed_ingress_with_self) + + # Open to IPv4 cidr blocks + computed_ingress_with_cidr_blocks = var.computed_ingress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_ingress_with_ipv6_cidr_blocks = var.computed_ingress_with_ipv6_cidr_blocks + + # Open for security group id + computed_ingress_with_source_security_group_id = var.computed_ingress_with_source_security_group_id + + ############################# + # Number of computed ingress + ############################# + number_of_computed_ingress_rules = var.auto_number_of_computed_ingress_rules + var.number_of_computed_ingress_rules + number_of_computed_ingress_with_self = var.auto_number_of_computed_ingress_with_self + var.number_of_computed_ingress_with_self + number_of_computed_ingress_with_cidr_blocks = var.number_of_computed_ingress_with_cidr_blocks + number_of_computed_ingress_with_ipv6_cidr_blocks = var.number_of_computed_ingress_with_ipv6_cidr_blocks + number_of_computed_ingress_with_source_security_group_id = var.number_of_computed_ingress_with_source_security_group_id + + ######### + # Egress + ######### + # Rules by names - open for default CIDR + egress_rules = sort(compact(distinct(concat(var.auto_egress_rules, var.egress_rules, [""])))) + + # Open for self + egress_with_self = concat(var.auto_egress_with_self, var.egress_with_self) + + # Open to IPv4 cidr blocks + egress_with_cidr_blocks = var.egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + egress_with_ipv6_cidr_blocks = var.egress_with_ipv6_cidr_blocks + + # Open for security group id + egress_with_source_security_group_id = var.egress_with_source_security_group_id + + # Default egress CIDR blocks + egress_cidr_blocks = var.egress_cidr_blocks + egress_ipv6_cidr_blocks = var.egress_ipv6_cidr_blocks + + # Default prefix list ids + egress_prefix_list_ids = var.egress_prefix_list_ids + + ################## + # Computed Egress + ################## + # Rules by names - open for default CIDR + computed_egress_rules = sort(compact(distinct(concat(var.auto_computed_egress_rules, var.computed_egress_rules, [""])))) + + # Open for self + computed_egress_with_self = concat(var.auto_computed_egress_with_self, var.computed_egress_with_self) + + # Open to IPv4 cidr blocks + computed_egress_with_cidr_blocks = var.computed_egress_with_cidr_blocks + + # Open to IPv6 cidr blocks + computed_egress_with_ipv6_cidr_blocks = var.computed_egress_with_ipv6_cidr_blocks + + # Open for security group id + computed_egress_with_source_security_group_id = var.computed_egress_with_source_security_group_id + + ############################# + # Number of computed egress + ############################# + number_of_computed_egress_rules = var.auto_number_of_computed_egress_rules + var.number_of_computed_egress_rules + number_of_computed_egress_with_self = var.auto_number_of_computed_egress_with_self + var.number_of_computed_egress_with_self + number_of_computed_egress_with_cidr_blocks = var.number_of_computed_egress_with_cidr_blocks + number_of_computed_egress_with_ipv6_cidr_blocks = var.number_of_computed_egress_with_ipv6_cidr_blocks + number_of_computed_egress_with_source_security_group_id = var.number_of_computed_egress_with_source_security_group_id +} diff --git a/modules/aws-security-group/modules/zookeeper/outputs.tf b/modules/aws-security-group/modules/zookeeper/outputs.tf new file mode 100644 index 0000000..481dd14 --- /dev/null +++ b/modules/aws-security-group/modules/zookeeper/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = module.sg.security_group_arn +} + +output "security_group_id" { + description = "The ID of the security group" + value = module.sg.security_group_id +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = module.sg.security_group_vpc_id +} + +output "security_group_owner_id" { + description = "The owner ID" + value = module.sg.security_group_owner_id +} + +output "security_group_name" { + description = "The name of the security group" + value = module.sg.security_group_name +} + +output "security_group_description" { + description = "The description of the security group" + value = module.sg.security_group_description +} diff --git a/modules/aws-security-group/modules/zookeeper/variables.tf b/modules/aws-security-group/modules/zookeeper/variables.tf new file mode 100644 index 0000000..4d33156 --- /dev/null +++ b/modules/aws-security-group/modules/zookeeper/variables.tf @@ -0,0 +1,348 @@ +################# +# Security group +################# +variable "create" { + description = "Whether to create security group and all rules" + type = bool + default = true +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string +} + +variable "name" { + description = "Name of security group" + type = string +} + +variable "use_name_prefix" { + description = "Whether to use name_prefix or fixed name. Should be true to able to update security group name after initial creation" + type = bool + default = true +} + +variable "description" { + description = "Description of security group" + type = string + default = "Security Group managed by Terraform" +} + +variable "revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. Enable for EMR." + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to security group" + type = map(string) + default = {} +} + +########## +# Ingress +########## +variable "ingress_rules" { + description = "List of ingress rules to create by name" + type = list(string) + default = [] +} + +variable "ingress_with_self" { + description = "List of ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "ingress_with_cidr_blocks" { + description = "List of ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_ipv6_cidr_blocks" { + description = "List of ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_with_source_security_group_id" { + description = "List of ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all ingress rules" + type = list(string) + default = [] +} + +variable "ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all ingress rules" + type = list(string) + default = [] +} + +################### +# Computed Ingress +################### +variable "computed_ingress_rules" { + description = "List of computed ingress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_ingress_with_self" { + description = "List of computed ingress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_cidr_blocks" { + description = "List of computed ingress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_ipv6_cidr_blocks" { + description = "List of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_with_source_security_group_id" { + description = "List of computed ingress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_ingress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed ingress rules" + type = list(string) + default = [] +} + +variable "computed_ingress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = list(string) + default = [] +} + +################################### +# Number of computed ingress rules +################################### +variable "number_of_computed_ingress_rules" { + description = "Number of computed ingress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_self" { + description = "Number of computed ingress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_cidr_blocks" { + description = "Number of computed ingress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_ipv6_cidr_blocks" { + description = "Number of computed ingress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_with_source_security_group_id" { + description = "Number of computed ingress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_ingress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed ingress rules" + type = number + default = 0 +} + +variable "number_of_computed_ingress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed ingress rules" + type = number + default = 0 +} + +######### +# Egress +######### +variable "egress_rules" { + description = "List of egress rules to create by name" + type = list(string) + default = [] +} + +variable "egress_with_self" { + description = "List of egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "egress_with_cidr_blocks" { + description = "List of egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_ipv6_cidr_blocks" { + description = "List of egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "egress_with_source_security_group_id" { + description = "List of egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all egress rules" + type = list(string) + default = ["::/0"] +} + +variable "egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all egress rules" + type = list(string) + default = [] +} + +################## +# Computed Egress +################## +variable "computed_egress_rules" { + description = "List of computed egress rules to create by name" + type = list(string) + default = [] +} + +variable "computed_egress_with_self" { + description = "List of computed egress rules to create where 'self' is defined" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_cidr_blocks" { + description = "List of computed egress rules to create where 'cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_ipv6_cidr_blocks" { + description = "List of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_with_source_security_group_id" { + description = "List of computed egress rules to create where 'source_security_group_id' is used" + type = list(map(string)) + default = [] +} + +variable "computed_egress_cidr_blocks" { + description = "List of IPv4 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "computed_egress_ipv6_cidr_blocks" { + description = "List of IPv6 CIDR ranges to use on all computed egress rules" + type = list(string) + default = ["::/0"] +} + +variable "computed_egress_prefix_list_ids" { + description = "List of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = list(string) + default = [] +} + +################################## +# Number of computed egress rules +################################## +variable "number_of_computed_egress_rules" { + description = "Number of computed egress rules to create by name" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_self" { + description = "Number of computed egress rules to create where 'self' is defined" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_cidr_blocks" { + description = "Number of computed egress rules to create where 'cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_ipv6_cidr_blocks" { + description = "Number of computed egress rules to create where 'ipv6_cidr_blocks' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_with_source_security_group_id" { + description = "Number of computed egress rules to create where 'source_security_group_id' is used" + type = number + default = 0 +} + +variable "number_of_computed_egress_cidr_blocks" { + description = "Number of IPv4 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_ipv6_cidr_blocks" { + description = "Number of IPv6 CIDR ranges to use on all computed egress rules" + type = number + default = 0 +} + +variable "number_of_computed_egress_prefix_list_ids" { + description = "Number of prefix list IDs (for allowing access to VPC endpoints) to use on all computed egress rules" + type = number + default = 0 +} diff --git a/modules/aws-security-group/modules/zookeeper/versions.tf b/modules/aws-security-group/modules/zookeeper/versions.tf new file mode 100644 index 0000000..088a433 --- /dev/null +++ b/modules/aws-security-group/modules/zookeeper/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.29" + } + } +} diff --git a/modules/aws-security-group/outputs.tf b/modules/aws-security-group/outputs.tf new file mode 100644 index 0000000..f9ffe98 --- /dev/null +++ b/modules/aws-security-group/outputs.tf @@ -0,0 +1,29 @@ +output "security_group_arn" { + description = "The ARN of the security group" + value = try(aws_security_group.this[0].arn, aws_security_group.this_name_prefix[0].arn, "") +} + +output "security_group_id" { + description = "The ID of the security group" + value = try(aws_security_group.this[0].id, aws_security_group.this_name_prefix[0].id, "") +} + +output "security_group_vpc_id" { + description = "The VPC ID" + value = try(aws_security_group.this[0].vpc_id, aws_security_group.this_name_prefix[0].vpc_id, "") +} + +output "security_group_owner_id" { + description = "The owner ID" + value = try(aws_security_group.this[0].owner_id, aws_security_group.this_name_prefix[0].owner_id, "") +} + +output "security_group_name" { + description = "The name of the security group" + value = try(aws_security_group.this[0].name, aws_security_group.this_name_prefix[0].name, "") +} + +output "security_group_description" { + description = "The description of the security group" + value = try(aws_security_group.this[0].description, aws_security_group.this_name_prefix[0].description, "") +} diff --git a/modules/aws-security-group/rules.tf b/modules/aws-security-group/rules.tf new file mode 100644 index 0000000..21fe7af --- /dev/null +++ b/modules/aws-security-group/rules.tf @@ -0,0 +1,484 @@ +variable "rules" { + description = "Map of known security group rules (define as 'name' = ['from port', 'to port', 'protocol', 'description'])" + type = map(list(any)) + + # Protocols (tcp, udp, icmp, all - are allowed keywords) or numbers (from https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml): + # All = -1, IPV4-ICMP = 1, TCP = 6, UDP = 17, IPV6-ICMP = 58 + default = { + # ActiveMQ + activemq-5671-tcp = [5671, 5671, "tcp", "ActiveMQ AMQP"] + activemq-8883-tcp = [8883, 8883, "tcp", "ActiveMQ MQTT"] + activemq-61614-tcp = [61614, 61614, "tcp", "ActiveMQ STOMP"] + activemq-61617-tcp = [61617, 61617, "tcp", "ActiveMQ OpenWire"] + activemq-61619-tcp = [61619, 61619, "tcp", "ActiveMQ WebSocket"] + # Alert Manager + alertmanager-9093-tcp = [9093, 9093, "tcp", "Alert Manager"] + alertmanager-9094-tcp = [9094, 9094, "tcp", "Alert Manager Cluster"] + # Carbon relay + carbon-line-in-tcp = [2003, 2003, "tcp", "Carbon line-in"] + carbon-line-in-udp = [2003, 2003, "udp", "Carbon line-in"] + carbon-pickle-tcp = [2013, 2013, "tcp", "Carbon pickle"] + carbon-pickle-udp = [2013, 2013, "udp", "Carbon pickle"] + carbon-admin-tcp = [2004, 2004, "tcp", "Carbon admin"] + carbon-gui-udp = [8081, 8081, "tcp", "Carbon GUI"] + # Cassandra + cassandra-clients-tcp = [9042, 9042, "tcp", "Cassandra clients"] + cassandra-thrift-clients-tcp = [9160, 9160, "tcp", "Cassandra Thrift clients"] + cassandra-jmx-tcp = [7199, 7199, "tcp", "JMX"] + # Consul + consul-tcp = [8300, 8300, "tcp", "Consul server"] + consul-grpc-tcp = [8502, 8502, "tcp", "Consul gRPC"] + consul-webui-http-tcp = [8500, 8500, "tcp", "Consul web UI HTTP"] + consul-webui-https-tcp = [8501, 8501, "tcp", "Consul web UI HTTPS"] + consul-dns-tcp = [8600, 8600, "tcp", "Consul DNS"] + consul-dns-udp = [8600, 8600, "udp", "Consul DNS"] + consul-serf-lan-tcp = [8301, 8301, "tcp", "Serf LAN"] + consul-serf-lan-udp = [8301, 8301, "udp", "Serf LAN"] + consul-serf-wan-tcp = [8302, 8302, "tcp", "Serf WAN"] + consul-serf-wan-udp = [8302, 8302, "udp", "Serf WAN"] + # Docker Swarm + docker-swarm-mngmt-tcp = [2377, 2377, "tcp", "Docker Swarm cluster management"] + docker-swarm-node-tcp = [7946, 7946, "tcp", "Docker Swarm node"] + docker-swarm-node-udp = [7946, 7946, "udp", "Docker Swarm node"] + docker-swarm-overlay-udp = [4789, 4789, "udp", "Docker Swarm Overlay Network Traffic"] + # DNS + dns-udp = [53, 53, "udp", "DNS"] + dns-tcp = [53, 53, "tcp", "DNS"] + # Etcd + etcd-client-tcp = [2379, 2379, "tcp", "Etcd Client"] + etcd-peer-tcp = [2380, 2380, "tcp", "Etcd Peer"] + # NTP - Network Time Protocol + ntp-udp = [123, 123, "udp", "NTP"] + # Elasticsearch + elasticsearch-rest-tcp = [9200, 9200, "tcp", "Elasticsearch REST interface"] + elasticsearch-java-tcp = [9300, 9300, "tcp", "Elasticsearch Java interface"] + # Grafana + grafana-tcp = [3000, 3000, "tcp", "Grafana Dashboard"] + # Graphite Statsd + graphite-webui = [80, 80, "tcp", "Graphite admin interface"] + graphite-2003-tcp = [2003, 2003, "tcp", "Carbon receiver plain text"] + graphite-2004-tcp = [2004, 2004, "tcp", "Carbon receiver pickle"] + graphite-2023-tcp = [2023, 2023, "tcp", "Carbon aggregator plaintext"] + graphite-2024-tcp = [2024, 2024, "tcp", "Carbon aggregator pickle"] + graphite-8080-tcp = [8080, 8080, "tcp", "Graphite gunicorn port"] + graphite-8125-tcp = [8125, 8125, "tcp", "Statsd TCP"] + graphite-8125-udp = [8125, 8125, "udp", "Statsd UDP default"] + graphite-8126-tcp = [8126, 8126, "tcp", "Statsd admin"] + # HTTP + http-80-tcp = [80, 80, "tcp", "HTTP"] + http-8080-tcp = [8080, 8080, "tcp", "HTTP"] + # HTTPS + https-443-tcp = [443, 443, "tcp", "HTTPS"] + https-8443-tcp = [8443, 8443, "tcp", "HTTPS"] + # IPSEC + ipsec-500-udp = [500, 500, "udp", "IPSEC ISAKMP"] + ipsec-4500-udp = [4500, 4500, "udp", "IPSEC NAT-T"] + # Kafka + kafka-broker-tcp = [9092, 9092, "tcp", "Kafka PLAINTEXT enable broker 0.8.2+"] + kafka-broker-tls-tcp = [9094, 9094, "tcp", "Kafka TLS enabled broker 0.8.2+"] + kafka-broker-tls-public-tcp = [9194, 9194, "tcp", "Kafka TLS Public enabled broker 0.8.2+ (MSK specific)"] + kafka-broker-sasl-scram-tcp = [9096, 9096, "tcp", "Kafka SASL/SCRAM enabled broker (MSK specific)"] + kafka-broker-sasl-scram-public-tcp = [9196, 9196, "tcp", "Kafka SASL/SCRAM Public enabled broker (MSK specific)"] + kafka-broker-sasl-iam-tcp = [9098, 9098, "tcp", "Kafka SASL/IAM access control enabled (MSK specific)"] + kafka-broker-sasl-iam-public-tcp = [9198, 9198, "tcp", "Kafka SASL/IAM Public access control enabled (MSK specific)"] + kafka-jmx-exporter-tcp = [11001, 11001, "tcp", "Kafka JMX Exporter"] + kafka-node-exporter-tcp = [11002, 11002, "tcp", "Kafka Node Exporter"] + # Kibana + kibana-tcp = [5601, 5601, "tcp", "Kibana Web Interface"] + # Kubernetes + kubernetes-api-tcp = [6443, 6443, "tcp", "Kubernetes API Server"] + # LDAP + ldap-tcp = [389, 389, "tcp", "LDAP"] + # LDAPS + ldaps-tcp = [636, 636, "tcp", "LDAPS"] + # Logstash + logstash-tcp = [5044, 5044, "tcp", "Logstash"] + # Memcached + memcached-tcp = [11211, 11211, "tcp", "Memcached"] + # MinIO + minio-tcp = [9000, 9000, "tcp", "MinIO"] + # MongoDB + mongodb-27017-tcp = [27017, 27017, "tcp", "MongoDB"] + mongodb-27018-tcp = [27018, 27018, "tcp", "MongoDB shard"] + mongodb-27019-tcp = [27019, 27019, "tcp", "MongoDB config server"] + # MySQL + mysql-tcp = [3306, 3306, "tcp", "MySQL/Aurora"] + # MSSQL Server + mssql-tcp = [1433, 1433, "tcp", "MSSQL Server"] + mssql-udp = [1434, 1434, "udp", "MSSQL Browser"] + mssql-analytics-tcp = [2383, 2383, "tcp", "MSSQL Analytics"] + mssql-broker-tcp = [4022, 4022, "tcp", "MSSQL Broker"] + # NFS/EFS + nfs-tcp = [2049, 2049, "tcp", "NFS/EFS"] + # Nomad + nomad-http-tcp = [4646, 4646, "tcp", "Nomad HTTP"] + nomad-rpc-tcp = [4647, 4647, "tcp", "Nomad RPC"] + nomad-serf-tcp = [4648, 4648, "tcp", "Serf"] + nomad-serf-udp = [4648, 4648, "udp", "Serf"] + # OpenVPN + openvpn-udp = [1194, 1194, "udp", "OpenVPN"] + openvpn-tcp = [943, 943, "tcp", "OpenVPN"] + openvpn-https-tcp = [443, 443, "tcp", "OpenVPN"] + # PostgreSQL + postgresql-tcp = [5432, 5432, "tcp", "PostgreSQL"] + # Puppet + puppet-tcp = [8140, 8140, "tcp", "Puppet"] + puppetdb-tcp = [8081, 8081, "tcp", "PuppetDB"] + # Prometheus + prometheus-http-tcp = [9090, 9090, "tcp", "Prometheus"] + prometheus-pushgateway-http-tcp = [9091, 9091, "tcp", "Prometheus Pushgateway"] + # Oracle Database + oracle-db-tcp = [1521, 1521, "tcp", "Oracle"] + # Octopus Tentacles + octopus-tentacle-tcp = [10933, 10933, "tcp", "Octopus Tentacle"] + # RabbitMQ + rabbitmq-4369-tcp = [4369, 4369, "tcp", "RabbitMQ epmd"] + rabbitmq-5671-tcp = [5671, 5671, "tcp", "RabbitMQ"] + rabbitmq-5672-tcp = [5672, 5672, "tcp", "RabbitMQ"] + rabbitmq-15672-tcp = [15672, 15672, "tcp", "RabbitMQ"] + rabbitmq-25672-tcp = [25672, 25672, "tcp", "RabbitMQ"] + # RDP + rdp-tcp = [3389, 3389, "tcp", "Remote Desktop"] + rdp-udp = [3389, 3389, "udp", "Remote Desktop"] + # Redis + redis-tcp = [6379, 6379, "tcp", "Redis"] + # Redshift + redshift-tcp = [5439, 5439, "tcp", "Redshift"] + # SaltStack + saltstack-tcp = [4505, 4506, "tcp", "SaltStack"] + # SMTP + smtp-tcp = [25, 25, "tcp", "SMTP"] + smtp-submission-587-tcp = [587, 587, "tcp", "SMTP Submission"] + smtp-submission-2587-tcp = [2587, 2587, "tcp", "SMTP Submission"] + smtps-465-tcp = [465, 465, "tcp", "SMTPS"] + smtps-2456-tcp = [2465, 2465, "tcp", "SMTPS"] + # Solr + solr-tcp = [8983, 8987, "tcp", "Solr"] + # Splunk + splunk-indexer-tcp = [9997, 9997, "tcp", "Splunk indexer"] + splunk-web-tcp = [8000, 8000, "tcp", "Splunk Web"] + splunk-splunkd-tcp = [8089, 8089, "tcp", "Splunkd"] + splunk-hec-tcp = [8088, 8088, "tcp", "Splunk HEC"] + # Squid + squid-proxy-tcp = [3128, 3128, "tcp", "Squid default proxy"] + # SSH + ssh-tcp = [22, 22, "tcp", "SSH"] + # Storm + storm-nimbus-tcp = [6627, 6627, "tcp", "Nimbus"] + storm-ui-tcp = [8080, 8080, "tcp", "Storm UI"] + storm-supervisor-tcp = [6700, 6703, "tcp", "Supervisor"] + # Wazuh + wazuh-server-agent-connection-tcp = [1514, 1514, "tcp", "Agent connection service(TCP)"] + wazuh-server-agent-connection-udp = [1514, 1514, "udp", "Agent connection service(UDP)"] + wazuh-server-agent-enrollment = [1515, 1515, "tcp", "Agent enrollment service"] + wazuh-server-agent-cluster-daemon = [1516, 1516, "tcp", "Wazuh cluster daemon"] + wazuh-server-syslog-collector-tcp = [514, 514, "tcp", "Wazuh Syslog collector(TCP)"] + wazuh-server-syslog-collector-udp = [514, 514, "udp", "Wazuh Syslog collector(UDP)"] + wazuh-server-restful-api = [55000, 55000, "tcp", "Wazuh server RESTful API"] + wazuh-indexer-restful-api = [9200, 9200, "tcp", "Wazuh indexer RESTful API"] + wazuh-dashboard = [443, 443, "tcp", "Wazuh web user interface"] + # Web + web-jmx-tcp = [1099, 1099, "tcp", "JMX"] + # WinRM + winrm-http-tcp = [5985, 5985, "tcp", "WinRM HTTP"] + winrm-https-tcp = [5986, 5986, "tcp", "WinRM HTTPS"] + # Zabbix + zabbix-server = [10051, 10051, "tcp", "Zabbix Server"] + zabbix-proxy = [10051, 10051, "tcp", "Zabbix Proxy"] + zabbix-agent = [10050, 10050, "tcp", "Zabbix Agent"] + # Zipkin + zipkin-admin-tcp = [9990, 9990, "tcp", "Zipkin Admin port collector"] + zipkin-admin-query-tcp = [9901, 9901, "tcp", "Zipkin Admin port query"] + zipkin-admin-web-tcp = [9991, 9991, "tcp", "Zipkin Admin port web"] + zipkin-query-tcp = [9411, 9411, "tcp", "Zipkin query port"] + zipkin-web-tcp = [8080, 8080, "tcp", "Zipkin web port"] + # Zookeeper + zookeeper-2181-tcp = [2181, 2181, "tcp", "Zookeeper"] + zookeeper-2182-tls-tcp = [2182, 2182, "tcp", "Zookeeper TLS (MSK specific)"] + zookeeper-2888-tcp = [2888, 2888, "tcp", "Zookeeper"] + zookeeper-3888-tcp = [3888, 3888, "tcp", "Zookeeper"] + zookeeper-jmx-tcp = [7199, 7199, "tcp", "JMX"] + # Open all ports & protocols + all-all = [-1, -1, "-1", "All protocols"] + all-tcp = [0, 65535, "tcp", "All TCP ports"] + all-udp = [0, 65535, "udp", "All UDP ports"] + all-icmp = [-1, -1, "icmp", "All IPV4 ICMP"] + all-ipv6-icmp = [-1, -1, 58, "All IPV6 ICMP"] + # This is a fallback rule to pass to lookup() as default. It does not open anything, because it should never be used. + _ = ["", "", ""] + } +} + +variable "auto_groups" { + description = "Map of groups of security group rules to use to generate modules (see update_groups.sh)" + type = map(map(list(string))) + + # Valid keys - ingress_rules, egress_rules, ingress_with_self, egress_with_self + default = { + activemq = { + ingress_rules = ["activemq-5671-tcp", "activemq-8883-tcp", "activemq-61614-tcp", "activemq-61617-tcp", "activemq-61619-tcp"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + alertmanager = { + ingress_rules = ["alertmanager-9093-tcp", "alertmanager-9094-tcp"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + carbon-relay-ng = { + ingress_rules = ["carbon-line-in-tcp", "carbon-line-in-udp", "carbon-pickle-tcp", "carbon-pickle-udp", "carbon-gui-udp"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + cassandra = { + ingress_rules = ["cassandra-clients-tcp", "cassandra-thrift-clients-tcp", "cassandra-jmx-tcp"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + consul = { + ingress_rules = ["consul-tcp", "consul-grpc-tcp", "consul-webui-http-tcp", "consul-webui-https-tcp", "consul-dns-tcp", "consul-dns-udp", "consul-serf-lan-tcp", "consul-serf-lan-udp", "consul-serf-wan-tcp", "consul-serf-wan-udp"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + docker-swarm = { + ingress_rules = ["docker-swarm-mngmt-tcp", "docker-swarm-node-tcp", "docker-swarm-node-udp", "docker-swarm-overlay-udp"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + etcd = { + ingress_rules = ["etcd-client-tcp", "etcd-peer-tcp"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + elasticsearch = { + ingress_rules = ["elasticsearch-rest-tcp", "elasticsearch-java-tcp"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + grafana = { + ingress_rules = ["grafana-tcp"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + graphite-statsd = { + ingress_rules = ["graphite-webui", "graphite-2003-tcp", "graphite-2004-tcp", "graphite-2023-tcp", "graphite-2024-tcp", "graphite-8080-tcp", "graphite-8125-tcp", "graphite-8125-udp", "graphite-8126-tcp"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + http-80 = { + ingress_rules = ["http-80-tcp"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + http-8080 = { + ingress_rules = ["http-8080-tcp"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + https-443 = { + ingress_rules = ["https-443-tcp"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + https-8443 = { + ingress_rules = ["https-8443-tcp"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + ipsec-500 = { + ingress_rules = ["ipsec-500-udp"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + ipsec-4500 = { + ingress_rules = ["ipsec-4500-udp"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + kafka = { + ingress_rules = ["kafka-broker-tcp", "kafka-broker-tls-tcp", "kafka-broker-tls-public-tcp", "kafka-broker-sasl-scram-tcp", "kafka-broker-sasl-scram-tcp", "kafka-broker-sasl-iam-tcp", "kafka-broker-sasl-iam-public-tcp", "kafka-jmx-exporter-tcp", "kafka-node-exporter-tcp"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + kubernetes-api = { + ingress_rules = ["kubernetes-api-tcp"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + kibana = { + ingress_rules = ["kibana-tcp"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + ldap = { + ingress_rules = ["ldap-tcp"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + ldaps = { + ingress_rules = ["ldaps-tcp"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + logstash = { + ingress_rules = ["logstash-tcp"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + memcached = { + ingress_rules = ["memcached-tcp"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + minio = { + ingress_rules = ["minio-tcp"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + mongodb = { + ingress_rules = ["mongodb-27017-tcp", "mongodb-27018-tcp", "mongodb-27019-tcp"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + mysql = { + ingress_rules = ["mysql-tcp"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + mssql = { + ingress_rules = ["mssql-tcp", "mssql-udp", "mssql-analytics-tcp", "mssql-broker-tcp"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + nfs = { + ingress_rules = ["nfs-tcp"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + nomad = { + ingress_rules = ["nomad-http-tcp", "nomad-rpc-tcp", "nomad-serf-tcp", "nomad-serf-udp"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + openvpn = { + ingress_rules = ["openvpn-udp", "openvpn-tcp", "openvpn-https-tcp"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + postgresql = { + ingress_rules = ["postgresql-tcp"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + oracle-db = { + ingress_rules = ["oracle-db-tcp"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + ntp = { + ingress_rules = ["ntp-udp"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + puppet = { + ingress_rules = ["puppet-tcp", "puppetdb-tcp"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + prometheus = { + ingress_rules = ["prometheus-http-tcp", "prometheus-pushgateway-http-tcp"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + rabbitmq = { + ingress_rules = ["rabbitmq-4369-tcp", "rabbitmq-5671-tcp", "rabbitmq-5672-tcp", "rabbitmq-15672-tcp", "rabbitmq-25672-tcp"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + rdp = { + ingress_rules = ["rdp-tcp", "rdp-udp"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + redis = { + ingress_rules = ["redis-tcp"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + redshift = { + ingress_rules = ["redshift-tcp"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + smtp = { + ingress_rules = ["smtp-tcp"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + smtp-submission = { + ingress_rules = ["smtp-submission-587-tcp", "smtp-submission-2587-tcp"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + smtps = { + ingress_rules = ["smtps-465-tcp", "smtps-2465-tcp"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + solr = { + ingress_rules = ["solr-tcp"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + splunk = { + ingress_rules = ["splunk-indexer-tcp", "splunk-clients-tcp", "splunk-splunkd-tcp", "splunk-hec-tcp"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + squid = { + ingress_rules = ["squid-proxy-tcp"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + ssh = { + ingress_rules = ["ssh-tcp"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + storm = { + ingress_rules = ["storm-nimbus-tcp", "storm-ui-tcp", "storm-supervisor-tcp"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + wazuh = { + ingress_rules = ["wazuh-server-agent-connection-tcp", "wazuh-server-agent-connection-udp", "wazuh-server-agent-enrollment", "wazuh-server-agent-cluster-daemon", "wazuh-server-syslog-collector-tcp", "wazuh-server-syslog-collector-udp", "wazuh-server-restful-api", "wazuh-indexer-restful-api", "wazuh-dashboard", ] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + web = { + ingress_rules = ["http-80-tcp", "http-8080-tcp", "https-443-tcp", "web-jmx-tcp"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + winrm = { + ingress_rules = ["winrm-http-tcp", "winrm-https-tcp"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + zabbix = { + ingress_rules = ["zabbix-server", "zabbix-proxy", "zabbix-agent"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + zipkin = { + ingress_rules = ["zipkin-admin-tcp", "zipkin-admin-query-tcp", "zipkin-admin-web-tcp", "zipkin-query-tcp", "zipkin-web-tcp"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + zookeeper = { + ingress_rules = ["zookeeper-2181-tcp", "zookeeper-2182-tls-tcp", "zookeeper-2888-tcp", "zookeeper-3888-tcp", "zookeeper-jmx-tcp"] + ingress_with_self = ["all-all"] + egress_rules = ["all-all"] + } + } +} diff --git a/modules/aws-security-group/update_groups.sh b/modules/aws-security-group/update_groups.sh new file mode 100644 index 0000000..2d65420 --- /dev/null +++ b/modules/aws-security-group/update_groups.sh @@ -0,0 +1,253 @@ +#!/usr/bin/env bash + +# This script generates each public module (eg, "http-80", "ssh") and specify rules required for each group. +# This script should be run after rules.tf is changed to refresh all related modules. +# outputs.tf and variables.tf for all group modules are the same for all + +set -e + +# Change location to the directory where this script it located +cd "$(dirname "${BASH_SOURCE[0]}")" + +check_dependencies() { + if [[ ! $(command -v sed) ]]; then + echo "ERROR: The binary 'sed' is required by this script but is not installed or in the system's PATH." + echo "Check documentation: https://www.gnu.org/software/sed/" + exit 1 + fi + + if [[ ! $(command -v hcl2json) ]]; then + echo "ERROR: The binary 'hcl2json' is required by this script but is not installed or in the system's PATH." + echo "Check documentation: https://github.com/tmccombs/hcl2json" + exit 1 + fi + + if [[ ! $(command -v jq) ]]; then + echo "ERROR: The binary 'jq' is required by this script but is not installed or in the system's PATH." + echo "Check documentation: https://github.com/stedolan/jq" + exit 1 + fi +} + +auto_groups_data() { + hcl2json rules.tf | jq -r '..|.auto_groups?|values|.default' +} + +auto_groups_keys() { + local data=$1 + + echo "$data" | jq -r ".|keys|@sh" | tr -d "'" +} + +get_auto_value() { + local data=$1 + local group=$2 + local var=$3 + + echo "$data" | jq -rc '.[$group][$var]' --arg group "$group" --arg var "$var" +} + +set_list_if_null() { + if [[ "null" == "$1" ]]; then + echo "[]" + else + echo "$1" + fi +} + +set_zero_if_null() { + if [[ "null" == "$1" ]]; then + echo 0 + else + echo "$1" + fi +} + +main() { + check_dependencies + + readonly local auto_groups_data="$(auto_groups_data)" + + if [[ -z "$(auto_groups_data)" ]]; then + echo "There are no modules to update. Check values of auto_groups inside rules.tf" + exit 0 + fi + + readonly local auto_groups_keys=($(auto_groups_keys "$auto_groups_data")) + + local ingress_rules="" + local ingress_with_self="" + local egress_rules="" + local egress_with_self="" + local list_of_modules="" + + for group in "${auto_groups_keys[@]}"; do + + echo "Making group: $group" + + mkdir -p "modules/$group" + cp modules/_templates/{main,outputs,variables,versions}.tf "modules/$group" + + # Get group values + ingress_rules=$(get_auto_value "$auto_groups_data" "$group" "ingress_rules") + ingress_with_self=$(get_auto_value "$auto_groups_data" "$group" "ingress_with_self") + egress_rules=$(get_auto_value "$auto_groups_data" "$group" "egress_rules") + egress_with_self=$(get_auto_value "$auto_groups_data" "$group" "egress_with_self") + + # Computed values + computed_ingress_rules=$(get_auto_value "$auto_groups_data" "$group" "computed_ingress_rules") + computed_ingress_with_self=$(get_auto_value "$auto_groups_data" "$group" "computed_ingress_with_self") + computed_egress_rules=$(get_auto_value "$auto_groups_data" "$group" "computed_egress_rules") + computed_egress_with_self=$(get_auto_value "$auto_groups_data" "$group" "computed_egress_with_self") + + # Number of computed values + number_of_computed_ingress_rules=$(get_auto_value "$auto_groups_data" "$group" "number_of_computed_ingress_rules") + number_of_computed_ingress_with_self=$(get_auto_value "$auto_groups_data" "$group" "number_of_computed_ingress_with_self") + number_of_computed_egress_rules=$(get_auto_value "$auto_groups_data" "$group" "number_of_computed_egress_rules") + number_of_computed_egress_with_self=$(get_auto_value "$auto_groups_data" "$group" "number_of_computed_egress_with_self") + + # Set to empty lists, if no value was specified + ingress_rules=$(set_list_if_null "$ingress_rules") + ingress_with_self=$(set_list_if_null "$ingress_with_self") + egress_rules=$(set_list_if_null "$egress_rules") + egress_with_self=$(set_list_if_null "$egress_with_self") + + # Set to empty lists, if no computed value was specified + computed_ingress_rules=$(set_list_if_null "$computed_ingress_rules") + computed_ingress_with_self=$(set_list_if_null "$computed_ingress_with_self") + computed_egress_rules=$(set_list_if_null "$computed_egress_rules") + computed_egress_with_self=$(set_list_if_null "$computed_egress_with_self") + + # Set to zero, if no value was specified + number_of_computed_ingress_rules=$(set_zero_if_null "$number_of_computed_ingress_rules") + number_of_computed_ingress_with_self=$(set_zero_if_null "$number_of_computed_ingress_with_self") + number_of_computed_egress_rules=$(set_zero_if_null "$number_of_computed_egress_rules") + number_of_computed_egress_with_self=$(set_zero_if_null "$number_of_computed_egress_with_self") + + # ingress_with_self and egress_with_self are stored as simple lists (like this - ["all-all","all-tcp"]), + # so we make map (like this - [{"rule"="all-all"},{"rule"="all-tcp"}]) + ingress_with_self=$(echo "$ingress_with_self" | jq -rc "[{rule:.[]}]" | tr ':' '=') + egress_with_self=$(echo "$egress_with_self" | jq -rc "[{rule:.[]}]" | tr ':' '=') + + cat <
"::/0"
]
list(object({| n/a | yes | +| [tags](#input\_tags) | Key-value map of resource tags. If configured with a provider default\_tags configuration block present, tags with matching keys will overwrite those defined at the provider-level. | `map(string)` | `{}` | no | + +## Outputs + +No outputs. + \ No newline at end of file diff --git a/modules/aws-shield/group_resource_type/locals.tf b/modules/aws-shield/group_resource_type/locals.tf new file mode 100644 index 0000000..f74b546 --- /dev/null +++ b/modules/aws-shield/group_resource_type/locals.tf @@ -0,0 +1,3 @@ +locals { + tags = var.tags +} \ No newline at end of file diff --git a/modules/aws-shield/group_resource_type/main.tf b/modules/aws-shield/group_resource_type/main.tf new file mode 100644 index 0000000..cfbefe6 --- /dev/null +++ b/modules/aws-shield/group_resource_type/main.tf @@ -0,0 +1,9 @@ +resource "aws_shield_protection_group" "resource_type_protection_group" { + count = length(var.resource_type_protection_group) + protection_group_id = var.resource_type_protection_group.group_id + aggregation = var.resource_type_protection_group.aggregation + pattern = "BY_RESOURCE_TYPE" + resource_type = var.resource_type_protection_group.resource_type + + tags = local.tags +} \ No newline at end of file diff --git a/modules/aws-shield/group_resource_type/provider.tf b/modules/aws-shield/group_resource_type/provider.tf new file mode 100644 index 0000000..c142005 --- /dev/null +++ b/modules/aws-shield/group_resource_type/provider.tf @@ -0,0 +1,9 @@ +terraform { + required_version = ">= 0.14" + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.22" + } + } +} \ No newline at end of file diff --git a/modules/aws-shield/group_resource_type/variables.tf b/modules/aws-shield/group_resource_type/variables.tf new file mode 100644 index 0000000..cfb708a --- /dev/null +++ b/modules/aws-shield/group_resource_type/variables.tf @@ -0,0 +1,26 @@ +variable "tags" { + type = map(string) + description = "Key-value map of resource tags. If configured with a provider default_tags configuration block present, tags with matching keys will overwrite those defined at the provider-level." + default = {} +} + +variable "resource_type_protection_group" { + type = list(object({ + group_id = string + aggregation = string + members = list(string) + resource_type = string + })) + validation { + condition = contains([ + "CLOUDFRONT_DISTRIBUTION", + "ROUTE_53_HOSTED_ZONE", + "GLOBAL_ACCELERATOR", + "APPLICATION_LOAD_BALANCER", + "CLASSIC_LOAD_BALANCER", + "ELASTIC_IP_ALLOCATION", + ], var.resource_type) + error_message = "Valid values are limited in validation section." + } + description = "all shield protection group values list as resource type" +} diff --git a/modules/aws-shield/main.tf b/modules/aws-shield/main.tf new file mode 100644 index 0000000..e9bdf15 --- /dev/null +++ b/modules/aws-shield/main.tf @@ -0,0 +1,15 @@ +resource "aws_shield_protection" "shield" { + for_each = { for k, v in var.name_resource_arn_map : k => v if !lookup(v, "cross_account_shield", false) } + name = each.key + resource_arn = lookup(each.value, "arn", null) + tags = var.tags +} + +resource "aws_shield_protection" "cross_account_shield" { + provider = aws.shared_infra + for_each = { for k, v in var.name_resource_arn_map : k => v if lookup(v, "cross_account_shield", false) } + name = each.key + resource_arn = lookup(each.value, "arn", null) + + tags = var.tags +} \ No newline at end of file diff --git a/modules/aws-shield/outputs.tf b/modules/aws-shield/outputs.tf new file mode 100644 index 0000000..2cc5303 --- /dev/null +++ b/modules/aws-shield/outputs.tf @@ -0,0 +1,9 @@ +output "shield" { + value = { for key, value in aws_shield_protection.shield : key => value } + description = "A map of properties for the created AWS Shield protection." +} + +output "cross_account_shield" { + value = { for key, value in aws_shield_protection.cross_account_shield : key => value } + description = "A map of properties for the created AWS Shield protection." +} \ No newline at end of file diff --git a/modules/aws-shield/variables.tf b/modules/aws-shield/variables.tf new file mode 100644 index 0000000..dc43314 --- /dev/null +++ b/modules/aws-shield/variables.tf @@ -0,0 +1,11 @@ +variable "name_resource_arn_map" { + type = any + description = "A map of names and ARNs of resources to be protected. The name will be used as the name of the resource in the AWS console." + default = {} +} + +variable "tags" { + type = map(string) + description = "A map of tag names and values for tags to apply to all taggable resources created by the module. Default value is a blank map to allow for using Default Tags in the provider." + default = {} +} \ No newline at end of file diff --git a/modules/aws-shield/versions.tf b/modules/aws-shield/versions.tf new file mode 100644 index 0000000..c142005 --- /dev/null +++ b/modules/aws-shield/versions.tf @@ -0,0 +1,9 @@ +terraform { + required_version = ">= 0.14" + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.22" + } + } +} \ No newline at end of file diff --git a/modules/aws-sns-master/README.md b/modules/aws-sns-master/README.md new file mode 100644 index 0000000..d216e3d --- /dev/null +++ b/modules/aws-sns-master/README.md @@ -0,0 +1,90 @@ +# AWS SNS Topic Terraform module + +Terraform module which creates SNS resources on AWS + +## Usage + +```hcl +module "sns_topic" { + source = "terraform-aws-modules/sns/aws" + version = "~> 3.0" + + name = "my-topic" +} +``` + +## Examples + +- [Complete SNS topics](https://github.com/terraform-aws-modules/terraform-aws-sns/tree/master/examples/complete) + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.0 | +| [aws](#requirement\_aws) | >= 4.0 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 4.0 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_sns_topic.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sns_topic) | resource | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [application\_failure\_feedback\_role\_arn](#input\_application\_failure\_feedback\_role\_arn) | IAM role for failure feedback | `string` | `null` | no | +| [application\_success\_feedback\_role\_arn](#input\_application\_success\_feedback\_role\_arn) | The IAM role permitted to receive success feedback for this topic | `string` | `null` | no | +| [application\_success\_feedback\_sample\_rate](#input\_application\_success\_feedback\_sample\_rate) | Percentage of success to sample | `string` | `null` | no | +| [content\_based\_deduplication](#input\_content\_based\_deduplication) | Boolean indicating whether or not to enable content-based deduplication for FIFO topics. | `bool` | `false` | no | +| [create\_sns\_topic](#input\_create\_sns\_topic) | Whether to create the SNS topic | `bool` | `true` | no | +| [delivery\_policy](#input\_delivery\_policy) | The SNS delivery policy | `string` | `null` | no | +| [display\_name](#input\_display\_name) | The display name for the SNS topic | `string` | `null` | no | +| [fifo\_topic](#input\_fifo\_topic) | Boolean indicating whether or not to create a FIFO (first-in-first-out) topic | `bool` | `false` | no | +| [firehose\_failure\_feedback\_role\_arn](#input\_firehose\_failure\_feedback\_role\_arn) | IAM role for failure feedback | `string` | `null` | no | +| [firehose\_success\_feedback\_role\_arn](#input\_firehose\_success\_feedback\_role\_arn) | The IAM role permitted to receive success feedback for this topic | `string` | `null` | no | +| [firehose\_success\_feedback\_sample\_rate](#input\_firehose\_success\_feedback\_sample\_rate) | Percentage of success to sample | `number` | `null` | no | +| [http\_failure\_feedback\_role\_arn](#input\_http\_failure\_feedback\_role\_arn) | IAM role for failure feedback | `string` | `null` | no | +| [http\_success\_feedback\_role\_arn](#input\_http\_success\_feedback\_role\_arn) | The IAM role permitted to receive success feedback for this topic | `string` | `null` | no | +| [http\_success\_feedback\_sample\_rate](#input\_http\_success\_feedback\_sample\_rate) | Percentage of success to sample | `string` | `null` | no | +| [kms\_master\_key\_id](#input\_kms\_master\_key\_id) | The ID of an AWS-managed customer master key (CMK) for Amazon SNS or a custom CMK | `string` | `null` | no | +| [lambda\_failure\_feedback\_role\_arn](#input\_lambda\_failure\_feedback\_role\_arn) | IAM role for failure feedback | `string` | `null` | no | +| [lambda\_success\_feedback\_role\_arn](#input\_lambda\_success\_feedback\_role\_arn) | The IAM role permitted to receive success feedback for this topic | `string` | `null` | no | +| [lambda\_success\_feedback\_sample\_rate](#input\_lambda\_success\_feedback\_sample\_rate) | Percentage of success to sample | `string` | `null` | no | +| [name](#input\_name) | The name of the SNS topic to create | `string` | `null` | no | +| [name\_prefix](#input\_name\_prefix) | The prefix name of the SNS topic to create | `string` | `null` | no | +| [policy](#input\_policy) | The fully-formed AWS policy as JSON | `string` | `null` | no | +| [sqs\_failure\_feedback\_role\_arn](#input\_sqs\_failure\_feedback\_role\_arn) | IAM role for failure feedback | `string` | `null` | no | +| [sqs\_success\_feedback\_role\_arn](#input\_sqs\_success\_feedback\_role\_arn) | The IAM role permitted to receive success feedback for this topic | `string` | `null` | no | +| [sqs\_success\_feedback\_sample\_rate](#input\_sqs\_success\_feedback\_sample\_rate) | Percentage of success to sample | `string` | `null` | no | +| [tags](#input\_tags) | A mapping of tags to assign to all resources | `map(string)` | `{}` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [sns\_topic\_arn](#output\_sns\_topic\_arn) | ARN of SNS topic | +| [sns\_topic\_id](#output\_sns\_topic\_id) | ID of SNS topic | +| [sns\_topic\_name](#output\_sns\_topic\_name) | NAME of SNS topic | +| [sns\_topic\_owner](#output\_sns\_topic\_owner) | OWNER of SNS topic | + + +## Authors + +Module is maintained by [Anton Babenko](https://github.com/antonbabenko) with help from [these awesome contributors](https://github.com/terraform-aws-modules/terraform-aws-sns/graphs/contributors). + +## License + +Apache 2 Licensed. See [LICENSE](https://github.com/terraform-aws-modules/terraform-aws-sns/tree/master/LICENSE) for full details. diff --git a/modules/aws-sns-master/examples/complete/README.md b/modules/aws-sns-master/examples/complete/README.md new file mode 100644 index 0000000..b696131 --- /dev/null +++ b/modules/aws-sns-master/examples/complete/README.md @@ -0,0 +1,54 @@ +# Complete SNS topic example + +Configuration in this directory creates SNS topics. + +## Usage + +To run this example you need to execute: + +```bash +$ terraform init +$ terraform plan +$ terraform apply +``` + +Note that this example may create resources which cost money. Run `terraform destroy` when you don't need these resources. + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.0 | +| [aws](#requirement\_aws) | >= 4.0 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 4.0 | + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [users\_encrypted](#module\_users\_encrypted) | ../../ | n/a | +| [users\_unencrypted](#module\_users\_unencrypted) | ../../ | n/a | + +## Resources + +| Name | Type | +|------|------| +| [aws_kms_key.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | resource | + +## Inputs + +No inputs. + +## Outputs + +| Name | Description | +|------|-------------| +| [users\_encrypted\_sns\_topic\_arn](#output\_users\_encrypted\_sns\_topic\_arn) | The ARN of the SNS topic | +| [users\_unencrypted\_sns\_topic\_arn](#output\_users\_unencrypted\_sns\_topic\_arn) | The ARN of the SNS topic | + diff --git a/modules/aws-sns-master/examples/complete/main.tf b/modules/aws-sns-master/examples/complete/main.tf new file mode 100644 index 0000000..c418d1f --- /dev/null +++ b/modules/aws-sns-master/examples/complete/main.tf @@ -0,0 +1,27 @@ +provider "aws" { + region = "eu-west-1" +} + +resource "aws_kms_key" "this" {} + +module "users_unencrypted" { + source = "../../" + + name = "users-unencrypted" + + tags = { + Secure = "false" + } +} + +module "users_encrypted" { + source = "../../" + + name_prefix = "users-encrypted-" + display_name = "users-encrypted" + kms_master_key_id = aws_kms_key.this.id + + tags = { + Secure = "true" + } +} diff --git a/modules/aws-sns-master/examples/complete/outputs.tf b/modules/aws-sns-master/examples/complete/outputs.tf new file mode 100644 index 0000000..2568e14 --- /dev/null +++ b/modules/aws-sns-master/examples/complete/outputs.tf @@ -0,0 +1,9 @@ +output "users_unencrypted_sns_topic_arn" { + description = "The ARN of the SNS topic" + value = module.users_unencrypted.sns_topic_arn +} + +output "users_encrypted_sns_topic_arn" { + description = "The ARN of the SNS topic" + value = module.users_encrypted.sns_topic_arn +} diff --git a/modules/aws-sns-master/examples/complete/variables.tf b/modules/aws-sns-master/examples/complete/variables.tf new file mode 100644 index 0000000..e69de29 diff --git a/modules/aws-sns-master/examples/complete/versions.tf b/modules/aws-sns-master/examples/complete/versions.tf new file mode 100644 index 0000000..d8dd1a4 --- /dev/null +++ b/modules/aws-sns-master/examples/complete/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.0" + } + } +} diff --git a/modules/aws-sns-master/main.tf b/modules/aws-sns-master/main.tf new file mode 100644 index 0000000..ae17a9a --- /dev/null +++ b/modules/aws-sns-master/main.tf @@ -0,0 +1,30 @@ +resource "aws_sns_topic" "this" { + count = var.create_sns_topic ? 1 : 0 + + name = var.name + name_prefix = var.name_prefix + + display_name = var.display_name + policy = var.policy + delivery_policy = var.delivery_policy + application_success_feedback_role_arn = var.application_success_feedback_role_arn + application_success_feedback_sample_rate = var.application_success_feedback_sample_rate + application_failure_feedback_role_arn = var.application_failure_feedback_role_arn + firehose_success_feedback_role_arn = var.firehose_success_feedback_role_arn + firehose_success_feedback_sample_rate = var.firehose_success_feedback_sample_rate + firehose_failure_feedback_role_arn = var.firehose_failure_feedback_role_arn + http_success_feedback_role_arn = var.http_success_feedback_role_arn + http_success_feedback_sample_rate = var.http_success_feedback_sample_rate + http_failure_feedback_role_arn = var.http_failure_feedback_role_arn + lambda_success_feedback_role_arn = var.lambda_success_feedback_role_arn + lambda_success_feedback_sample_rate = var.lambda_success_feedback_sample_rate + lambda_failure_feedback_role_arn = var.lambda_failure_feedback_role_arn + sqs_success_feedback_role_arn = var.sqs_success_feedback_role_arn + sqs_success_feedback_sample_rate = var.sqs_success_feedback_sample_rate + sqs_failure_feedback_role_arn = var.sqs_failure_feedback_role_arn + kms_master_key_id = var.kms_master_key_id + fifo_topic = var.fifo_topic + content_based_deduplication = var.content_based_deduplication + + tags = var.tags +} diff --git a/modules/aws-sns-master/outputs.tf b/modules/aws-sns-master/outputs.tf new file mode 100644 index 0000000..9c582f5 --- /dev/null +++ b/modules/aws-sns-master/outputs.tf @@ -0,0 +1,19 @@ +output "sns_topic_arn" { + description = "ARN of SNS topic" + value = try(aws_sns_topic.this[0].arn, "") +} + +output "sns_topic_name" { + description = "NAME of SNS topic" + value = try(aws_sns_topic.this[0].name, "") +} + +output "sns_topic_id" { + description = "ID of SNS topic" + value = try(aws_sns_topic.this[0].id, "") +} + +output "sns_topic_owner" { + description = "OWNER of SNS topic" + value = try(aws_sns_topic.this[0].owner, "") +} diff --git a/modules/aws-sns-master/variables.tf b/modules/aws-sns-master/variables.tf new file mode 100644 index 0000000..b3885a2 --- /dev/null +++ b/modules/aws-sns-master/variables.tf @@ -0,0 +1,149 @@ +variable "create_sns_topic" { + description = "Whether to create the SNS topic" + type = bool + default = true +} + +variable "name" { + description = "The name of the SNS topic to create" + type = string + default = null +} + +variable "name_prefix" { + description = "The prefix name of the SNS topic to create" + type = string + default = null +} + +variable "display_name" { + description = "The display name for the SNS topic" + type = string + default = null +} + +variable "policy" { + description = "The fully-formed AWS policy as JSON" + type = string + default = null +} + +variable "delivery_policy" { + description = "The SNS delivery policy" + type = string + default = null +} + +variable "application_success_feedback_role_arn" { + description = "The IAM role permitted to receive success feedback for this topic" + type = string + default = null +} + +variable "application_success_feedback_sample_rate" { + description = "Percentage of success to sample" + type = string + default = null +} + +variable "application_failure_feedback_role_arn" { + description = "IAM role for failure feedback" + type = string + default = null +} + +variable "firehose_success_feedback_role_arn" { + description = "The IAM role permitted to receive success feedback for this topic" + type = string + default = null +} + +variable "firehose_success_feedback_sample_rate" { + description = "Percentage of success to sample" + type = number + default = null +} + +variable "firehose_failure_feedback_role_arn" { + description = "IAM role for failure feedback" + type = string + default = null +} + +variable "http_success_feedback_role_arn" { + description = "The IAM role permitted to receive success feedback for this topic" + type = string + default = null +} + +variable "http_success_feedback_sample_rate" { + description = "Percentage of success to sample" + type = string + default = null +} + +variable "http_failure_feedback_role_arn" { + description = "IAM role for failure feedback" + type = string + default = null +} + +variable "lambda_success_feedback_role_arn" { + description = "The IAM role permitted to receive success feedback for this topic" + type = string + default = null +} + +variable "lambda_success_feedback_sample_rate" { + description = "Percentage of success to sample" + type = string + default = null +} + +variable "lambda_failure_feedback_role_arn" { + description = "IAM role for failure feedback" + type = string + default = null +} + +variable "sqs_success_feedback_role_arn" { + description = "The IAM role permitted to receive success feedback for this topic" + type = string + default = null +} + +variable "sqs_success_feedback_sample_rate" { + description = "Percentage of success to sample" + type = string + default = null +} + +variable "sqs_failure_feedback_role_arn" { + description = "IAM role for failure feedback" + type = string + default = null +} + +variable "kms_master_key_id" { + description = "The ID of an AWS-managed customer master key (CMK) for Amazon SNS or a custom CMK" + type = string + default = null +} + +variable "fifo_topic" { + description = "Boolean indicating whether or not to create a FIFO (first-in-first-out) topic" + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to all resources" + type = map(string) + default = {} +} + +variable "content_based_deduplication" { + description = "Boolean indicating whether or not to enable content-based deduplication for FIFO topics." + type = bool + default = false +} diff --git a/modules/aws-sns-master/versions.tf b/modules/aws-sns-master/versions.tf new file mode 100644 index 0000000..d8dd1a4 --- /dev/null +++ b/modules/aws-sns-master/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.0" + } + } +} diff --git a/modules/aws-sns/README.md b/modules/aws-sns/README.md new file mode 100644 index 0000000..416b6c5 --- /dev/null +++ b/modules/aws-sns/README.md @@ -0,0 +1,124 @@ +# AWS SNS Topic Terraform module + +Terraform module which creates SNS resources on AWS +## Usage + +### Simple Topic + +```hcl +module "sns_topic" { + source = "git::https://github.com/kloia/platform-modules//aws-sns?ref=main" + + name = "simple" + + tags = { + Environment = "dev" + Terraform = "true" + } +} +``` + +### Topic w/ SQS Subscription + +```hcl +module "sns_topic" { + source = "git::https://github.com/kloia/platform-modules//aws-sns?ref=main" + + name = "pub-sub" + + topic_policy_statements = { + pub = { + actions = ["sns:Publish"] + principals = [{ + type = "AWS" + identifiers = ["arn:aws:iam::66666666666:role/publisher"] + }] + }, + + sub = { + actions = [ + "sns:Subscribe", + "sns:Receive", + ] + + principals = [{ + type = "AWS" + identifiers = ["*"] + }] + + conditions = [{ + test = "StringLike" + variable = "sns:Endpoint" + values = ["arn:aws:sqs:eu-west-1:11111111111:subscriber"] + }] + } + } + + subscriptions = { + sqs = { + protocol = "sqs" + endpoint = "arn:aws:sqs:eu-west-1:11111111111:subscriber" + } + } + + tags = { + Environment = "dev" + Terraform = "true" + } +} +``` + +### FIFO Topic w/ FIFO SQS Subscription + +```hcl +module "sns_topic" { + source = "git::https://github.com/kloia/platform-modules//aws-sns?ref=main" + + name = "my-topic" + + # SQS queue must be FIFO as well + fifo_topic = true + content_based_deduplication = true + + topic_policy_statements = { + pub = { + actions = ["sns:Publish"] + principals = [{ + type = "AWS" + identifiers = ["arn:aws:iam::66666666666:role/publisher"] + }] + }, + + sub = { + actions = [ + "sns:Subscribe", + "sns:Receive", + ] + + principals = [{ + type = "AWS" + identifiers = ["*"] + }] + + conditions = [{ + test = "StringLike" + variable = "sns:Endpoint" + values = ["arn:aws:sqs:eu-west-1:11111111111:subscriber.fifo"] + }] + } + } + + subscriptions = { + sqs = { + protocol = "sqs" + endpoint = "arn:aws:sqs:eu-west-1:11111111111:subscriber.fifo" + } + } + + tags = { + Environment = "dev" + Terraform = "true" + } +} +``` + diff --git a/modules/aws-sns/examples/complete/README.md b/modules/aws-sns/examples/complete/README.md new file mode 100644 index 0000000..712bdc1 --- /dev/null +++ b/modules/aws-sns/examples/complete/README.md @@ -0,0 +1,71 @@ +# Complete SNS topic example + +Configuration in this directory creates: +- A simple, default SNS topic +- A FIFO SNS topic with FIFO SQS subscription; shows most of the supported arguments +- A disabled SNS topic + +## Usage + +To run this example you need to execute: + +```bash +$ terraform init +$ terraform plan +$ terraform apply +``` + +Note that this example may create resources which cost money. Run `terraform destroy` when you don't need these resources. + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.0 | +| [aws](#requirement\_aws) | >= 5.25 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 5.25 | + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [complete\_sns](#module\_complete\_sns) | ../../ | n/a | +| [default\_sns](#module\_default\_sns) | ../../ | n/a | +| [disabled\_sns](#module\_disabled\_sns) | ../../ | n/a | +| [kms](#module\_kms) | https://github.com/kloia/platform-modules/tree/main/aws-kms | ~> 1.0 | +| [sqs](#module\_sqs) | https://github.com/kloia/platform-modules/tree/main/terraform-aws-sqs | ~> 4.0 | + +## Resources + +| Name | Type | +|------|------| +| [aws_iam_role.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | +| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source | + +## Inputs + +No inputs. + +## Outputs + +| Name | Description | +|------|-------------| +| [complete\_sns\_subscriptions](#output\_complete\_sns\_subscriptions) | Map of subscriptions created and their attributes | +| [complete\_sns\_topic\_arn](#output\_complete\_sns\_topic\_arn) | The ARN of the SNS topic, as a more obvious property (clone of id) | +| [complete\_sns\_topic\_beginning\_archive\_time](#output\_complete\_sns\_topic\_beginning\_archive\_time) | The oldest timestamp at which a FIFO topic subscriber can start a replay | +| [complete\_sns\_topic\_id](#output\_complete\_sns\_topic\_id) | The ARN of the SNS topic | +| [complete\_sns\_topic\_name](#output\_complete\_sns\_topic\_name) | The name of the topic | +| [complete\_sns\_topic\_owner](#output\_complete\_sns\_topic\_owner) | The AWS Account ID of the SNS topic owner | +| [default\_sns\_subscriptions](#output\_default\_sns\_subscriptions) | Map of subscriptions created and their attributes | +| [default\_sns\_topic\_arn](#output\_default\_sns\_topic\_arn) | The ARN of the SNS topic, as a more obvious property (clone of id) | +| [default\_sns\_topic\_beginning\_archive\_time](#output\_default\_sns\_topic\_beginning\_archive\_time) | The oldest timestamp at which a FIFO topic subscriber can start a replay | +| [default\_sns\_topic\_id](#output\_default\_sns\_topic\_id) | The ARN of the SNS topic | +| [default\_sns\_topic\_name](#output\_default\_sns\_topic\_name) | The name of the topic | +| [default\_sns\_topic\_owner](#output\_default\_sns\_topic\_owner) | The AWS Account ID of the SNS topic owner | + diff --git a/modules/aws-sns/examples/complete/main.tf b/modules/aws-sns/examples/complete/main.tf new file mode 100644 index 0000000..b024b2d --- /dev/null +++ b/modules/aws-sns/examples/complete/main.tf @@ -0,0 +1,273 @@ +provider "aws" { + region = local.region +} + +data "aws_caller_identity" "current" {} + +locals { + region = "eu-west-1" + name = "sns-ex-${basename(path.cwd)}" + + tags = { + Name = local.name + Example = "complete" + Repository = "github.com/terraform-aws-modules/terraform-aws-sns" + } +} + +################################################################################ +# SNS Module +################################################################################ + +module "default_sns" { + source = "../../" + + name = "${local.name}-default" + signature_version = 2 + + data_protection_policy = jsonencode( + { + Description = "Deny Inbound Address" + Name = "DenyInboundEmailAdressPolicy" + Statement = [ + { + "DataDirection" = "Inbound" + "DataIdentifier" = [ + "arn:aws:dataprotection::aws:data-identifier/EmailAddress", + ] + "Operation" = { + "Deny" = {} + } + "Principal" = [ + "*", + ] + "Sid" = "DenyInboundEmailAddress" + }, + ] + Version = "2021-06-01" + } + ) + + tags = local.tags +} + +module "complete_sns" { + source = "../../" + + name = local.name + use_name_prefix = true + display_name = "complete" + kms_master_key_id = module.kms.key_id + tracing_config = "Active" + + # SQS queue must be FIFO as well + fifo_topic = true + content_based_deduplication = true + + delivery_policy = jsonencode({ + "http" : { + "defaultHealthyRetryPolicy" : { + "minDelayTarget" : 20, + "maxDelayTarget" : 20, + "numRetries" : 3, + "numMaxDelayRetries" : 0, + "numNoDelayRetries" : 0, + "numMinDelayRetries" : 0, + "backoffFunction" : "linear" + }, + "disableSubscriptionOverrides" : false, + "defaultThrottlePolicy" : { + "maxReceivesPerSecond" : 1 + } + } + }) + + # # Example config for archive_policy for SNS FIFO message archiving + # # You can not delete a topic with an active message archive policy + # # You must first deactivate the topic before it can be deleted + # # https://docs.aws.amazon.com/sns/latest/dg/message-archiving-and-replay-topic-owner.html + # archive_policy = jsonencode({ + # "MessageRetentionPeriod": 30 + # }) + + create_topic_policy = true + enable_default_topic_policy = true + topic_policy_statements = { + pub = { + actions = ["sns:Publish"] + principals = [{ + type = "AWS" + identifiers = [data.aws_caller_identity.current.arn] + }] + }, + + sub = { + actions = [ + "sns:Subscribe", + "sns:Receive", + ] + + principals = [{ + type = "AWS" + identifiers = ["*"] + }] + + conditions = [{ + test = "StringLike" + variable = "sns:Endpoint" + values = [module.sqs.queue_arn] + }] + } + } + + subscriptions = { + sqs = { + protocol = "sqs" + endpoint = module.sqs.queue_arn + + # # example of replay_policy for SNS FIFO message replay + # # https://docs.aws.amazon.com/sns/latest/dg/message-archiving-and-replay-subscriber.html + # replay_policy = jsonencode({ + # "PointType": "Timestamp" + # "StartingPoint": timestamp() + # }) + } + } + + # Feedback + application_feedback = { + failure_role_arn = aws_iam_role.this.arn + success_role_arn = aws_iam_role.this.arn + success_sample_rate = 100 + } + firehose_feedback = { + failure_role_arn = aws_iam_role.this.arn + success_role_arn = aws_iam_role.this.arn + success_sample_rate = 100 + } + http_feedback = { + failure_role_arn = aws_iam_role.this.arn + success_role_arn = aws_iam_role.this.arn + success_sample_rate = 100 + } + lambda_feedback = { + failure_role_arn = aws_iam_role.this.arn + success_role_arn = aws_iam_role.this.arn + success_sample_rate = 100 + } + sqs_feedback = { + failure_role_arn = aws_iam_role.this.arn + success_role_arn = aws_iam_role.this.arn + success_sample_rate = 100 + } + + tags = local.tags +} + +module "disabled_sns" { + source = "../../" + + create = false +} + +################################################################################ +# Supporting Resources +################################################################################ + +module "kms" { + source = "terraform-aws-modules/kms/aws" + version = "~> 1.0" + + aliases = ["sns/${local.name}"] + description = "KMS key to encrypt topic" + + # Policy + key_statements = [ + { + sid = "SNS" + actions = [ + "kms:GenerateDataKey*", + "kms:Decrypt" + ] + resources = ["*"] + principals = [{ + type = "Service" + identifiers = ["sns.amazonaws.com"] + }] + } + ] + + tags = local.tags +} + +module "sqs" { + source = "terraform-aws-modules/sqs/aws" + version = "~> 4.0" + + name = local.name + fifo_queue = true + + create_queue_policy = true + queue_policy_statements = { + sns = { + sid = "SNS" + actions = ["sqs:SendMessage"] + + principals = [ + { + type = "Service" + identifiers = ["sns.amazonaws.com"] + } + ] + + condition = { + test = "ArnEquals" + variable = "aws:SourceArn" + values = [module.complete_sns.topic_arn] + } + } + } + + tags = local.tags +} + +resource "aws_iam_role" "this" { + name = local.name + + assume_role_policy = jsonencode({ + Version = "2012-10-17" + Statement = [ + { + Action = "sts:AssumeRole" + Effect = "Allow" + Sid = "SnsAssume" + Principal = { + Service = "sns.amazonaws.com" + } + }, + ] + }) + + inline_policy { + name = local.name + + policy = jsonencode({ + Version = "2012-10-17" + Statement = [ + { + Action = [ + "logs:CreateLogGroup", + "logs:CreateLogStream", + "logs:PutLogEvents", + "logs:PutMetricFilter", + "logs:PutRetentionPolicy", + ] + Effect = "Allow" + Resource = "*" + }, + ] + }) + } + + tags = local.tags +} diff --git a/modules/aws-sns/examples/complete/outputs.tf b/modules/aws-sns/examples/complete/outputs.tf new file mode 100644 index 0000000..c086335 --- /dev/null +++ b/modules/aws-sns/examples/complete/outputs.tf @@ -0,0 +1,67 @@ +################################################################################ +# Default +################################################################################ + +output "default_sns_topic_arn" { + description = "The ARN of the SNS topic, as a more obvious property (clone of id)" + value = module.default_sns.topic_arn +} + +output "default_sns_topic_id" { + description = "The ARN of the SNS topic" + value = module.default_sns.topic_id +} + +output "default_sns_topic_name" { + description = "The name of the topic" + value = module.default_sns.topic_name +} + +output "default_sns_topic_owner" { + description = "The AWS Account ID of the SNS topic owner" + value = module.default_sns.topic_owner +} + +output "default_sns_topic_beginning_archive_time" { + description = "The oldest timestamp at which a FIFO topic subscriber can start a replay" + value = module.default_sns.topic_beginning_archive_time +} + +output "default_sns_subscriptions" { + description = "Map of subscriptions created and their attributes" + value = module.default_sns.subscriptions +} + +################################################################################ +# Complete +################################################################################ + +output "complete_sns_topic_arn" { + description = "The ARN of the SNS topic, as a more obvious property (clone of id)" + value = module.complete_sns.topic_arn +} + +output "complete_sns_topic_id" { + description = "The ARN of the SNS topic" + value = module.complete_sns.topic_id +} + +output "complete_sns_topic_name" { + description = "The name of the topic" + value = module.complete_sns.topic_name +} + +output "complete_sns_topic_owner" { + description = "The AWS Account ID of the SNS topic owner" + value = module.complete_sns.topic_owner +} + +output "complete_sns_topic_beginning_archive_time" { + description = "The oldest timestamp at which a FIFO topic subscriber can start a replay" + value = module.complete_sns.topic_beginning_archive_time +} + +output "complete_sns_subscriptions" { + description = "Map of subscriptions created and their attributes" + value = module.complete_sns.subscriptions +} diff --git a/modules/aws-sns/examples/complete/variables.tf b/modules/aws-sns/examples/complete/variables.tf new file mode 100644 index 0000000..e69de29 diff --git a/modules/aws-sns/examples/complete/versions.tf b/modules/aws-sns/examples/complete/versions.tf new file mode 100644 index 0000000..2c1a62c --- /dev/null +++ b/modules/aws-sns/examples/complete/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.25" + } + } +} diff --git a/modules/aws-sns/main.tf b/modules/aws-sns/main.tf new file mode 100644 index 0000000..0b0fe6c --- /dev/null +++ b/modules/aws-sns/main.tf @@ -0,0 +1,170 @@ +data "aws_caller_identity" "current" {} + +################################################################################ +# Topic +################################################################################ + +resource "aws_sns_topic" "this" { + count = var.create ? 1 : 0 + + name = var.use_name_prefix ? null : var.name + name_prefix = var.use_name_prefix ? var.name : null + + application_failure_feedback_role_arn = try(var.application_feedback.failure_role_arn, null) + application_success_feedback_role_arn = try(var.application_feedback.success_role_arn, null) + application_success_feedback_sample_rate = try(var.application_feedback.success_sample_rate, null) + + content_based_deduplication = var.content_based_deduplication + delivery_policy = var.delivery_policy + display_name = var.display_name + fifo_topic = var.fifo_topic + signature_version = var.fifo_topic ? null : var.signature_version + tracing_config = var.tracing_config + + firehose_failure_feedback_role_arn = try(var.firehose_feedback.failure_role_arn, null) + firehose_success_feedback_role_arn = try(var.firehose_feedback.success_role_arn, null) + firehose_success_feedback_sample_rate = try(var.firehose_feedback.success_sample_rate, null) + + http_failure_feedback_role_arn = try(var.http_feedback.failure_role_arn, null) + http_success_feedback_role_arn = try(var.http_feedback.success_role_arn, null) + http_success_feedback_sample_rate = try(var.http_feedback.success_sample_rate, null) + + kms_master_key_id = var.kms_master_key_id + + lambda_failure_feedback_role_arn = try(var.lambda_feedback.failure_role_arn, null) + lambda_success_feedback_role_arn = try(var.lambda_feedback.success_role_arn, null) + lambda_success_feedback_sample_rate = try(var.lambda_feedback.success_sample_rate, null) + + policy = var.create_topic_policy ? null : var.topic_policy + + sqs_failure_feedback_role_arn = try(var.sqs_feedback.failure_role_arn, null) + sqs_success_feedback_role_arn = try(var.sqs_feedback.success_role_arn, null) + sqs_success_feedback_sample_rate = try(var.sqs_feedback.success_sample_rate, null) + + archive_policy = try(var.archive_policy, null) + + tags = var.tags +} + +################################################################################ +# Topic Policy +################################################################################ + +data "aws_iam_policy_document" "this" { + count = var.create && var.create_topic_policy ? 1 : 0 + + source_policy_documents = var.source_topic_policy_documents + override_policy_documents = var.override_topic_policy_documents + + dynamic "statement" { + for_each = var.enable_default_topic_policy ? [1] : [] + + content { + sid = "__default_statement_ID" + actions = [ + "sns:Subscribe", + "sns:SetTopicAttributes", + "sns:RemovePermission", + "sns:Publish", + "sns:ListSubscriptionsByTopic", + "sns:GetTopicAttributes", + "sns:DeleteTopic", + "sns:AddPermission", + ] + effect = "Allow" + resources = [aws_sns_topic.this[0].arn] + + principals { + type = "AWS" + identifiers = ["*"] + } + + condition { + test = "StringEquals" + values = [data.aws_caller_identity.current.account_id] + variable = "AWS:SourceOwner" + } + } + } + + dynamic "statement" { + for_each = var.topic_policy_statements + + content { + sid = try(statement.value.sid, statement.key) + actions = try(statement.value.actions, null) + not_actions = try(statement.value.not_actions, null) + effect = try(statement.value.effect, null) + # This avoids the chicken vs the egg scenario since its embedded and can reference the topic + resources = try(statement.value.resources, [aws_sns_topic.this[0].arn]) + not_resources = try(statement.value.not_resources, null) + + dynamic "principals" { + for_each = try(statement.value.principals, []) + + content { + type = principals.value.type + identifiers = principals.value.identifiers + } + } + + dynamic "not_principals" { + for_each = try(statement.value.not_principals, []) + + content { + type = not_principals.value.type + identifiers = not_principals.value.identifiers + } + } + + dynamic "condition" { + for_each = try(statement.value.conditions, []) + + content { + test = condition.value.test + values = condition.value.values + variable = condition.value.variable + } + } + } + } +} + +resource "aws_sns_topic_policy" "this" { + count = var.create && var.create_topic_policy ? 1 : 0 + + arn = aws_sns_topic.this[0].arn + policy = data.aws_iam_policy_document.this[0].json +} + +################################################################################ +# Subscription(s) +################################################################################ + +resource "aws_sns_topic_subscription" "this" { + for_each = { for k, v in var.subscriptions : k => v if var.create && var.create_subscription } + + confirmation_timeout_in_minutes = try(each.value.confirmation_timeout_in_minutes, null) + delivery_policy = try(each.value.delivery_policy, null) + endpoint = each.value.endpoint + endpoint_auto_confirms = try(each.value.endpoint_auto_confirms, null) + filter_policy = try(each.value.filter_policy, null) + filter_policy_scope = try(each.value.filter_policy_scope, null) + protocol = each.value.protocol + raw_message_delivery = try(each.value.raw_message_delivery, null) + redrive_policy = try(each.value.redrive_policy, null) + replay_policy = try(each.value.replay_policy, null) + subscription_role_arn = try(each.value.subscription_role_arn, null) + topic_arn = aws_sns_topic.this[0].arn +} + +################################################################################ +# Data Protection Policy +################################################################################ + +resource "aws_sns_topic_data_protection_policy" "this" { + count = var.create && var.data_protection_policy != null && !var.fifo_topic ? 1 : 0 + + arn = aws_sns_topic.this[0].arn + policy = var.data_protection_policy +} diff --git a/modules/aws-sns/outputs.tf b/modules/aws-sns/outputs.tf new file mode 100644 index 0000000..e564477 --- /dev/null +++ b/modules/aws-sns/outputs.tf @@ -0,0 +1,37 @@ +################################################################################ +# Topic +################################################################################ + +output "topic_arn" { + description = "The ARN of the SNS topic, as a more obvious property (clone of id)" + value = try(aws_sns_topic.this[0].arn, null) +} + +output "topic_id" { + description = "The ARN of the SNS topic" + value = try(aws_sns_topic.this[0].id, null) +} + +output "topic_name" { + description = "The name of the topic" + value = try(aws_sns_topic.this[0].name, null) +} + +output "topic_owner" { + description = "The AWS Account ID of the SNS topic owner" + value = try(aws_sns_topic.this[0].owner, null) +} + +output "topic_beginning_archive_time" { + description = "The oldest timestamp at which a FIFO topic subscriber can start a replay" + value = try(aws_sns_topic.this[0].beginning_archive_time, null) +} + +################################################################################ +# Subscription(s) +################################################################################ + +output "subscriptions" { + description = "Map of subscriptions created and their attributes" + value = aws_sns_topic_subscription.this +} diff --git a/modules/aws-sns/variables.tf b/modules/aws-sns/variables.tf new file mode 100644 index 0000000..64240e1 --- /dev/null +++ b/modules/aws-sns/variables.tf @@ -0,0 +1,201 @@ +variable "create" { + description = "Determines whether resources will be created (affects all resources)" + type = bool + default = true +} + +variable "tags" { + description = "A map of tags to add to all resources" + type = map(string) + default = {} +} + +################################################################################ +# Topic +################################################################################ + +variable "name" { + description = "The name of the SNS topic to create" + type = string + default = null +} + +variable "use_name_prefix" { + description = "Determines whether `name` is used as a prefix" + type = bool + default = false +} + +variable "application_feedback" { + description = "Map of IAM role ARNs and sample rate for success and failure feedback" + type = map(string) + default = {} + # Example: + # application_feedback = { + # failure_role_arn = "arn:aws:iam::11111111111:role/failure" + # success_role_arn = "arn:aws:iam::11111111111:role/success" + # success_sample_rate = 75 + # } +} + +variable "content_based_deduplication" { + description = "Boolean indicating whether or not to enable content-based deduplication for FIFO topics." + type = bool + default = false +} + +variable "delivery_policy" { + description = "The SNS delivery policy" + type = string + default = null +} + +variable "display_name" { + description = "The display name for the SNS topic" + type = string + default = null +} + +variable "fifo_topic" { + description = "Boolean indicating whether or not to create a FIFO (first-in-first-out) topic" + type = bool + default = false +} + +variable "firehose_feedback" { + description = "Map of IAM role ARNs and sample rate for success and failure feedback" + type = map(string) + default = {} + # Example: + # application_feedback = { + # failure_role_arn = "arn:aws:iam::11111111111:role/failure" + # success_role_arn = "arn:aws:iam::11111111111:role/success" + # success_sample_rate = 75 + # } +} + +variable "http_feedback" { + description = "Map of IAM role ARNs and sample rate for success and failure feedback" + type = map(string) + default = {} + # Example: + # application_feedback = { + # failure_role_arn = "arn:aws:iam::11111111111:role/failure" + # success_role_arn = "arn:aws:iam::11111111111:role/success" + # success_sample_rate = 75 + # } +} + +variable "kms_master_key_id" { + description = "The ID of an AWS-managed customer master key (CMK) for Amazon SNS or a custom CMK" + type = string + default = null +} + +variable "lambda_feedback" { + description = "Map of IAM role ARNs and sample rate for success and failure feedback" + type = map(string) + default = {} + # Example: + # application_feedback = { + # failure_role_arn = "arn:aws:iam::11111111111:role/failure" + # success_role_arn = "arn:aws:iam::11111111111:role/success" + # success_sample_rate = 75 + # } +} + +variable "topic_policy" { + description = "An externally created fully-formed AWS policy as JSON" + type = string + default = null +} + +variable "sqs_feedback" { + description = "Map of IAM role ARNs and sample rate for success and failure feedback" + type = map(string) + default = {} + # Example: + # application_feedback = { + # failure_role_arn = "arn:aws:iam::11111111111:role/failure" + # success_role_arn = "arn:aws:iam::11111111111:role/success" + # success_sample_rate = 75 + # } +} + +variable "signature_version" { + description = "If SignatureVersion should be 1 (SHA1) or 2 (SHA256). The signature version corresponds to the hashing algorithm used while creating the signature of the notifications, subscription confirmations, or unsubscribe confirmation messages sent by Amazon SNS." + type = number + default = null +} + +variable "tracing_config" { + description = "Tracing mode of an Amazon SNS topic. Valid values: PassThrough, Active." + type = string + default = null +} + +variable "archive_policy" { + description = "The message archive policy for FIFO topics." + type = string + default = null +} + +################################################################################ +# Topic Policy +################################################################################ + +variable "create_topic_policy" { + description = "Determines whether an SNS topic policy is created" + type = bool + default = true +} + +variable "source_topic_policy_documents" { + description = "List of IAM policy documents that are merged together into the exported document. Statements must have unique `sid`s" + type = list(string) + default = [] +} + +variable "override_topic_policy_documents" { + description = "List of IAM policy documents that are merged together into the exported document. In merging, statements with non-blank `sid`s will override statements with the same `sid`" + type = list(string) + default = [] +} + +variable "enable_default_topic_policy" { + description = "Specifies whether to enable the default topic policy. Defaults to `true`" + type = bool + default = true +} + +variable "topic_policy_statements" { + description = "A map of IAM policy [statements](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document#statement) for custom permission usage" + type = any + default = {} +} + +################################################################################ +# Subscription(s) +################################################################################ + +variable "create_subscription" { + description = "Determines whether an SNS subscription is created" + type = bool + default = true +} + +variable "subscriptions" { + description = "A map of subscription definitions to create" + type = any + default = {} +} + +################################################################################ +# Data Protection Policy +################################################################################ + +variable "data_protection_policy" { + description = "A map of data protection policy statements" + type = string + default = null +} diff --git a/modules/aws-sns/versions.tf b/modules/aws-sns/versions.tf new file mode 100644 index 0000000..2c1a62c --- /dev/null +++ b/modules/aws-sns/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.25" + } + } +} diff --git a/modules/aws-ssm-parameter-store/.gitignore b/modules/aws-ssm-parameter-store/.gitignore new file mode 100644 index 0000000..8d1abcf --- /dev/null +++ b/modules/aws-ssm-parameter-store/.gitignore @@ -0,0 +1,11 @@ +*.tfstate +*.tfstate.* +**/*.pem +**/.terraform +**/terraform.tfstate +**/terraform.tfstate.backup +.idea +*.iml + +.build-harness +build-harness diff --git a/modules/aws-ssm-parameter-store/README.md b/modules/aws-ssm-parameter-store/README.md new file mode 100644 index 0000000..85e01de --- /dev/null +++ b/modules/aws-ssm-parameter-store/README.md @@ -0,0 +1,160 @@ + + +# terraform-aws-ssm-parameter-store + +Terraform module for providing read and write access to the AWS SSM Parameter Store. + +--- + + +## Usage + + +**IMPORTANT:** We do not pin modules to versions in our examples because of the +difficulty of keeping the versions in the documentation in sync with the latest released versions. +We highly recommend that in your code you pin the version to the exact version you are +using so that your infrastructure remains stable, and update versions in a +systematic way so that they do not catch you by surprise. + +Also, because of a bug in the Terraform registry ([hashicorp/terraform#21417](https://github.com/hashicorp/terraform/issues/21417)), +the registry shows many of our inputs as required when in fact they are optional. +The table below correctly indicates which inputs are required. + + +This example creates a new `String` parameter called `/cp/prod/app/database/master_password` with the value of `password1`. + +```hcl +module "store_write" { + source = "kloia/ssm-parameter-store/aws" + # Cloud Posse recommends pinning every module to a specific version + # version = "x.x.x" + + parameter_write = [ + { + name = "/cp/prod/app/database/master_password" + value = "password1" + type = "String" + overwrite = "true" + description = "Production database master password" + } + ] + + tags = { + ManagedBy = "Terraform" + } +} +``` + +This example reads a value from the parameter store with the name `/cp/prod/app/database/master_password` + +```hcl +module "store_read" { + source = "kloia/ssm-parameter-store/aws" + # Cloud Posse recommends pinning every module to a specific version + # version = "x.x.x" + + parameter_read = ["/cp/prod/app/database/master_password"] +} +``` + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.0 | +| [aws](#requirement\_aws) | >= 2.0 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 2.0 | + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [this](#module\_this) | cloudposse/label/null | 0.25.0 | + +## Resources + +| Name | Type | +|------|------| +| [aws_ssm_parameter.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ssm_parameter) | resource | +| [aws_ssm_parameter.ignore_value_changes](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ssm_parameter) | resource | +| [aws_ssm_parameter.read](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ssm_parameter) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [descriptor\_formats](#input\_descriptor\_formats) | Describe additional descriptors to be output in the `descriptors` output map.
group_id = string
aggregation = string
members = list(string)
resource_type = string
}))
{| no | +| [tags](#input\_tags) | Additional tags (e.g. `{'BusinessUnit': 'XYZ'}`).
"allowed_pattern": null,
"data_type": "text",
"description": null,
"overwrite": "false",
"tier": "Standard",
"type": "SecureString"
}
{| no | + +## Outputs + +| Name | Description | +|------|-------------| +| [arn\_map](#output\_arn\_map) | A map of the names and ARNs created | +| [map](#output\_map) | A map of the names and values created | +| [names](#output\_names) | A list of all of the parameter names | +| [values](#output\_values) | A list of all of the parameter values | + \ No newline at end of file diff --git a/modules/aws-ssm-parameter-store/main.tf b/modules/aws-ssm-parameter-store/main.tf new file mode 100644 index 0000000..7492df3 --- /dev/null +++ b/modules/aws-ssm-parameter-store/main.tf @@ -0,0 +1,53 @@ +locals { + enabled = var.enabled + parameter_write = local.enabled && !var.ignore_value_changes ? { for e in var.parameter_write : e.name => merge(var.parameter_write_defaults, merge(e, { value = try(join(",", e.value), e.value) })) } : {} + parameter_write_ignore_values = local.enabled && var.ignore_value_changes ? { for e in var.parameter_write : e.name => merge(var.parameter_write_defaults, merge(e, { value = try(join(",", e.value), e.value) })) } : {} + parameter_read = local.enabled ? var.parameter_read : [] +} + +data "aws_ssm_parameter" "read" { + count = var.cross_account_read == false ? length(local.parameter_read) : 0 + name = element(local.parameter_read, count.index) +} + +data "aws_ssm_parameter" "cross_account_read" { + count = var.cross_account_read == true ? length(local.parameter_read) : 0 + name = element(local.parameter_read, count.index) + provider = aws.cross_account +} + +resource "aws_ssm_parameter" "default" { + for_each = local.parameter_write + name = each.key + + description = each.value.description + type = each.value.type + tier = each.value.tier + key_id = each.value.type == "SecureString" && length(var.kms_arn) > 0 ? var.kms_arn : "" + value = each.value.value + overwrite = each.value.overwrite + allowed_pattern = each.value.allowed_pattern + data_type = each.value.data_type + +} + +resource "aws_ssm_parameter" "ignore_value_changes" { + for_each = local.parameter_write_ignore_values + name = each.key + + description = each.value.description + type = each.value.type + tier = each.value.tier + key_id = each.value.type == "SecureString" && length(var.kms_arn) > 0 ? var.kms_arn : "" + value = each.value.value + overwrite = each.value.overwrite + allowed_pattern = each.value.allowed_pattern + data_type = each.value.data_type + + + lifecycle { + ignore_changes = [ + value, + ] + } +} diff --git a/modules/aws-ssm-parameter-store/outputs.tf b/modules/aws-ssm-parameter-store/outputs.tf new file mode 100644 index 0000000..3a0b9e5 --- /dev/null +++ b/modules/aws-ssm-parameter-store/outputs.tf @@ -0,0 +1,39 @@ +# Splitting and joining, and then compacting a list to get a normalised list +locals { + name_list = compact(concat(keys(local.parameter_write), keys(local.parameter_write_ignore_values), local.parameter_read)) + + value_list = compact( + concat( + [for p in aws_ssm_parameter.default : p.value], [for p in aws_ssm_parameter.ignore_value_changes : p.value], data.aws_ssm_parameter.read.*.value, data.aws_ssm_parameter.cross_account_read.*.value + ) + ) + + arn_list = compact( + concat( + [for p in aws_ssm_parameter.default : p.arn], [for p in aws_ssm_parameter.ignore_value_changes : p.arn], data.aws_ssm_parameter.read.*.arn, data.aws_ssm_parameter.cross_account_read.*.arn + ) + ) +} + +output "names" { + # Names are not sensitive + value = local.name_list + description = "A list of all of the parameter names" +} + +output "values" { + description = "A list of all of the parameter values" + value = local.value_list + sensitive = true +} + +output "map" { + description = "A map of the names and values created" + value = try(zipmap(local.name_list, local.value_list), "Failed") + sensitive = true +} + +output "arn_map" { + description = "A map of the names and ARNs created" + value = try(zipmap(local.name_list, local.arn_list), "Failed") +} diff --git a/modules/aws-ssm-parameter-store/variables.tf b/modules/aws-ssm-parameter-store/variables.tf new file mode 100644 index 0000000..9a8c968 --- /dev/null +++ b/modules/aws-ssm-parameter-store/variables.tf @@ -0,0 +1,47 @@ +variable "enabled" { + description = "Create resources if enabled true" + default = true +} + +variable "parameter_read" { + type = list(string) + description = "List of parameters to read from SSM. These must already exist otherwise an error is returned. Can be used with `parameter_write` as long as the parameters are different." + default = [] +} + +variable "parameter_write" { + type = list(map(string)) + description = "List of maps with the parameter values to write to SSM Parameter Store" + default = [] +} + +variable "kms_arn" { + type = string + default = "" + description = "The ARN of a KMS key used to encrypt and decrypt SecretString values" +} + +variable "parameter_write_defaults" { + type = map(any) + description = "Parameter write default settings" + default = { + description = null + type = "SecureString" + tier = "Standard" + overwrite = "false" + allowed_pattern = null + data_type = "text" + } +} + +variable "ignore_value_changes" { + type = bool + description = "Whether to ignore future external changes in paramater values" + default = false +} + +variable "cross_account_read" { + type = bool + description = "Read parameter from cross account" + default = false +} \ No newline at end of file diff --git a/modules/aws-ssm-parameter-store/versions.tf b/modules/aws-ssm-parameter-store/versions.tf new file mode 100644 index 0000000..5b2c49b --- /dev/null +++ b/modules/aws-ssm-parameter-store/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 2.0" + } + } +} diff --git a/modules/aws-transit-gateway/.editorconfig b/modules/aws-transit-gateway/.editorconfig new file mode 100644 index 0000000..88cb251 --- /dev/null +++ b/modules/aws-transit-gateway/.editorconfig @@ -0,0 +1,30 @@ +# EditorConfig is awesome: http://EditorConfig.org +# Uses editorconfig to maintain consistent coding styles + +# top-most EditorConfig file +root = true + +# Unix-style newlines with a newline ending every file +[*] +charset = utf-8 +end_of_line = lf +indent_size = 2 +indent_style = space +insert_final_newline = true +max_line_length = 80 +trim_trailing_whitespace = true + +[*.{tf,tfvars}] +indent_size = 2 +indent_style = space + +[*.md] +max_line_length = 0 +trim_trailing_whitespace = false + +[Makefile] +tab_width = 2 +indent_style = tab + +[COMMIT_EDITMSG] +max_line_length = 0 diff --git a/modules/aws-transit-gateway/.github/workflows/lock.yml b/modules/aws-transit-gateway/.github/workflows/lock.yml new file mode 100644 index 0000000..6b6c9ce --- /dev/null +++ b/modules/aws-transit-gateway/.github/workflows/lock.yml @@ -0,0 +1,21 @@ +name: 'Lock Threads' + +on: + schedule: + - cron: '50 1 * * *' + +jobs: + lock: + runs-on: ubuntu-latest + steps: + - uses: dessant/lock-threads@v4 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + issue-comment: > + I'm going to lock this issue because it has been closed for _30 days_ ⏳. This helps our maintainers find and focus on the active issues. + If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further. + issue-inactive-days: '30' + pr-comment: > + I'm going to lock this pull request because it has been closed for _30 days_ ⏳. This helps our maintainers find and focus on the active issues. + If you have found a problem that seems related to this change, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further. + pr-inactive-days: '30' diff --git a/modules/aws-transit-gateway/.github/workflows/pr-title.yml b/modules/aws-transit-gateway/.github/workflows/pr-title.yml new file mode 100644 index 0000000..cb32a0f --- /dev/null +++ b/modules/aws-transit-gateway/.github/workflows/pr-title.yml @@ -0,0 +1,52 @@ +name: 'Validate PR title' + +on: + pull_request_target: + types: + - opened + - edited + - synchronize + +jobs: + main: + name: Validate PR title + runs-on: ubuntu-latest + steps: + # Please look up the latest version from + # https://github.com/amannn/action-semantic-pull-request/releases + - uses: amannn/action-semantic-pull-request@v5.0.2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + # Configure which types are allowed. + # Default: https://github.com/commitizen/conventional-commit-types + types: | + fix + feat + docs + ci + chore + # Configure that a scope must always be provided. + requireScope: false + # Configure additional validation for the subject based on a regex. + # This example ensures the subject starts with an uppercase character. + subjectPattern: ^[A-Z].+$ + # If `subjectPattern` is configured, you can use this property to override + # the default error message that is shown when the pattern doesn't match. + # The variables `subject` and `title` can be used within the message. + subjectPatternError: | + The subject "{subject}" found in the pull request title "{title}" + didn't match the configured pattern. Please ensure that the subject + starts with an uppercase character. + # For work-in-progress PRs you can typically use draft pull requests + # from Github. However, private repositories on the free plan don't have + # this option and therefore this action allows you to opt-in to using the + # special "[WIP]" prefix to indicate this state. This will avoid the + # validation of the PR title and the pull request checks remain pending. + # Note that a second check will be reported if this is enabled. + wip: true + # When using "Squash and merge" on a PR with only one commit, GitHub + # will suggest using that commit message instead of the PR title for the + # merge commit, and it's easy to commit this by mistake. Enable this option + # to also validate the commit message for one commit PRs. + validateSingleCommit: false diff --git a/modules/aws-transit-gateway/.github/workflows/pre-commit.yml b/modules/aws-transit-gateway/.github/workflows/pre-commit.yml new file mode 100644 index 0000000..cb82671 --- /dev/null +++ b/modules/aws-transit-gateway/.github/workflows/pre-commit.yml @@ -0,0 +1,83 @@ +name: Pre-Commit + +on: + pull_request: + branches: + - main + - master + +env: + TERRAFORM_DOCS_VERSION: v0.16.0 + TFLINT_VERSION: v0.44.1 + +jobs: + collectInputs: + name: Collect workflow inputs + runs-on: ubuntu-latest + outputs: + directories: ${{ steps.dirs.outputs.directories }} + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Get root directories + id: dirs + uses: clowdhaus/terraform-composite-actions/directories@v1.8.3 + + preCommitMinVersions: + name: Min TF pre-commit + needs: collectInputs + runs-on: ubuntu-latest + strategy: + matrix: + directory: ${{ fromJson(needs.collectInputs.outputs.directories) }} + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Terraform min/max versions + id: minMax + uses: clowdhaus/terraform-min-max@v1.2.4 + with: + directory: ${{ matrix.directory }} + + - name: Pre-commit Terraform ${{ steps.minMax.outputs.minVersion }} + # Run only validate pre-commit check on min version supported + if: ${{ matrix.directory != '.' }} + uses: clowdhaus/terraform-composite-actions/pre-commit@v1.8.3 + with: + terraform-version: ${{ steps.minMax.outputs.minVersion }} + tflint-version: ${{ env.TFLINT_VERSION }} + args: 'terraform_validate --color=always --show-diff-on-failure --files ${{ matrix.directory }}/*' + + - name: Pre-commit Terraform ${{ steps.minMax.outputs.minVersion }} + # Run only validate pre-commit check on min version supported + if: ${{ matrix.directory == '.' }} + uses: clowdhaus/terraform-composite-actions/pre-commit@v1.8.3 + with: + terraform-version: ${{ steps.minMax.outputs.minVersion }} + tflint-version: ${{ env.TFLINT_VERSION }} + args: 'terraform_validate --color=always --show-diff-on-failure --files $(ls *.tf)' + + preCommitMaxVersion: + name: Max TF pre-commit + runs-on: ubuntu-latest + needs: collectInputs + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + ref: ${{ github.event.pull_request.head.ref }} + repository: ${{github.event.pull_request.head.repo.full_name}} + + - name: Terraform min/max versions + id: minMax + uses: clowdhaus/terraform-min-max@v1.2.4 + + - name: Pre-commit Terraform ${{ steps.minMax.outputs.maxVersion }} + uses: clowdhaus/terraform-composite-actions/pre-commit@v1.8.3 + with: + terraform-version: ${{ steps.minMax.outputs.maxVersion }} + tflint-version: ${{ env.TFLINT_VERSION }} + terraform-docs-version: ${{ env.TERRAFORM_DOCS_VERSION }} + install-hcledit: true diff --git a/modules/aws-transit-gateway/.github/workflows/release.yml b/modules/aws-transit-gateway/.github/workflows/release.yml new file mode 100644 index 0000000..81f6747 --- /dev/null +++ b/modules/aws-transit-gateway/.github/workflows/release.yml @@ -0,0 +1,37 @@ +name: Release + +on: + workflow_dispatch: + push: + branches: + - main + - master + paths: + - '**/*.tpl' + - '**/*.py' + - '**/*.tf' + - '.github/workflows/release.yml' + +jobs: + release: + name: Release + runs-on: ubuntu-latest + # Skip running release workflow on forks + if: github.repository_owner == 'terraform-aws-modules' + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + persist-credentials: false + fetch-depth: 0 + + - name: Release + uses: cycjimmy/semantic-release-action@v3 + with: + semantic_version: 18.0.0 + extra_plugins: | + @semantic-release/changelog@6.0.0 + @semantic-release/git@10.0.0 + conventional-changelog-conventionalcommits@4.6.3 + env: + GITHUB_TOKEN: ${{ secrets.SEMANTIC_RELEASE_TOKEN }} diff --git a/modules/aws-transit-gateway/.github/workflows/stale-actions.yaml b/modules/aws-transit-gateway/.github/workflows/stale-actions.yaml new file mode 100644 index 0000000..5037995 --- /dev/null +++ b/modules/aws-transit-gateway/.github/workflows/stale-actions.yaml @@ -0,0 +1,32 @@ +name: 'Mark or close stale issues and PRs' +on: + schedule: + - cron: '0 0 * * *' + +jobs: + stale: + runs-on: ubuntu-latest + steps: + - uses: actions/stale@v6 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + # Staling issues and PR's + days-before-stale: 30 + stale-issue-label: stale + stale-pr-label: stale + stale-issue-message: | + This issue has been automatically marked as stale because it has been open 30 days + with no activity. Remove stale label or comment or this issue will be closed in 10 days + stale-pr-message: | + This PR has been automatically marked as stale because it has been open 30 days + with no activity. Remove stale label or comment or this PR will be closed in 10 days + # Not stale if have this labels or part of milestone + exempt-issue-labels: bug,wip,on-hold + exempt-pr-labels: bug,wip,on-hold + exempt-all-milestones: true + # Close issue operations + # Label will be automatically removed if the issues are no longer closed nor locked. + days-before-close: 10 + delete-branch: true + close-issue-message: This issue was automatically closed because of stale in 10 days + close-pr-message: This PR was automatically closed because of stale in 10 days diff --git a/modules/aws-transit-gateway/.gitignore b/modules/aws-transit-gateway/.gitignore new file mode 100644 index 0000000..0da622a --- /dev/null +++ b/modules/aws-transit-gateway/.gitignore @@ -0,0 +1,34 @@ +# Local .terraform directories +**/.terraform/* + +# Terraform lockfile +.terraform.lock.hcl + +# .tfstate files +*.tfstate +*.tfstate.* +*.tfplan + +# 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 + +# Ignore CLI configuration files +.terraformrc +terraform.rc + +# Lambda directories +builds/ +__pycache__/ diff --git a/modules/aws-transit-gateway/.pre-commit-config.yaml b/modules/aws-transit-gateway/.pre-commit-config.yaml new file mode 100644 index 0000000..d5886a6 --- /dev/null +++ b/modules/aws-transit-gateway/.pre-commit-config.yaml @@ -0,0 +1,29 @@ +repos: + - repo: https://github.com/antonbabenko/pre-commit-terraform + rev: v1.77.0 + hooks: + - id: terraform_fmt + - id: terraform_validate + - id: terraform_docs + args: + - '--args=--lockfile=false' + - id: terraform_tflint + args: + - '--args=--only=terraform_deprecated_interpolation' + - '--args=--only=terraform_deprecated_index' + - '--args=--only=terraform_unused_declarations' + - '--args=--only=terraform_comment_syntax' + - '--args=--only=terraform_documented_outputs' + - '--args=--only=terraform_documented_variables' + - '--args=--only=terraform_typed_variables' + - '--args=--only=terraform_module_pinned_source' + - '--args=--only=terraform_naming_convention' + - '--args=--only=terraform_required_version' + - '--args=--only=terraform_required_providers' + - '--args=--only=terraform_standard_module_structure' + - '--args=--only=terraform_workspace_remote' + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.4.0 + hooks: + - id: check-merge-conflict + - id: end-of-file-fixer diff --git a/modules/aws-transit-gateway/.releaserc.json b/modules/aws-transit-gateway/.releaserc.json new file mode 100644 index 0000000..66b3eef --- /dev/null +++ b/modules/aws-transit-gateway/.releaserc.json @@ -0,0 +1,45 @@ +{ + "branches": [ + "main", + "master" + ], + "ci": false, + "plugins": [ + [ + "@semantic-release/commit-analyzer", + { + "preset": "conventionalcommits" + } + ], + [ + "@semantic-release/release-notes-generator", + { + "preset": "conventionalcommits" + } + ], + [ + "@semantic-release/github", + { + "successComment": "This ${issue.pull_request ? 'PR is included' : 'issue has been resolved'} in version ${nextRelease.version} :tada:", + "labels": false, + "releasedLabels": false + } + ], + [ + "@semantic-release/changelog", + { + "changelogFile": "CHANGELOG.md", + "changelogTitle": "# Changelog\n\nAll notable changes to this project will be documented in this file." + } + ], + [ + "@semantic-release/git", + { + "assets": [ + "CHANGELOG.md" + ], + "message": "chore(release): version ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}" + } + ] + ] +} diff --git a/modules/aws-transit-gateway/CHANGELOG.md b/modules/aws-transit-gateway/CHANGELOG.md new file mode 100644 index 0000000..9e835f8 --- /dev/null +++ b/modules/aws-transit-gateway/CHANGELOG.md @@ -0,0 +1,151 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +## [2.10.0](https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/compare/v2.9.0...v2.10.0) (2023-04-26) + + +### Features + +* Fixed typo in mutlicast to multicast, also in the variable name ([#108](https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/issues/108)) ([baaa7f4](https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/commit/baaa7f44c458d29b95d372e3faae7f89a148da0c)) + +## [2.9.0](https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/compare/v2.8.2...v2.9.0) (2023-02-27) + + +### Features + +* Added tags per VPC attachment ([#103](https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/issues/103)) ([e4d6df2](https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/commit/e4d6df2aa4bab0d840bbab71276cca3bc69f9113)) + +### [2.8.2](https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/compare/v2.8.1...v2.8.2) (2023-01-24) + + +### Bug Fixes + +* Use a version for to avoid GitHub API rate limiting on CI workflows ([#96](https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/issues/96)) ([de6e0cf](https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/commit/de6e0cf41b7ee1b84e506f77415257f01f51065d)) + +### [2.8.1](https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/compare/v2.8.0...v2.8.1) (2022-10-27) + + +### Bug Fixes + +* Update CI configuration files to use latest version ([#88](https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/issues/88)) ([12ccdcc](https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/commit/12ccdcc0a209973e391e05079f3e1f04c0a78ff7)) + +## [2.8.0](https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/compare/v2.7.0...v2.8.0) (2022-05-09) + + +### Features + +* Added TGW multicast support ([#73](https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/issues/73)) ([a4d569b](https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/commit/a4d569b7f03443921d9dff7ce54f8acc06aed7fa)) + +## [2.7.0](https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/compare/v2.6.0...v2.7.0) (2022-03-26) + + +### Features + +* Add support for transit gateway CIDR blocks ([#69](https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/issues/69)) ([131ed50](https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/commit/131ed5006713aec86a20147796ce6489f6daadc6)) + +## [2.6.0](https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/compare/v2.5.1...v2.6.0) (2022-03-26) + + +### Features + +* Update Terraform minimum supported version to `v0.13.1` ([#68](https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/issues/68)) ([4e8f9c9](https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/commit/4e8f9c95d429d8f623db563388fe759707e38379)) + +### [2.5.1](https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/compare/v2.5.0...v2.5.1) (2022-01-10) + + +### Bug Fixes + +* update CI/CD process to enable auto-release workflow ([#63](https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/issues/63)) ([558f5ff](https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/commit/558f5ff261d9e5b25304c3f38ae0242850c92b2b)) + + +## [v2.5.0] - 2021-07-07 + +- fix: add tags if the default route table association is enabled ([#52](https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/issues/52)) + + + +## [v2.4.0] - 2021-05-24 + +- feat: Optionally update VPC Route Tables for attached VPCs ([#35](https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/issues/35)) + + + +## [v2.3.0] - 2021-05-19 + +- feat: default tgw route table tags ([#49](https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/issues/49)) + + + +## [v2.2.0] - 2021-05-19 + +- feat: adding appliance_mode_support to vpc attachments ([#48](https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/issues/48)) + + + +## [v2.1.0] - 2021-05-05 + +- fix: Update map function to work in Terraform 0.15 ([#44](https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/issues/44)) +- chore: update CI/CD to use stable `terraform-docs` release artifact and discoverable Apache2.0 license ([#42](https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/issues/42)) + + + +## [v2.0.0] - 2021-04-27 + +- feat: Shorten outputs (removing this_) ([#41](https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/issues/41)) +- chore: update documentation and pin `terraform_docs` version to avoid future changes ([#40](https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/issues/40)) +- chore: align ci-cd static checks to use individual minimum Terraform versions ([#38](https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/issues/38)) +- fix: bump min supported version due to types unsupported on current ([#37](https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/issues/37)) +- chore: add ci-cd workflow for pre-commit checks ([#36](https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/issues/36)) + + + +## [v1.4.0] - 2020-11-24 + +- fix: Updated supported Terraform versions ([#30](https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/issues/30)) +- docs: typos on example readme.mds ([#21](https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/issues/21)) + + + +## [v1.3.0] - 2020-08-18 + +- fix: Added support for multi-account deployments ([#20](https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/issues/20)) + + + +## [v1.2.0] - 2020-08-17 + +- chore: Minor updates in docs +- fix: fix variable in aws_ec2_transit_gateway_route_table_propagation ([#13](https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/issues/13)) + + + +## [v1.1.0] - 2020-01-16 + +- Updated notes in example + + + +## [v1.0.0] - 2020-01-15 + +- Added code for the module + + + +## v0.0.1 - 2020-01-15 + +- Initial commit + + +[Unreleased]: https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/compare/v2.5.0...HEAD +[v2.5.0]: https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/compare/v2.4.0...v2.5.0 +[v2.4.0]: https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/compare/v2.3.0...v2.4.0 +[v2.3.0]: https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/compare/v2.2.0...v2.3.0 +[v2.2.0]: https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/compare/v2.1.0...v2.2.0 +[v2.1.0]: https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/compare/v2.0.0...v2.1.0 +[v2.0.0]: https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/compare/v1.4.0...v2.0.0 +[v1.4.0]: https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/compare/v1.3.0...v1.4.0 +[v1.3.0]: https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/compare/v1.2.0...v1.3.0 +[v1.2.0]: https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/compare/v1.1.0...v1.2.0 +[v1.1.0]: https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/compare/v1.0.0...v1.1.0 +[v1.0.0]: https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/compare/v0.0.1...v1.0.0 diff --git a/modules/aws-transit-gateway/LICENSE b/modules/aws-transit-gateway/LICENSE new file mode 100644 index 0000000..d9a10c0 --- /dev/null +++ b/modules/aws-transit-gateway/LICENSE @@ -0,0 +1,176 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + 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 diff --git a/modules/aws-transit-gateway/README.md b/modules/aws-transit-gateway/README.md new file mode 100644 index 0000000..9ddff42 --- /dev/null +++ b/modules/aws-transit-gateway/README.md @@ -0,0 +1,164 @@ +# AWS Transit Gateway Terraform module + +Terraform module which creates Transit Gateway resources on AWS. + +## Usage with VPC module + +```hcl +module "tgw" { + source = "terraform-aws-modules/transit-gateway/aws" + version = "~> 2.0" + + name = "my-tgw" + description = "My TGW shared with several other AWS accounts" + + enable_auto_accept_shared_attachments = true + + vpc_attachments = { + vpc = { + vpc_id = module.vpc.vpc_id + subnet_ids = module.vpc.private_subnets + dns_support = true + ipv6_support = true + + tgw_routes = [ + { + destination_cidr_block = "30.0.0.0/16" + }, + { + blackhole = true + destination_cidr_block = "40.0.0.0/20" + } + ] + vpc_route_table_ids = ["rtb-xyz", "rtb-abc"] + vpc_cidrs = ["10.0.0.0/16", "20.0.0.0/16"] + } + } + + ram_allow_external_principals = true + ram_principals = [307990089504] + + tags = { + Purpose = "tgw-complete-example" + } +} + +module "vpc" { + source = "terraform-aws-modules/vpc/aws" + version = "~> 3.0" + + name = "my-vpc" + + cidr = "10.10.0.0/16" + + azs = ["eu-west-1a", "eu-west-1b", "eu-west-1c"] + private_subnets = ["10.10.1.0/24", "10.10.2.0/24", "10.10.3.0/24"] + + enable_ipv6 = true + private_subnet_assign_ipv6_address_on_creation = true + private_subnet_ipv6_prefixes = [0, 1, 2] +} +``` + +## Examples + +- [Complete example](https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/tree/master/examples/complete) shows TGW in combination with the [VPC module](https://github.com/terraform-aws-modules/terraform-aws-vpc) and [Resource Access Manager (RAM)](https://aws.amazon.com/ram/). +- [Multi-account example](https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/tree/master/examples/multi-account) shows TGW resources shared with different AWS accounts (via [Resource Access Manager (RAM)](https://aws.amazon.com/ram/)). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 4.4 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 4.4 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_ec2_tag.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ec2_tag) | resource | +| [aws_ec2_transit_gateway.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ec2_transit_gateway) | resource | +| [aws_ec2_transit_gateway_route.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ec2_transit_gateway_route) | resource | +| [aws_ec2_transit_gateway_route_table.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ec2_transit_gateway_route_table) | resource | +| [aws_ec2_transit_gateway_route_table_association.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ec2_transit_gateway_route_table_association) | resource | +| [aws_ec2_transit_gateway_route_table_propagation.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ec2_transit_gateway_route_table_propagation) | resource | +| [aws_ec2_transit_gateway_vpc_attachment.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ec2_transit_gateway_vpc_attachment) | resource | +| [aws_ram_principal_association.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ram_principal_association) | resource | +| [aws_ram_resource_association.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ram_resource_association) | resource | +| [aws_ram_resource_share.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ram_resource_share) | resource | +| [aws_ram_resource_share_accepter.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ram_resource_share_accepter) | resource | +| [aws_route.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route) | resource | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [amazon\_side\_asn](#input\_amazon\_side\_asn) | The Autonomous System Number (ASN) for the Amazon side of the gateway. By default the TGW is created with the current default Amazon ASN. | `string` | `null` | no | +| [create\_tgw](#input\_create\_tgw) | Controls if TGW should be created (it affects almost all resources) | `bool` | `true` | no | +| [description](#input\_description) | Description of the EC2 Transit Gateway | `string` | `null` | no | +| [enable\_auto\_accept\_shared\_attachments](#input\_enable\_auto\_accept\_shared\_attachments) | Whether resource attachment requests are automatically accepted | `bool` | `false` | no | +| [enable\_default\_route\_table\_association](#input\_enable\_default\_route\_table\_association) | Whether resource attachments are automatically associated with the default association route table | `bool` | `true` | no | +| [enable\_default\_route\_table\_propagation](#input\_enable\_default\_route\_table\_propagation) | Whether resource attachments automatically propagate routes to the default propagation route table | `bool` | `true` | no | +| [enable\_dns\_support](#input\_enable\_dns\_support) | Should be true to enable DNS support in the TGW | `bool` | `true` | no | +| [enable\_multicast\_support](#input\_enable\_multicast\_support) | Whether multicast support is enabled | `bool` | `false` | no | +| [enable\_vpn\_ecmp\_support](#input\_enable\_vpn\_ecmp\_support) | Whether VPN Equal Cost Multipath Protocol support is enabled | `bool` | `true` | no | +| [name](#input\_name) | Name to be used on all the resources as identifier | `string` | `""` | no | +| [ram\_allow\_external\_principals](#input\_ram\_allow\_external\_principals) | Indicates whether principals outside your organization can be associated with a resource share. | `bool` | `false` | no | +| [ram\_name](#input\_ram\_name) | The name of the resource share of TGW | `string` | `""` | no | +| [ram\_principals](#input\_ram\_principals) | A list of principals to share TGW with. Possible values are an AWS account ID, an AWS Organizations Organization ARN, or an AWS Organizations Organization Unit ARN | `list(string)` | `[]` | no | +| [ram\_resource\_share\_arn](#input\_ram\_resource\_share\_arn) | ARN of RAM resource share | `string` | `""` | no | +| [ram\_tags](#input\_ram\_tags) | Additional tags for the RAM | `map(string)` | `{}` | no | +| [share\_tgw](#input\_share\_tgw) | Whether to share your transit gateway with other accounts | `bool` | `true` | no | +| [tags](#input\_tags) | A map of tags to add to all resources | `map(string)` | `{}` | no | +| [tgw\_default\_route\_table\_tags](#input\_tgw\_default\_route\_table\_tags) | Additional tags for the Default TGW route table | `map(string)` | `{}` | no | +| [tgw\_route\_table\_tags](#input\_tgw\_route\_table\_tags) | Additional tags for the TGW route table | `map(string)` | `{}` | no | +| [tgw\_tags](#input\_tgw\_tags) | Additional tags for the TGW | `map(string)` | `{}` | no | +| [tgw\_vpc\_attachment\_tags](#input\_tgw\_vpc\_attachment\_tags) | Additional tags for VPC attachments | `map(string)` | `{}` | no | +| [timeouts](#input\_timeouts) | Create, update, and delete timeout configurations for the transit gateway | `map(string)` | `{}` | no | +| [transit\_gateway\_cidr\_blocks](#input\_transit\_gateway\_cidr\_blocks) | One or more IPv4 or IPv6 CIDR blocks for the transit gateway. Must be a size /24 CIDR block or larger for IPv4, or a size /64 CIDR block or larger for IPv6 | `list(string)` | `[]` | no | +| [transit\_gateway\_route\_table\_id](#input\_transit\_gateway\_route\_table\_id) | Identifier of EC2 Transit Gateway Route Table to use with the Target Gateway when reusing it between multiple TGWs | `string` | `null` | no | +| [vpc\_attachments](#input\_vpc\_attachments) | Maps of maps of VPC details to attach to TGW. Type 'any' to disable type validation by Terraform. | `any` | `{}` | no | +| [tgw\_route\_table\_env](#tgw\_route\_table\_env) | Identifier of EC2 Transit Gateway Route Table environment to use with routes. Required if you create vpc-attachment | `string` | `null` | no | +| [cross\_account\_assosiation\_propagation](#cross\_account\_assosiation\_propagation) | Cross account assosiation and propagation | `bool` | `false` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [ec2\_transit\_gateway\_arn](#output\_ec2\_transit\_gateway\_arn) | EC2 Transit Gateway Amazon Resource Name (ARN) | +| [ec2\_transit\_gateway\_association\_default\_route\_table\_id](#output\_ec2\_transit\_gateway\_association\_default\_route\_table\_id) | Identifier of the default association route table | +| [ec2\_transit\_gateway\_id](#output\_ec2\_transit\_gateway\_id) | EC2 Transit Gateway identifier | +| [ec2\_transit\_gateway\_owner\_id](#output\_ec2\_transit\_gateway\_owner\_id) | Identifier of the AWS account that owns the EC2 Transit Gateway | +| [ec2\_transit\_gateway\_propagation\_default\_route\_table\_id](#output\_ec2\_transit\_gateway\_propagation\_default\_route\_table\_id) | Identifier of the default propagation route table | +| [ec2\_transit\_gateway\_route\_ids](#output\_ec2\_transit\_gateway\_route\_ids) | List of EC2 Transit Gateway Route Table identifier combined with destination | +| [ec2\_transit\_gateway\_route\_table\_association](#output\_ec2\_transit\_gateway\_route\_table\_association) | Map of EC2 Transit Gateway Route Table Association attributes | +| [ec2\_transit\_gateway\_route\_table\_association\_ids](#output\_ec2\_transit\_gateway\_route\_table\_association\_ids) | List of EC2 Transit Gateway Route Table Association identifiers | +| [ec2\_transit\_gateway\_route\_table\_default\_association\_route\_table](#output\_ec2\_transit\_gateway\_route\_table\_default\_association\_route\_table) | Boolean whether this is the default association route table for the EC2 Transit Gateway | +| [ec2\_transit\_gateway\_route\_table\_default\_propagation\_route\_table](#output\_ec2\_transit\_gateway\_route\_table\_default\_propagation\_route\_table) | Boolean whether this is the default propagation route table for the EC2 Transit Gateway | +| [ec2\_transit\_gateway\_route\_table\_id](#output\_ec2\_transit\_gateway\_route\_table\_id) | EC2 Transit Gateway Route Table identifier | +| [ec2\_transit\_gateway\_route\_table\_propagation](#output\_ec2\_transit\_gateway\_route\_table\_propagation) | Map of EC2 Transit Gateway Route Table Propagation attributes | +| [ec2\_transit\_gateway\_route\_table\_propagation\_ids](#output\_ec2\_transit\_gateway\_route\_table\_propagation\_ids) | List of EC2 Transit Gateway Route Table Propagation identifiers | +| [ec2\_transit\_gateway\_vpc\_attachment](#output\_ec2\_transit\_gateway\_vpc\_attachment) | Map of EC2 Transit Gateway VPC Attachment attributes | +| [ec2\_transit\_gateway\_vpc\_attachment\_ids](#output\_ec2\_transit\_gateway\_vpc\_attachment\_ids) | List of EC2 Transit Gateway VPC Attachment identifiers | +| [ram\_principal\_association\_id](#output\_ram\_principal\_association\_id) | The Amazon Resource Name (ARN) of the Resource Share and the principal, separated by a comma | +| [ram\_resource\_share\_id](#output\_ram\_resource\_share\_id) | The Amazon Resource Name (ARN) of the resource share | + + +## Authors + +Module is maintained by [Anton Babenko](https://github.com/antonbabenko) with help from [these awesome contributors](https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/graphs/contributors). + +## License + +Apache 2 Licensed. See [LICENSE](https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/tree/master/LICENSE) for full details. diff --git a/modules/aws-transit-gateway/examples/complete/README.md b/modules/aws-transit-gateway/examples/complete/README.md new file mode 100644 index 0000000..b11a040 --- /dev/null +++ b/modules/aws-transit-gateway/examples/complete/README.md @@ -0,0 +1,66 @@ +# Complete AWS Transit Gateway example + +Configuration in this directory creates AWS Transit Gateway, attach VPC to it and share it with other AWS principals using [Resource Access Manager (RAM)](https://aws.amazon.com/ram/). + +## Usage + +To run this example you need to execute: + +```bash +$ terraform init +$ terraform plan +$ terraform apply +``` + +Note that this example may create resources which cost money. Run `terraform destroy` when you don't need these resources. + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 4.4 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [tgw](#module\_tgw) | ../../ | n/a | +| [vpc1](#module\_vpc1) | terraform-aws-modules/vpc/aws | ~> 3.0 | +| [vpc2](#module\_vpc2) | terraform-aws-modules/vpc/aws | ~> 3.0 | + +## Resources + +No resources. + +## Inputs + +No inputs. + +## Outputs + +| Name | Description | +|------|-------------| +| [ec2\_transit\_gateway\_arn](#output\_ec2\_transit\_gateway\_arn) | EC2 Transit Gateway Amazon Resource Name (ARN) | +| [ec2\_transit\_gateway\_association\_default\_route\_table\_id](#output\_ec2\_transit\_gateway\_association\_default\_route\_table\_id) | Identifier of the default association route table | +| [ec2\_transit\_gateway\_id](#output\_ec2\_transit\_gateway\_id) | EC2 Transit Gateway identifier | +| [ec2\_transit\_gateway\_owner\_id](#output\_ec2\_transit\_gateway\_owner\_id) | Identifier of the AWS account that owns the EC2 Transit Gateway | +| [ec2\_transit\_gateway\_propagation\_default\_route\_table\_id](#output\_ec2\_transit\_gateway\_propagation\_default\_route\_table\_id) | Identifier of the default propagation route table | +| [ec2\_transit\_gateway\_route\_ids](#output\_ec2\_transit\_gateway\_route\_ids) | List of EC2 Transit Gateway Route Table identifier combined with destination | +| [ec2\_transit\_gateway\_route\_table\_association](#output\_ec2\_transit\_gateway\_route\_table\_association) | Map of EC2 Transit Gateway Route Table Association attributes | +| [ec2\_transit\_gateway\_route\_table\_association\_ids](#output\_ec2\_transit\_gateway\_route\_table\_association\_ids) | List of EC2 Transit Gateway Route Table Association identifiers | +| [ec2\_transit\_gateway\_route\_table\_default\_association\_route\_table](#output\_ec2\_transit\_gateway\_route\_table\_default\_association\_route\_table) | Boolean whether this is the default association route table for the EC2 Transit Gateway | +| [ec2\_transit\_gateway\_route\_table\_default\_propagation\_route\_table](#output\_ec2\_transit\_gateway\_route\_table\_default\_propagation\_route\_table) | Boolean whether this is the default propagation route table for the EC2 Transit Gateway | +| [ec2\_transit\_gateway\_route\_table\_id](#output\_ec2\_transit\_gateway\_route\_table\_id) | EC2 Transit Gateway Route Table identifier | +| [ec2\_transit\_gateway\_route\_table\_propagation](#output\_ec2\_transit\_gateway\_route\_table\_propagation) | Map of EC2 Transit Gateway Route Table Propagation attributes | +| [ec2\_transit\_gateway\_route\_table\_propagation\_ids](#output\_ec2\_transit\_gateway\_route\_table\_propagation\_ids) | List of EC2 Transit Gateway Route Table Propagation identifiers | +| [ec2\_transit\_gateway\_vpc\_attachment](#output\_ec2\_transit\_gateway\_vpc\_attachment) | Map of EC2 Transit Gateway VPC Attachment attributes | +| [ec2\_transit\_gateway\_vpc\_attachment\_ids](#output\_ec2\_transit\_gateway\_vpc\_attachment\_ids) | List of EC2 Transit Gateway VPC Attachment identifiers | +| [ram\_principal\_association\_id](#output\_ram\_principal\_association\_id) | The Amazon Resource Name (ARN) of the Resource Share and the principal, separated by a comma | +| [ram\_resource\_share\_id](#output\_ram\_resource\_share\_id) | The Amazon Resource Name (ARN) of the resource share | + diff --git a/modules/aws-transit-gateway/examples/complete/main.tf b/modules/aws-transit-gateway/examples/complete/main.tf new file mode 100644 index 0000000..a3be95f --- /dev/null +++ b/modules/aws-transit-gateway/examples/complete/main.tf @@ -0,0 +1,114 @@ +provider "aws" { + region = local.region +} + +locals { + name = "ex-tgw-${replace(basename(path.cwd), "_", "-")}" + region = "eu-west-1" + + tags = { + Example = local.name + GithubRepo = "terraform-aws-eks" + GithubOrg = "terraform-aws-transit-gateway" + } +} + +################################################################################ +# Transit Gateway Module +################################################################################ + +module "tgw" { + source = "../../" + + name = local.name + description = "My TGW shared with several other AWS accounts" + amazon_side_asn = 64532 + + transit_gateway_cidr_blocks = ["10.99.0.0/24"] + + # When "true" there is no need for RAM resources if using multiple AWS accounts + enable_auto_accept_shared_attachments = true + + # When "true", allows service discovery through IGMP + enable_multicast_support = false + + vpc_attachments = { + vpc1 = { + vpc_id = module.vpc1.vpc_id + subnet_ids = module.vpc1.private_subnets + dns_support = true + ipv6_support = true + + transit_gateway_default_route_table_association = false + transit_gateway_default_route_table_propagation = false + + tgw_routes = [ + { + destination_cidr_block = "30.0.0.0/16" + }, + { + blackhole = true + destination_cidr_block = "0.0.0.0/0" + } + ] + }, + vpc2 = { + vpc_id = module.vpc2.vpc_id + subnet_ids = module.vpc2.private_subnets + + tgw_routes = [ + { + destination_cidr_block = "50.0.0.0/16" + }, + { + blackhole = true + destination_cidr_block = "10.10.10.10/32" + } + ] + tags = { + Name = "${local.name}-vpc2" + } + }, + } + + ram_allow_external_principals = true + ram_principals = [307990089504] + + tags = local.tags +} + +################################################################################ +# Supporting resources +################################################################################ + +module "vpc1" { + source = "terraform-aws-modules/vpc/aws" + version = "~> 3.0" + + name = "${local.name}-vpc1" + cidr = "10.10.0.0/16" + + azs = ["${local.region}a", "${local.region}b", "${local.region}c"] + private_subnets = ["10.10.1.0/24", "10.10.2.0/24", "10.10.3.0/24"] + + enable_ipv6 = true + private_subnet_assign_ipv6_address_on_creation = true + private_subnet_ipv6_prefixes = [0, 1, 2] + + tags = local.tags +} + +module "vpc2" { + source = "terraform-aws-modules/vpc/aws" + version = "~> 3.0" + + name = "${local.name}-vpc2" + cidr = "10.20.0.0/16" + + azs = ["${local.region}a", "${local.region}b", "${local.region}c"] + private_subnets = ["10.20.1.0/24", "10.20.2.0/24", "10.20.3.0/24"] + + enable_ipv6 = false + + tags = local.tags +} diff --git a/modules/aws-transit-gateway/examples/complete/outputs.tf b/modules/aws-transit-gateway/examples/complete/outputs.tf new file mode 100644 index 0000000..b9a0a40 --- /dev/null +++ b/modules/aws-transit-gateway/examples/complete/outputs.tf @@ -0,0 +1,100 @@ +################################################################################ +# Transit Gateway +################################################################################ + +output "ec2_transit_gateway_arn" { + description = "EC2 Transit Gateway Amazon Resource Name (ARN)" + value = module.tgw.ec2_transit_gateway_arn +} + +output "ec2_transit_gateway_id" { + description = "EC2 Transit Gateway identifier" + value = module.tgw.ec2_transit_gateway_id +} + +output "ec2_transit_gateway_owner_id" { + description = "Identifier of the AWS account that owns the EC2 Transit Gateway" + value = module.tgw.ec2_transit_gateway_owner_id +} + +output "ec2_transit_gateway_association_default_route_table_id" { + description = "Identifier of the default association route table" + value = module.tgw.ec2_transit_gateway_association_default_route_table_id +} + +output "ec2_transit_gateway_propagation_default_route_table_id" { + description = "Identifier of the default propagation route table" + value = module.tgw.ec2_transit_gateway_propagation_default_route_table_id +} + +################################################################################ +# VPC Attachment +################################################################################ + +output "ec2_transit_gateway_vpc_attachment_ids" { + description = "List of EC2 Transit Gateway VPC Attachment identifiers" + value = module.tgw.ec2_transit_gateway_vpc_attachment_ids +} + +output "ec2_transit_gateway_vpc_attachment" { + description = "Map of EC2 Transit Gateway VPC Attachment attributes" + value = module.tgw.ec2_transit_gateway_vpc_attachment +} + +################################################################################ +# Route Table / Routes +################################################################################ + +output "ec2_transit_gateway_route_table_id" { + description = "EC2 Transit Gateway Route Table identifier" + value = module.tgw.ec2_transit_gateway_route_table_id +} + +output "ec2_transit_gateway_route_table_default_association_route_table" { + description = "Boolean whether this is the default association route table for the EC2 Transit Gateway" + value = module.tgw.ec2_transit_gateway_route_table_default_association_route_table +} + +output "ec2_transit_gateway_route_table_default_propagation_route_table" { + description = "Boolean whether this is the default propagation route table for the EC2 Transit Gateway" + value = module.tgw.ec2_transit_gateway_route_table_default_propagation_route_table +} + +output "ec2_transit_gateway_route_ids" { + description = "List of EC2 Transit Gateway Route Table identifier combined with destination" + value = module.tgw.ec2_transit_gateway_route_ids +} + +output "ec2_transit_gateway_route_table_association_ids" { + description = "List of EC2 Transit Gateway Route Table Association identifiers" + value = module.tgw.ec2_transit_gateway_route_table_association_ids +} + +output "ec2_transit_gateway_route_table_association" { + description = "Map of EC2 Transit Gateway Route Table Association attributes" + value = module.tgw.ec2_transit_gateway_route_table_association +} + +output "ec2_transit_gateway_route_table_propagation_ids" { + description = "List of EC2 Transit Gateway Route Table Propagation identifiers" + value = module.tgw.ec2_transit_gateway_route_table_propagation_ids +} + +output "ec2_transit_gateway_route_table_propagation" { + description = "Map of EC2 Transit Gateway Route Table Propagation attributes" + value = module.tgw.ec2_transit_gateway_route_table_propagation +} + +################################################################################ +# Resource Access Manager +################################################################################ + +output "ram_resource_share_id" { + description = "The Amazon Resource Name (ARN) of the resource share" + value = module.tgw.ram_resource_share_id +} + +output "ram_principal_association_id" { + description = "The Amazon Resource Name (ARN) of the Resource Share and the principal, separated by a comma" + value = module.tgw.ram_principal_association_id +} diff --git a/modules/aws-transit-gateway/examples/complete/variables.tf b/modules/aws-transit-gateway/examples/complete/variables.tf new file mode 100644 index 0000000..e69de29 diff --git a/modules/aws-transit-gateway/examples/complete/versions.tf b/modules/aws-transit-gateway/examples/complete/versions.tf new file mode 100644 index 0000000..03533eb --- /dev/null +++ b/modules/aws-transit-gateway/examples/complete/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.4" + } + } +} diff --git a/modules/aws-transit-gateway/examples/multi-account/README.md b/modules/aws-transit-gateway/examples/multi-account/README.md new file mode 100644 index 0000000..a6b439d --- /dev/null +++ b/modules/aws-transit-gateway/examples/multi-account/README.md @@ -0,0 +1,67 @@ +# Complete AWS Transit Gateway example + +Configuration in this directory creates AWS Transit Gateway, attach VPC to it and share it with other AWS principals using [Resource Access Manager (RAM)](https://aws.amazon.com/ram/). + +## Usage + +To run this example you need to execute: + +```bash +$ terraform init +$ terraform plan +$ terraform apply +``` + +Note that this example may create resources which cost money. Run `terraform destroy` when you don't need these resources. + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 4.4 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [tgw](#module\_tgw) | ../../ | n/a | +| [tgw\_peer](#module\_tgw\_peer) | ../../ | n/a | +| [vpc1](#module\_vpc1) | terraform-aws-modules/vpc/aws | ~> 3.0 | +| [vpc2](#module\_vpc2) | terraform-aws-modules/vpc/aws | ~> 3.0 | + +## Resources + +No resources. + +## Inputs + +No inputs. + +## Outputs + +| Name | Description | +|------|-------------| +| [ec2\_transit\_gateway\_arn](#output\_ec2\_transit\_gateway\_arn) | EC2 Transit Gateway Amazon Resource Name (ARN) | +| [ec2\_transit\_gateway\_association\_default\_route\_table\_id](#output\_ec2\_transit\_gateway\_association\_default\_route\_table\_id) | Identifier of the default association route table | +| [ec2\_transit\_gateway\_id](#output\_ec2\_transit\_gateway\_id) | EC2 Transit Gateway identifier | +| [ec2\_transit\_gateway\_owner\_id](#output\_ec2\_transit\_gateway\_owner\_id) | Identifier of the AWS account that owns the EC2 Transit Gateway | +| [ec2\_transit\_gateway\_propagation\_default\_route\_table\_id](#output\_ec2\_transit\_gateway\_propagation\_default\_route\_table\_id) | Identifier of the default propagation route table | +| [ec2\_transit\_gateway\_route\_ids](#output\_ec2\_transit\_gateway\_route\_ids) | List of EC2 Transit Gateway Route Table identifier combined with destination | +| [ec2\_transit\_gateway\_route\_table\_association](#output\_ec2\_transit\_gateway\_route\_table\_association) | Map of EC2 Transit Gateway Route Table Association attributes | +| [ec2\_transit\_gateway\_route\_table\_association\_ids](#output\_ec2\_transit\_gateway\_route\_table\_association\_ids) | List of EC2 Transit Gateway Route Table Association identifiers | +| [ec2\_transit\_gateway\_route\_table\_default\_association\_route\_table](#output\_ec2\_transit\_gateway\_route\_table\_default\_association\_route\_table) | Boolean whether this is the default association route table for the EC2 Transit Gateway | +| [ec2\_transit\_gateway\_route\_table\_default\_propagation\_route\_table](#output\_ec2\_transit\_gateway\_route\_table\_default\_propagation\_route\_table) | Boolean whether this is the default propagation route table for the EC2 Transit Gateway | +| [ec2\_transit\_gateway\_route\_table\_id](#output\_ec2\_transit\_gateway\_route\_table\_id) | EC2 Transit Gateway Route Table identifier | +| [ec2\_transit\_gateway\_route\_table\_propagation](#output\_ec2\_transit\_gateway\_route\_table\_propagation) | Map of EC2 Transit Gateway Route Table Propagation attributes | +| [ec2\_transit\_gateway\_route\_table\_propagation\_ids](#output\_ec2\_transit\_gateway\_route\_table\_propagation\_ids) | List of EC2 Transit Gateway Route Table Propagation identifiers | +| [ec2\_transit\_gateway\_vpc\_attachment](#output\_ec2\_transit\_gateway\_vpc\_attachment) | Map of EC2 Transit Gateway VPC Attachment attributes | +| [ec2\_transit\_gateway\_vpc\_attachment\_ids](#output\_ec2\_transit\_gateway\_vpc\_attachment\_ids) | List of EC2 Transit Gateway VPC Attachment identifiers | +| [ram\_principal\_association\_id](#output\_ram\_principal\_association\_id) | The Amazon Resource Name (ARN) of the Resource Share and the principal, separated by a comma | +| [ram\_resource\_share\_id](#output\_ram\_resource\_share\_id) | The Amazon Resource Name (ARN) of the resource share | + diff --git a/modules/aws-transit-gateway/examples/multi-account/main.tf b/modules/aws-transit-gateway/examples/multi-account/main.tf new file mode 100644 index 0000000..54dbcb2 --- /dev/null +++ b/modules/aws-transit-gateway/examples/multi-account/main.tf @@ -0,0 +1,164 @@ +provider "aws" { + region = local.region +} + +# This provider is required for attachment only installation in another AWS Account +provider "aws" { + region = local.region + alias = "peer" +} + +locals { + name = "ex-tgw-${replace(basename(path.cwd), "_", "-")}" + region = "eu-west-1" + + tags = { + Example = local.name + GithubRepo = "terraform-aws-eks" + GithubOrg = "terraform-aws-transit-gateway" + } +} + +################################################################################ +# Transit Gateway Module +################################################################################ + +module "tgw" { + source = "../../" + + name = local.name + description = "My TGW shared with several other AWS accounts" + amazon_side_asn = 64532 + + # When "true" there is no need for RAM resources if using multiple AWS accounts + enable_auto_accept_shared_attachments = true + + vpc_attachments = { + vpc1 = { + vpc_id = module.vpc1.vpc_id + subnet_ids = module.vpc1.private_subnets + dns_support = true + ipv6_support = true + + transit_gateway_default_route_table_association = false + transit_gateway_default_route_table_propagation = false + + tgw_routes = [ + { + destination_cidr_block = "30.0.0.0/16" + }, + { + blackhole = true + destination_cidr_block = "0.0.0.0/0" + } + ] + }, + vpc2 = { + vpc_id = module.vpc2.vpc_id + subnet_ids = module.vpc2.private_subnets + + tgw_routes = [ + { + destination_cidr_block = "50.0.0.0/16" + }, + { + blackhole = true + destination_cidr_block = "10.10.10.10/32" + } + ] + }, + } + + ram_allow_external_principals = true + ram_principals = [307990089504] + + tags = local.tags +} + +module "tgw_peer" { + # This is optional and connects to another account. Meaning you need to be authenticated with 2 separate AWS Accounts + source = "../../" + + providers = { + aws = aws.peer + } + + name = "${local.name}-peer" + description = "My TGW shared with several other AWS accounts" + amazon_side_asn = 64532 + + create_tgw = false + share_tgw = true + ram_resource_share_arn = module.tgw.ram_resource_share_id + # When "true" there is no need for RAM resources if using multiple AWS accounts + enable_auto_accept_shared_attachments = true + + vpc_attachments = { + vpc1 = { + tgw_id = module.tgw.ec2_transit_gateway_id + vpc_id = module.vpc1.vpc_id + subnet_ids = module.vpc1.private_subnets + dns_support = true + ipv6_support = true + + transit_gateway_default_route_table_association = false + transit_gateway_default_route_table_propagation = false + + tgw_routes = [ + { + destination_cidr_block = "30.0.0.0/16" + }, + { + blackhole = true + destination_cidr_block = "0.0.0.0/0" + } + ] + }, + } + + ram_allow_external_principals = true + ram_principals = [307990089504] + + tags = local.tags +} + +################################################################################ +# Supporting resources +################################################################################ + +module "vpc1" { + source = "terraform-aws-modules/vpc/aws" + version = "~> 3.0" + + name = "${local.name}-vpc1" + cidr = "10.10.0.0/16" + + azs = ["${local.region}a", "${local.region}b", "${local.region}c"] + private_subnets = ["10.10.1.0/24", "10.10.2.0/24", "10.10.3.0/24"] + + enable_ipv6 = true + private_subnet_assign_ipv6_address_on_creation = true + private_subnet_ipv6_prefixes = [0, 1, 2] + + tags = local.tags +} + + +module "vpc2" { + source = "terraform-aws-modules/vpc/aws" + version = "~> 3.0" + + providers = { + aws = aws.peer + } + + name = "${local.name}-vpc2" + cidr = "10.20.0.0/16" + + azs = ["${local.region}a", "${local.region}b", "${local.region}c"] + private_subnets = ["10.20.1.0/24", "10.20.2.0/24", "10.20.3.0/24"] + + enable_ipv6 = false + + tags = local.tags +} diff --git a/modules/aws-transit-gateway/examples/multi-account/outputs.tf b/modules/aws-transit-gateway/examples/multi-account/outputs.tf new file mode 100644 index 0000000..b9a0a40 --- /dev/null +++ b/modules/aws-transit-gateway/examples/multi-account/outputs.tf @@ -0,0 +1,100 @@ +################################################################################ +# Transit Gateway +################################################################################ + +output "ec2_transit_gateway_arn" { + description = "EC2 Transit Gateway Amazon Resource Name (ARN)" + value = module.tgw.ec2_transit_gateway_arn +} + +output "ec2_transit_gateway_id" { + description = "EC2 Transit Gateway identifier" + value = module.tgw.ec2_transit_gateway_id +} + +output "ec2_transit_gateway_owner_id" { + description = "Identifier of the AWS account that owns the EC2 Transit Gateway" + value = module.tgw.ec2_transit_gateway_owner_id +} + +output "ec2_transit_gateway_association_default_route_table_id" { + description = "Identifier of the default association route table" + value = module.tgw.ec2_transit_gateway_association_default_route_table_id +} + +output "ec2_transit_gateway_propagation_default_route_table_id" { + description = "Identifier of the default propagation route table" + value = module.tgw.ec2_transit_gateway_propagation_default_route_table_id +} + +################################################################################ +# VPC Attachment +################################################################################ + +output "ec2_transit_gateway_vpc_attachment_ids" { + description = "List of EC2 Transit Gateway VPC Attachment identifiers" + value = module.tgw.ec2_transit_gateway_vpc_attachment_ids +} + +output "ec2_transit_gateway_vpc_attachment" { + description = "Map of EC2 Transit Gateway VPC Attachment attributes" + value = module.tgw.ec2_transit_gateway_vpc_attachment +} + +################################################################################ +# Route Table / Routes +################################################################################ + +output "ec2_transit_gateway_route_table_id" { + description = "EC2 Transit Gateway Route Table identifier" + value = module.tgw.ec2_transit_gateway_route_table_id +} + +output "ec2_transit_gateway_route_table_default_association_route_table" { + description = "Boolean whether this is the default association route table for the EC2 Transit Gateway" + value = module.tgw.ec2_transit_gateway_route_table_default_association_route_table +} + +output "ec2_transit_gateway_route_table_default_propagation_route_table" { + description = "Boolean whether this is the default propagation route table for the EC2 Transit Gateway" + value = module.tgw.ec2_transit_gateway_route_table_default_propagation_route_table +} + +output "ec2_transit_gateway_route_ids" { + description = "List of EC2 Transit Gateway Route Table identifier combined with destination" + value = module.tgw.ec2_transit_gateway_route_ids +} + +output "ec2_transit_gateway_route_table_association_ids" { + description = "List of EC2 Transit Gateway Route Table Association identifiers" + value = module.tgw.ec2_transit_gateway_route_table_association_ids +} + +output "ec2_transit_gateway_route_table_association" { + description = "Map of EC2 Transit Gateway Route Table Association attributes" + value = module.tgw.ec2_transit_gateway_route_table_association +} + +output "ec2_transit_gateway_route_table_propagation_ids" { + description = "List of EC2 Transit Gateway Route Table Propagation identifiers" + value = module.tgw.ec2_transit_gateway_route_table_propagation_ids +} + +output "ec2_transit_gateway_route_table_propagation" { + description = "Map of EC2 Transit Gateway Route Table Propagation attributes" + value = module.tgw.ec2_transit_gateway_route_table_propagation +} + +################################################################################ +# Resource Access Manager +################################################################################ + +output "ram_resource_share_id" { + description = "The Amazon Resource Name (ARN) of the resource share" + value = module.tgw.ram_resource_share_id +} + +output "ram_principal_association_id" { + description = "The Amazon Resource Name (ARN) of the Resource Share and the principal, separated by a comma" + value = module.tgw.ram_principal_association_id +} diff --git a/modules/aws-transit-gateway/examples/multi-account/variables.tf b/modules/aws-transit-gateway/examples/multi-account/variables.tf new file mode 100644 index 0000000..e69de29 diff --git a/modules/aws-transit-gateway/examples/multi-account/versions.tf b/modules/aws-transit-gateway/examples/multi-account/versions.tf new file mode 100644 index 0000000..03533eb --- /dev/null +++ b/modules/aws-transit-gateway/examples/multi-account/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.4" + } + } +} diff --git a/modules/aws-transit-gateway/main.tf b/modules/aws-transit-gateway/main.tf new file mode 100644 index 0000000..a199cd7 --- /dev/null +++ b/modules/aws-transit-gateway/main.tf @@ -0,0 +1,250 @@ +locals { + # List of maps with key and route values + vpc_attachments_with_routes = chunklist(flatten([ + for k, v in var.vpc_attachments : setproduct([{ key = k }], v.tgw_routes) if can(v.tgw_routes) + ]), 2) + + tgw_default_route_table_tags_merged = merge( + var.tags, + { Name = var.name }, + var.tgw_default_route_table_tags, + ) + # List of cidr + vpc_route_table_destination_cidrs = flatten([ + for k, v in var.vpc_attachments : [ + for cidr in try(v.vpc_cidrs, []) : { + cidr = cidr + } + ] + ]) + # List of route tables + vpc_route_table_id = flatten([ + for k, v in var.vpc_attachments : [ + for rtb_id in try(v.vpc_route_table_ids, []) : { + rtb_id = rtb_id + } + ] + ]) + #List of maps of subnet route information. + vpc_routes = flatten([ + for rtb_id in local.vpc_route_table_id : [ + for cidr in local.vpc_route_table_destination_cidrs : { + route_cidr = cidr + route_rtb_id = rtb_id + } + ] + ]) +} + +################################################################################ +# Transit Gateway +################################################################################ + +resource "aws_ec2_transit_gateway" "this" { + count = var.create_tgw ? 1 : 0 + + description = coalesce(var.description, var.name) + amazon_side_asn = var.amazon_side_asn + default_route_table_association = var.enable_default_route_table_association ? "enable" : "disable" + default_route_table_propagation = var.enable_default_route_table_propagation ? "enable" : "disable" + auto_accept_shared_attachments = var.enable_auto_accept_shared_attachments ? "enable" : "disable" + multicast_support = var.enable_multicast_support ? "enable" : "disable" + vpn_ecmp_support = var.enable_vpn_ecmp_support ? "enable" : "disable" + dns_support = var.enable_dns_support ? "enable" : "disable" + transit_gateway_cidr_blocks = var.transit_gateway_cidr_blocks + + timeouts { + create = try(var.timeouts.create, null) + update = try(var.timeouts.update, null) + delete = try(var.timeouts.delete, null) + } + + tags = merge( + var.tags, + { Name = var.name }, + var.tgw_tags, + ) +} + +resource "aws_ec2_tag" "this" { + for_each = { for k, v in local.tgw_default_route_table_tags_merged : k => v if var.create_tgw && var.enable_default_route_table_association } + + resource_id = aws_ec2_transit_gateway.this[0].association_default_route_table_id + key = each.key + value = each.value +} + +################################################################################ +# Peer Attachment +################################################################################ + +# transit GW Peer +data "aws_ec2_transit_gateway_peering_attachment" "this" { + count = var.peer_attachment != {} ? 1 : 0 + provider = aws.peer_accepter + depends_on = [aws_ec2_transit_gateway_peering_attachment.this] + + filter { + name = "transit-gateway-id" + values = [try(var.peer_attachment.peer_transit_gateway_id, "id")] + } + # If you use multiple tgw peering you must fix this values. + filter { + name = "state" + values = ["pendingAcceptance", "available"] + } +} + +resource "aws_ec2_transit_gateway_peering_attachment" "this" { + count = var.peer_attachment != {} ? 1 : 0 + + peer_account_id = var.peer_attachment.peer_account_id + peer_region = var.peer_attachment.peer_region + peer_transit_gateway_id = var.peer_attachment.peer_transit_gateway_id + transit_gateway_id = var.peer_attachment.tgw_id + + tags = merge( + var.tags, + { Name = var.name }, + var.tgw_peer_attachment_tags, + ) +} + +resource "aws_ec2_transit_gateway_peering_attachment_accepter" "this" { + count = var.peer_attachment != {} ? 1 : 0 + provider = aws.peer_accepter + transit_gateway_attachment_id = data.aws_ec2_transit_gateway_peering_attachment.this[0].id +} + +################################################################################ +# VPC Attachment +################################################################################ + +resource "aws_ec2_transit_gateway_vpc_attachment" "this" { + for_each = var.vpc_attachments + + transit_gateway_id = var.create_tgw ? aws_ec2_transit_gateway.this[0].id : each.value.tgw_id + vpc_id = each.value.vpc_id + subnet_ids = each.value.subnet_ids + + dns_support = try(each.value.dns_support, true) ? "enable" : "disable" + ipv6_support = try(each.value.ipv6_support, false) ? "enable" : "disable" + appliance_mode_support = try(each.value.appliance_mode_support, false) ? "enable" : "disable" + transit_gateway_default_route_table_association = try(each.value.transit_gateway_default_route_table_association, true) + transit_gateway_default_route_table_propagation = try(each.value.transit_gateway_default_route_table_propagation, true) + + tags = merge( + var.tags, + { Name = var.name }, + var.tgw_vpc_attachment_tags, + try(each.value.tags, {}), + ) +} + +################################################################################ +# Route Table / Routes +################################################################################ + +resource "aws_ec2_transit_gateway_route_table" "this" { + count = var.create_tgw ? 1 : 0 + + transit_gateway_id = aws_ec2_transit_gateway.this[0].id + + tags = merge( + var.tags, + var.tgw_route_table_tags, + ) +} + +resource "aws_ec2_transit_gateway_route" "this" { + count = length(local.vpc_attachments_with_routes) + + destination_cidr_block = local.vpc_attachments_with_routes[count.index][1].destination_cidr_block + blackhole = try(local.vpc_attachments_with_routes[count.index][1].blackhole, null) + + transit_gateway_route_table_id = var.create_tgw ? aws_ec2_transit_gateway_route_table.this[0].id : var.transit_gateway_route_table_id + transit_gateway_attachment_id = tobool(try(local.vpc_attachments_with_routes[count.index][1].blackhole, false)) == false ? aws_ec2_transit_gateway_vpc_attachment.this[local.vpc_attachments_with_routes[count.index][0].key].id : null +} + +resource "aws_route" "this" { + for_each = { for routes in local.vpc_routes : "${routes.route_rtb_id.rtb_id}.${routes.route_cidr.cidr}" => routes } + + route_table_id = each.value.route_rtb_id.rtb_id + destination_cidr_block = each.value.route_cidr.cidr + transit_gateway_id = var.create_tgw ? aws_ec2_transit_gateway.this[0].id : join(",", [for k, v in var.vpc_attachments : v.tgw_id]) +} + +resource "aws_ec2_transit_gateway_route_table_association" "this" { + for_each = { + for k, v in var.vpc_attachments : k => v if var.create_tgw && try(v.transit_gateway_default_route_table_association, true) != true + } + + # Create association if it was not set already by aws_ec2_transit_gateway_vpc_attachment resource + transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.this[each.key].id + transit_gateway_route_table_id = var.create_tgw ? aws_ec2_transit_gateway_route_table.this[0].id : try(each.value.transit_gateway_route_table_id, var.transit_gateway_route_table_id) +} + +resource "aws_ec2_transit_gateway_route_table_propagation" "this" { + for_each = { + for k, v in var.vpc_attachments : k => v if var.create_tgw && try(v.transit_gateway_default_route_table_propagation, true) != true + } + + # Create association if it was not set already by aws_ec2_transit_gateway_vpc_attachment resource + transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.this[each.key].id + transit_gateway_route_table_id = var.create_tgw ? aws_ec2_transit_gateway_route_table.this[0].id : try(each.value.transit_gateway_route_table_id, var.transit_gateway_route_table_id) +} + +## Peer requester & Peer accepter static routes +resource "aws_ec2_transit_gateway_route" "requester" { + count = var.peer_attachment == {} ? 0 : length(var.peer_attachment.peer_requester_routes) + + destination_cidr_block = var.peer_attachment.peer_requester_routes[count.index] + transit_gateway_attachment_id = data.aws_ec2_transit_gateway_peering_attachment.this[0].id + transit_gateway_route_table_id = var.create_tgw ? aws_ec2_transit_gateway.this[0].association_default_route_table_id : var.transit_gateway_route_table_id_requester +} + +resource "aws_ec2_transit_gateway_route" "accepter" { + count = var.peer_attachment == {} ? 0 : length(var.peer_attachment.peer_accepter_routes) + + provider = aws.peer_accepter + destination_cidr_block = var.peer_attachment.peer_accepter_routes[count.index] + transit_gateway_attachment_id = data.aws_ec2_transit_gateway_peering_attachment.this[0].id + transit_gateway_route_table_id = var.create_tgw ? aws_ec2_transit_gateway.this[0].association_default_route_table_id : var.transit_gateway_route_table_id_accepter +} + +################################################################################ +# Resource Access Manager +################################################################################ + +resource "aws_ram_resource_share" "this" { + count = var.create_tgw && var.share_tgw ? 1 : 0 + + name = coalesce(var.ram_name, var.name) + allow_external_principals = var.ram_allow_external_principals + + tags = merge( + var.tags, + { Name = coalesce(var.ram_name, var.name) }, + var.ram_tags, + ) +} + +resource "aws_ram_resource_association" "this" { + count = var.create_tgw && var.share_tgw ? 1 : 0 + + resource_arn = aws_ec2_transit_gateway.this[0].arn + resource_share_arn = aws_ram_resource_share.this[0].id +} + +resource "aws_ram_principal_association" "this" { + count = var.create_tgw && var.share_tgw ? length(var.ram_principals) : 0 + + principal = var.ram_principals[count.index] + resource_share_arn = aws_ram_resource_share.this[0].arn +} + +resource "aws_ram_resource_share_accepter" "this" { + count = !var.create_tgw && var.share_tgw ? 1 : 0 + + share_arn = var.ram_resource_share_arn +} diff --git a/modules/aws-transit-gateway/outputs.tf b/modules/aws-transit-gateway/outputs.tf new file mode 100644 index 0000000..8dcb8a5 --- /dev/null +++ b/modules/aws-transit-gateway/outputs.tf @@ -0,0 +1,100 @@ +################################################################################ +# Transit Gateway +################################################################################ + +output "ec2_transit_gateway_arn" { + description = "EC2 Transit Gateway Amazon Resource Name (ARN)" + value = try(aws_ec2_transit_gateway.this[0].arn, "") +} + +output "ec2_transit_gateway_id" { + description = "EC2 Transit Gateway identifier" + value = try(aws_ec2_transit_gateway.this[0].id, "") +} + +output "ec2_transit_gateway_owner_id" { + description = "Identifier of the AWS account that owns the EC2 Transit Gateway" + value = try(aws_ec2_transit_gateway.this[0].owner_id, "") +} + +output "ec2_transit_gateway_association_default_route_table_id" { + description = "Identifier of the default association route table" + value = try(aws_ec2_transit_gateway.this[0].association_default_route_table_id, "") +} + +output "ec2_transit_gateway_propagation_default_route_table_id" { + description = "Identifier of the default propagation route table" + value = try(aws_ec2_transit_gateway.this[0].propagation_default_route_table_id, "") +} + +################################################################################ +# VPC Attachment +################################################################################ + +output "ec2_transit_gateway_vpc_attachment_ids" { + description = "List of EC2 Transit Gateway VPC Attachment identifiers" + value = [for k, v in aws_ec2_transit_gateway_vpc_attachment.this : v.id] +} + +output "ec2_transit_gateway_vpc_attachment" { + description = "Map of EC2 Transit Gateway VPC Attachment attributes" + value = aws_ec2_transit_gateway_vpc_attachment.this +} + +################################################################################ +# Route Table / Routes +################################################################################ + +output "ec2_transit_gateway_route_table_id" { + description = "EC2 Transit Gateway Route Table identifier" + value = try(aws_ec2_transit_gateway_route_table.this[0].id, "") +} + +output "ec2_transit_gateway_route_table_default_association_route_table" { + description = "Boolean whether this is the default association route table for the EC2 Transit Gateway" + value = try(aws_ec2_transit_gateway_route_table.this[0].default_association_route_table, "") +} + +output "ec2_transit_gateway_route_table_default_propagation_route_table" { + description = "Boolean whether this is the default propagation route table for the EC2 Transit Gateway" + value = try(aws_ec2_transit_gateway_route_table.this[0].default_propagation_route_table, "") +} + +output "ec2_transit_gateway_route_ids" { + description = "List of EC2 Transit Gateway Route Table identifier combined with destination" + value = aws_ec2_transit_gateway_route.this[*].id +} + +output "ec2_transit_gateway_route_table_association_ids" { + description = "List of EC2 Transit Gateway Route Table Association identifiers" + value = [for k, v in aws_ec2_transit_gateway_route_table_association.this : v.id] +} + +output "ec2_transit_gateway_route_table_association" { + description = "Map of EC2 Transit Gateway Route Table Association attributes" + value = aws_ec2_transit_gateway_route_table_association.this +} + +output "ec2_transit_gateway_route_table_propagation_ids" { + description = "List of EC2 Transit Gateway Route Table Propagation identifiers" + value = [for k, v in aws_ec2_transit_gateway_route_table_propagation.this : v.id] +} + +output "ec2_transit_gateway_route_table_propagation" { + description = "Map of EC2 Transit Gateway Route Table Propagation attributes" + value = aws_ec2_transit_gateway_route_table_propagation.this +} + +################################################################################ +# Resource Access Manager +################################################################################ + +output "ram_resource_share_id" { + description = "The Amazon Resource Name (ARN) of the resource share" + value = try(aws_ram_resource_share.this[0].id, "") +} + +output "ram_principal_association_id" { + description = "The Amazon Resource Name (ARN) of the Resource Share and the principal, separated by a comma" + value = try(aws_ram_principal_association.this[0].id, "") +} diff --git a/modules/aws-transit-gateway/variables.tf b/modules/aws-transit-gateway/variables.tf new file mode 100644 index 0000000..fca6828 --- /dev/null +++ b/modules/aws-transit-gateway/variables.tf @@ -0,0 +1,225 @@ +variable "name" { + description = "Name to be used on all the resources as identifier" + type = string + default = "" +} + +variable "tags" { + description = "A map of tags to add to all resources" + type = map(string) + default = {} +} + + +################################################################################ +# Transit Gateway +################################################################################ + +variable "create_tgw" { + description = "Controls if TGW should be created (it affects almost all resources)" + type = bool + default = true +} + +variable "peer_tgw" { + description = "Controls if TGW Peer should be created (it affects almost all resources)" + type = bool + default = false +} + +variable "tgw_accepter" { + description = "Controls TGW Peer Accepter if TGW Peer should be created (it affects almost all resources)" + type = bool + default = false +} + +variable "tgw_id" { + description = "The ID of the local TGW for peerings" + type = string + default = "" +} + +variable "tgw_peering_attachment_id" { + description = "The ID of the TGW attachment for peerings" + type = string + default = "" +} + +variable "description" { + description = "Description of the EC2 Transit Gateway" + type = string + default = null +} + +variable "amazon_side_asn" { + description = "The Autonomous System Number (ASN) for the Amazon side of the gateway. By default the TGW is created with the current default Amazon ASN." + type = string + default = null +} + +variable "enable_default_route_table_association" { + description = "Whether resource attachments are automatically associated with the default association route table" + type = bool + default = true +} + +variable "enable_default_route_table_propagation" { + description = "Whether resource attachments automatically propagate routes to the default propagation route table" + type = bool + default = true +} + +variable "enable_auto_accept_shared_attachments" { + description = "Whether resource attachment requests are automatically accepted" + type = bool + default = false +} + +variable "enable_vpn_ecmp_support" { + description = "Whether VPN Equal Cost Multipath Protocol support is enabled" + type = bool + default = true +} + +variable "enable_multicast_support" { + description = "Whether multicast support is enabled" + type = bool + default = false +} + +variable "enable_dns_support" { + description = "Should be true to enable DNS support in the TGW" + type = bool + default = true +} + +variable "transit_gateway_cidr_blocks" { + description = "One or more IPv4 or IPv6 CIDR blocks for the transit gateway. Must be a size /24 CIDR block or larger for IPv4, or a size /64 CIDR block or larger for IPv6" + type = list(string) + default = [] +} + +variable "timeouts" { + description = "Create, update, and delete timeout configurations for the transit gateway" + type = map(string) + default = {} +} + +variable "tgw_tags" { + description = "Additional tags for the TGW" + type = map(string) + default = {} +} + +variable "tgw_default_route_table_tags" { + description = "Additional tags for the Default TGW route table" + type = map(string) + default = {} +} + +################################################################################ +# VPC Attachment +################################################################################ + +variable "vpc_attachments" { + description = "Maps of maps of VPC details to attach to TGW. Type 'any' to disable type validation by Terraform." + type = any + default = {} +} + +variable "tgw_vpc_attachment_tags" { + description = "Additional tags for VPC attachments" + type = map(string) + default = {} +} + + +################################################################################ +# Peer Attachment +################################################################################ + +variable "peer_attachment" { + description = "Maps of maps of Peer details to attach to TGW. Type 'any' to disable type validation by Terraform." + type = any + default = {} +} + +variable "peer_attachment_id" { + description = "(Required) The ID of the EC2 Transit Gateway Peering Attachment to manage." + type = string + default = "" +} + +variable "tgw_peer_attachment_tags" { + description = "Additional tags for Peer attachments" + type = map(string) + default = {} +} + +################################################################################ +# Route Table / Routes +################################################################################ + +variable "transit_gateway_route_table_id" { + description = "Identifier of EC2 Transit Gateway Route Table to use with the Target Gateway when reusing it between multiple TGWs" + type = string + default = null +} + +variable "tgw_route_table_tags" { + description = "Additional tags for the TGW route table" + type = map(string) + default = {} +} + +variable "transit_gateway_route_table_id_requester" { + description = "Identifier of EC2 Transit Gateway Route Table to use with the Target Gateway when reusing it between multiple TGWs" + type = string + default = null +} + +variable "transit_gateway_route_table_id_accepter" { + description = "Identifier of EC2 Transit Gateway Route Table to use with the Target Gateway when reusing it between multiple TGWs" + type = string + default = null +} + +################################################################################ +# Resource Access Manager +################################################################################ + +variable "share_tgw" { + description = "Whether to share your transit gateway with other accounts" + type = bool + default = true +} + +variable "ram_name" { + description = "The name of the resource share of TGW" + type = string + default = "" +} + +variable "ram_allow_external_principals" { + description = "Indicates whether principals outside your organization can be associated with a resource share." + type = bool + default = false +} + +variable "ram_principals" { + description = "A list of principals to share TGW with. Possible values are an AWS account ID, an AWS Organizations Organization ARN, or an AWS Organizations Organization Unit ARN" + type = list(string) + default = [] +} + +variable "ram_resource_share_arn" { + description = "ARN of RAM resource share" + type = string + default = "" +} + +variable "ram_tags" { + description = "Additional tags for the RAM" + type = map(string) + default = {} +} diff --git a/modules/aws-transit-gateway/versions.tf b/modules/aws-transit-gateway/versions.tf new file mode 100644 index 0000000..03533eb --- /dev/null +++ b/modules/aws-transit-gateway/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.4" + } + } +} diff --git a/modules/aws-vpc-peering-accepter/README.md b/modules/aws-vpc-peering-accepter/README.md new file mode 100644 index 0000000..568c72d --- /dev/null +++ b/modules/aws-vpc-peering-accepter/README.md @@ -0,0 +1,117 @@ +# vpc-peering-accepter + +This module accepts VPC Peering request. + +## Usage + +This module has three functions: + +- Accepts VPC peering requests and creates routes that indicate VPC-peering. +- Accepts multiple VPC Peering requests without route propagation. +- Accepts multiple VPC Peering requests with route propagation. + +## Accept peering request with route propagation + +```hcl +module "peering-accepter" { + source = "../vpc-peering-requester" + + vpc_peer_id = dependency.vpc-requester.outputs.vpc_peering_id + requester_vpc_cidr_block = dependency.vpc-requester.outputs.requester_vpc_cidr_block + + #Create route in database route table requester_vpc_cidr_block => vpc-peering-id + accepter_database_route_table_ids = ["rtb-1","rtb-2"] + +} +``` + +If you want to use this module with the vpc-peering-accepter module, set the `accepter_private_route_table_ids` variables. Because of the dependency cycle, the acceptor takes all of the variables from the requester. + +`accepter_private_route_table_ids` + +## Accept multiple peering requests without route propagation + +```hcl +module "peering-accepter" { + source = "../vpc-peering-requester" + + vpc_peering_ids = dependency.vpc-requester.outputs.vpc_peering_id + requester_vpc_cidr_block = dependency.vpc-requester.outputs.requester_vpc_cidr_block + + #Create route in database route table requester_vpc_cidr_block => vpc-peering-id + accepter_database_route_table_ids = ["rtb-1","rtb-2"] + +} +``` + +## Accept multiple peering requests with route propagation + +```hcl +module "peering-accepter" { + source = "../vpc-peering-requester" + + vpc_peer_ids = dependency.vpc-requester.outputs.vpc_peer_ids + + #Create route in specified tables: requester_cidr => peer_id + accepter_private_route_table_ids = ["rtb-1","rtb-2", "rtb-3"] + requester_peer_info = [ + { + requester_cidr = "192.168.240.0/21" + peer_id = "pcx-03d3ebd458ebae90f" + }, + { + requester_cidr = "192.168.240.0/21" + peer_id = "pcx-0016cf5631d7a80df" + }, + ] +} +``` + + +## Requirements + +No requirements. + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | n/a | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_route.accepter_private_route_table_route](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route) | resource | +| [aws_route.accepter_public_route_table_route](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route) | resource | +| [aws_route.accepter_table_multiple_route](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route) | resource | +| [aws_vpc_peering_connection_accepter.batch_peer](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_peering_connection_accepter) | resource | +| [aws_vpc_peering_connection_accepter.peer](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_peering_connection_accepter) | resource | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [accepter\_all\_private\_route\_table\_ids](#input\_accepter\_all\_private\_route\_table\_ids) | All private route table IDs of accepter VPC route tables | `list(string)` | `[]` | no | +| [accepter\_private\_route\_table\_ids](#input\_accepter\_private\_route\_table\_ids) | The eks route table IDs of accepter VPC route tables | `list(string)` | `[]` | no | +| [accepter\_public\_route\_table\_ids](#input\_accepter\_public\_route\_table\_ids) | The eks route table IDs of accepter VPC route tables | `list(string)` | `[]` | no | +| [requester\_vpc\_cidr\_block](#input\_requester\_vpc\_cidr\_block) | The CIDR Block of the requester VPC | `string` | `""` | no | +| [tags](#input\_tags) | Tags for the peering connection | `map(string)` | `{}` | no | +| [vpc\_peer\_id](#input\_vpc\_peer\_id) | VPC peering connection ID | `string` | `""` | no | +| [vpc\_peer\_ids](#input\_vpc\_peer\_ids) | VPC peering connections IDs for batch operations | `list(string)` | `[]` | no | +| [requester\_peer\_info](#input\_requester\_peer\_info) | VPC peering connections IDs and cidr blocks for batch operatipn | `list(object({ requester_cidr = string, peer_id = string}))` | `[]` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [accepter\_private\_route\_table\_ids](#output\_accepter\_private\_route\_table\_ids) | The eks route table IDs of accepter VPC route tables | +| [accepter\_public\_route\_table\_ids](#output\_accepter\_public\_route\_table\_ids) | The eks route table IDs of accepter VPC route tables | +| [requester\_vpc\_cidr\_block](#output\_requester\_vpc\_cidr\_block) | The CIDR Block of the requester VPC | +| [vpc\_peering\_id](#output\_vpc\_peering\_id) | ID of the vpc peering | +| [routes\_with\_requester\_peer\_info](#output\_routes\_with\_requester\_peer\_info) | Route table ids, requester cidr and peer id | + \ No newline at end of file diff --git a/modules/aws-vpc-peering-accepter/main.tf b/modules/aws-vpc-peering-accepter/main.tf new file mode 100644 index 0000000..964c5fd --- /dev/null +++ b/modules/aws-vpc-peering-accepter/main.tf @@ -0,0 +1,32 @@ + + +resource "aws_vpc_peering_connection_accepter" "peer" { + count = var.vpc_peer_id != "" ? 1 : 0 + vpc_peering_connection_id = var.vpc_peer_id + auto_accept = true + + tags = merge(var.tags, { + Name = var.name + Side = "Accepter" + }) + + accepter { + allow_remote_vpc_dns_resolution = true + } +} + + +resource "aws_vpc_peering_connection_accepter" "batch_peer" { + count = length(var.vpc_peer_ids) > 0 ? length(var.vpc_peer_ids) : 0 + vpc_peering_connection_id = var.vpc_peer_ids[count.index] + auto_accept = true + + tags = merge(var.tags, { + Name = var.name + Side = "Accepter" + }) + + accepter { + allow_remote_vpc_dns_resolution = true + } +} diff --git a/modules/aws-vpc-peering-accepter/outputs.tf b/modules/aws-vpc-peering-accepter/outputs.tf new file mode 100644 index 0000000..623da58 --- /dev/null +++ b/modules/aws-vpc-peering-accepter/outputs.tf @@ -0,0 +1,23 @@ +output "vpc_peering_id" { + description = "ID of the vpc peering" + value = var.vpc_peer_id +} + +output "requester_vpc_cidr_block" { + description = "The CIDR Block of the requester VPC" + value = var.requester_vpc_cidr_block +} + +output "accepter_private_route_table_ids" { + description = "The eks route table IDs of accepter VPC route tables" + value = var.accepter_private_route_table_ids +} + +output "accepter_public_route_table_ids" { + description = "The eks route table IDs of accepter VPC route tables" + value = var.accepter_public_route_table_ids +} + +output "routes_with_requester_peer_info" { + value = local.routes +} \ No newline at end of file diff --git a/modules/aws-vpc-peering-accepter/routes.tf b/modules/aws-vpc-peering-accepter/routes.tf new file mode 100644 index 0000000..dfdcca5 --- /dev/null +++ b/modules/aws-vpc-peering-accepter/routes.tf @@ -0,0 +1,42 @@ + +resource "aws_route" "accepter_private_route_table_route" { + count = length(var.accepter_private_route_table_ids) > 0 && length(var.requester_peer_info) == 0 ? length(var.accepter_private_route_table_ids) : 0 + vpc_peering_connection_id = var.vpc_peer_id + route_table_id = var.accepter_private_route_table_ids[count.index] + destination_cidr_block = var.requester_vpc_cidr_block + +} + + +resource "aws_route" "accepter_public_route_table_route" { + count = length(var.accepter_public_route_table_ids) > 0 && length(var.requester_peer_info) == 0 ? length(var.accepter_public_route_table_ids) : 0 + vpc_peering_connection_id = var.vpc_peer_id + route_table_id = var.accepter_public_route_table_ids[count.index] + destination_cidr_block = var.requester_vpc_cidr_block + +} + +# Multiple peerin acceptance with multpile route propagation. +locals { + + route_tables = length(var.accepter_private_route_table_ids) > 0 ? var.accepter_private_route_table_ids : var.accepter_public_route_table_ids + peer_detail = var.requester_peer_info + + routes = flatten([ + for table in local.route_tables : [ + for p in local.peer_detail : { + table_id = table + cidr = p.requester_cidr + peer_id = p.peer_id + } + ] + ] + ) +} + +resource "aws_route" "accepter_table_multiple_route" { + for_each = { for routes in local.routes : "${routes.table_id}.${routes.peer_id}" => routes } + vpc_peering_connection_id = each.value.peer_id + route_table_id = each.value.table_id + destination_cidr_block = each.value.cidr +} diff --git a/modules/aws-vpc-peering-accepter/variables.tf b/modules/aws-vpc-peering-accepter/variables.tf new file mode 100644 index 0000000..7310e17 --- /dev/null +++ b/modules/aws-vpc-peering-accepter/variables.tf @@ -0,0 +1,57 @@ +variable "name" { + description = "The Name of VPC Peering" + type = string + default = "" +} + +variable "vpc_peer_id" { + description = "VPC peering connection ID" + type = string + default = "" +} + +variable "vpc_peer_ids" { + description = "VPC peering connections IDs for batch operations" + type = list(string) + default = [] + +} + +variable "accepter_all_private_route_table_ids" { + description = "All private route table IDs of accepter VPC route tables" + type = list(string) + default = [] +} + +variable "requester_vpc_cidr_block" { + description = "The CIDR Block of the requester VPC" + type = string + default = "" +} + +variable "accepter_private_route_table_ids" { + description = "The eks route table IDs of accepter VPC route tables" + type = list(string) + default = [] +} + +variable "accepter_public_route_table_ids" { + description = "The eks route table IDs of accepter VPC route tables" + type = list(string) + default = [] +} + +variable "tags" { + description = "Tags for the peering connection" + default = {} + type = map(string) +} + +variable "requester_peer_info" { + description = "Tags for the peering connection" + default = [] + type = list(object({ + requester_cidr = string + peer_id = string + })) +} diff --git a/modules/aws-vpc-peering-requester/README.md b/modules/aws-vpc-peering-requester/README.md new file mode 100644 index 0000000..7bcad39 --- /dev/null +++ b/modules/aws-vpc-peering-requester/README.md @@ -0,0 +1,80 @@ +# vpc-peering-requester + +This module creates VPC Peering request. + +## Usage + +This module has two functions: it creates VPC peering requests and it creates routes which indicate VPC-peering. + +```hcl +module "peering-requester" { + source = "../vpc-peering-requester" + + peer_owner_account_id = "
"allowed_pattern": null,
"data_type": "text",
"description": null,
"overwrite": "false",
"tier": "Standard",
"type": "SecureString"
}
[| no | +| [default\_network\_acl\_ingress](#input\_default\_network\_acl\_ingress) | List of maps of ingress rules to set on the Default Network ACL | `list(map(string))` |
{
"action": "allow",
"cidr_block": "0.0.0.0/0",
"from_port": 0,
"protocol": "-1",
"rule_no": 100,
"to_port": 0
},
{
"action": "allow",
"from_port": 0,
"ipv6_cidr_block": "::/0",
"protocol": "-1",
"rule_no": 101,
"to_port": 0
}
]
[| no | +| [default\_network\_acl\_name](#input\_default\_network\_acl\_name) | Name to be used on the Default Network ACL | `string` | `null` | no | +| [default\_network\_acl\_tags](#input\_default\_network\_acl\_tags) | Additional tags for the Default Network ACL | `map(string)` | `{}` | no | +| [default\_route\_table\_name](#input\_default\_route\_table\_name) | Name to be used on the default route table | `string` | `null` | no | +| [default\_route\_table\_propagating\_vgws](#input\_default\_route\_table\_propagating\_vgws) | List of virtual gateways for propagation | `list(string)` | `[]` | no | +| [default\_route\_table\_routes](#input\_default\_route\_table\_routes) | Configuration block of routes. See https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/default_route_table#route | `list(map(string))` | `[]` | no | +| [default\_route\_table\_tags](#input\_default\_route\_table\_tags) | Additional tags for the default route table | `map(string)` | `{}` | no | +| [default\_security\_group\_egress](#input\_default\_security\_group\_egress) | List of maps of egress rules to set on the default security group | `list(map(string))` | `[]` | no | +| [default\_security\_group\_ingress](#input\_default\_security\_group\_ingress) | List of maps of ingress rules to set on the default security group | `list(map(string))` | `[]` | no | +| [default\_security\_group\_name](#input\_default\_security\_group\_name) | Name to be used on the default security group | `string` | `null` | no | +| [default\_security\_group\_tags](#input\_default\_security\_group\_tags) | Additional tags for the default security group | `map(string)` | `{}` | no | +| [default\_vpc\_enable\_classiclink](#input\_default\_vpc\_enable\_classiclink) | [DEPRECATED](https://github.com/hashicorp/terraform/issues/31730) Should be true to enable ClassicLink in the Default VPC | `bool` | `false` | no | +| [default\_vpc\_enable\_dns\_hostnames](#input\_default\_vpc\_enable\_dns\_hostnames) | Should be true to enable DNS hostnames in the Default VPC | `bool` | `false` | no | +| [default\_vpc\_enable\_dns\_support](#input\_default\_vpc\_enable\_dns\_support) | Should be true to enable DNS support in the Default VPC | `bool` | `true` | no | +| [default\_vpc\_name](#input\_default\_vpc\_name) | Name to be used on the Default VPC | `string` | `null` | no | +| [default\_vpc\_tags](#input\_default\_vpc\_tags) | Additional tags for the Default VPC | `map(string)` | `{}` | no | +| [dhcp\_options\_domain\_name](#input\_dhcp\_options\_domain\_name) | Specifies DNS name for DHCP options set (requires enable\_dhcp\_options set to true) | `string` | `""` | no | +| [dhcp\_options\_domain\_name\_servers](#input\_dhcp\_options\_domain\_name\_servers) | Specify a list of DNS server addresses for DHCP options set, default to AWS provided (requires enable\_dhcp\_options set to true) | `list(string)` |
{
"action": "allow",
"cidr_block": "0.0.0.0/0",
"from_port": 0,
"protocol": "-1",
"rule_no": 100,
"to_port": 0
},
{
"action": "allow",
"from_port": 0,
"ipv6_cidr_block": "::/0",
"protocol": "-1",
"rule_no": 101,
"to_port": 0
}
]
[| no | +| [dhcp\_options\_netbios\_name\_servers](#input\_dhcp\_options\_netbios\_name\_servers) | Specify a list of netbios servers for DHCP options set (requires enable\_dhcp\_options set to true) | `list(string)` | `[]` | no | +| [dhcp\_options\_netbios\_node\_type](#input\_dhcp\_options\_netbios\_node\_type) | Specify netbios node\_type for DHCP options set (requires enable\_dhcp\_options set to true) | `string` | `""` | no | +| [dhcp\_options\_ntp\_servers](#input\_dhcp\_options\_ntp\_servers) | Specify a list of NTP servers for DHCP options set (requires enable\_dhcp\_options set to true) | `list(string)` | `[]` | no | +| [dhcp\_options\_tags](#input\_dhcp\_options\_tags) | Additional tags for the DHCP option set (requires enable\_dhcp\_options set to true) | `map(string)` | `{}` | no | +| [enable\_classiclink](#input\_enable\_classiclink) | [DEPRECATED](https://github.com/hashicorp/terraform/issues/31730) Should be true to enable ClassicLink for the VPC. Only valid in regions and accounts that support EC2 Classic. | `bool` | `null` | no | +| [enable\_classiclink\_dns\_support](#input\_enable\_classiclink\_dns\_support) | [DEPRECATED](https://github.com/hashicorp/terraform/issues/31730) Should be true to enable ClassicLink DNS Support for the VPC. Only valid in regions and accounts that support EC2 Classic. | `bool` | `null` | no | +| [enable\_dhcp\_options](#input\_enable\_dhcp\_options) | Should be true if you want to specify a DHCP options set with a custom domain name, DNS servers, NTP servers, netbios servers, and/or netbios server type | `bool` | `false` | no | +| [enable\_dns\_hostnames](#input\_enable\_dns\_hostnames) | Should be true to enable DNS hostnames in the VPC | `bool` | `false` | no | +| [enable\_dns\_support](#input\_enable\_dns\_support) | Should be true to enable DNS support in the VPC | `bool` | `true` | no | +| [enable\_flow\_log](#input\_enable\_flow\_log) | Whether or not to enable VPC Flow Logs | `bool` | `false` | no | +| [enable\_ipv6](#input\_enable\_ipv6) | Requests an Amazon-provided IPv6 CIDR block with a /56 prefix length for the VPC. You cannot specify the range of IP addresses, or the size of the CIDR block. | `bool` | `false` | no | +| [enable\_nat\_gateway](#input\_enable\_nat\_gateway) | Should be true if you want to provision NAT Gateways for each of your private networks | `bool` | `false` | no | +| [enable\_nat\_gateway\_for\_db](#input\_enable\_nat\_gateway\_for\_db) | Controls if nat gateway for db should be enabled | `bool` | `true` | no | +| [external\_nat\_ip\_ids](#input\_external\_nat\_ip\_ids) | List of EIP IDs to be assigned to the NAT Gateways (used in combination with reuse\_nat\_ips) | `list(string)` | `[]` | no | +| [external\_nat\_ips](#input\_external\_nat\_ips) | List of EIPs to be used for `nat_public_ips` output (used in combination with reuse\_nat\_ips and external\_nat\_ip\_ids) | `list(string)` | `[]` | no | +| [flow\_log\_cloudwatch\_iam\_role\_arn](#input\_flow\_log\_cloudwatch\_iam\_role\_arn) | The ARN for the IAM role that's used to post flow logs to a CloudWatch Logs log group. When flow\_log\_destination\_arn is set to ARN of Cloudwatch Logs, this argument needs to be provided. | `string` | `""` | no | +| [flow\_log\_cloudwatch\_log\_group\_kms\_key\_id](#input\_flow\_log\_cloudwatch\_log\_group\_kms\_key\_id) | The ARN of the KMS Key to use when encrypting log data for VPC flow logs. | `string` | `null` | no | +| [flow\_log\_cloudwatch\_log\_group\_name\_prefix](#input\_flow\_log\_cloudwatch\_log\_group\_name\_prefix) | Specifies the name prefix of CloudWatch Log Group for VPC flow logs. | `string` | `"/aws/vpc-flow-log/"` | no | +| [flow\_log\_cloudwatch\_log\_group\_retention\_in\_days](#input\_flow\_log\_cloudwatch\_log\_group\_retention\_in\_days) | Specifies the number of days you want to retain log events in the specified log group for VPC flow logs. | `number` | `null` | no | +| [flow\_log\_destination\_arn](#input\_flow\_log\_destination\_arn) | The ARN of the CloudWatch log group or S3 bucket where VPC Flow Logs will be pushed. If this ARN is a S3 bucket the appropriate permissions need to be set on that bucket's policy. When create\_flow\_log\_cloudwatch\_log\_group is set to false this argument must be provided. | `string` | `""` | no | +| [flow\_log\_destination\_type](#input\_flow\_log\_destination\_type) | Type of flow log destination. Can be s3 or cloud-watch-logs. | `string` | `"cloud-watch-logs"` | no | +| [flow\_log\_file\_format](#input\_flow\_log\_file\_format) | (Optional) The format for the flow log. Valid values: `plain-text`, `parquet`. | `string` | `"plain-text"` | no | +| [flow\_log\_hive\_compatible\_partitions](#input\_flow\_log\_hive\_compatible\_partitions) | (Optional) Indicates whether to use Hive-compatible prefixes for flow logs stored in Amazon S3. | `bool` | `false` | no | +| [flow\_log\_log\_format](#input\_flow\_log\_log\_format) | The fields to include in the flow log record, in the order in which they should appear. | `string` | `null` | no | +| [flow\_log\_max\_aggregation\_interval](#input\_flow\_log\_max\_aggregation\_interval) | The maximum interval of time during which a flow of packets is captured and aggregated into a flow log record. Valid Values: `60` seconds or `600` seconds. | `number` | `600` | no | +| [flow\_log\_per\_hour\_partition](#input\_flow\_log\_per\_hour\_partition) | (Optional) Indicates whether to partition the flow log per hour. This reduces the cost and response time for queries. | `bool` | `false` | no | +| [flow\_log\_traffic\_type](#input\_flow\_log\_traffic\_type) | The type of traffic to capture. Valid values: ACCEPT, REJECT, ALL. | `string` | `"ALL"` | no | +| [igw\_tags](#input\_igw\_tags) | Additional tags for the internet gateway | `map(string)` | `{}` | no | +| [instance\_tenancy](#input\_instance\_tenancy) | A tenancy option for instances launched into the VPC | `string` | `"default"` | no | +| [manage\_default\_network\_acl](#input\_manage\_default\_network\_acl) | Should be true to adopt and manage Default Network ACL | `bool` | `false` | no | +| [manage\_default\_route\_table](#input\_manage\_default\_route\_table) | Should be true to manage default route table | `bool` | `false` | no | +| [manage\_default\_security\_group](#input\_manage\_default\_security\_group) | Should be true to adopt and manage default security group | `bool` | `false` | no | +| [manage\_default\_vpc](#input\_manage\_default\_vpc) | Should be true to adopt and manage Default VPC | `bool` | `false` | no | +| [map\_public\_ip\_on\_launch](#input\_map\_public\_ip\_on\_launch) | Should be false if you do not want to auto-assign public IP on launch | `bool` | `true` | no | +| [name](#input\_name) | Name to be used on all the resources as identifier | `string` | `""` | no | +| [nat\_eip\_tags](#input\_nat\_eip\_tags) | Additional tags for the NAT EIP | `map(string)` | `{}` | no | +| [nat\_gateway\_destination\_cidr\_block](#input\_nat\_gateway\_destination\_cidr\_block) | Used to pass a custom destination route for private NAT Gateway. If not specified, the default 0.0.0.0/0 is used as a destination route. | `string` | `"0.0.0.0/0"` | no | +| [nat\_gateway\_tags](#input\_nat\_gateway\_tags) | Additional tags for the NAT gateways | `map(string)` | `{}` | no | +| [one\_nat\_gateway\_per\_az](#input\_one\_nat\_gateway\_per\_az) | Should be true if you want only one NAT Gateway per availability zone. Requires `var.azs` to be set, and the number of `public_subnets` created to be greater than or equal to the number of availability zones specified in `var.azs`. | `bool` | `false` | no | +| [private\_acl\_tags](#input\_private\_acl\_tags) | Additional tags for the private subnets network ACL | `map(string)` | `{}` | no | +| [private\_dedicated\_network\_acl](#input\_private\_dedicated\_network\_acl) | Whether to use dedicated network ACL (not default) and custom rules for private subnets | `bool` | `false` | no | +| [private\_inbound\_acl\_rules](#input\_private\_inbound\_acl\_rules) | Private subnets inbound network ACLs | `list(map(string))` |
"AmazonProvidedDNS"
]
[| no | +| [private\_outbound\_acl\_rules](#input\_private\_outbound\_acl\_rules) | Private subnets outbound network ACLs | `list(map(string))` |
{
"cidr_block": "0.0.0.0/0",
"from_port": 0,
"protocol": "-1",
"rule_action": "allow",
"rule_number": 100,
"to_port": 0
}
]
[| no | +| [private\_route\_table\_tags](#input\_private\_route\_table\_tags) | Additional tags for the private route tables | `map(string)` | `{}` | no | +| [private\_subnet\_assign\_ipv6\_address\_on\_creation](#input\_private\_subnet\_assign\_ipv6\_address\_on\_creation) | Assign IPv6 address on private subnet, must be disabled to change IPv6 CIDRs. This is the IPv6 equivalent of map\_public\_ip\_on\_launch | `bool` | `null` | no | +| [private\_subnet\_ipv6\_prefixes](#input\_private\_subnet\_ipv6\_prefixes) | Assigns IPv6 private subnet id based on the Amazon provided /56 prefix base 10 integer (0-256). Must be of equal length to the corresponding IPv4 subnet list | `list(string)` | `[]` | no | +| [private\_subnet\_suffix](#input\_private\_subnet\_suffix) | Suffix to append to private subnets name | `string` | `"private"` | no | +| [private\_subnet\_tags](#input\_private\_subnet\_tags) | Additional tags for the private subnets | `map(string)` | `{}` | no | +| [private\_subnets](#input\_private\_subnets) | n/a | `list(map(string))` |
{
"cidr_block": "0.0.0.0/0",
"from_port": 0,
"protocol": "-1",
"rule_action": "allow",
"rule_number": 100,
"to_port": 0
}
]
[| no | +| [propagate\_private\_route\_tables\_vgw](#input\_propagate\_private\_route\_tables\_vgw) | Should be true if you want route table propagation | `bool` | `false` | no | +| [propagate\_public\_route\_tables\_vgw](#input\_propagate\_public\_route\_tables\_vgw) | Should be true if you want route table propagation | `bool` | `false` | no | +| [public\_acl\_tags](#input\_public\_acl\_tags) | Additional tags for the public subnets network ACL | `map(string)` | `{}` | no | +| [public\_dedicated\_network\_acl](#input\_public\_dedicated\_network\_acl) | Whether to use dedicated network ACL (not default) and custom rules for public subnets | `bool` | `false` | no | +| [public\_inbound\_acl\_rules](#input\_public\_inbound\_acl\_rules) | Public subnets inbound network ACLs | `list(map(string))` |
{
"availability_zone": "us-east-1a",
"cidr_block": "10.0.1.0/24",
"name": "subnet-1"
},
{
"availability_zone": "us-east-1b",
"cidr_block": "10.0.2.0/24",
"name": "subnet-2"
}
]
[| no | +| [public\_outbound\_acl\_rules](#input\_public\_outbound\_acl\_rules) | Public subnets outbound network ACLs | `list(map(string))` |
{
"cidr_block": "0.0.0.0/0",
"from_port": 0,
"protocol": "-1",
"rule_action": "allow",
"rule_number": 100,
"to_port": 0
}
]
[| no | +| [public\_route\_table\_tags](#input\_public\_route\_table\_tags) | Additional tags for the public route tables | `map(string)` | `{}` | no | +| [public\_subnet\_assign\_ipv6\_address\_on\_creation](#input\_public\_subnet\_assign\_ipv6\_address\_on\_creation) | Assign IPv6 address on public subnet, must be disabled to change IPv6 CIDRs. This is the IPv6 equivalent of map\_public\_ip\_on\_launch | `bool` | `null` | no | +| [public\_subnet\_ipv6\_prefixes](#input\_public\_subnet\_ipv6\_prefixes) | Assigns IPv6 public subnet id based on the Amazon provided /56 prefix base 10 integer (0-256). Must be of equal length to the corresponding IPv4 subnet list | `list(string)` | `[]` | no | +| [public\_subnet\_suffix](#input\_public\_subnet\_suffix) | Suffix to append to public subnets name | `string` | `"public"` | no | +| [public\_subnet\_tags](#input\_public\_subnet\_tags) | Additional tags for the public subnets | `map(string)` | `{}` | no | +| [public\_subnets](#input\_public\_subnets) | A list of public subnets inside the VPC | `list(string)` | `[]` | no | +| [reuse\_nat\_ips](#input\_reuse\_nat\_ips) | Should be true if you don't want EIPs to be created for your NAT Gateways and will instead pass them in via the 'external\_nat\_ip\_ids' variable | `bool` | `false` | no | +| [secondary\_cidr\_blocks](#input\_secondary\_cidr\_blocks) | List of secondary CIDR blocks to associate with the VPC to extend the IP Address pool | `list(string)` | `[]` | no | +| [single\_nat\_gateway](#input\_single\_nat\_gateway) | Should be true if you want to provision a single shared NAT Gateway across all of your private networks | `bool` | `false` | no | +| [tags](#input\_tags) | A map of tags to add to all resources | `map(string)` | `{}` | no | +| [vpc\_flow\_log\_permissions\_boundary](#input\_vpc\_flow\_log\_permissions\_boundary) | The ARN of the Permissions Boundary for the VPC Flow Log IAM Role | `string` | `null` | no | +| [vpc\_flow\_log\_tags](#input\_vpc\_flow\_log\_tags) | Additional tags for the VPC Flow Logs | `map(string)` | `{}` | no | +| [vpc\_tags](#input\_vpc\_tags) | Additional tags for the VPC | `map(string)` | `{}` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [all\_private\_route\_table\_ids](#output\_all\_private\_route\_table\_ids) | List of IDs of all private route tables | +| [all\_private\_subnets](#output\_all\_private\_subnets) | n/a | +| [azs](#output\_azs) | A list of availability zones specified as argument to this module | +| [default\_network\_acl\_id](#output\_default\_network\_acl\_id) | The ID of the default network ACL | +| [default\_route\_table\_id](#output\_default\_route\_table\_id) | The ID of the default route table | +| [default\_security\_group\_id](#output\_default\_security\_group\_id) | The ID of the security group created by default on VPC creation | +| [dhcp\_options\_id](#output\_dhcp\_options\_id) | The ID of the DHCP options | +| [egress\_only\_internet\_gateway\_id](#output\_egress\_only\_internet\_gateway\_id) | The ID of the egress only Internet Gateway | +| [igw\_arn](#output\_igw\_arn) | The ARN of the Internet Gateway | +| [igw\_id](#output\_igw\_id) | The ID of the Internet Gateway | +| [name](#output\_name) | The name of the VPC specified as argument to this module | +| [nat\_ids](#output\_nat\_ids) | List of allocation ID of Elastic IPs created for AWS NAT Gateway | +| [nat\_public\_ips](#output\_nat\_public\_ips) | List of public Elastic IPs created for AWS NAT Gateway | +| [natgw\_ids](#output\_natgw\_ids) | List of NAT Gateway IDs | +| [private\_ipv6\_egress\_route\_ids](#output\_private\_ipv6\_egress\_route\_ids) | List of IDs of the ipv6 egress route | +| [private\_nat\_gateway\_route\_ids](#output\_private\_nat\_gateway\_route\_ids) | List of IDs of the private nat gateway route | +| [private\_network\_acl\_arn](#output\_private\_network\_acl\_arn) | ARN of the private network ACL | +| [private\_network\_acl\_id](#output\_private\_network\_acl\_id) | ID of the private network ACL | +| [private\_route\_table\_association\_ids](#output\_private\_route\_table\_association\_ids) | List of IDs of the private route table association | +| [private\_route\_table\_ids](#output\_private\_route\_table\_ids) | List of IDs of private route tables | +| [private\_subnet\_arns](#output\_private\_subnet\_arns) | List of ARNs of private subnets | +| [private\_subnets](#output\_private\_subnets) | List of IDs of private subnets | +| [private\_subnets\_cidr\_blocks](#output\_private\_subnets\_cidr\_blocks) | List of cidr\_blocks of private subnets | +| [private\_subnets\_ipv6\_cidr\_blocks](#output\_private\_subnets\_ipv6\_cidr\_blocks) | List of IPv6 cidr\_blocks of private subnets in an IPv6 enabled VPC | +| [public\_internet\_gateway\_ipv6\_route\_id](#output\_public\_internet\_gateway\_ipv6\_route\_id) | ID of the IPv6 internet gateway route | +| [public\_internet\_gateway\_route\_id](#output\_public\_internet\_gateway\_route\_id) | ID of the internet gateway route | +| [public\_network\_acl\_arn](#output\_public\_network\_acl\_arn) | ARN of the public network ACL | +| [public\_network\_acl\_id](#output\_public\_network\_acl\_id) | ID of the public network ACL | +| [public\_route\_table\_association\_ids](#output\_public\_route\_table\_association\_ids) | List of IDs of the public route table association | +| [public\_route\_table\_ids](#output\_public\_route\_table\_ids) | List of IDs of public route tables | +| [public\_subnet\_arns](#output\_public\_subnet\_arns) | List of ARNs of public subnets | +| [public\_subnet\_ids](#output\_public\_subnet\_ids) | ID of the public subnets | +| [public\_subnets](#output\_public\_subnets) | List of IDs of public subnets | +| [public\_subnets\_cidr\_blocks](#output\_public\_subnets\_cidr\_blocks) | List of cidr\_blocks of public subnets | +| [public\_subnets\_ipv6\_cidr\_blocks](#output\_public\_subnets\_ipv6\_cidr\_blocks) | List of IPv6 cidr\_blocks of public subnets in an IPv6 enabled VPC | +| [vpc\_arn](#output\_vpc\_arn) | The ARN of the VPC | +| [vpc\_cidr\_block](#output\_vpc\_cidr\_block) | The CIDR block of the VPC | +| [vpc\_enable\_dns\_hostnames](#output\_vpc\_enable\_dns\_hostnames) | Whether or not the VPC has DNS hostname support | +| [vpc\_enable\_dns\_support](#output\_vpc\_enable\_dns\_support) | Whether or not the VPC has DNS support | +| [vpc\_flow\_log\_cloudwatch\_iam\_role\_arn](#output\_vpc\_flow\_log\_cloudwatch\_iam\_role\_arn) | The ARN of the IAM role used when pushing logs to Cloudwatch log group | +| [vpc\_flow\_log\_destination\_arn](#output\_vpc\_flow\_log\_destination\_arn) | The ARN of the destination for VPC Flow Logs | +| [vpc\_flow\_log\_destination\_type](#output\_vpc\_flow\_log\_destination\_type) | The type of the destination for VPC Flow Logs | +| [vpc\_flow\_log\_id](#output\_vpc\_flow\_log\_id) | The ID of the Flow Log resource | +| [vpc\_id](#output\_vpc\_id) | The ID of the VPC | +| [vpc\_instance\_tenancy](#output\_vpc\_instance\_tenancy) | Tenancy of instances spin up within VPC | +| [vpc\_ipv6\_association\_id](#output\_vpc\_ipv6\_association\_id) | The association ID for the IPv6 CIDR block | +| [vpc\_ipv6\_cidr\_block](#output\_vpc\_ipv6\_cidr\_block) | The IPv6 CIDR block | +| [vpc\_main\_route\_table\_id](#output\_vpc\_main\_route\_table\_id) | The ID of the main route table associated with this VPC | +| [vpc\_owner\_id](#output\_vpc\_owner\_id) | The ID of the AWS account that owns the VPC | +| [vpc\_secondary\_cidr\_blocks](#output\_vpc\_secondary\_cidr\_blocks) | List of secondary CIDR blocks of the VPC | + diff --git a/modules/aws-vpc/main.tf b/modules/aws-vpc/main.tf new file mode 100644 index 0000000..8e74c80 --- /dev/null +++ b/modules/aws-vpc/main.tf @@ -0,0 +1,563 @@ +locals { + max_subnet_length = max( + length(var.private_subnets), + ) + nat_gateway_count = var.single_nat_gateway ? 1 : var.one_nat_gateway_per_az ? length(var.azs) : local.max_subnet_length + + # Use `local.vpc_id` to give a hint to Terraform that subnets should be deleted before secondary CIDR blocks can be free! + vpc_id = try(aws_vpc_ipv4_cidr_block_association.this[0].vpc_id, aws_vpc.this[0].id, "") + + create_vpc = var.create_vpc + + +} + + + + + + +################################################################################ +# VPC +################################################################################ + +resource "aws_vpc" "this" { + count = local.create_vpc ? 1 : 0 + + cidr_block = var.cidr + instance_tenancy = var.instance_tenancy + enable_dns_hostnames = var.enable_dns_hostnames + enable_dns_support = var.enable_dns_support + assign_generated_ipv6_cidr_block = var.enable_ipv6 + + tags = merge( + { "Name" = var.name }, + var.tags, + var.vpc_tags, + ) +} + +resource "aws_vpc_ipv4_cidr_block_association" "this" { + count = local.create_vpc && length(var.secondary_cidr_blocks) > 0 ? length(var.secondary_cidr_blocks) : 0 + + # Do not turn this into `local.vpc_id` + vpc_id = aws_vpc.this[0].id + + cidr_block = element(var.secondary_cidr_blocks, count.index) +} + +resource "aws_default_security_group" "this" { + count = local.create_vpc && var.manage_default_security_group ? 1 : 0 + + vpc_id = aws_vpc.this[0].id + + dynamic "ingress" { + for_each = var.default_security_group_ingress + content { + self = lookup(ingress.value, "self", null) + cidr_blocks = compact(split(",", lookup(ingress.value, "cidr_blocks", ""))) + ipv6_cidr_blocks = compact(split(",", lookup(ingress.value, "ipv6_cidr_blocks", ""))) + prefix_list_ids = compact(split(",", lookup(ingress.value, "prefix_list_ids", ""))) + security_groups = compact(split(",", lookup(ingress.value, "security_groups", ""))) + description = lookup(ingress.value, "description", null) + from_port = lookup(ingress.value, "from_port", 0) + to_port = lookup(ingress.value, "to_port", 0) + protocol = lookup(ingress.value, "protocol", "-1") + } + } + + dynamic "egress" { + for_each = var.default_security_group_egress + content { + self = lookup(egress.value, "self", null) + cidr_blocks = compact(split(",", lookup(egress.value, "cidr_blocks", ""))) + ipv6_cidr_blocks = compact(split(",", lookup(egress.value, "ipv6_cidr_blocks", ""))) + prefix_list_ids = compact(split(",", lookup(egress.value, "prefix_list_ids", ""))) + security_groups = compact(split(",", lookup(egress.value, "security_groups", ""))) + description = lookup(egress.value, "description", null) + from_port = lookup(egress.value, "from_port", 0) + to_port = lookup(egress.value, "to_port", 0) + protocol = lookup(egress.value, "protocol", "-1") + } + } + + tags = merge( + { "Name" = coalesce(var.default_security_group_name, var.name) }, + var.tags, + var.default_security_group_tags, + ) +} + +################################################################################ +# DHCP Options Set +################################################################################ + +resource "aws_vpc_dhcp_options" "this" { + count = local.create_vpc && var.enable_dhcp_options ? 1 : 0 + + domain_name = var.dhcp_options_domain_name + domain_name_servers = var.dhcp_options_domain_name_servers + ntp_servers = var.dhcp_options_ntp_servers + netbios_name_servers = var.dhcp_options_netbios_name_servers + netbios_node_type = var.dhcp_options_netbios_node_type + + tags = merge( + { "Name" = var.name }, + var.tags, + var.dhcp_options_tags, + ) +} + +resource "aws_vpc_dhcp_options_association" "this" { + count = local.create_vpc && var.enable_dhcp_options ? 1 : 0 + + vpc_id = local.vpc_id + dhcp_options_id = aws_vpc_dhcp_options.this[0].id +} + +################################################################################ +# Internet Gateway +################################################################################ + +resource "aws_internet_gateway" "this" { + count = local.create_vpc && var.create_igw && length(var.public_subnets) > 0 ? 1 : 0 + + vpc_id = local.vpc_id + + tags = merge( + { "Name" = var.name }, + var.tags, + var.igw_tags, + ) +} + +resource "aws_egress_only_internet_gateway" "this" { + count = local.create_vpc && var.create_egress_only_igw && var.enable_ipv6 && local.max_subnet_length > 0 ? 1 : 0 + + vpc_id = local.vpc_id + + tags = merge( + { "Name" = var.name }, + var.tags, + var.igw_tags, + ) +} + +################################################################################ +# Default route +################################################################################ + +resource "aws_default_route_table" "default" { + count = local.create_vpc && var.manage_default_route_table ? 1 : 0 + + default_route_table_id = aws_vpc.this[0].default_route_table_id + propagating_vgws = var.default_route_table_propagating_vgws + + dynamic "route" { + for_each = var.default_route_table_routes + content { + # One of the following destinations must be provided + cidr_block = route.value.cidr_block + ipv6_cidr_block = lookup(route.value, "ipv6_cidr_block", null) + + # One of the following targets must be provided + egress_only_gateway_id = lookup(route.value, "egress_only_gateway_id", null) + gateway_id = lookup(route.value, "gateway_id", null) + instance_id = lookup(route.value, "instance_id", null) + nat_gateway_id = lookup(route.value, "nat_gateway_id", null) + network_interface_id = lookup(route.value, "network_interface_id", null) + transit_gateway_id = lookup(route.value, "transit_gateway_id", null) + vpc_endpoint_id = lookup(route.value, "vpc_endpoint_id", null) + vpc_peering_connection_id = lookup(route.value, "vpc_peering_connection_id", null) + } + } + + timeouts { + create = "5m" + update = "5m" + } + + tags = merge( + { "Name" = coalesce(var.default_route_table_name, var.name) }, + var.tags, + var.default_route_table_tags, + ) +} + +################################################################################ +# Publiс routes +################################################################################ + +resource "aws_route_table" "public" { + count = local.create_vpc && length(var.public_subnets) > 0 ? 1 : 0 + + vpc_id = local.vpc_id + + tags = merge( + { "Name" = "${var.name}-${var.public_subnet_suffix}" }, + var.tags, + var.public_route_table_tags, + ) +} + +resource "aws_route" "public_internet_gateway" { + count = local.create_vpc && var.create_igw && length(var.public_subnets) > 0 ? 1 : 0 + + route_table_id = aws_route_table.public[0].id + destination_cidr_block = "0.0.0.0/0" + gateway_id = aws_internet_gateway.this[0].id + + timeouts { + create = "5m" + } +} + +resource "aws_route" "public_internet_gateway_ipv6" { + count = local.create_vpc && var.create_igw && var.enable_ipv6 && length(var.public_subnets) > 0 ? 1 : 0 + + route_table_id = aws_route_table.public[0].id + destination_ipv6_cidr_block = "::/0" + gateway_id = aws_internet_gateway.this[0].id +} + + + + + + +################################################################################ +# Private routes +# There are as many routing tables as the number of NAT gateways +################################################################################ + +resource "aws_route_table" "private" { + count = local.create_vpc && var.create_private_subnet_route_table && local.max_subnet_length > 0 ? length(var.private_subnets) : 0 + + vpc_id = local.vpc_id + + tags = merge( + { + "Name" = var.single_nat_gateway ? "${var.name}-${var.private_subnet_suffix}" : "${var.name}-${var.private_subnets[count.index].name}-${var.private_subnets[count.index].availability_zone}" + }, + var.tags, + var.private_route_table_tags, + ) +} + + + +resource "aws_route" "private_nat_gateway" { + # not necessary for now however + # if you only want spesifik subnets to be routed to nat gateway (for private subnets to public internet, put them into private_subnets variable as first elements, e.g: + # create a custom variable like, length of private subnets to be routed to nat gw, let's say give it 2 and put 2 subnets to 0. and 1. element at this private_subnets list and change length(var.private_subnets) to length(givenCount) ) + count = local.create_vpc && var.create_private_subnet_route_table && var.enable_nat_gateway ? length(var.private_subnets) : 0 + + route_table_id = element(aws_route_table.private[*].id, count.index) + destination_cidr_block = var.nat_gateway_destination_cidr_block + nat_gateway_id = element(aws_nat_gateway.this[*].id, count.index) + + timeouts { + create = "5m" + } +} + +resource "aws_route" "private_ipv6_egress" { + count = local.create_vpc && var.create_private_subnet_route_table && var.create_egress_only_igw && var.enable_ipv6 ? length(var.private_subnets) : 0 + + route_table_id = element(aws_route_table.private[*].id, count.index) + destination_ipv6_cidr_block = "::/0" + egress_only_gateway_id = element(aws_egress_only_internet_gateway.this[*].id, 0) +} + + + + + +################################################################################ +# Public subnet +################################################################################ + +resource "aws_subnet" "public" { + count = local.create_vpc && length(var.public_subnets) > 0 && (false == var.one_nat_gateway_per_az || length(var.public_subnets) >= length(var.azs)) ? length(var.public_subnets) : 0 + + vpc_id = local.vpc_id + cidr_block = element(concat(var.public_subnets, [""]), count.index) + availability_zone = length(regexall("^[a-z]{2}-", element(var.azs, count.index))) > 0 ? element(var.azs, count.index) : null + availability_zone_id = length(regexall("^[a-z]{2}-", element(var.azs, count.index))) == 0 ? element(var.azs, count.index) : null + map_public_ip_on_launch = var.map_public_ip_on_launch + assign_ipv6_address_on_creation = var.public_subnet_assign_ipv6_address_on_creation == null ? var.assign_ipv6_address_on_creation : var.public_subnet_assign_ipv6_address_on_creation + + ipv6_cidr_block = var.enable_ipv6 && length(var.public_subnet_ipv6_prefixes) > 0 ? cidrsubnet(aws_vpc.this[0].ipv6_cidr_block, 8, var.public_subnet_ipv6_prefixes[count.index]) : null + + tags = merge( + { + "Name" = format( + "${var.name}-${var.public_subnet_suffix}-%s", + element(var.azs, count.index), + ) + }, + var.tags, + var.public_subnet_tags, + ) +} + +################################################################################ +# Private subnet +################################################################################ + +resource "aws_subnet" "private" { + count = local.create_vpc && length(var.private_subnets) > 0 ? length(var.private_subnets) : 0 + + vpc_id = local.vpc_id + cidr_block = var.private_subnets[count.index].cidr_block + availability_zone = var.private_subnets[count.index].availability_zone + # availability_zone = length(regexall("^[a-z]{2}-", element(var.azs, count.index))) > 0 ? element(var.azs, count.index) : null + # availability_zone_id = length(regexall("^[a-z]{2}-", element(var.azs, count.index))) == 0 ? element(var.azs, count.index) : null + assign_ipv6_address_on_creation = var.private_subnet_assign_ipv6_address_on_creation == null ? var.assign_ipv6_address_on_creation : var.private_subnet_assign_ipv6_address_on_creation + + ipv6_cidr_block = var.enable_ipv6 && length(var.private_subnet_ipv6_prefixes) > 0 ? cidrsubnet(aws_vpc.this[0].ipv6_cidr_block, 8, var.private_subnet_ipv6_prefixes[count.index]) : null + + tags = merge( + { + "Name" = "${var.private_subnets[count.index].name}-${var.private_subnets[count.index].availability_zone}", + + }, + var.tags, + var.private_subnet_tags, + try(var.private_subnets[count.index].additional_tags, {}) + ) +} + + + +################################################################################ +# Default Network ACLs +################################################################################ + +resource "aws_default_network_acl" "this" { + count = local.create_vpc && var.manage_default_network_acl ? 1 : 0 + + default_network_acl_id = aws_vpc.this[0].default_network_acl_id + + # subnet_ids is using lifecycle ignore_changes, so it is not necessary to list + # any explicitly. See https://github.com/terraform-aws-modules/terraform-aws-vpc/issues/736. + subnet_ids = null + + dynamic "ingress" { + for_each = var.default_network_acl_ingress + content { + action = ingress.value.action + cidr_block = lookup(ingress.value, "cidr_block", null) + from_port = ingress.value.from_port + icmp_code = lookup(ingress.value, "icmp_code", null) + icmp_type = lookup(ingress.value, "icmp_type", null) + ipv6_cidr_block = lookup(ingress.value, "ipv6_cidr_block", null) + protocol = ingress.value.protocol + rule_no = ingress.value.rule_no + to_port = ingress.value.to_port + } + } + dynamic "egress" { + for_each = var.default_network_acl_egress + content { + action = egress.value.action + cidr_block = lookup(egress.value, "cidr_block", null) + from_port = egress.value.from_port + icmp_code = lookup(egress.value, "icmp_code", null) + icmp_type = lookup(egress.value, "icmp_type", null) + ipv6_cidr_block = lookup(egress.value, "ipv6_cidr_block", null) + protocol = egress.value.protocol + rule_no = egress.value.rule_no + to_port = egress.value.to_port + } + } + + tags = merge( + { "Name" = coalesce(var.default_network_acl_name, var.name) }, + var.tags, + var.default_network_acl_tags, + ) + + lifecycle { + ignore_changes = [subnet_ids] + } +} + + +################################################################################ +# Public Network ACLs +################################################################################ + +resource "aws_network_acl" "public" { + count = local.create_vpc && var.public_dedicated_network_acl && length(var.public_subnets) > 0 ? 1 : 0 + + vpc_id = local.vpc_id + subnet_ids = aws_subnet.public[*].id + + tags = merge( + { "Name" = "${var.name}-${var.public_subnet_suffix}" }, + var.tags, + var.public_acl_tags, + ) +} + +resource "aws_network_acl_rule" "public_inbound" { + count = local.create_vpc && var.public_dedicated_network_acl && length(var.public_subnets) > 0 ? length(var.public_inbound_acl_rules) : 0 + + network_acl_id = aws_network_acl.public[0].id + + egress = false + rule_number = var.public_inbound_acl_rules[count.index]["rule_number"] + rule_action = var.public_inbound_acl_rules[count.index]["rule_action"] + from_port = lookup(var.public_inbound_acl_rules[count.index], "from_port", null) + to_port = lookup(var.public_inbound_acl_rules[count.index], "to_port", null) + icmp_code = lookup(var.public_inbound_acl_rules[count.index], "icmp_code", null) + icmp_type = lookup(var.public_inbound_acl_rules[count.index], "icmp_type", null) + protocol = var.public_inbound_acl_rules[count.index]["protocol"] + cidr_block = lookup(var.public_inbound_acl_rules[count.index], "cidr_block", null) + ipv6_cidr_block = lookup(var.public_inbound_acl_rules[count.index], "ipv6_cidr_block", null) +} + +resource "aws_network_acl_rule" "public_outbound" { + count = local.create_vpc && var.public_dedicated_network_acl && length(var.public_subnets) > 0 ? length(var.public_outbound_acl_rules) : 0 + + network_acl_id = aws_network_acl.public[0].id + + egress = true + rule_number = var.public_outbound_acl_rules[count.index]["rule_number"] + rule_action = var.public_outbound_acl_rules[count.index]["rule_action"] + from_port = lookup(var.public_outbound_acl_rules[count.index], "from_port", null) + to_port = lookup(var.public_outbound_acl_rules[count.index], "to_port", null) + icmp_code = lookup(var.public_outbound_acl_rules[count.index], "icmp_code", null) + icmp_type = lookup(var.public_outbound_acl_rules[count.index], "icmp_type", null) + protocol = var.public_outbound_acl_rules[count.index]["protocol"] + cidr_block = lookup(var.public_outbound_acl_rules[count.index], "cidr_block", null) + ipv6_cidr_block = lookup(var.public_outbound_acl_rules[count.index], "ipv6_cidr_block", null) +} + +################################################################################ +# Private Network ACLs +################################################################################ + +resource "aws_network_acl" "private" { + count = local.create_vpc && var.private_dedicated_network_acl && length(var.private_subnets) > 0 ? 1 : 0 + + vpc_id = local.vpc_id + subnet_ids = aws_subnet.private[*].id + + tags = merge( + { "Name" = "${var.name}-${var.private_subnet_suffix}" }, + var.tags, + var.private_acl_tags, + ) +} + +resource "aws_network_acl_rule" "private_inbound" { + count = local.create_vpc && var.private_dedicated_network_acl && length(var.private_subnets) > 0 ? length(var.private_inbound_acl_rules) : 0 + + network_acl_id = aws_network_acl.private[0].id + + egress = false + rule_number = var.private_inbound_acl_rules[count.index]["rule_number"] + rule_action = var.private_inbound_acl_rules[count.index]["rule_action"] + from_port = lookup(var.private_inbound_acl_rules[count.index], "from_port", null) + to_port = lookup(var.private_inbound_acl_rules[count.index], "to_port", null) + icmp_code = lookup(var.private_inbound_acl_rules[count.index], "icmp_code", null) + icmp_type = lookup(var.private_inbound_acl_rules[count.index], "icmp_type", null) + protocol = var.private_inbound_acl_rules[count.index]["protocol"] + cidr_block = lookup(var.private_inbound_acl_rules[count.index], "cidr_block", null) + ipv6_cidr_block = lookup(var.private_inbound_acl_rules[count.index], "ipv6_cidr_block", null) +} + +resource "aws_network_acl_rule" "private_outbound" { + count = local.create_vpc && var.private_dedicated_network_acl && length(var.private_subnets) > 0 ? length(var.private_outbound_acl_rules) : 0 + + network_acl_id = aws_network_acl.private[0].id + + egress = true + rule_number = var.private_outbound_acl_rules[count.index]["rule_number"] + rule_action = var.private_outbound_acl_rules[count.index]["rule_action"] + from_port = lookup(var.private_outbound_acl_rules[count.index], "from_port", null) + to_port = lookup(var.private_outbound_acl_rules[count.index], "to_port", null) + icmp_code = lookup(var.private_outbound_acl_rules[count.index], "icmp_code", null) + icmp_type = lookup(var.private_outbound_acl_rules[count.index], "icmp_type", null) + protocol = var.private_outbound_acl_rules[count.index]["protocol"] + cidr_block = lookup(var.private_outbound_acl_rules[count.index], "cidr_block", null) + ipv6_cidr_block = lookup(var.private_outbound_acl_rules[count.index], "ipv6_cidr_block", null) +} + + +################################################################################ +# NAT Gateway +################################################################################ + +locals { + nat_gateway_ips = var.reuse_nat_ips ? var.external_nat_ip_ids : try(aws_eip.nat[*].id, []) +} + +resource "aws_eip" "nat" { + count = local.create_vpc && var.enable_nat_gateway && false == var.reuse_nat_ips ? local.nat_gateway_count : 0 + + vpc = true + + tags = merge( + { + "Name" = format( + "${var.name}-%s", + element(var.azs, var.single_nat_gateway ? 0 : count.index), + ) + }, + var.tags, + var.nat_eip_tags, + ) +} + +resource "aws_nat_gateway" "this" { + count = local.create_vpc && var.enable_nat_gateway ? local.nat_gateway_count : 0 + + allocation_id = element( + local.nat_gateway_ips, + var.single_nat_gateway ? 0 : count.index, + ) + subnet_id = element( + aws_subnet.public[*].id, + var.single_nat_gateway ? 0 : count.index, + ) + + tags = merge( + { + "Name" = format( + "${var.name}-%s", + element(var.azs, var.single_nat_gateway ? 0 : count.index), + ) + }, + var.tags, + var.nat_gateway_tags, + ) + + depends_on = [aws_internet_gateway.this] +} + + + +################################################################################ +# Route table association +################################################################################ + +resource "aws_route_table_association" "private" { + count = local.create_vpc && length(var.private_subnets) > 0 ? length(var.private_subnets) : 0 + + subnet_id = element(aws_subnet.private[*].id, count.index) + route_table_id = element( + aws_route_table.private[*].id, + var.single_nat_gateway ? 0 : count.index, + ) +} + + +resource "aws_route_table_association" "public" { + count = local.create_vpc && length(var.public_subnets) > 0 ? length(var.public_subnets) : 0 + + subnet_id = element(aws_subnet.public[*].id, count.index) + route_table_id = aws_route_table.public[0].id +} diff --git a/modules/aws-vpc/modules/vpc-endpoints/README.md b/modules/aws-vpc/modules/vpc-endpoints/README.md new file mode 100644 index 0000000..5382aef --- /dev/null +++ b/modules/aws-vpc/modules/vpc-endpoints/README.md @@ -0,0 +1,93 @@ +# AWS VPC Endpoints Terraform sub-module + +Terraform sub-module which creates VPC endpoint resources on AWS. + +## Usage + + +```hcl +module "endpoints" { + + vpc_id = "vpc-12345678" + security_group_ids = ["sg-12345678"] + + endpoints = { + s3 = { + # interface endpoint + service = "s3" + tags = { Name = "s3-vpc-endpoint" } + }, + dynamodb = { + # gateway endpoint + service = "dynamodb" + route_table_ids = ["rt-12322456", "rt-43433343", "rt-11223344"] + tags = { Name = "dynamodb-vpc-endpoint" } + }, + sns = { + service = "sns" + subnet_ids = ["subnet-12345678", "subnet-87654321"] + tags = { Name = "sns-vpc-endpoint" } + }, + sqs = { + service = "sqs" + private_dns_enabled = true + security_group_ids = ["sg-987654321"] + subnet_ids = ["subnet-12345678", "subnet-87654321"] + tags = { Name = "sqs-vpc-endpoint" } + }, + } + + tags = { + Owner = "user" + Environment = "dev" + } +} +``` + +## Examples + +- [Complete-VPC](../../examples/complete-vpc) with VPC Endpoints. + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.28 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 3.28 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_vpc_endpoint.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_endpoint) | resource | +| [aws_vpc_endpoint_service.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/vpc_endpoint_service) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [create](#input\_create) | Determines whether resources will be created | `bool` | `true` | no | +| [endpoints](#input\_endpoints) | A map of interface and/or gateway endpoints containing their properties and configurations | `any` | `{}` | no | +| [security\_group\_ids](#input\_security\_group\_ids) | Default security group IDs to associate with the VPC endpoints | `list(string)` | `[]` | no | +| [subnet\_ids](#input\_subnet\_ids) | Default subnets IDs to associate with the VPC endpoints | `list(string)` | `[]` | no | +| [tags](#input\_tags) | A map of tags to use on all resources | `map(string)` | `{}` | no | +| [timeouts](#input\_timeouts) | Define maximum timeout for creating, updating, and deleting VPC endpoint resources | `map(string)` | `{}` | no | +| [vpc\_id](#input\_vpc\_id) | The ID of the VPC in which the endpoint will be used | `string` | `null` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [endpoints](#output\_endpoints) | Array containing the full resource object and attributes for all endpoints created | + diff --git a/modules/aws-vpc/modules/vpc-endpoints/main.tf b/modules/aws-vpc/modules/vpc-endpoints/main.tf new file mode 100644 index 0000000..b538c7a --- /dev/null +++ b/modules/aws-vpc/modules/vpc-endpoints/main.tf @@ -0,0 +1,42 @@ +################################################################################ +# Endpoint(s) +################################################################################ + +locals { + endpoints = { for k, v in var.endpoints : k => v if var.create && try(v.create, true) } +} + +data "aws_vpc_endpoint_service" "this" { + for_each = local.endpoints + + service = lookup(each.value, "service", null) + service_name = lookup(each.value, "service_name", null) + + filter { + name = "service-type" + values = [lookup(each.value, "service_type", "Interface")] + } +} + +resource "aws_vpc_endpoint" "this" { + for_each = local.endpoints + + vpc_id = var.vpc_id + service_name = data.aws_vpc_endpoint_service.this[each.key].service_name + vpc_endpoint_type = lookup(each.value, "service_type", "Interface") + auto_accept = lookup(each.value, "auto_accept", null) + + security_group_ids = lookup(each.value, "service_type", "Interface") == "Interface" ? length(distinct(concat(var.security_group_ids, lookup(each.value, "security_group_ids", [])))) > 0 ? distinct(concat(var.security_group_ids, lookup(each.value, "security_group_ids", []))) : null : null + subnet_ids = lookup(each.value, "service_type", "Interface") == "Interface" ? distinct(concat(var.subnet_ids, lookup(each.value, "subnet_ids", []))) : null + route_table_ids = lookup(each.value, "service_type", "Interface") == "Gateway" ? lookup(each.value, "route_table_ids", null) : null + policy = lookup(each.value, "policy", null) + private_dns_enabled = lookup(each.value, "service_type", "Interface") == "Interface" ? lookup(each.value, "private_dns_enabled", null) : null + + tags = merge(var.tags, lookup(each.value, "tags", {})) + + timeouts { + create = lookup(var.timeouts, "create", "10m") + update = lookup(var.timeouts, "update", "10m") + delete = lookup(var.timeouts, "delete", "10m") + } +} diff --git a/modules/aws-vpc/modules/vpc-endpoints/outputs.tf b/modules/aws-vpc/modules/vpc-endpoints/outputs.tf new file mode 100644 index 0000000..88aa989 --- /dev/null +++ b/modules/aws-vpc/modules/vpc-endpoints/outputs.tf @@ -0,0 +1,4 @@ +output "endpoints" { + description = "Array containing the full resource object and attributes for all endpoints created" + value = aws_vpc_endpoint.this +} diff --git a/modules/aws-vpc/modules/vpc-endpoints/variables.tf b/modules/aws-vpc/modules/vpc-endpoints/variables.tf new file mode 100644 index 0000000..afcebc3 --- /dev/null +++ b/modules/aws-vpc/modules/vpc-endpoints/variables.tf @@ -0,0 +1,41 @@ +variable "create" { + description = "Determines whether resources will be created" + type = bool + default = true +} + +variable "vpc_id" { + description = "The ID of the VPC in which the endpoint will be used" + type = string + default = null +} + +variable "endpoints" { + description = "A map of interface and/or gateway endpoints containing their properties and configurations" + type = any + default = {} +} + +variable "security_group_ids" { + description = "Default security group IDs to associate with the VPC endpoints" + type = list(string) + default = [] +} + +variable "subnet_ids" { + description = "Default subnets IDs to associate with the VPC endpoints" + type = list(string) + default = [] +} + +variable "tags" { + description = "A map of tags to use on all resources" + type = map(string) + default = {} +} + +variable "timeouts" { + description = "Define maximum timeout for creating, updating, and deleting VPC endpoint resources" + type = map(string) + default = {} +} diff --git a/modules/aws-vpc/modules/vpc-endpoints/versions.tf b/modules/aws-vpc/modules/vpc-endpoints/versions.tf new file mode 100644 index 0000000..ab4d354 --- /dev/null +++ b/modules/aws-vpc/modules/vpc-endpoints/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.28" + } + } +} diff --git a/modules/aws-vpc/outputs.tf b/modules/aws-vpc/outputs.tf new file mode 100644 index 0000000..7196fbf --- /dev/null +++ b/modules/aws-vpc/outputs.tf @@ -0,0 +1,265 @@ +output "vpc_id" { + description = "The ID of the VPC" + value = try(aws_vpc.this[0].id, "") +} + +output "public_subnet_ids" { + description = "ID of the public subnets" + value = try(aws_subnet.public[*].id, []) +} + +output "vpc_arn" { + description = "The ARN of the VPC" + value = try(aws_vpc.this[0].arn, "") +} + +output "vpc_cidr_block" { + description = "The CIDR block of the VPC" + value = try(aws_vpc.this[0].cidr_block, "") +} + +output "default_security_group_id" { + description = "The ID of the security group created by default on VPC creation" + value = try(aws_vpc.this[0].default_security_group_id, "") +} + +output "default_network_acl_id" { + description = "The ID of the default network ACL" + value = try(aws_vpc.this[0].default_network_acl_id, "") +} + +output "default_route_table_id" { + description = "The ID of the default route table" + value = try(aws_vpc.this[0].default_route_table_id, "") +} + +output "vpc_instance_tenancy" { + description = "Tenancy of instances spin up within VPC" + value = try(aws_vpc.this[0].instance_tenancy, "") +} + +output "vpc_enable_dns_support" { + description = "Whether or not the VPC has DNS support" + value = try(aws_vpc.this[0].enable_dns_support, "") +} + +output "vpc_enable_dns_hostnames" { + description = "Whether or not the VPC has DNS hostname support" + value = try(aws_vpc.this[0].enable_dns_hostnames, "") +} + +output "vpc_main_route_table_id" { + description = "The ID of the main route table associated with this VPC" + value = try(aws_vpc.this[0].main_route_table_id, "") +} + +output "vpc_ipv6_association_id" { + description = "The association ID for the IPv6 CIDR block" + value = try(aws_vpc.this[0].ipv6_association_id, "") +} + +output "vpc_ipv6_cidr_block" { + description = "The IPv6 CIDR block" + value = try(aws_vpc.this[0].ipv6_cidr_block, "") +} + +output "vpc_secondary_cidr_blocks" { + description = "List of secondary CIDR blocks of the VPC" + value = compact(aws_vpc_ipv4_cidr_block_association.this[*].cidr_block) +} + +output "vpc_owner_id" { + description = "The ID of the AWS account that owns the VPC" + value = try(aws_vpc.this[0].owner_id, "") +} + +output "private_subnets" { + description = "List of IDs of private subnets" + value = aws_subnet.private[*].id +} + +output "private_subnet_arns" { + description = "List of ARNs of private subnets" + value = aws_subnet.private[*].arn +} + +output "private_subnets_cidr_blocks" { + description = "List of cidr_blocks of private subnets" + value = compact(aws_subnet.private[*].cidr_block) +} + +output "private_subnets_ipv6_cidr_blocks" { + description = "List of IPv6 cidr_blocks of private subnets in an IPv6 enabled VPC" + value = compact(aws_subnet.private[*].ipv6_cidr_block) +} + +output "public_subnets" { + description = "List of IDs of public subnets" + value = aws_subnet.public[*].id +} + +output "public_subnet_arns" { + description = "List of ARNs of public subnets" + value = aws_subnet.public[*].arn +} + +output "public_subnets_cidr_blocks" { + description = "List of cidr_blocks of public subnets" + value = compact(aws_subnet.public[*].cidr_block) +} + +output "public_subnets_ipv6_cidr_blocks" { + description = "List of IPv6 cidr_blocks of public subnets in an IPv6 enabled VPC" + value = compact(aws_subnet.public[*].ipv6_cidr_block) +} + +output "all_private_route_table_ids" { + value = concat( + try(aws_route_table.private[*].id, []), + ) + description = "List of IDs of all private route tables" +} + +output "public_route_table_ids" { + description = "List of IDs of public route tables" + value = aws_route_table.public[*].id +} + +output "private_route_table_ids" { + description = "List of IDs of private route tables" + value = aws_route_table.private[*].id +} + +output "all_route_table_ids" { + description = "List of IDs of private and public route tables" + value = concat(aws_route_table.private[*].id, aws_route_table.public[*].id) +} + +output "public_internet_gateway_route_id" { + description = "ID of the internet gateway route" + value = try(aws_route.public_internet_gateway[0].id, "") +} + +output "public_internet_gateway_ipv6_route_id" { + description = "ID of the IPv6 internet gateway route" + value = try(aws_route.public_internet_gateway_ipv6[0].id, "") +} + +output "private_nat_gateway_route_ids" { + description = "List of IDs of the private nat gateway route" + value = aws_route.private_nat_gateway[*].id +} + +output "private_ipv6_egress_route_ids" { + description = "List of IDs of the ipv6 egress route" + value = aws_route.private_ipv6_egress[*].id +} + + + + +output "private_route_table_association_ids" { + description = "List of IDs of the private route table association" + value = aws_route_table_association.private[*].id +} + + +output "public_route_table_association_ids" { + description = "List of IDs of the public route table association" + value = aws_route_table_association.public[*].id +} + +output "dhcp_options_id" { + description = "The ID of the DHCP options" + value = try(aws_vpc_dhcp_options.this[0].id, "") +} + +output "nat_ids" { + description = "List of allocation ID of Elastic IPs created for AWS NAT Gateway" + value = aws_eip.nat[*].id +} + +output "nat_public_ips" { + description = "List of public Elastic IPs created for AWS NAT Gateway" + value = var.reuse_nat_ips ? var.external_nat_ips : aws_eip.nat[*].public_ip +} + +output "natgw_ids" { + description = "List of NAT Gateway IDs" + value = aws_nat_gateway.this[*].id +} + +output "igw_id" { + description = "The ID of the Internet Gateway" + value = try(aws_internet_gateway.this[0].id, "") +} + +output "igw_arn" { + description = "The ARN of the Internet Gateway" + value = try(aws_internet_gateway.this[0].arn, "") +} + +output "egress_only_internet_gateway_id" { + description = "The ID of the egress only Internet Gateway" + value = try(aws_egress_only_internet_gateway.this[0].id, "") +} + + +output "public_network_acl_id" { + description = "ID of the public network ACL" + value = try(aws_network_acl.public[0].id, "") +} + +output "public_network_acl_arn" { + description = "ARN of the public network ACL" + value = try(aws_network_acl.public[0].arn, "") +} + +output "private_network_acl_id" { + description = "ID of the private network ACL" + value = try(aws_network_acl.private[0].id, "") +} + +output "private_network_acl_arn" { + description = "ARN of the private network ACL" + value = try(aws_network_acl.private[0].arn, "") +} + +# VPC flow log +output "vpc_flow_log_id" { + description = "The ID of the Flow Log resource" + value = try(aws_flow_log.this[0].id, "") +} + +output "vpc_flow_log_destination_arn" { + description = "The ARN of the destination for VPC Flow Logs" + value = local.flow_log_destination_arn +} + +output "vpc_flow_log_destination_type" { + description = "The type of the destination for VPC Flow Logs" + value = var.flow_log_destination_type +} + +output "vpc_flow_log_cloudwatch_iam_role_arn" { + description = "The ARN of the IAM role used when pushing logs to Cloudwatch log group" + value = local.flow_log_iam_role_arn +} + +# Static values (arguments) +output "azs" { + description = "A list of availability zones specified as argument to this module" + value = var.azs +} + +output "name" { + description = "The name of the VPC specified as argument to this module" + value = var.name +} + +output "all_private_subnets" { + value = try(aws_subnet.private[*]) +} + + + diff --git a/modules/aws-vpc/variables.tf b/modules/aws-vpc/variables.tf new file mode 100644 index 0000000..cb37ba2 --- /dev/null +++ b/modules/aws-vpc/variables.tf @@ -0,0 +1,682 @@ +variable "private_subnets" { + type = any + default = [ + { + name = "subnet-1" + cidr_block = "10.0.1.0/24" + availability_zone = "us-east-1a" + additional_tags = {} + }, + { + name = "subnet-2" + cidr_block = "10.0.2.0/24" + availability_zone = "us-east-1b" + additional_tags = {} + } + ] +} + +variable "create_vpc" { + description = "Controls if VPC should be created (it affects almost all resources)" + type = bool + default = true +} + +variable "name" { + description = "Name to be used on all the resources as identifier" + type = string + default = "" +} + +variable "cidr" { + description = "The CIDR block for the VPC. Default value is a valid CIDR, but not acceptable by AWS and should be overridden" + type = string + default = "0.0.0.0/0" +} + +variable "enable_ipv6" { + description = "Requests an Amazon-provided IPv6 CIDR block with a /56 prefix length for the VPC. You cannot specify the range of IP addresses, or the size of the CIDR block." + type = bool + default = false +} + +variable "private_subnet_ipv6_prefixes" { + description = "Assigns IPv6 private subnet id based on the Amazon provided /56 prefix base 10 integer (0-256). Must be of equal length to the corresponding IPv4 subnet list" + type = list(string) + default = [] +} + +variable "public_subnet_ipv6_prefixes" { + description = "Assigns IPv6 public subnet id based on the Amazon provided /56 prefix base 10 integer (0-256). Must be of equal length to the corresponding IPv4 subnet list" + type = list(string) + default = [] +} + +variable "assign_ipv6_address_on_creation" { + description = "Assign IPv6 address on subnet, must be disabled to change IPv6 CIDRs. This is the IPv6 equivalent of map_public_ip_on_launch" + type = bool + default = false +} + + +variable "private_subnet_assign_ipv6_address_on_creation" { + description = "Assign IPv6 address on private subnet, must be disabled to change IPv6 CIDRs. This is the IPv6 equivalent of map_public_ip_on_launch" + type = bool + default = null +} + +variable "public_subnet_assign_ipv6_address_on_creation" { + description = "Assign IPv6 address on public subnet, must be disabled to change IPv6 CIDRs. This is the IPv6 equivalent of map_public_ip_on_launch" + type = bool + default = null +} + +variable "secondary_cidr_blocks" { + description = "List of secondary CIDR blocks to associate with the VPC to extend the IP Address pool" + type = list(string) + default = [] +} + +variable "instance_tenancy" { + description = "A tenancy option for instances launched into the VPC" + type = string + default = "default" +} + +variable "public_subnet_suffix" { + description = "Suffix to append to public subnets name" + type = string + default = "public" +} + +variable "private_subnet_suffix" { + description = "Suffix to append to private subnets name" + type = string + default = "private" +} + + +variable "public_subnets" { + description = "A list of public subnets inside the VPC" + type = list(string) + default = [] +} + +variable "create_private_subnet_route_table" { + description = "Controls if separate route table for private should be created" + type = bool + default = false + +} + +variable "azs" { + description = "A list of availability zones names or ids in the region" + type = list(string) + default = [] +} + +variable "enable_dns_hostnames" { + description = "Should be true to enable DNS hostnames in the VPC" + type = bool + default = false +} + +variable "enable_dns_support" { + description = "Should be true to enable DNS support in the VPC" + type = bool + default = true +} + +# tflint-ignore: terraform_unused_declarations +variable "enable_classiclink" { + description = "[DEPRECATED](https://github.com/hashicorp/terraform/issues/31730) Should be true to enable ClassicLink for the VPC. Only valid in regions and accounts that support EC2 Classic." + type = bool + default = null +} + +# tflint-ignore: terraform_unused_declarations +variable "enable_classiclink_dns_support" { + description = "[DEPRECATED](https://github.com/hashicorp/terraform/issues/31730) Should be true to enable ClassicLink DNS Support for the VPC. Only valid in regions and accounts that support EC2 Classic." + type = bool + default = null +} + +variable "enable_nat_gateway" { + description = "Should be true if you want to provision NAT Gateways for each of your private networks" + type = bool + default = false +} + +variable "nat_gateway_destination_cidr_block" { + description = "Used to pass a custom destination route for private NAT Gateway. If not specified, the default 0.0.0.0/0 is used as a destination route." + type = string + default = "0.0.0.0/0" +} + +variable "single_nat_gateway" { + description = "Should be true if you want to provision a single shared NAT Gateway across all of your private networks" + type = bool + default = false +} + +variable "one_nat_gateway_per_az" { + description = "Should be true if you want only one NAT Gateway per availability zone. Requires `var.azs` to be set, and the number of `public_subnets` created to be greater than or equal to the number of availability zones specified in `var.azs`." + type = bool + default = false +} + +variable "reuse_nat_ips" { + description = "Should be true if you don't want EIPs to be created for your NAT Gateways and will instead pass them in via the 'external_nat_ip_ids' variable" + type = bool + default = false +} + +variable "external_nat_ip_ids" { + description = "List of EIP IDs to be assigned to the NAT Gateways (used in combination with reuse_nat_ips)" + type = list(string) + default = [] +} + +variable "external_nat_ips" { + description = "List of EIPs to be used for `nat_public_ips` output (used in combination with reuse_nat_ips and external_nat_ip_ids)" + type = list(string) + default = [] +} + +variable "map_public_ip_on_launch" { + description = "Should be false if you do not want to auto-assign public IP on launch" + type = bool + default = true +} + +variable "amazon_side_asn" { + description = "The Autonomous System Number (ASN) for the Amazon side of the gateway. By default the virtual private gateway is created with the current default Amazon ASN." + type = string + default = "64512" +} + +variable "propagate_private_route_tables_vgw" { + description = "Should be true if you want route table propagation" + type = bool + default = false +} + +variable "propagate_public_route_tables_vgw" { + description = "Should be true if you want route table propagation" + type = bool + default = false +} + +variable "manage_default_route_table" { + description = "Should be true to manage default route table" + type = bool + default = false +} + +variable "default_route_table_name" { + description = "Name to be used on the default route table" + type = string + default = null +} + +variable "default_route_table_propagating_vgws" { + description = "List of virtual gateways for propagation" + type = list(string) + default = [] +} + +variable "default_route_table_routes" { + description = "Configuration block of routes. See https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/default_route_table#route" + type = list(map(string)) + default = [] +} + +variable "default_route_table_tags" { + description = "Additional tags for the default route table" + type = map(string) + default = {} +} + +variable "tags" { + description = "A map of tags to add to all resources" + type = map(string) + default = {} +} + +variable "vpc_tags" { + description = "Additional tags for the VPC" + type = map(string) + default = {} +} + +variable "igw_tags" { + description = "Additional tags for the internet gateway" + type = map(string) + default = {} +} + +variable "public_subnet_tags" { + description = "Additional tags for the public subnets" + type = map(string) + default = {} +} + +variable "private_subnet_tags" { + description = "Additional tags for the private subnets" + type = map(string) + default = {} +} + +variable "public_route_table_tags" { + description = "Additional tags for the public route tables" + type = map(string) + default = {} +} + +variable "private_route_table_tags" { + description = "Additional tags for the private route tables" + type = map(string) + default = {} +} + +variable "public_acl_tags" { + description = "Additional tags for the public subnets network ACL" + type = map(string) + default = {} +} + +variable "private_acl_tags" { + description = "Additional tags for the private subnets network ACL" + type = map(string) + default = {} +} + +variable "dhcp_options_tags" { + description = "Additional tags for the DHCP option set (requires enable_dhcp_options set to true)" + type = map(string) + default = {} +} + +variable "nat_gateway_tags" { + description = "Additional tags for the NAT gateways" + type = map(string) + default = {} +} + +variable "nat_eip_tags" { + description = "Additional tags for the NAT EIP" + type = map(string) + default = {} +} + +variable "vpc_flow_log_tags" { + description = "Additional tags for the VPC Flow Logs" + type = map(string) + default = {} +} + +variable "vpc_flow_log_permissions_boundary" { + description = "The ARN of the Permissions Boundary for the VPC Flow Log IAM Role" + type = string + default = null +} + +variable "enable_dhcp_options" { + description = "Should be true if you want to specify a DHCP options set with a custom domain name, DNS servers, NTP servers, netbios servers, and/or netbios server type" + type = bool + default = false +} + +variable "dhcp_options_domain_name" { + description = "Specifies DNS name for DHCP options set (requires enable_dhcp_options set to true)" + type = string + default = "" +} + +variable "dhcp_options_domain_name_servers" { + description = "Specify a list of DNS server addresses for DHCP options set, default to AWS provided (requires enable_dhcp_options set to true)" + type = list(string) + default = ["AmazonProvidedDNS"] +} + +variable "dhcp_options_ntp_servers" { + description = "Specify a list of NTP servers for DHCP options set (requires enable_dhcp_options set to true)" + type = list(string) + default = [] +} + +variable "dhcp_options_netbios_name_servers" { + description = "Specify a list of netbios servers for DHCP options set (requires enable_dhcp_options set to true)" + type = list(string) + default = [] +} + +variable "dhcp_options_netbios_node_type" { + description = "Specify netbios node_type for DHCP options set (requires enable_dhcp_options set to true)" + type = string + default = "" +} + +variable "manage_default_vpc" { + description = "Should be true to adopt and manage Default VPC" + type = bool + default = false +} + +variable "default_vpc_name" { + description = "Name to be used on the Default VPC" + type = string + default = null +} + +variable "default_vpc_enable_dns_support" { + description = "Should be true to enable DNS support in the Default VPC" + type = bool + default = true +} + +variable "default_vpc_enable_dns_hostnames" { + description = "Should be true to enable DNS hostnames in the Default VPC" + type = bool + default = false +} + +# tflint-ignore: terraform_unused_declarations +variable "default_vpc_enable_classiclink" { + description = "[DEPRECATED](https://github.com/hashicorp/terraform/issues/31730) Should be true to enable ClassicLink in the Default VPC" + type = bool + default = false +} + +variable "default_vpc_tags" { + description = "Additional tags for the Default VPC" + type = map(string) + default = {} +} + +variable "manage_default_network_acl" { + description = "Should be true to adopt and manage Default Network ACL" + type = bool + default = false +} + +variable "default_network_acl_name" { + description = "Name to be used on the Default Network ACL" + type = string + default = null +} + +variable "default_network_acl_tags" { + description = "Additional tags for the Default Network ACL" + type = map(string) + default = {} +} + +variable "public_dedicated_network_acl" { + description = "Whether to use dedicated network ACL (not default) and custom rules for public subnets" + type = bool + default = false +} + +variable "private_dedicated_network_acl" { + description = "Whether to use dedicated network ACL (not default) and custom rules for private subnets" + type = bool + default = false +} + +variable "default_network_acl_ingress" { + description = "List of maps of ingress rules to set on the Default Network ACL" + type = list(map(string)) + + default = [ + { + rule_no = 100 + action = "allow" + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_block = "0.0.0.0/0" + }, + { + rule_no = 101 + action = "allow" + from_port = 0 + to_port = 0 + protocol = "-1" + ipv6_cidr_block = "::/0" + }, + ] +} + +variable "default_network_acl_egress" { + description = "List of maps of egress rules to set on the Default Network ACL" + type = list(map(string)) + + default = [ + { + rule_no = 100 + action = "allow" + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_block = "0.0.0.0/0" + }, + { + rule_no = 101 + action = "allow" + from_port = 0 + to_port = 0 + protocol = "-1" + ipv6_cidr_block = "::/0" + }, + ] +} + + + +variable "public_inbound_acl_rules" { + description = "Public subnets inbound network ACLs" + type = list(map(string)) + + default = [ + { + rule_number = 100 + rule_action = "allow" + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_block = "0.0.0.0/0" + }, + ] +} + +variable "public_outbound_acl_rules" { + description = "Public subnets outbound network ACLs" + type = list(map(string)) + + default = [ + { + rule_number = 100 + rule_action = "allow" + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_block = "0.0.0.0/0" + }, + ] +} + +variable "private_inbound_acl_rules" { + description = "Private subnets inbound network ACLs" + type = list(map(string)) + + default = [ + { + rule_number = 100 + rule_action = "allow" + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_block = "0.0.0.0/0" + }, + ] +} + +variable "private_outbound_acl_rules" { + description = "Private subnets outbound network ACLs" + type = list(map(string)) + + default = [ + { + rule_number = 100 + rule_action = "allow" + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_block = "0.0.0.0/0" + }, + ] +} + +variable "manage_default_security_group" { + description = "Should be true to adopt and manage default security group" + type = bool + default = false +} + +variable "default_security_group_name" { + description = "Name to be used on the default security group" + type = string + default = null +} + +variable "default_security_group_ingress" { + description = "List of maps of ingress rules to set on the default security group" + type = list(map(string)) + default = [] +} + +variable "enable_flow_log" { + description = "Whether or not to enable VPC Flow Logs" + type = bool + default = false +} + +variable "default_security_group_egress" { + description = "List of maps of egress rules to set on the default security group" + type = list(map(string)) + default = [] +} + +variable "default_security_group_tags" { + description = "Additional tags for the default security group" + type = map(string) + default = {} +} + +variable "create_flow_log_cloudwatch_log_group" { + description = "Whether to create CloudWatch log group for VPC Flow Logs" + type = bool + default = false +} + +variable "create_flow_log_cloudwatch_iam_role" { + description = "Whether to create IAM role for VPC Flow Logs" + type = bool + default = false +} + +variable "flow_log_traffic_type" { + description = "The type of traffic to capture. Valid values: ACCEPT, REJECT, ALL." + type = string + default = "ALL" +} + +variable "flow_log_destination_type" { + description = "Type of flow log destination. Can be s3 or cloud-watch-logs." + type = string + default = "cloud-watch-logs" +} + +variable "flow_log_log_format" { + description = "The fields to include in the flow log record, in the order in which they should appear." + type = string + default = null +} + +variable "flow_log_destination_arn" { + description = "The ARN of the CloudWatch log group or S3 bucket where VPC Flow Logs will be pushed. If this ARN is a S3 bucket the appropriate permissions need to be set on that bucket's policy. When create_flow_log_cloudwatch_log_group is set to false this argument must be provided." + type = string + default = "" +} + +variable "flow_log_cloudwatch_iam_role_arn" { + description = "The ARN for the IAM role that's used to post flow logs to a CloudWatch Logs log group. When flow_log_destination_arn is set to ARN of Cloudwatch Logs, this argument needs to be provided." + type = string + default = "" +} + +variable "flow_log_cloudwatch_log_group_name_prefix" { + description = "Specifies the name prefix of CloudWatch Log Group for VPC flow logs." + type = string + default = "/aws/vpc-flow-log/" +} + +variable "flow_log_cloudwatch_log_group_retention_in_days" { + description = "Specifies the number of days you want to retain log events in the specified log group for VPC flow logs." + type = number + default = null +} + +variable "flow_log_cloudwatch_log_group_kms_key_id" { + description = "The ARN of the KMS Key to use when encrypting log data for VPC flow logs." + type = string + default = null +} + +variable "flow_log_max_aggregation_interval" { + description = "The maximum interval of time during which a flow of packets is captured and aggregated into a flow log record. Valid Values: `60` seconds or `600` seconds." + type = number + default = 600 +} + +variable "create_igw" { + description = "Controls if an Internet Gateway is created for public subnets and the related routes that connect them." + type = bool + default = true +} + +variable "create_egress_only_igw" { + description = "Controls if an Egress Only Internet Gateway is created and its related routes." + type = bool + default = true +} + +variable "flow_log_file_format" { + description = "(Optional) The format for the flow log. Valid values: `plain-text`, `parquet`." + type = string + default = "plain-text" + validation { + condition = can(regex("^(plain-text|parquet)$", + var.flow_log_file_format)) + error_message = "ERROR valid values: plain-text, parquet." + } +} + +variable "flow_log_hive_compatible_partitions" { + description = "(Optional) Indicates whether to use Hive-compatible prefixes for flow logs stored in Amazon S3." + type = bool + default = false +} + +variable "flow_log_per_hour_partition" { + description = "(Optional) Indicates whether to partition the flow log per hour. This reduces the cost and response time for queries." + type = bool + default = false +} + +variable "enable_nat_gateway_for_db" { + description = "Controls if nat gateway for db should be enabled" + type = bool + default = true +} diff --git a/modules/aws-vpc/versions.tf b/modules/aws-vpc/versions.tf new file mode 100644 index 0000000..5a9fd0f --- /dev/null +++ b/modules/aws-vpc/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.63" + } + } +} diff --git a/modules/aws-vpc/vpc-flow-logs.tf b/modules/aws-vpc/vpc-flow-logs.tf new file mode 100644 index 0000000..209ccc5 --- /dev/null +++ b/modules/aws-vpc/vpc-flow-logs.tf @@ -0,0 +1,113 @@ +locals { + # Only create flow log if user selected to create a VPC as well + enable_flow_log = var.create_vpc && var.enable_flow_log + + create_flow_log_cloudwatch_iam_role = local.enable_flow_log && var.flow_log_destination_type != "s3" && var.create_flow_log_cloudwatch_iam_role + create_flow_log_cloudwatch_log_group = local.enable_flow_log && var.flow_log_destination_type != "s3" && var.create_flow_log_cloudwatch_log_group + + flow_log_destination_arn = local.create_flow_log_cloudwatch_log_group ? aws_cloudwatch_log_group.flow_log[0].arn : var.flow_log_destination_arn + flow_log_iam_role_arn = var.flow_log_destination_type != "s3" && local.create_flow_log_cloudwatch_iam_role ? aws_iam_role.vpc_flow_log_cloudwatch[0].arn : var.flow_log_cloudwatch_iam_role_arn +} + +################################################################################ +# Flow Log +################################################################################ + +resource "aws_flow_log" "this" { + count = local.enable_flow_log ? 1 : 0 + + log_destination_type = var.flow_log_destination_type + log_destination = local.flow_log_destination_arn + log_format = var.flow_log_log_format + iam_role_arn = local.flow_log_iam_role_arn + traffic_type = var.flow_log_traffic_type + vpc_id = local.vpc_id + max_aggregation_interval = var.flow_log_max_aggregation_interval + + dynamic "destination_options" { + for_each = var.flow_log_destination_type == "s3" ? [true] : [] + + content { + file_format = var.flow_log_file_format + hive_compatible_partitions = var.flow_log_hive_compatible_partitions + per_hour_partition = var.flow_log_per_hour_partition + } + } + + tags = merge(var.tags, var.vpc_flow_log_tags) +} + +################################################################################ +# Flow Log CloudWatch +################################################################################ + +resource "aws_cloudwatch_log_group" "flow_log" { + count = local.create_flow_log_cloudwatch_log_group ? 1 : 0 + + name = "${var.flow_log_cloudwatch_log_group_name_prefix}${local.vpc_id}" + retention_in_days = var.flow_log_cloudwatch_log_group_retention_in_days + kms_key_id = var.flow_log_cloudwatch_log_group_kms_key_id + + tags = merge(var.tags, var.vpc_flow_log_tags) +} + +resource "aws_iam_role" "vpc_flow_log_cloudwatch" { + count = local.create_flow_log_cloudwatch_iam_role ? 1 : 0 + + name_prefix = "vpc-flow-log-role-" + assume_role_policy = data.aws_iam_policy_document.flow_log_cloudwatch_assume_role[0].json + permissions_boundary = var.vpc_flow_log_permissions_boundary + + tags = merge(var.tags, var.vpc_flow_log_tags) +} + +data "aws_iam_policy_document" "flow_log_cloudwatch_assume_role" { + count = local.create_flow_log_cloudwatch_iam_role ? 1 : 0 + + statement { + sid = "AWSVPCFlowLogsAssumeRole" + + principals { + type = "Service" + identifiers = ["vpc-flow-logs.amazonaws.com"] + } + + effect = "Allow" + + actions = ["sts:AssumeRole"] + } +} + +resource "aws_iam_role_policy_attachment" "vpc_flow_log_cloudwatch" { + count = local.create_flow_log_cloudwatch_iam_role ? 1 : 0 + + role = aws_iam_role.vpc_flow_log_cloudwatch[0].name + policy_arn = aws_iam_policy.vpc_flow_log_cloudwatch[0].arn +} + +resource "aws_iam_policy" "vpc_flow_log_cloudwatch" { + count = local.create_flow_log_cloudwatch_iam_role ? 1 : 0 + + name_prefix = "vpc-flow-log-to-cloudwatch-" + policy = data.aws_iam_policy_document.vpc_flow_log_cloudwatch[0].json + tags = merge(var.tags, var.vpc_flow_log_tags) +} + +data "aws_iam_policy_document" "vpc_flow_log_cloudwatch" { + count = local.create_flow_log_cloudwatch_iam_role ? 1 : 0 + + statement { + sid = "AWSVPCFlowLogsPushToCloudWatch" + + effect = "Allow" + + actions = [ + "logs:CreateLogStream", + "logs:PutLogEvents", + "logs:DescribeLogGroups", + "logs:DescribeLogStreams", + ] + + resources = ["*"] + } +} diff --git a/modules/aws-waf-ip-set/README.md b/modules/aws-waf-ip-set/README.md new file mode 100644 index 0000000..2987c3c --- /dev/null +++ b/modules/aws-waf-ip-set/README.md @@ -0,0 +1,62 @@ +### Used to create whitelist and blacklist for to feed waf rules. + + +Example -> Create a trusted ip set, basically you need to fill the necessary variables, it's dynamically generated by module +``` + ip_set_name = "${local.env}-TrustedIPSet" + ip_set_addresses = [ + "65.20.23.23/32 + ] + ip_set_description = "${local.env} Trusted IP Set" +``` + + +Example -> Create a blacklist ip set, basically you need to fill the necessary variables, it's dynamically generated by module + +``` + blacklist_ip_set_name = "${local.env}-BlacklistIPSet" + blacklist_ip_set_description = "Black list consists of blocked IP addresses" + blacklist_ip_addresses = [] +``` + + + + +## Requirements + +No requirements. + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | n/a | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_wafv2_ip_set.blacklist_ip_set](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/wafv2_ip_set) | resource | +| [aws_wafv2_ip_set.whitelist_ip_set](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/wafv2_ip_set) | resource | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [blacklist\_ip\_addresses](#input\_blacklist\_ip\_addresses) | Blacklist IP addresses | `list(string)` | `[]` | no | +| [blacklist\_ip\_set\_description](#input\_blacklist\_ip\_set\_description) | Description of the IP set | `string` | `""` | no | +| [blacklist\_ip\_set\_name](#input\_blacklist\_ip\_set\_name) | IP Set Name | `string` | `""` | no | +| [ip\_set\_addresses](#input\_ip\_set\_addresses) | IP addresses | `list(string)` | `[]` | no | +| [ip\_set\_description](#input\_ip\_set\_description) | Description of the IP set | `string` | `""` | no | +| [ip\_set\_name](#input\_ip\_set\_name) | IP Set Name | `string` | `""` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [blacklist\_ip\_set\_arn](#output\_blacklist\_ip\_set\_arn) | arn of blacklist ip set | +| [whitelist\_ip\_set\_arn](#output\_whitelist\_ip\_set\_arn) | arn of whitelist ip set | diff --git a/modules/aws-waf-ip-set/main.tf b/modules/aws-waf-ip-set/main.tf new file mode 100644 index 0000000..e70b5ab --- /dev/null +++ b/modules/aws-waf-ip-set/main.tf @@ -0,0 +1,29 @@ +resource "aws_wafv2_ip_set" "blacklist_ip_set" { + + ip_address_version = "IPV4" + scope = var.blacklist_scope + description = var.blacklist_ip_set_description + name = var.blacklist_ip_set_name + addresses = var.blacklist_ip_addresses + + +} + +resource "aws_wafv2_ip_set" "whitelist_ip_set" { + ip_address_version = "IPV4" + scope = var.whitelist_scope + description = var.ip_set_description + name = var.ip_set_name + addresses = var.ip_set_addresses + +} + + +resource "aws_wafv2_ip_set" "ip_addresses" { + for_each = var.ip_address_groups + ip_address_version = each.value.ip_address_version + scope = each.value.whitelist_scope + description = each.value.ip_set_description + name = each.value.ip_set_name + addresses = each.value.ip_set_addresses +} diff --git a/modules/aws-waf-ip-set/output.tf b/modules/aws-waf-ip-set/output.tf new file mode 100644 index 0000000..4abfe4c --- /dev/null +++ b/modules/aws-waf-ip-set/output.tf @@ -0,0 +1,15 @@ +output "blacklist_ip_set_arn" { + value = aws_wafv2_ip_set.blacklist_ip_set.arn + description = "arn of blacklist ip set" +} + +output "whitelist_ip_set_arn" { + value = aws_wafv2_ip_set.whitelist_ip_set.arn + description = "arn of whitelist ip set" +} + +output "dynamic_waf_ip_set_arns" { + value = { for key, ip_set in aws_wafv2_ip_set.ip_addresses : key => ip_set.arn } + description = "Map of ARNs for dynamically created IP address groups" +} + diff --git a/modules/aws-waf-ip-set/variables.tf b/modules/aws-waf-ip-set/variables.tf new file mode 100644 index 0000000..5e8fbd9 --- /dev/null +++ b/modules/aws-waf-ip-set/variables.tf @@ -0,0 +1,58 @@ +variable "ip_set_addresses" { + description = "IP addresses" + type = list(string) + default = [] +} + +variable "ip_set_name" { + description = "IP Set Name" + default = "" +} + +variable "ip_set_description" { + description = "Description of the IP set" + default = "" + +} + +variable "whitelist_scope" { + description = "" + default = "REGIONAL" +} + +variable "blacklist_ip_addresses" { + description = "Blacklist IP addresses" + type = list(string) + default = [] +} + +variable "blacklist_ip_set_name" { + description = "IP Set Name" + default = "" +} + +variable "blacklist_ip_set_description" { + description = "Description of the IP set" + default = "" + +} + +variable "blacklist_scope" { + description = "" + default = "REGIONAL" +} + + + + +variable "ip_address_groups" { + description = "Map of IP address groups for creating multiple AWS WAFv2 IP Sets" + type = map(object({ + ip_address_version = string + whitelist_scope = string + ip_set_description = string + ip_set_name = string + ip_set_addresses = list(string) + })) + default = {} +} diff --git a/modules/aws-waf/README.md b/modules/aws-waf/README.md new file mode 100644 index 0000000..bc56d31 --- /dev/null +++ b/modules/aws-waf/README.md @@ -0,0 +1,389 @@ +# terraform-aws-waf-webaclv2 + + +Terraform module to configure WAF Web ACL V2 for Application Load Balancer or Cloudfront distribution. + +Supported WAF v2 components: + +- Module supports all AWS managed rules defined in https://docs.aws.amazon.com/waf/latest/developerguide/aws-managed-rule-groups-list.html. +- Associating WAFv2 ACL with one or more Application Load Balancers (ALB) +- Blocking IP Sets +- Rate limiting IPs (and optional scopedown statements) +- Byte Match statements +- Geo set statements +- Logical Statements (AND, OR, NOT) +- Size constraint statements +- Label Match statements +- Regex Pattern Match statements +- Custom responses + +## Terraform versions + +Terraform 0.13+ Pin module version to `~> v3.0`. Submit pull-requests to `main` branch. +Terraform 0.12 < 0.13. Pin module version to `~> v1.0`. + +## Usage + +Please pin down version of this module to exact version + +If referring directly to the code instead of a pinned version, take note that from release 3.0.0 all future changes will only be made to the `main` branch. + +```hcl +module "waf" { + source = "kloia/waf/aws" + version = "~> 3.0.0" + + name_prefix = "test-waf-setup" + alb_arn = module.alb.arn + + scope = "REGIONAL" + + create_alb_association = true + + allow_default_action = true # set to allow if not specified + + visibility_config = { + metric_name = "test-waf-setup-waf-main-metrics" + } + + rules = [ + { + name = "AWSManagedRulesCommonRuleSet-rule-1" + priority = "1" + + override_action = "none" + + visibility_config = { + metric_name = "AWSManagedRulesCommonRuleSet-metric" + } + + managed_rule_group_statement = { + name = "AWSManagedRulesCommonRuleSet" + vendor_name = "AWS" + excluded_rule = [ + "SizeRestrictions_QUERYSTRING", + "SizeRestrictions_BODY", + "GenericRFI_QUERYARGUMENTS" + ] + } + }, + { + name = "AWSManagedRulesKnownBadInputsRuleSet-rule-2" + priority = "2" + + override_action = "count" + + visibility_config = { + metric_name = "AWSManagedRulesKnownBadInputsRuleSet-metric" + } + + managed_rule_group_statement = { + name = "AWSManagedRulesKnownBadInputsRuleSet" + vendor_name = "AWS" + } + }, + { + name = "AWSManagedRulesPHPRuleSet-rule-3" + priority = "3" + + override_action = "none" + + visibility_config = { + cloudwatch_metrics_enabled = false + metric_name = "AWSManagedRulesPHPRuleSet-metric" + sampled_requests_enabled = false + } + + managed_rule_group_statement = { + name = "AWSManagedRulesPHPRuleSet" + vendor_name = "AWS" + } + }, + ### Byte Match Rule example + # Refer to https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/wafv2_web_acl#byte-match-statement + # for all of the options available. + # Additional examples available in the examples directory + { + name = "ByteMatchRule-4" + priority = "4" + + action = "count" + + visibility_config = { + cloudwatch_metrics_enabled = false + metric_name = "ByteMatchRule-metric" + sampled_requests_enabled = false + } + + byte_match_statement = { + field_to_match = { + uri_path = "{}" + } + positional_constraint = "STARTS_WITH" + search_string = "/path/to/match" + priority = 0 + type = "NONE" + } + }, + ### Geo Match Rule example + { + name = "GeoMatchRule-5" + priority = "5" + + action = "allow" + + visibility_config = { + cloudwatch_metrics_enabled = false + metric_name = "GeoMatchRule-metric" + sampled_requests_enabled = false + } + + geo_match_statement = { + country_codes = ["NL", "GB", "US"] + } + }, + ### IP Set Rule example + { + name = "IpSetRule-6" + priority = "6" + + action = "allow" + + visibility_config = { + cloudwatch_metrics_enabled = false + metric_name = "IpSetRule-metric" + sampled_requests_enabled = false + } + + ip_set_reference_statement = { + arn = "arn:aws:wafv2:eu-west-1:111122223333:regional/ipset/ip-set-test/a1bcdef2-1234-123a-abc0-1234a5bc67d8" + } + }, + ### IP Rate Based Rule example + { + name = "IpRateBasedRule-7" + priority = "7" + + action = "block" + + visibility_config = { + cloudwatch_metrics_enabled = false + metric_name = "IpRateBasedRule-metric" + sampled_requests_enabled = false + } + + rate_based_statement = { + limit = 100 + aggregate_key_type = "IP" + # Optional scope_down_statement to refine what gets rate limited + scope_down_statement = { + not_statement = { + byte_match_statement = { + field_to_match = { + uri_path = "{}" + } + positional_constraint = "STARTS_WITH" + search_string = "/path/to/match" + priority = 0 + type = "NONE" + } + } + } + } + }, + ### NOT rule example (can be applied to byte_match, geo_match, and ip_set rules) + { + name = "NotByteMatchRule-8" + priority = "8" + + action = "count" + + visibility_config = { + cloudwatch_metrics_enabled = false + metric_name = "NotByteMatchRule-metric" + sampled_requests_enabled = false + } + + not_statement = { + byte_match_statement = { + field_to_match = { + uri_path = "{}" + } + positional_constraint = "STARTS_WITH" + search_string = "/path/to/match" + priority = 0 + type = "NONE" + } + } + }, + ### Size constraint Rule example + # Refer to https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/wafv2_web_acl#size-constraint-statement + # for all of the options available. + # Additional examples available in the examples directory + { + name = "BodySizeConstraint" + priority = 0 + size_constraint_statement = { + field_to_match = { + body = "{}" + } + comparison_operator = "GT" + size = 8192 + priority = 0 + type = "NONE" + } + + action = "count" + + visibility_config = { + cloudwatch_metrics_enabled = true + metric_name = "BodySizeConstraint" + sampled_requests_enabled = true + } + }, + ### Regex Pattern Set Reference Rule example + # Refer to https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/wafv2_web_acl#regex-pattern-set-reference-statement + # for all of the options available. + # Additional examples available in the examples directory + { + name = "MatchRegexRule-1" + priority = "1" + + action = "none" + + visibility_config = { + cloudwatch_metrics_enabled = true + metric_name = "RegexBadBotsUserAgent-metric" + sampled_requests_enabled = false + } + + # You need to previously create you regex pattern + # Refer to https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/wafv2_regex_pattern_set + # for all of the options available. + regex_pattern_set_reference_statement = { + arn = aws_wafv2_regex_pattern_set.example.arn + field_to_match = { + single_header = { + name = "user-agent" + } + } + priority = 0 + type = "LOWERCASE" # The text transformation type + } + } + ] + + tags = { + "Name" = "test-waf-setup" + "Env" = "test" + } +} +``` + +### Cloudfront configuration + +```hcl +provider "aws" { + alias = "us-east" + + version = ">= 3.38" + region = "us-east-1" +} + +module "waf" { + providers = { + aws = aws.us-east + } + + source = "kloia/waf/aws" + version = "~> 3.0.0" + + name_prefix = "test-waf-setup-cloudfront" + scope = "CLOUDFRONT" + create_alb_association = false + ... +} +``` + +## Logging configuration + +When you enable logging configuration for WAFv2. Remember to follow naming convention defined in https://docs.aws.amazon.com/waf/latest/developerguide/logging.html. + +Importantly, make sure that Amazon Kinesis Data Firehose is using a name starting with the prefix aws-waf-logs-. + +## Examples + +* [WAF ACL](https://github.com/kloia/terraform-modules/tree/main/terraform-aws-waf/examples/core) +* [WAF ACL with configuration logging](https://github.com/kloia/terraform-modules/tree/main/terraform-aws-waf/examples/wafv2-logging-configuration) +* [WAF ACL with ip rules](https://github.com/kloia/terraform-modules/tree/main/terraform-aws-waf/examples/wafv2-ip-rules) +* [WAF ACL with bytematch rules](https://github.com/kloia/terraform-modules/tree/main/terraform-aws-waf/examples/wafv2-bytematch-rules) +* [WAF ACL with geo match rules](https://github.com/kloia/terraform-modules/tree/main/terraform-aws-waf/examples/wafv2-geo-rules) +* [WAF ACL with and / or rules](https://github.com/kloia/terraform-modules/tree/main/terraform-aws-waf/examples/wafv2-and-or-rules) +* [WAF ACL with label match rules](https://github.com/kloia/terraform-modules/tree/main/terraform-aws-waf/examples/wafv2-labelmatch-rules) +* [WAF ACL with regex pattern rules](https://github.com/kloia/terraform-modules/tree/main/terraform-aws-waf/examples/wafv2-regex-pattern-rules) + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.7 | +| [aws](#requirement\_aws) | >= 4.0.0 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 4.0.0 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_wafv2_web_acl.main](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/wafv2_web_acl) | resource | +| [aws_wafv2_web_acl_association.alb_list](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/wafv2_web_acl_association) | resource | +| [aws_wafv2_web_acl_association.main](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/wafv2_web_acl_association) | resource | +| [aws_wafv2_web_acl_logging_configuration.main](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/wafv2_web_acl_logging_configuration) | resource | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [alb\_arn](#input\_alb\_arn) | Application Load Balancer ARN | `string` | `""` | no | +| [alb\_arn\_list](#input\_alb\_arn\_list) | Application Load Balancer ARN list | `list(string)` | `[]` | no | +| [allow\_default\_action](#input\_allow\_default\_action) | Set to `true` for WAF to allow requests by default. Set to `false` for WAF to block requests by default. | `bool` | `true` | no | +| [create\_alb\_association](#input\_create\_alb\_association) | Whether to create alb association with WAF web acl | `bool` | `true` | no | +| [create\_logging\_configuration](#input\_create\_logging\_configuration) | Whether to create logging configuration in order start logging from a WAFv2 Web ACL to Amazon Kinesis Data Firehose. | `bool` | `false` | no | +| [custom\_response\_bodies](#input\_custom\_response\_bodies) | Custom response bodies to be referenced on a per rule basis. https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/wafv2_web_acl#custom-response-body |
{
"cidr_block": "0.0.0.0/0",
"from_port": 0,
"protocol": "-1",
"rule_action": "allow",
"rule_number": 100,
"to_port": 0
}
]
list(object({| `[]` | no | +| [description](#input\_description) | A friendly description of the WebACL | `string` | `null` | no | +| [enabled](#input\_enabled) | Whether to create the resources. Set to `false` to prevent the module from creating any resources | `bool` | `true` | no | +| [log\_destination\_configs](#input\_log\_destination\_configs) | The Amazon Kinesis Data Firehose Amazon Resource Name (ARNs) that you want to associate with the web ACL. Currently, only 1 ARN is supported. | `list(string)` | `[]` | no | +| [logging\_filter](#input\_logging\_filter) | A configuration block that specifies which web requests are kept in the logs and which are dropped. You can filter on the rule action and on the web request labels that were applied by matching rules during web ACL evaluation. | `any` | `{}` | no | +| [name\_prefix](#input\_name\_prefix) | Name prefix used to create resources. | `string` | n/a | yes | +| [redacted\_fields](#input\_redacted\_fields) | The parts of the request that you want to keep out of the logs. Up to 100 `redacted_fields` blocks are supported. | `any` | `[]` | no | +| [rules](#input\_rules) | List of WAF rules. | `any` | `[]` | no | +| [scope](#input\_scope) | Specifies whether this is for an AWS CloudFront distribution or for a regional application. Valid values are CLOUDFRONT or REGIONAL. To work with CloudFront, you must also specify the region us-east-1 (N. Virginia) on the AWS provider. | `string` | `"REGIONAL"` | no | +| [tags](#input\_tags) | A map of tags (key-value pairs) passed to resources. | `map(string)` | `{}` | no | +| [visibility\_config](#input\_visibility\_config) | Visibility config for WAFv2 web acl. https://www.terraform.io/docs/providers/aws/r/wafv2_web_acl.html#visibility-configuration | `map(string)` | `{}` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [web\_acl\_arn](#output\_web\_acl\_arn) | The ARN of the WAFv2 WebACL. | +| [web\_acl\_assoc\_acl\_arn](#output\_web\_acl\_assoc\_acl\_arn) | The ARN of the Web ACL attached to the Web ACL Association | +| [web\_acl\_assoc\_alb\_list\_acl\_arn](#output\_web\_acl\_assoc\_alb\_list\_acl\_arn) | The ARN of the Web ACL attached to the Web ACL Association for the alb\_list resource | +| [web\_acl\_assoc\_alb\_list\_id](#output\_web\_acl\_assoc\_alb\_list\_id) | The ID of the Web ACL Association for the alb\_list resource | +| [web\_acl\_assoc\_alb\_list\_resource\_arn](#output\_web\_acl\_assoc\_alb\_list\_resource\_arn) | The ARN of the ALB attached to the Web ACL Association for the alb\_list resource | +| [web\_acl\_assoc\_id](#output\_web\_acl\_assoc\_id) | The ID of the Web ACL Association | +| [web\_acl\_assoc\_resource\_arn](#output\_web\_acl\_assoc\_resource\_arn) | The ARN of the ALB attached to the Web ACL Association | +| [web\_acl\_capacity](#output\_web\_acl\_capacity) | The web ACL capacity units (WCUs) currently being used by this web ACL. | +| [web\_acl\_id](#output\_web\_acl\_id) | The ID of the WAFv2 WebACL. | +| [web\_acl\_name](#output\_web\_acl\_name) | The name of the WAFv2 WebACL. | +| [web\_acl\_rule\_names](#output\_web\_acl\_rule\_names) | List of created rule names | +| [web\_acl\_visibility\_config\_name](#output\_web\_acl\_visibility\_config\_name) | The web ACL visibility config name | + \ No newline at end of file diff --git a/modules/aws-waf/examples/core/README.md b/modules/aws-waf/examples/core/README.md new file mode 100644 index 0000000..c2e598a --- /dev/null +++ b/modules/aws-waf/examples/core/README.md @@ -0,0 +1,9 @@ + +## Example deployment flow + +```bash +terraform init +terraform validate +terraform plan +terraform apply --auto-approve +``` \ No newline at end of file diff --git a/modules/aws-waf/examples/core/main.tf b/modules/aws-waf/examples/core/main.tf new file mode 100644 index 0000000..f24f381 --- /dev/null +++ b/modules/aws-waf/examples/core/main.tf @@ -0,0 +1,122 @@ +provider "aws" { + region = "eu-west-1" +} + +##### +# Web Application Firewall configuration +##### +module "waf" { + source = "../.." + + name_prefix = "test-waf-setup" + allow_default_action = true + + visibility_config = { + cloudwatch_metrics_enabled = false + metric_name = "test-waf-setup-waf-main-metrics" + sampled_requests_enabled = false + } + + rules = [ + { + # Uses optional excluded_rules to exclude certain managed rules + name = "AWSManagedRulesCommonRuleSet-rule-1" + priority = "1" + + override_action = "none" + + visibility_config = { + cloudwatch_metrics_enabled = false + metric_name = "AWSManagedRulesCommonRuleSet-metric" + sampled_requests_enabled = false + } + + managed_rule_group_statement = { + name = "AWSManagedRulesCommonRuleSet" + vendor_name = "AWS" + excluded_rule = [ + "SizeRestrictions_QUERYSTRING", + "SizeRestrictions_BODY", + "GenericRFI_QUERYARGUMENTS" + ] + } + }, + { + name = "AWSManagedRulesKnownBadInputsRuleSet-rule-2" + priority = "2" + + override_action = "count" + + visibility_config = { + cloudwatch_metrics_enabled = false + metric_name = "AWSManagedRulesKnownBadInputsRuleSet-metric" + sampled_requests_enabled = false + } + + managed_rule_group_statement = { + name = "AWSManagedRulesKnownBadInputsRuleSet" + vendor_name = "AWS" + } + }, + { + # Uses an optional scope down statement to further refine what the rule is being applied to + name = "AWSManagedRulesPHPRuleSet-rule-3" + priority = "3" + + override_action = "none" + + visibility_config = { + cloudwatch_metrics_enabled = false + metric_name = "AWSManagedRulesPHPRuleSet-metric" + sampled_requests_enabled = false + } + + managed_rule_group_statement = { + name = "AWSManagedRulesPHPRuleSet" + vendor_name = "AWS" + + # Optional scope_down_statement + scope_down_statement = { + geo_match_statement = { + country_codes = ["NL", "GB", "US"] + } + } + } + }, + { + name = "AWSManagedRulesBotControlRuleSet-rule-4" + priority = "4" + + override_action = "none" + + visibility_config = { + cloudwatch_metrics_enabled = false + metric_name = "AWSManagedRulesBotControlRuleSet-metric" + sampled_requests_enabled = false + } + + managed_rule_group_statement = { + name = "AWSManagedRulesBotControlRuleSet" + vendor_name = "AWS" + } + }, + { + name = "block-nl-us-traffic" + priority = "5" + action = "block" + + geo_match_statement = { + country_codes = ["NL", "US"] + } + + visibility_config = { + cloudwatch_metrics_enabled = false + sampled_requests_enabled = false + } + } + ] + + tags = { + "Environment" = "test" + } +} diff --git a/modules/aws-waf/examples/wafv2-and-or-rules/main.tf b/modules/aws-waf/examples/wafv2-and-or-rules/main.tf new file mode 100644 index 0000000..16ee6d9 --- /dev/null +++ b/modules/aws-waf/examples/wafv2-and-or-rules/main.tf @@ -0,0 +1,130 @@ +provider "aws" { + region = "eu-west-1" +} + +##### +# IP set resources +##### +resource "aws_wafv2_ip_set" "custom_ip_set" { + name = "${var.name_prefix}-custom-ip-set" + + scope = "REGIONAL" + ip_address_version = "IPV4" + + addresses = [ + "10.0.0.0/16", + "10.10.0.0/16" + ] +} + +##### +# Web Application Firewall configuration +##### +module "waf" { + source = "../.." + + name_prefix = var.name_prefix + + allow_default_action = true + + scope = "REGIONAL" + + visibility_config = { + cloudwatch_metrics_enabled = false + metric_name = "${var.name_prefix}-waf-setup-waf-main-metrics" + sampled_requests_enabled = false + } + + rules = [ + { + name = "AWSManagedRulesCommonRuleSet-rule-1" + priority = "1" + + override_action = "none" + + visibility_config = { + cloudwatch_metrics_enabled = false + metric_name = "AWSManagedRulesCommonRuleSet-metric" + sampled_requests_enabled = false + } + + managed_rule_group_statement = { + name = "AWSManagedRulesCommonRuleSet" + vendor_name = "AWS" + excluded_rule = [ + "SizeRestrictions_QUERYSTRING", + "SizeRestrictions_BODY", + "GenericRFI_QUERYARGUMENTS" + ] + } + }, + { + ### AND rule example + name = "block-specific-uri-path-and-requests-from-nl-gb-and-us" + priority = 2 + action = "block" + + and_statement = { + statements = [ # 2 or more statements are required for AND + { + byte_match_statement = { + field_to_match = { + uri_path = "{}" + } + positional_constraint = "STARTS_WITH" + search_string = "/path/to/match" + priority = 0 + type = "NONE" + } + }, + { + geo_match_statement = { + country_codes = ["NL", "GB", "US"] + } + } + ] + } + + visibility_config = { + cloudwatch_metrics_enabled = false + sampled_requests_enabled = false + } + }, + { + ### OR rule example + name = "block-specific-ip-set-or-body-contains-hotmail" + priority = 3 + action = "block" + + or_statement = { + statements = [ # 2 or more statements are required for OR + { + ip_set_reference_statement = { + arn = aws_wafv2_ip_set.custom_ip_set.arn + } + }, + { + byte_match_statement = { + field_to_match = { + body = "{}" + } + positional_constraint = "CONTAINS" + search_string = "@hotmail.com" + priority = 0 + type = "NONE" + } + } + ] + } + + visibility_config = { + cloudwatch_metrics_enabled = false + sampled_requests_enabled = false + } + } + ] + + tags = { + "Environment" = "test" + } +} diff --git a/modules/aws-waf/examples/wafv2-and-or-rules/outputs.tf b/modules/aws-waf/examples/wafv2-and-or-rules/outputs.tf new file mode 100644 index 0000000..7a216ba --- /dev/null +++ b/modules/aws-waf/examples/wafv2-and-or-rules/outputs.tf @@ -0,0 +1,24 @@ +output "web_acl_name" { + description = "The name of the WAFv2 WebACL." + value = module.waf.web_acl_name +} + +output "web_acl_arn" { + description = "The ARN of the WAFv2 WebACL." + value = module.waf.web_acl_arn +} + +output "web_acl_capacity" { + description = "The web ACL capacity units (WCUs) currently being used by this web ACL." + value = module.waf.web_acl_capacity +} + +output "web_acl_visibility_config_name" { + description = "The web ACL visibility config name" + value = module.waf.web_acl_visibility_config_name +} + +output "web_acl_rule_names" { + description = "List of created rule names" + value = module.waf.web_acl_rule_names +} diff --git a/modules/aws-waf/examples/wafv2-and-or-rules/variables.tf b/modules/aws-waf/examples/wafv2-and-or-rules/variables.tf new file mode 100644 index 0000000..0519052 --- /dev/null +++ b/modules/aws-waf/examples/wafv2-and-or-rules/variables.tf @@ -0,0 +1,5 @@ +variable "name_prefix" { + description = "A prefix used for naming resources." + type = string + default = "example" +} diff --git a/modules/aws-waf/examples/wafv2-bytematch-rules/main.tf b/modules/aws-waf/examples/wafv2-bytematch-rules/main.tf new file mode 100644 index 0000000..27f7869 --- /dev/null +++ b/modules/aws-waf/examples/wafv2-bytematch-rules/main.tf @@ -0,0 +1,134 @@ +provider "aws" { + region = "eu-west-1" +} + +##### +# Web Application Firewall configuration +##### +module "waf" { + source = "../.." + + name_prefix = var.name_prefix + + allow_default_action = true + + scope = "REGIONAL" + + visibility_config = { + cloudwatch_metrics_enabled = false + metric_name = "${var.name_prefix}-waf-setup-waf-main-metrics" + sampled_requests_enabled = false + } + + rules = [ + { + name = "AWSManagedRulesCommonRuleSet-rule-1" + priority = "1" + + override_action = "none" + + visibility_config = { + cloudwatch_metrics_enabled = false + metric_name = "AWSManagedRulesCommonRuleSet-metric" + sampled_requests_enabled = false + } + + managed_rule_group_statement = { + name = "AWSManagedRulesCommonRuleSet" + vendor_name = "AWS" + excluded_rule = [ + "SizeRestrictions_QUERYSTRING", + "SizeRestrictions_BODY", + "GenericRFI_QUERYARGUMENTS" + ] + } + }, + { + name = "block-specific-uri-path" + priority = "2" + action = "block" + + byte_match_statement = { + field_to_match = { + uri_path = "{}" + } + positional_constraint = "STARTS_WITH" + search_string = "/path/to/match" + priority = 0 + type = "NONE" # The text transformation type + } + + visibility_config = { + cloudwatch_metrics_enabled = false + sampled_requests_enabled = false + } + }, + { + name = "block-if-request-body-contains-hotmail-email" + priority = "3" + action = "block" + + byte_match_statement = { + field_to_match = { + body = "{}" + } + positional_constraint = "CONTAINS" + search_string = "@hotmail.com" + priority = 0 + type = "NONE" # The text transformation type + } + + visibility_config = { + cloudwatch_metrics_enabled = false + sampled_requests_enabled = false + } + }, + { + name = "block-all-post-requests" + priority = "4" + action = "block" + + byte_match_statement = { + field_to_match = { + method = "{}" + } + positional_constraint = "EXACTLY" + search_string = "post" + priority = 0 + type = "LOWERCASE" # The text transformation type + } + + visibility_config = { + cloudwatch_metrics_enabled = false + sampled_requests_enabled = false + } + }, + { + # Blocks a single user by checking the username header + name = "block-single-user" + priority = "5" + action = "block" + + byte_match_statement = { + field_to_match = { + single_header = { + name = "Username" + } + } + positional_constraint = "EXACTLY" + search_string = "testuser" + priority = 0 + type = "LOWERCASE" # The text transformation type + } + + visibility_config = { + cloudwatch_metrics_enabled = false + sampled_requests_enabled = false + } + } + ] + + tags = { + "Environment" = "test" + } +} diff --git a/modules/aws-waf/examples/wafv2-bytematch-rules/outputs.tf b/modules/aws-waf/examples/wafv2-bytematch-rules/outputs.tf new file mode 100644 index 0000000..7a216ba --- /dev/null +++ b/modules/aws-waf/examples/wafv2-bytematch-rules/outputs.tf @@ -0,0 +1,24 @@ +output "web_acl_name" { + description = "The name of the WAFv2 WebACL." + value = module.waf.web_acl_name +} + +output "web_acl_arn" { + description = "The ARN of the WAFv2 WebACL." + value = module.waf.web_acl_arn +} + +output "web_acl_capacity" { + description = "The web ACL capacity units (WCUs) currently being used by this web ACL." + value = module.waf.web_acl_capacity +} + +output "web_acl_visibility_config_name" { + description = "The web ACL visibility config name" + value = module.waf.web_acl_visibility_config_name +} + +output "web_acl_rule_names" { + description = "List of created rule names" + value = module.waf.web_acl_rule_names +} diff --git a/modules/aws-waf/examples/wafv2-bytematch-rules/variables.tf b/modules/aws-waf/examples/wafv2-bytematch-rules/variables.tf new file mode 100644 index 0000000..0519052 --- /dev/null +++ b/modules/aws-waf/examples/wafv2-bytematch-rules/variables.tf @@ -0,0 +1,5 @@ +variable "name_prefix" { + description = "A prefix used for naming resources." + type = string + default = "example" +} diff --git a/modules/aws-waf/examples/wafv2-custom-json-response-managed-rule-group/main.tf b/modules/aws-waf/examples/wafv2-custom-json-response-managed-rule-group/main.tf new file mode 100644 index 0000000..3aa1be3 --- /dev/null +++ b/modules/aws-waf/examples/wafv2-custom-json-response-managed-rule-group/main.tf @@ -0,0 +1,64 @@ +provider "aws" { + region = "eu-west-1" +} + +module "waf" { + source = "../.." + + name_prefix = var.name_prefix + allow_default_action = true + + visibility_config = { + cloudwatch_metrics_enabled = false + metric_name = "${var.name_prefix}-waf-setup-waf-main-metrics" + sampled_requests_enabled = false + } + + custom_response_bodies = [ + { + key = "403-forbidden-json" + content = "{\"code\":403,\"message\":\"Forbidden\"}" + content_type = "APPLICATION_JSON" + } + ] + + rules = [ + { + name = "AWSManagedRulesCommonRuleSet-rule" + priority = "0" + + override_action = "count" + + visibility_config = { + cloudwatch_metrics_enabled = true + metric_name = "AWSManagedRulesCommonRuleSet-metric" + sampled_requests_enabled = true + } + + managed_rule_group_statement = { + name = "AWSManagedRulesCommonRuleSet" + vendor_name = "AWS" + } + }, + { + name = "JsonResponse" + priority = "1" + action = "block" + custom_response = { + custom_response_body_key = "403-forbidden-json" + response_code = 403 + } + + visibility_config = { + cloudwatch_metrics_enabled = true + metric_name = "AWSManagedRulesCommonRuleSetJsonResponse" + sampled_requests_enabled = true + } + + label_match_statement = { + key = "awswaf:managed:aws:" + scope = "NAMESPACE" + } + }, + ] +} diff --git a/modules/aws-waf/examples/wafv2-custom-json-response-managed-rule-group/variables.tf b/modules/aws-waf/examples/wafv2-custom-json-response-managed-rule-group/variables.tf new file mode 100644 index 0000000..0519052 --- /dev/null +++ b/modules/aws-waf/examples/wafv2-custom-json-response-managed-rule-group/variables.tf @@ -0,0 +1,5 @@ +variable "name_prefix" { + description = "A prefix used for naming resources." + type = string + default = "example" +} diff --git a/modules/aws-waf/examples/wafv2-custom-response-code/main.tf b/modules/aws-waf/examples/wafv2-custom-response-code/main.tf new file mode 100644 index 0000000..6c7509a --- /dev/null +++ b/modules/aws-waf/examples/wafv2-custom-response-code/main.tf @@ -0,0 +1,66 @@ +provider "aws" { + region = "eu-west-1" +} + +module "waf" { + source = "../.." + + name_prefix = var.name_prefix + allow_default_action = true + + + visibility_config = { + cloudwatch_metrics_enabled = false + metric_name = "${var.name_prefix}-waf-setup-waf-main-metrics" + sampled_requests_enabled = false + } + + rules = [ + { + name = "ip-rate-based" + priority = "6" + action = "block" + rule_labels = ["LabelNameA"] + + custom_response = { + response_code = 412 + } + + rate_based_statement = { + limit = 2000 # Note this is by default in a 5-min span, ref: https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/wafv2_web_acl#rate_based_statement + aggregate_key_type = "IP" + } + + visibility_config = { + cloudwatch_metrics_enabled = false + metric_name = "IPRateBased-metric" + sampled_requests_enabled = false + } + }, + { + # Note: custom responses can not be applied to AWS managed rule groups directly. Must use a label technique, ref: https://aws.amazon.com/blogs/security/how-to-customize-behavior-of-aws-managed-rules-for-aws-waf/ + name = "AWSManagedRulesBotControlRuleSet-rule-0" + priority = "0" + + # Note: override_action is for managed rule sets only, otherwise would be action + override_action = "none" + + managed_rule_group_statement = { + name = "AWSManagedRulesBotControlRuleSet" + vendor_name = "AWS", + excluded_rule = [ + "SignalNonBrowserUserAgent", + "CategoryHttpLibrary", + "SignalAutomatedBrowser", + "CategoryMonitoring" + ] + } + + visibility_config = { + cloudwatch_metrics_enabled = false + metric_name = "AWSManagedRulesBotControlRuleSet-metric" + sampled_requests_enabled = false + } + } + ] +} diff --git a/modules/aws-waf/examples/wafv2-custom-response-code/outputs.tf b/modules/aws-waf/examples/wafv2-custom-response-code/outputs.tf new file mode 100644 index 0000000..7a216ba --- /dev/null +++ b/modules/aws-waf/examples/wafv2-custom-response-code/outputs.tf @@ -0,0 +1,24 @@ +output "web_acl_name" { + description = "The name of the WAFv2 WebACL." + value = module.waf.web_acl_name +} + +output "web_acl_arn" { + description = "The ARN of the WAFv2 WebACL." + value = module.waf.web_acl_arn +} + +output "web_acl_capacity" { + description = "The web ACL capacity units (WCUs) currently being used by this web ACL." + value = module.waf.web_acl_capacity +} + +output "web_acl_visibility_config_name" { + description = "The web ACL visibility config name" + value = module.waf.web_acl_visibility_config_name +} + +output "web_acl_rule_names" { + description = "List of created rule names" + value = module.waf.web_acl_rule_names +} diff --git a/modules/aws-waf/examples/wafv2-custom-response-code/variables.tf b/modules/aws-waf/examples/wafv2-custom-response-code/variables.tf new file mode 100644 index 0000000..0519052 --- /dev/null +++ b/modules/aws-waf/examples/wafv2-custom-response-code/variables.tf @@ -0,0 +1,5 @@ +variable "name_prefix" { + description = "A prefix used for naming resources." + type = string + default = "example" +} diff --git a/modules/aws-waf/examples/wafv2-custom-response/main.tf b/modules/aws-waf/examples/wafv2-custom-response/main.tf new file mode 100644 index 0000000..f11c729 --- /dev/null +++ b/modules/aws-waf/examples/wafv2-custom-response/main.tf @@ -0,0 +1,89 @@ +provider "aws" { + region = "eu-west-1" +} + +module "waf" { + source = "../.." + + name_prefix = var.name_prefix + allow_default_action = true + + visibility_config = { + cloudwatch_metrics_enabled = false + metric_name = "${var.name_prefix}-waf-setup-waf-main-metrics" + sampled_requests_enabled = false + } + + custom_response_bodies = [ + { + key = "custom_response_body_1", + content = "You are not authorized to access this resource.", + content_type = "TEXT_PLAIN" + }, + { + key = "custom_response_body_2", + content = "You there are not authorized to access this resource.", + content_type = "TEXT_PLAIN" + } + ] + + rules = [ + { + name = "ip-rate-based" + priority = "6" + action = "block" + rule_labels = ["LabelNameA", "LabelNameB"] + + custom_response = { + custom_response_body_key = "default_1", + response_code = 412 + response_headers = [ + { + name = "X-Custom-Header-1" + value = "You are not authorized to access this resource." + }, + { + name = "X-Custom-Header-2" + value = "Not authorized to access this resource." + } + ] + } + + rate_based_statement = { + limit = 2000 # Note this is by default in a 5-min span, ref: https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/wafv2_web_acl#rate_based_statement + aggregate_key_type = "IP" + } + + visibility_config = { + cloudwatch_metrics_enabled = false + metric_name = "IPRateBased-metric" + sampled_requests_enabled = false + } + }, + { + # Note: custom responses can not be applied to AWS managed rule groups directly. Must use a label technique, ref: https://aws.amazon.com/blogs/security/how-to-customize-behavior-of-aws-managed-rules-for-aws-waf/ + name = "AWSManagedRulesBotControlRuleSet-rule-0" + priority = "0" + + # Note: override_action is for managed rule sets only, otherwise would be action + override_action = "none" + + managed_rule_group_statement = { + name = "AWSManagedRulesBotControlRuleSet" + vendor_name = "AWS", + excluded_rule = [ + "SignalNonBrowserUserAgent", + "CategoryHttpLibrary", + "SignalAutomatedBrowser", + "CategoryMonitoring" + ] + } + + visibility_config = { + cloudwatch_metrics_enabled = false + metric_name = "AWSManagedRulesBotControlRuleSet-metric" + sampled_requests_enabled = false + } + } + ] +} diff --git a/modules/aws-waf/examples/wafv2-custom-response/outputs.tf b/modules/aws-waf/examples/wafv2-custom-response/outputs.tf new file mode 100644 index 0000000..7a216ba --- /dev/null +++ b/modules/aws-waf/examples/wafv2-custom-response/outputs.tf @@ -0,0 +1,24 @@ +output "web_acl_name" { + description = "The name of the WAFv2 WebACL." + value = module.waf.web_acl_name +} + +output "web_acl_arn" { + description = "The ARN of the WAFv2 WebACL." + value = module.waf.web_acl_arn +} + +output "web_acl_capacity" { + description = "The web ACL capacity units (WCUs) currently being used by this web ACL." + value = module.waf.web_acl_capacity +} + +output "web_acl_visibility_config_name" { + description = "The web ACL visibility config name" + value = module.waf.web_acl_visibility_config_name +} + +output "web_acl_rule_names" { + description = "List of created rule names" + value = module.waf.web_acl_rule_names +} diff --git a/modules/aws-waf/examples/wafv2-custom-response/variables.tf b/modules/aws-waf/examples/wafv2-custom-response/variables.tf new file mode 100644 index 0000000..0519052 --- /dev/null +++ b/modules/aws-waf/examples/wafv2-custom-response/variables.tf @@ -0,0 +1,5 @@ +variable "name_prefix" { + description = "A prefix used for naming resources." + type = string + default = "example" +} diff --git a/modules/aws-waf/examples/wafv2-geo-rules/main.tf b/modules/aws-waf/examples/wafv2-geo-rules/main.tf new file mode 100644 index 0000000..1a9bea4 --- /dev/null +++ b/modules/aws-waf/examples/wafv2-geo-rules/main.tf @@ -0,0 +1,69 @@ +provider "aws" { + region = "eu-west-1" +} + +##### +# Web Application Firewall configuration +##### +module "waf" { + source = "../.." + + name_prefix = var.name_prefix + + allow_default_action = true + + scope = "REGIONAL" + + visibility_config = { + cloudwatch_metrics_enabled = false + metric_name = "${var.name_prefix}-waf-setup-waf-main-metrics" + sampled_requests_enabled = false + } + + rules = [ + { + name = "AWSManagedRulesCommonRuleSet-rule-1" + priority = "1" + + override_action = "none" + + visibility_config = { + cloudwatch_metrics_enabled = false + metric_name = "AWSManagedRulesCommonRuleSet-metric" + sampled_requests_enabled = false + } + + managed_rule_group_statement = { + name = "AWSManagedRulesCommonRuleSet" + vendor_name = "AWS" + excluded_rule = [ + "SizeRestrictions_QUERYSTRING", + "SizeRestrictions_BODY", + "GenericRFI_QUERYARGUMENTS" + ] + } + }, + { + name = "allow-nl-gb-us-traffic-only" + priority = "2" + action = "allow" + + geo_match_statement = { + country_codes = ["NL", "GB", "US"], + forwarded_ip_config = { + header_name = "X-Forwarded-For" + fallback_behavior = "NO_MATCH" + } + } + + visibility_config = { + cloudwatch_metrics_enabled = false + sampled_requests_enabled = false + } + } + ] + + tags = { + "Environment" = "test" + } +} diff --git a/modules/aws-waf/examples/wafv2-geo-rules/outputs.tf b/modules/aws-waf/examples/wafv2-geo-rules/outputs.tf new file mode 100644 index 0000000..7a216ba --- /dev/null +++ b/modules/aws-waf/examples/wafv2-geo-rules/outputs.tf @@ -0,0 +1,24 @@ +output "web_acl_name" { + description = "The name of the WAFv2 WebACL." + value = module.waf.web_acl_name +} + +output "web_acl_arn" { + description = "The ARN of the WAFv2 WebACL." + value = module.waf.web_acl_arn +} + +output "web_acl_capacity" { + description = "The web ACL capacity units (WCUs) currently being used by this web ACL." + value = module.waf.web_acl_capacity +} + +output "web_acl_visibility_config_name" { + description = "The web ACL visibility config name" + value = module.waf.web_acl_visibility_config_name +} + +output "web_acl_rule_names" { + description = "List of created rule names" + value = module.waf.web_acl_rule_names +} diff --git a/modules/aws-waf/examples/wafv2-geo-rules/variables.tf b/modules/aws-waf/examples/wafv2-geo-rules/variables.tf new file mode 100644 index 0000000..0519052 --- /dev/null +++ b/modules/aws-waf/examples/wafv2-geo-rules/variables.tf @@ -0,0 +1,5 @@ +variable "name_prefix" { + description = "A prefix used for naming resources." + type = string + default = "example" +} diff --git a/modules/aws-waf/examples/wafv2-ip-rules/main.tf b/modules/aws-waf/examples/wafv2-ip-rules/main.tf new file mode 100644 index 0000000..4cc8d0f --- /dev/null +++ b/modules/aws-waf/examples/wafv2-ip-rules/main.tf @@ -0,0 +1,184 @@ +provider "aws" { + region = "eu-west-1" +} + +##### +# IP set resources +##### +resource "aws_wafv2_ip_set" "block_ip_set" { + name = "${var.name_prefix}-generated-ips" + + scope = "REGIONAL" + ip_address_version = "IPV4" + + # generates a list of all /16s + addresses = formatlist("%s.0.0.0/16", range(0, 50)) +} + +resource "aws_wafv2_ip_set" "custom_ip_set" { + name = "${var.name_prefix}-custom-ip-set" + + scope = "REGIONAL" + ip_address_version = "IPV4" + + addresses = [ + "10.0.0.0/16", + "10.10.0.0/16" + ] +} + +##### +# Web Application Firewall configuration +##### +module "waf" { + source = "../.." + + name_prefix = var.name_prefix + + allow_default_action = true + + + visibility_config = { + cloudwatch_metrics_enabled = false + metric_name = "${var.name_prefix}-waf-setup-waf-main-metrics" + sampled_requests_enabled = false + } + + rules = [ + { + name = "AWSManagedRulesCommonRuleSet-rule-1" + priority = "1" + + override_action = "none" + + visibility_config = { + cloudwatch_metrics_enabled = false + metric_name = "AWSManagedRulesCommonRuleSet-metric" + sampled_requests_enabled = false + } + + managed_rule_group_statement = { + name = "AWSManagedRulesCommonRuleSet" + vendor_name = "AWS" + excluded_rule = [ + "SizeRestrictions_QUERYSTRING", + "SizeRestrictions_BODY", + "GenericRFI_QUERYARGUMENTS" + ] + } + }, + { + name = "ip-rate-limit" + priority = "2" + action = "count" + + rate_based_statement = { + limit = 100 + aggregate_key_type = "IP" + + # Optional scope_down_statement to refine what gets rate limited + scope_down_statement = { + not_statement = { # not statement to rate limit everything except the following path + byte_match_statement = { + field_to_match = { + uri_path = "{}" + } + positional_constraint = "STARTS_WITH" + search_string = "/path/to/match" + priority = 0 + type = "NONE" + } + } + } + } + + visibility_config = { + cloudwatch_metrics_enabled = false + sampled_requests_enabled = false + } + }, + { + name = "ip-rate-limit-with-or-scope-down" + priority = "3" + action = "count" + + rate_based_statement = { + limit = 100 + aggregate_key_type = "IP" + + # Optional scope_down_statement to refine what gets rate limited + scope_down_statement = { + or_statement = { # OR and AND statements require 2 or more statements to function + statements = [ + { + byte_match_statement = { + field_to_match = { + uri_path = "{}" + } + positional_constraint = "STARTS_WITH" + search_string = "/api" + priority = 0 + type = "NONE" + } + }, + { + byte_match_statement = { + field_to_match = { + body = "{}" + } + positional_constraint = "CONTAINS" + search_string = "@gmail.com" + priority = 0 + type = "NONE" + } + }, + { + geo_match_statement = { + country_codes = ["NL", "GB", "US"] + } + } + ] + } + } + } + + visibility_config = { + cloudwatch_metrics_enabled = false + sampled_requests_enabled = false + } + }, + { + name = "allow-custom-ip-set" + priority = "4" + action = "count" + + ip_set_reference_statement = { + arn = aws_wafv2_ip_set.custom_ip_set.arn + } + + visibility_config = { + cloudwatch_metrics_enabled = false + sampled_requests_enabled = false + } + }, + { + name = "block-ip-set" + priority = "5" + action = "block" + + ip_set_reference_statement = { + arn = aws_wafv2_ip_set.block_ip_set.arn + } + + visibility_config = { + cloudwatch_metrics_enabled = false + metric_name = "test-waf-setup-waf-ip-set-block-metrics" + sampled_requests_enabled = false + } + } + ] + + tags = { + "Environment" = "test" + } +} diff --git a/modules/aws-waf/examples/wafv2-ip-rules/outputs.tf b/modules/aws-waf/examples/wafv2-ip-rules/outputs.tf new file mode 100644 index 0000000..ea26ab6 --- /dev/null +++ b/modules/aws-waf/examples/wafv2-ip-rules/outputs.tf @@ -0,0 +1,34 @@ +output "web_acl_name" { + description = "The name of the WAFv2 WebACL." + value = module.waf.web_acl_name +} + +output "web_acl_arn" { + description = "The ARN of the WAFv2 WebACL." + value = module.waf.web_acl_arn +} + +output "web_acl_capacity" { + description = "The web ACL capacity units (WCUs) currently being used by this web ACL." + value = module.waf.web_acl_capacity +} + +output "web_acl_visibility_config_name" { + description = "The web ACL visibility config name" + value = module.waf.web_acl_visibility_config_name +} + +output "web_acl_rule_names" { + description = "List of created rule names" + value = module.waf.web_acl_rule_names +} + +output "custom_ip_set_arn" { + description = "The ARN of the Custom IP Set" + value = aws_wafv2_ip_set.custom_ip_set.arn +} + +output "block_ip_set_arn" { + description = "The ARN of the Block IP Set" + value = aws_wafv2_ip_set.block_ip_set.arn +} diff --git a/modules/aws-waf/examples/wafv2-ip-rules/variables.tf b/modules/aws-waf/examples/wafv2-ip-rules/variables.tf new file mode 100644 index 0000000..0519052 --- /dev/null +++ b/modules/aws-waf/examples/wafv2-ip-rules/variables.tf @@ -0,0 +1,5 @@ +variable "name_prefix" { + description = "A prefix used for naming resources." + type = string + default = "example" +} diff --git a/modules/aws-waf/examples/wafv2-labelmatch-rules/main.tf b/modules/aws-waf/examples/wafv2-labelmatch-rules/main.tf new file mode 100644 index 0000000..b75b876 --- /dev/null +++ b/modules/aws-waf/examples/wafv2-labelmatch-rules/main.tf @@ -0,0 +1,82 @@ +provider "aws" { + region = "eu-west-1" +} + +##### +# Web Application Firewall configuration +##### +module "waf" { + source = "../.." + + name_prefix = var.name_prefix + + allow_default_action = true + + scope = "REGIONAL" + + visibility_config = { + cloudwatch_metrics_enabled = false + metric_name = "${var.name_prefix}-waf-setup-waf-main-metrics" + sampled_requests_enabled = false + } + + rules = [ + { + name = "AWSManagedRulesBotControlRuleSet-rule-1" + priority = "1" + + override_action = "none" + + visibility_config = { + cloudwatch_metrics_enabled = false + metric_name = "AWSManagedRulesBotControlRuleSet-metric" + sampled_requests_enabled = false + } + + managed_rule_group_statement = { + name = "AWSManagedRulesBotControlRuleSet" + vendor_name = "AWS" + excluded_rule = [ + "SignalNonBrowserUserAgent" + ] + } + }, + { + name = "block-specific-agent" + priority = "2" + action = "block" + + and_statement = { + statements = [ + { + label_match_statement = { + key = "awswaf:managed:aws:bot-control:signal:non_browser_user_agent" + scope = "LABEL" + } + }, + { + byte_match_statement = { + field_to_match = { + single_header = { + name = "user-agent" + } + } + positional_constraint = "CONTAINS" + search_string = "BadBot" + priority = 0 + type = "NONE" + } + } + ] + } + visibility_config = { + cloudwatch_metrics_enabled = false + sampled_requests_enabled = false + } + } + ] + + tags = { + "Environment" = "test" + } +} diff --git a/modules/aws-waf/examples/wafv2-labelmatch-rules/outputs.tf b/modules/aws-waf/examples/wafv2-labelmatch-rules/outputs.tf new file mode 100644 index 0000000..7a216ba --- /dev/null +++ b/modules/aws-waf/examples/wafv2-labelmatch-rules/outputs.tf @@ -0,0 +1,24 @@ +output "web_acl_name" { + description = "The name of the WAFv2 WebACL." + value = module.waf.web_acl_name +} + +output "web_acl_arn" { + description = "The ARN of the WAFv2 WebACL." + value = module.waf.web_acl_arn +} + +output "web_acl_capacity" { + description = "The web ACL capacity units (WCUs) currently being used by this web ACL." + value = module.waf.web_acl_capacity +} + +output "web_acl_visibility_config_name" { + description = "The web ACL visibility config name" + value = module.waf.web_acl_visibility_config_name +} + +output "web_acl_rule_names" { + description = "List of created rule names" + value = module.waf.web_acl_rule_names +} diff --git a/modules/aws-waf/examples/wafv2-labelmatch-rules/variables.tf b/modules/aws-waf/examples/wafv2-labelmatch-rules/variables.tf new file mode 100644 index 0000000..0519052 --- /dev/null +++ b/modules/aws-waf/examples/wafv2-labelmatch-rules/variables.tf @@ -0,0 +1,5 @@ +variable "name_prefix" { + description = "A prefix used for naming resources." + type = string + default = "example" +} diff --git a/modules/aws-waf/examples/wafv2-logging-configuration/main.tf b/modules/aws-waf/examples/wafv2-logging-configuration/main.tf new file mode 100644 index 0000000..1112397 --- /dev/null +++ b/modules/aws-waf/examples/wafv2-logging-configuration/main.tf @@ -0,0 +1,198 @@ +provider "aws" { + region = "eu-west-1" +} + + + +##### +# Firehose configuration +##### + +resource "aws_s3_bucket" "bucket" { + bucket = "aws-waf-firehose-stream-test-bucket" + acl = "private" +} + +resource "aws_iam_role" "firehose" { + name = "firehose-stream-test-role" + + assume_role_policy = <
key = string
content = string
content_type = string
}))