Skip to content

Commit

Permalink
Merge pull request #1 from sudoblark/feature/initial-module-setup
Browse files Browse the repository at this point in the history
Initial module setup
  • Loading branch information
benjaminlukeclark authored Sep 14, 2024
2 parents 52cd12a + 531cb0c commit d8bd5d3
Show file tree
Hide file tree
Showing 12 changed files with 265 additions and 4 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/commit-to-pr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
validation:
strategy:
matrix:
folder: ["add", "folders", "here"]
folder: ["./", "examples/security_group"]
name: Terraform validate for ${{ matrix.folder }}
runs-on: ubuntu-20.04
steps:
Expand All @@ -41,7 +41,7 @@ jobs:
linting:
strategy:
matrix:
folder: ["add", "folders", "here"]
folder: ["./", "examples/security_group"]
name: Terraform lint for ${{ matrix.folder }}
runs-on: ubuntu-20.04
steps:
Expand All @@ -59,7 +59,7 @@ jobs:
plan:
strategy:
matrix:
folder: ["add", "folders", "here"]
folder: ["examples/security_group"]
name: Terraform plan for ${{ matrix.folder }}
runs-on: ubuntu-20.04
needs: [validation, linting]
Expand Down
1 change: 1 addition & 0 deletions .terraform-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1.5.1
63 changes: 62 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,72 @@ The below documentation is intended to assist users in utilising the module, the
the module itself, and the [examples](#examples) section which has examples of how to utilise the module.

<!-- BEGIN_TF_DOCS -->
## Requirements

| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | ~> 1.5.0 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.61.0 |

## Providers

| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | 5.67.0 |

## Modules

No modules.

## Resources

| Name | Type |
|------|------|
| [aws_security_group.groups](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource |
| [aws_security_group_rule.rule](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_application_name"></a> [application\_name](#input\_application\_name) | Name of the application utilising resource. | `string` | n/a | yes |
| <a name="input_environment"></a> [environment](#input\_environment) | Which environment this is being instantiated in. | `string` | n/a | yes |
| <a name="input_raw_security_groups"></a> [raw\_security\_groups](#input\_raw\_security\_groups) | Data structure<br>---------------<br>A list of dictionaries, where each dictionary has the following attributes:<br><br>REQUIRED<br>---------<br>- suffix : Security group suffix to use for naming and unique identifiers<br>- description : Description to give to the security group<br><br>OPTIONAL<br>---------<br>- rules: A list of dictionaries, where each dictionary has the following values:<br>-- name : Friendly name used through Terraform for instantiation and cross-referencing<br>-- type : Ingress/egress<br>-- from\_port : Start port<br>-- to\_port : End port<br>-- protocol : Protocol. If not icmp, icmpv6, tcp, udp, or all use the protocol number.<br>-- description : Friendly description of the rule, required for auditing purposes.<br><br>In addition, the following optional args are available:<br>-- cidr\_blocks : List of CIDR blocks. Cannot be specified with source\_security\_group\_id or self.<br>-- ipv6\_cidr\_blocks : List of IPv6 CIDR blocks. Cannot be specified with source\_security\_group\_id or self.<br>-- prefix\_list\_ids : List of Prefix List IDs.<br>-- self : Whether the security group itself will be added as a source to this ingress rule. Cannot be specified with cidr\_blocks, ipv6\_cidr\_blocks, or source\_security\_group\_id.<br>-- source\_security\_group\_id : Security group id to allow access to/from, depending on the type. Cannot be specified with cidr\_blocks, ipv6\_cidr\_blocks, or self. | <pre>list(<br> object({<br> suffix : string,<br> description : string,<br> rules : optional(list(<br> object({<br> name = string,<br> type = string,<br> from_port = string,<br> to_port = string,<br> protocol = string,<br> description = string,<br> cidr_blocks = optional(list(string), null),<br> ipv6_cidr_blocks = optional(list(string), null),<br> prefix_list_ids = optional(list(string), null),<br> self = optional(bool, null),<br> source_security_group_id = optional(string, null)<br> })<br> ), [])<br><br> })<br> )</pre> | n/a | yes |
| <a name="input_vpc_config"></a> [vpc\_config](#input\_vpc\_config) | AWS VPC ID within which to create the security group. | `string` | n/a | yes |

## Outputs

No outputs.
<!-- END_TF_DOCS -->

## Data structure
<POPULATE WITH YOUR DATA STRUCTURE>
```
Data structure
---------------
A list of dictionaries, where each dictionary has the following attributes:
REQUIRED
---------
- suffix : Security group suffix to use for naming and unique identifiers
- description : Description to give to the security group
OPTIONAL
---------
- rules: A list of dictionaries, where each dictionary has the following values:
-- name : Friendly name used through Terraform for instantiation and cross-referencing
-- type : Ingress/egress
-- from_port : Start port
-- to_port : End port
-- protocol : Protocol. If not icmp, icmpv6, tcp, udp, or all use the protocol number.
-- description : Friendly description of the rule, required for auditing purposes.
In addition, the following optional args are available:
-- cidr_blocks : List of CIDR blocks. Cannot be specified with source_security_group_id or self.
-- ipv6_cidr_blocks : List of IPv6 CIDR blocks. Cannot be specified with source_security_group_id or self.
-- prefix_list_ids : List of Prefix List IDs.
-- self : Whether the security group itself will be added as a source to this ingress rule. Cannot be specified with cidr_blocks, ipv6_cidr_blocks, or source_security_group_id.
-- source_security_group_id : Security group id to allow access to/from, depending on the type. Cannot be specified with cidr_blocks, ipv6_cidr_blocks, or self.
```

## Examples
See `examples` folder for an example setup.
11 changes: 11 additions & 0 deletions aws_security_group.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
resource "aws_security_group" "groups" {
for_each = { for group in var.raw_security_groups : group.suffix => group }

name = upper(format("aws-%s-%s-%s-SG",
var.environment,
var.application_name,
each.value["suffix"])
)
description = format("%s - Managed by Terraform", each.value["description"])
vpc_id = var.vpc_config
}
30 changes: 30 additions & 0 deletions aws_security_group_rule.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
locals {
actual_security_group_rules = flatten([
for group in var.raw_security_groups : [
for rule in group.rules : merge(rule, {
identifier : format("%s/%s", group.suffix, rule.name),
security_group_id = aws_security_group.groups[group.suffix].id
})
]
])
}

resource "aws_security_group_rule" "rule" {
for_each = { for rule in local.actual_security_group_rules : rule.identifier => rule }
type = each.value["type"]
from_port = each.value["from_port"]
to_port = each.value["to_port"]
protocol = each.value["protocol"]
security_group_id = each.value["security_group_id"]
description = each.value["description"]

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"], null)
self = try(each.value["self"], null)
source_security_group_id = try(each.value["source_security_group_id"], null)

depends_on = [
aws_security_group.groups
]
}
1 change: 1 addition & 0 deletions examples/security_group/.terraform-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1.5.1
2 changes: 2 additions & 0 deletions examples/security_group/data.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Get default VPC
data "aws_vpc" "vpc" {}
37 changes: 37 additions & 0 deletions examples/security_group/locals.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
locals {
raw_security_groups = [
{
"suffix" : "lambda",
"description" : "Lambda Function security group",
"rules" : [
{
"name" : "All traffic from VPC",
"type" : "ingress",
"from_port" : "0",
"to_port" : "0",
"protocol" : "-1",
"description" : "VPC Traffic (Ingress)",
"cidr_blocks" : ["1.2.3.0/24"]
},
{
"name" : "All traffic to VPC",
"type" : "egress",
"from_port" : "0",
"to_port" : "0",
"protocol" : "-1",
"description" : "VPC Traffic (Egress)",
"cidr_blocks" : ["1.2.3.0/24"]
},
{
"name" : "Public endpoint traffic",
"type" : "egress",
"from_port" : "443",
"to_port" : "443",
"protocol" : "tcp",
"description" : "Public Endpoint traffic (Egress)",
"cidr_blocks" : ["0.0.0.0/0"]
}
]
}
]
}
21 changes: 21 additions & 0 deletions examples/security_group/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 5.61.0"
}
}
required_version = "~> 1.5.0"
}

provider "aws" {
region = "eu-west-2"
}

module "security_group" {
source = "github.com/sudoblark/sudoblark.terraform.module.aws.security_group?ref=1.0.0"
environment = var.environment
application_name = var.application_name
raw_security_groups = local.raw_security_groups
vpc_config = data.aws_vpc.vpc.id
}
15 changes: 15 additions & 0 deletions examples/security_group/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
variable "environment" {
description = "Which environment this is being instantiated in."
type = string
validation {
condition = contains(["dev", "test", "prod"], var.environment)
error_message = "Must be either dev, test or prod"
}
default = "prod"
}

variable "application_name" {
description = "Name of the application utilising the resource resource."
type = string
default = "demo-app"
}
9 changes: 9 additions & 0 deletions main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 5.61.0"
}
}
required_version = "~> 1.5.0"
}
73 changes: 73 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Input variable definitions
variable "environment" {
description = "Which environment this is being instantiated in."
type = string
validation {
condition = contains(["dev", "test", "prod"], var.environment)
error_message = "Must be either dev, test or prod"
}
}

