Skip to content

Commit

Permalink
Merge pull request #16 from aidanmelen/matrix
Browse files Browse the repository at this point in the history
feat: Rule Matrix
  • Loading branch information
aidanmelen authored Sep 14, 2022
2 parents 256b055 + c2330e2 commit 7abe55d
Show file tree
Hide file tree
Showing 53 changed files with 7,262 additions and 5,453 deletions.
1 change: 1 addition & 0 deletions .makefile.docs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ test-basic Test the basic example
test-complete Test the complete example
test-customer Test the customer example
test-managed Test the managed example
test-matrix Test the matrix example
test-computed Test the computed example
test-rules-only Test the rules_only example
clean Clean project
116 changes: 27 additions & 89 deletions .terraform-docs
Original file line number Diff line number Diff line change
Expand Up @@ -2,116 +2,54 @@ content: |-
{{ .Header }}
## Features

This module aims to implement **ALL** combinations of arguments supported by AWS and latest stable version of Terraform.
This module aims to implement **ALL** combinations of `aws_security_group` and `aws_security_group_rule` arguments supported by AWS and latest stable version of Terraform.

Ingress and egress rules can be configured in a variety of ways:

- Customer ingress/egress rules. Customer rules for security groups are analogous to [AWS customer policies](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html#customer-managed-policies) for IAM.
- Managed ingress/egress rules (e.g. `all-all`, `https-443-tcp`, `postgresql-tcp`, and `ssh-tcp` just to name a few.). Please see [rules.tf](https://github.com/aidanmelen/terraform-aws-security-group-v2/tree/main/rules.tf) for the complete list of managed rules. Managed rules for security groups are analogous to [AWS managed policies](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html#aws-managed-policies) for IAM.
- Common egress/egress for common scenarios sech as `all-all-from-self`, `https-tcp-from-public`, and `all-all-to-public` just to name a few. Please see [rules.tf](https://github.com/aidanmelen/terraform-aws-security-group-v2/tree/main/rules.tf) for the complete list of common rules.
- Computed ingress/egress rules for manage Security Group rules that reference unknown values such as: `aws_vpc.vpc.cidr_blocks`, `aws_security_group.sg.id`, etc. computed rules support all customer, managed, and common rules.
- Conditionally create security group and/or all required security group rules.

What's more, this module was modeled after the [terraform-aws-modules/terraform-aws-security-group](https://github.com/terraform-aws-modules/terraform-aws-security-group#features) module and aims to have feature parody. Please see the [Acknowledgments](https://github.com/aidanmelen/terraform-aws-security-group-v2/blob/main/README.md#acknowledgments) section for more information.
What's more, this module was designed after the [terraform-aws-modules/terraform-aws-security-group](https://github.com/terraform-aws-modules/terraform-aws-security-group#features) module and aims to have feature parody. Please see the [Acknowledgments](https://github.com/aidanmelen/terraform-aws-security-group-v2/blob/main/README.md#acknowledgments) section for more information.

## Examples

### Security Group with basic rules

Recreate the [Basic Usage](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group#basic-usage) example from the `aws_security_group` resource with:
Create a Security Group with the following rules:

- Ingress `https-443-tcp` managed rules (ipv4/ipv6)
- Ingress `https-443-tcp` managed rules (ipv4 and ipv6)
- Egress `all-all-to-public` common rule

```hcl
{{ include "examples/basic/.main.tf.docs" }}
```

Please see the [Basic Example](https://github.com/aidanmelen/terraform-aws-security-group-v2/tree/main/examples/basic) for more information.

### Security Group with complete rules

Create a AWS Security Group with a broad mix of various features and settings provided by this module.

```hcl
{{ include "examples/complete/.main.tf.docs" }}
```

Please see the [Complete Example](https://github.com/aidanmelen/terraform-aws-security-group-v2/tree/main/examples/complete) for more information.

### Security Group with common scenario rules

Create security group with common scenario rules (e.g. `https-tcp-from-public`, `all-all-from-self`, `all-all-to-public`, etc). This is like a shortcut for managed rules that have a known source or destination.

<details><summary>Click to show</summary>

```hcl
{{ include "examples/common/.main.tf.docs" }}
```

</details><br/>

Please see the [Common Rules Example](https://github.com/aidanmelen/terraform-aws-security-group-v2/tree/main/examples/common) for more information.

### Security Group with customer rules

Create a security group with customer rules. Customer rules for security groups are analogous to [AWS customer policies](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html#customer-managed-policies) for IAM.

<details><summary>Click to show</summary>

```hcl
{{ include "examples/customer/.main.tf.docs" }}
```

</details><br/>

Please see the [customer Rules Example](https://github.com/aidanmelen/terraform-aws-security-group-v2/tree/main/examples/rules) for more information.

### Security Group with managed rules

Create a security group with managed rules. Managed rules for security groups are analogous to [AWS managed policies](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html#aws-managed-policies) for IAM.

<details><summary>Click to show</summary>

```hcl
{{ include "examples/managed/.main.tf.docs" }}
```

</details><br/>

Please see the [Managed Rules Example](https://github.com/aidanmelen/terraform-aws-security-group-v2/tree/main/examples/managed) for more information.

### Security Group with computed rules

Create a security group with a computed rules. Computed security group rules uses `count` to dynamically create rules with unknown values during the initial Terraform plan. Please see [Limitations on values used in for_each](https://www.terraform.io/language/meta-arguments/for_each#limitations-on-values-used-in-for_each).
Please see the full examples for more information:

<details><summary>Click to show</summary>
- [Basic Example](https://github.com/aidanmelen/terraform-aws-security-group-v2/tree/main/examples/basic)

```hcl
{{ include "examples/computed/.main.tf.docs" }}
```
- [Complete Example](https://github.com/aidanmelen/terraform-aws-security-group-v2/tree/main/examples/complete)

</details><br/>
- [Customer Rules Example](https://github.com/aidanmelen/terraform-aws-security-group-v2/tree/main/examples/rules)

Please see the [Computed Rules Example](https://github.com/aidanmelen/terraform-aws-security-group-v2/tree/main/examples/computed) for more information.
- [Managed Rules Example](https://github.com/aidanmelen/terraform-aws-security-group-v2/tree/main/examples/managed)

### Only rules with pre-existing security group
- [Common Rules Example](https://github.com/aidanmelen/terraform-aws-security-group-v2/tree/main/examples/common)

Use the module to create rules for a pre-existing security group.
- [Matrix Rules Example](https://github.com/aidanmelen/terraform-aws-security-group-v2/tree/main/examples/matrix)

<details><summary>Click to show</summary>
- [Computed Rules Example](https://github.com/aidanmelen/terraform-aws-security-group-v2/tree/main/examples/computed)

```hcl
{{ include "examples/rules_only/.main.tf.docs" }}
```
- [Rules Only Example](https://github.com/aidanmelen/terraform-aws-security-group-v2/tree/main/examples/rules_only)

</details><br/>
## Key Concepts

Please see the [Rules Only Example](https://github.com/aidanmelen/terraform-aws-security-group-v2/tree/main/examples/rules_only) for more information.
| Terminology | Description |
|---|---|
| **AWS Security Group Rule** | The Security Group (SG) rule resource (ingress/egress). |
| **Customer Rule** | A module rule where the customer explicitly declares all of the SG rule arguments. <br/><br/>These rules are analogous to [AWS customer policies](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html#customer-managed-policies) for IAM. |
| **Managed Rule** | A module rule that references an alias for a managed/[predefined](https://github.com/terraform-aws-modules/terraform-aws-security-group#security-group-with-predefined-rules) group of `from_port`, `to_port`, and `protocol` arguments. <br/><br/> E.g. `https-443-tcp`, `postgresql-tcp`, `ssh-tcp`, and `all-all`. Please see [rules.tf](https://github.com/aidanmelen/terraform-aws-security-group-v2/tree/main/rules.tf) for the complete list of managed rules. <br/><br/>These rules are analogous to [AWS managed policies](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html#aws-managed-policies) for IAM. |
| **Common Rule** | A module rule that references an alias for common scenarios where all SG rule arguments, including the source/destination, are known and managed. <br/><br/>E.g. `all-all-from-self`, `https-tcp-from-public`, and `all-all-to-public` just to name a few. Please see [rules.tf](https://github.com/aidanmelen/terraform-aws-security-group-v2/tree/main/rules.tf) for the complete list of common rules. |
| **Matrix Rules** | A map of module rule(s) and source(s)/destination(s) representing the multi-dimensional matrix rules to be applied. <br/><br/>These rules act like a [multi-dimension matrix in Github Actions](https://docs.github.com/en/actions/using-jobs/using-a-matrix-for-your-jobs#example-using-a-multi-dimension-matrix).|
| **Computed Rule** | A special module rule that works with [unknown values](https://github.com/hashicorp/terraform/issues/30937) such as: `aws_vpc.vpc.cidr_blocks`, `aws_security_group.sg.id`, etc. All types of module rules are supported. |

## Tests

Run Terratest using the [Makefile](https://github.com/aidanmelen/terraform-aws-security-group-v2/tree/main/Makefile) targets:

1. `make setup`
2. `make tests`

Expand All @@ -136,20 +74,20 @@ content: |-

This modules aims to improve on the venerable [terraform-aws-modules/terraform-aws-security-group](https://github.com/terraform-aws-modules/terraform-aws-security-group) module authored by [Anton Babenko](https://github.com/antonbabenko). It does so by:

- Reduce the amount of code with [`for` expressions](https://www.terraform.io/language/expressions/for). The [main.tf](https://github.com/aidanmelen/terraform-aws-security-group-v2/blob/main/main.tf) is ~100 lines when compared to the [~800 lines in the terraform-aws-security-group module](https://github.com/terraform-aws-modules/terraform-aws-security-group/blob/master/main.tf).
- Reduce the amount of code with [`for` expressions](https://www.terraform.io/language/expressions/for). The [main.tf](https://github.com/aidanmelen/terraform-aws-security-group-v2/blob/main/main.tf) and [matrix.tf](https://github.com/aidanmelen/terraform-aws-security-group-v2/blob/main/matrix.tf) are both ~100 lines.

- Follow DRY principals by using [Conditionally Omitted Arguments](https://www.hashicorp.com/blog/terraform-0-12-conditional-operator-improvements#conditionally-omitted-arguments) AKA nullables.

- Dynamically create customer, managed and common security group rule resources with [`for_each` meta-arguments](https://www.terraform.io/language/meta-arguments/for_each). `for_each` has two advantages over `count`:

1. Resources created with `for_each` are identified by a list of string values instead of by index with `count`.
2. If an element is removed from the middle of the list, every security group rule after that element would see its values change, resulting in more remote object changes than intended. Using `for_each` gives the same flexibility without the extra churn. Please see [When to Use for_each Instead of count](https://www.terraform.io/language/meta-arguments/count#when-to-use-for_each-instead-of-count).
2. If an element is removed from the middle of the list, every security group rule after that element would see its values change, resulting in more remote object changes than intended. Using `for_each` gives the same flexibility without the extra churn. Please see [When to Use for_each Instead of count](https://www.terraform.io/language/meta-arguments/count#when-to-use-for_each-instead-of-count) for more information.

- Computed security group rule resources must use `count` due to the [Limitations on values used in `for_each`](https://www.terraform.io/language/meta-arguments/for_each#limitations-on-values-used-in-for_each). However, this implementation uses the `length` function to dynamically set the `count` which is an improvement from the `number_of_computed_` variables used by the [terraform-aws-security-group](https://github.com/terraform-aws-modules/terraform-aws-security-group#note-about-value-of-count-cannot-be-computed) module.
- Computed security group rule resources must use `count` due to the [Limitations on values used in `for_each`](https://www.terraform.io/language/meta-arguments/for_each#limitations-on-values-used-in-for_each). However, this implementation uses the `length` function to dynamically set the `count` which is an improvement from the `number_of_computed_` variables used by the [terraform-aws-security-group](https://github.com/terraform-aws-modules/terraform-aws-security-group#note-about-value-of-count-cannot-be-computed) module. Please see [#30937](https://github.com/hashicorp/terraform/issues/30937) for more information on unknown values.

- Encourage the security best practice of restrictive rules by making users **opt-in** to common rules like `all-all-to-public`. This approach is consistent with the implementation of the `aws_security_group_rule` resource as described in the [NOTE on Egress rules](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group#basic-usage). Moreover, please see [no-public-egress-sgr](https://aquasecurity.github.io/tfsec/v0.61.3/checks/aws/vpc/no-public-egress-sgr/) for more information.

- Improve security by making it easy for users to declare granular customer, managed, common, and computed security group rules.
- Improve security by making it easy for users to declare granular customer, managed, common, matrix, and computed security group rules.

- Test examples with [Terratest](https://terratest.gruntwork.io/).

Expand Down
14 changes: 10 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@ setup: ## Setup project
terraform init
cd examples/basic && terraform init
cd examples/complete && terraform init
cd examples/common && terraform init
cd examples/customer && terraform init
cd examples/managed && terraform init
cd examples/common && terraform init
cd examples/matrix && terraform init
cd examples/computed && terraform init
cd examples/rules_only && terraform init

Expand Down Expand Up @@ -53,7 +54,7 @@ lint-all: docs ## Lint all files with pre-commit and render docs
pre-commit run --all-files
git add -A

tests: test-basic test-complete test-customer test-managed test-computed test-rules-only lint ## Tests with Terratest
tests: test-basic test-complete test-customer test-managed test-computed test-matrix test-rules-only lint ## Tests with Terratest

test-basic: ## Test the basic example
go test test/terraform_basic_test.go -timeout 5m -v |& tee test/terraform_basic_test.log
Expand All @@ -67,6 +68,9 @@ test-customer: ## Test the customer example
test-managed: ## Test the managed example
go test test/terraform_managed_test.go -timeout 5m -v |& tee test/terraform_managed_test.log

test-matrix: ## Test the matrix example
go test test/terraform_matrix_test.go -timeout 5m -v |& tee test/terraform_matrix_test.log

test-computed: ## Test the computed example
go test test/terraform_computed_test.go -timeout 5m -v |& tee test/terraform_computed_test.log

Expand All @@ -77,18 +81,20 @@ clean: ## Clean project
@rm -f .terraform.lock.hcl
@rm -f examples/basic/.tebasiclock.hcl
@rm -f examples/complete/.tebasiclock.hcl
@rm -f examples/common/.terraform.lock.hcl
@rm -f examples/customer/.terraform.lock.hcl
@rm -f examples/managed/.terraform.lock.hcl
@rm -f examples/common/.terraform.lock.hcl
@rm -f examples/matrix/.terraform.lock.hcl
@rm -f examples/computed/.terraform.lock.hcl
@rm -f examples/rules_only/.terraform.lock.hcl

@rm -rf .terraform
@rm -rf examples/basic/.terraform
@rm -rf examples/complete/.terraform
@rm -rf examples/common/.terraform
@rm -rf examples/customer/.terraform
@rm -rf examples/managed/.terraform
@rm -rf examples/common/.terraform
@rm -rf examples/matrix/.terraform
@rm -rf examples/computed/.terraform
@rm -rf examples/rules_only/.terraform

Expand Down
Loading

0 comments on commit 7abe55d

Please sign in to comment.