variable "application_name" {
description = "Name of the application utilising resource."
type = string
}

variable "vpc_config" {
description = "AWS VPC ID within which to create the security group."
type = string
}

variable "raw_security_groups" {
description = <<EOF
Data structure
---------------
A list of dictionaries, where each dictionary has the following attributes:
REQUIRED
---------
- suffix : Security group suffix to use for naming and unique identifiers
- description : Description to give to the security group
OPTIONAL
---------
- rules: A list of dictionaries, where each dictionary has the following values:
-- name : Friendly name used through Terraform for instantiation and cross-referencing
-- type : Ingress/egress
-- from_port : Start port
-- to_port : End port
-- protocol : Protocol. If not icmp, icmpv6, tcp, udp, or all use the protocol number.
-- description : Friendly description of the rule, required for auditing purposes.
In addition, the following optional args are available:
-- cidr_blocks : List of CIDR blocks. Cannot be specified with source_security_group_id or self.
-- ipv6_cidr_blocks : List of IPv6 CIDR blocks. Cannot be specified with source_security_group_id or self.
-- prefix_list_ids : List of Prefix List IDs.
-- self : Whether the security group itself will be added as a source to this ingress rule. Cannot be specified with cidr_blocks, ipv6_cidr_blocks, or source_security_group_id.
-- source_security_group_id : Security group id to allow access to/from, depending on the type. Cannot be specified with cidr_blocks, ipv6_cidr_blocks, or self.
EOF
type = list(
object({
suffix : string,
description : string,
rules : optional(list(
object({
name = string,
type = string,
from_port = string,
to_port = string,
protocol = string,
description = string,
cidr_blocks = optional(list(string), null),
ipv6_cidr_blocks = optional(list(string), null),
prefix_list_ids = optional(list(string), null),
self = optional(bool, null),
source_security_group_id = optional(string, null)
})
), [])

})
)
}

0 comments on commit d8bd5d3

Please sign in to comment.