diff --git a/.bumpversion.cfg b/.bumpversion.cfg index ee11dd6..1b11052 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,6 +1,7 @@ [bumpversion] -current_version = 0.0.0 +current_version = 1.0.0 commit = True message = Bumps version to {new_version} tag = False tag_name = {new_version} + diff --git a/.dependabot/config.yml b/.dependabot/config.yml index ab6dbbc..9706dd8 100644 --- a/.dependabot/config.yml +++ b/.dependabot/config.yml @@ -5,3 +5,15 @@ update_configs: - package_manager: "terraform" directory: "/" update_schedule: "daily" + + - package_manager: "terraform" + directory: "/tests/create_sg" + update_schedule: "daily" + + - package_manager: "terraform" + directory: "/tests/no_create_sg" + update_schedule: "daily" + + - package_manager: "terraform" + directory: "/tests/use_all_variables" + update_schedule: "daily" diff --git a/.editorconfig b/.editorconfig index 9c61d05..7109c82 100644 --- a/.editorconfig +++ b/.editorconfig @@ -8,6 +8,7 @@ insert_final_newline = true indent_style = space indent_size = 2 charset = utf-8 +tab_width = 4 [*.md] trim_trailing_whitespace = false @@ -15,6 +16,14 @@ trim_trailing_whitespace = false [*.py] indent_size = 4 +[go.mod] +indent_style = tab +indent_size = 1 + +[*.go] +indent_style = tab +indent_size = 1 + [Makefile] indent_style = tab indent_size = 1 diff --git a/LICENSE b/LICENSE index 261eeb9..d7f3287 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright [yyyy] [name of copyright owner] + Copyright 2019 Maintainers of plus3it/terraform-aws-tardigrade-security-group Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/Makefile b/Makefile index 1d88840..7947d76 100644 --- a/Makefile +++ b/Makefile @@ -100,24 +100,30 @@ json/format: | guard/program/jq $(FIND_JSON) | $(XARGS) bash -c 'echo "$$(jq --indent 4 -S . "{}")" > "{}"' @ echo "[$@]: Successfully formatted JSON files!" -docs/%: README_PARTS := _docs/MAIN.md <(echo) <(terraform-docs markdown table .) +tfdocs-awk/install: $(BIN_DIR) +tfdocs-awk/install: ARCHIVE := https://github.com/plus3it/tfdocs-awk/archive/master.tar.gz +tfdocs-awk/install: + $(CURL) $(ARCHIVE) | tar -C $(BIN_DIR) --strip-components=1 --wildcards '*.sh' --wildcards '*.awk' -xzvf - + +docs/%: README_PARTS := _docs/MAIN.md <(echo) <($(BIN_DIR)/terraform-docs.sh markdown table .) docs/%: README_FILE ?= README.md -docs/lint: | guard/program/terraform-docs +docs/lint: | guard/program/terraform-docs tfdocs-awk/install @ echo "[$@]: Linting documentation files.." diff $(README_FILE) <(cat $(README_PARTS)) @ echo "[$@]: Documentation files PASSED lint test!" -docs/generate: | guard/program/terraform-docs +docs/generate: | guard/program/terraform-docs tfdocs-awk/install @ echo "[$@]: Creating documentation files.." cat $(README_PARTS) > $(README_FILE) @ echo "[$@]: Documentation files creation complete!" -dep/install: guard/program/curl - curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh - -terratest/install: | guard/program/go guard/program/dep - cd tests && dep ensure +terratest/install: | guard/program/go + cd tests && go mod init terraform-aws-tardigrade-security-group/tests + cd tests && go build ./... + cd tests && go mod tidy -terratest/test: | guard/program/go guard/program/dep +terratest/test: | guard/program/go cd tests && go test -timeout 20m + +test: terratest/test diff --git a/README.md b/README.md index 92232a7..b2716a7 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Terraform module to create an EC2 security group | ingress\_rules | A schema list of ingress rules for the Security Group, see | list | `` | no | | name | Name of the Security Group | string | n/a | yes | | revoke\_rules\_on\_delete | Determines whether to forcibly remove rules when destroying the security group | string | `"false"` | no | -| tags | A map of tags for the Security Group | map | `` | no | +| tags | A map of tags for the Security Group | map(string) | `` | no | | vpc\_id | VPC ID in which to create the Security Group | string | n/a | yes | ## Outputs diff --git a/main.tf b/main.tf index 1d71edb..5bbedba 100644 --- a/main.tf +++ b/main.tf @@ -1,13 +1,41 @@ -provider "aws" {} +provider "aws" { +} resource "aws_security_group" "this" { - count = "${var.create_sg ? 1 : 0}" + count = var.create_sg ? 1 : 0 + + name = var.name + description = var.description + vpc_id = var.vpc_id + dynamic "ingress" { + for_each = var.ingress_rules + content { + cidr_blocks = lookup(ingress.value, "cidr_blocks", null) + description = lookup(ingress.value, "description", null) + from_port = lookup(ingress.value, "from_port", null) + ipv6_cidr_blocks = lookup(ingress.value, "ipv6_cidr_blocks", null) + prefix_list_ids = lookup(ingress.value, "prefix_list_ids", null) + protocol = lookup(ingress.value, "protocol", null) + security_groups = lookup(ingress.value, "security_groups", null) + self = lookup(ingress.value, "self", null) + to_port = lookup(ingress.value, "to_port", null) + } + } - name = "${var.name}" - description = "${var.description}" - vpc_id = "${var.vpc_id}" - ingress = ["${var.ingress_rules}"] - egress = ["${var.egress_rules}"] - revoke_rules_on_delete = "${var.revoke_rules_on_delete}" - tags = "${var.tags}" + dynamic "egress" { + for_each = var.egress_rules + content { + cidr_blocks = lookup(egress.value, "cidr_blocks", null) + description = lookup(egress.value, "description", null) + from_port = lookup(egress.value, "from_port", null) + ipv6_cidr_blocks = lookup(egress.value, "ipv6_cidr_blocks", null) + prefix_list_ids = lookup(egress.value, "prefix_list_ids", null) + protocol = lookup(egress.value, "protocol", null) + security_groups = lookup(egress.value, "security_groups", null) + self = lookup(egress.value, "self", null) + to_port = lookup(egress.value, "to_port", null) + } + } + revoke_rules_on_delete = var.revoke_rules_on_delete + tags = var.tags } diff --git a/outputs.tf b/outputs.tf index 3933cd2..112e58f 100644 --- a/outputs.tf +++ b/outputs.tf @@ -1,19 +1,19 @@ output "id" { description = "The ID of the Security Group" - value = "${join("", aws_security_group.this.*.id)}" + value = join("", aws_security_group.this.*.id) } output "arn" { description = "The ARN of the Security Group" - value = "${join("", aws_security_group.this.*.arn)}" + value = join("", aws_security_group.this.*.arn) } output "name" { description = "The name of the Security Group" - value = "${join("", aws_security_group.this.*.name)}" + value = join("", aws_security_group.this.*.name) } output "owner_id" { description = "The owner ID of the Security Group" - value = "${join("", aws_security_group.this.*.owner_id)}" + value = join("", aws_security_group.this.*.owner_id) } diff --git a/tests/create_sg/main.tf b/tests/create_sg/main.tf new file mode 100644 index 0000000..ea9a2cd --- /dev/null +++ b/tests/create_sg/main.tf @@ -0,0 +1,27 @@ +provider aws { + region = "us-east-1" +} + +module "vpc" { + source = "github.com/terraform-aws-modules/terraform-aws-vpc?ref=v2.15.0" + providers = { + aws = aws + } + + name = "tardigrade-security-group-testing" + cidr = "10.0.0.0/16" +} + +module "create_security_group" { + source = "../../" + providers = { + aws = aws + } + + create_sg = true + name = "tardigrade-security-group-testing" + vpc_id = module.vpc.vpc_id + tags = { + environment = "testing" + } +} diff --git a/tests/create_sg/versions.tf b/tests/create_sg/versions.tf new file mode 100644 index 0000000..ac97c6a --- /dev/null +++ b/tests/create_sg/versions.tf @@ -0,0 +1,4 @@ + +terraform { + required_version = ">= 0.12" +} diff --git a/tests/example_testcase/main.tf b/tests/example_testcase/main.tf deleted file mode 100644 index dbe7f9d..0000000 --- a/tests/example_testcase/main.tf +++ /dev/null @@ -1,7 +0,0 @@ -terraform { - required_version = "~> 0.11.0" -} - -module "example" { - source = "../../" -} diff --git a/tests/go.mod b/tests/go.mod new file mode 100644 index 0000000..2849f9c --- /dev/null +++ b/tests/go.mod @@ -0,0 +1,11 @@ +module terraform-aws-tardigrade-security-group/tests + +go 1.12 + +require ( + github.com/gruntwork-io/terratest v0.18.6 + github.com/magiconair/properties v1.8.1 // indirect + github.com/stretchr/testify v1.4.0 // indirect + golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472 // indirect + golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 // indirect +) diff --git a/tests/go.sum b/tests/go.sum new file mode 100644 index 0000000..9ce561c --- /dev/null +++ b/tests/go.sum @@ -0,0 +1,25 @@ +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/gruntwork-io/terratest v0.18.6 h1:6LQeJC7O3NErZLv7MNRUuUuFtlekg3z8rYSwOqtJ6ws= +github.com/gruntwork-io/terratest v0.18.6/go.mod h1:NjUn6YXA5Skxt8Rs20t3isYx5Rl+EgvGB8/+RRXddqk= +github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= +github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472 h1:Gv7RPwsi3eZ2Fgewe3CBsuOebPwO27PoXzRpJPsvSSM= +golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM= +golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/tests/module_test.go b/tests/module_test.go index d3905e0..61254e3 100644 --- a/tests/module_test.go +++ b/tests/module_test.go @@ -1,49 +1,49 @@ package testing import ( - "io/ioutil" - "log" - "os" - "testing" + "io/ioutil" + "log" + "os" + "testing" - "github.com/gruntwork-io/terratest/modules/terraform" + "github.com/gruntwork-io/terratest/modules/terraform" ) func TestModule(t *testing.T) { - files, err := ioutil.ReadDir("./") - - if err != nil { - log.Fatal(err) - } - - for _, f := range files { - // look for directories with test cases in it - if f.IsDir() && f.Name() != "vendor" { - investigateDirectory(t, f) - } - } + files, err := ioutil.ReadDir("./") + + if err != nil { + log.Fatal(err) + } + + for _, f := range files { + // look for directories with test cases in it + if f.IsDir() && f.Name() != "vendor" { + investigateDirectory(t, f) + } + } } func investigateDirectory(t *testing.T, directory os.FileInfo) { - // check if a prereq directory exists - prereqDir := directory.Name() + "/prereq/" - if _, err := os.Stat(prereqDir); err == nil { - prereqOptions := createTerraformOptions(prereqDir) - defer terraform.Destroy(t, prereqOptions) - terraform.InitAndApply(t, prereqOptions) - } - - // run terraform code for test case - terraformOptions := createTerraformOptions(directory.Name()) - defer terraform.Destroy(t, terraformOptions) - terraform.InitAndApply(t, terraformOptions) + // check if a prereq directory exists + prereqDir := directory.Name() + "/prereq/" + if _, err := os.Stat(prereqDir); err == nil { + prereqOptions := createTerraformOptions(prereqDir) + defer terraform.Destroy(t, prereqOptions) + terraform.InitAndApply(t, prereqOptions) + } + + // run terraform code for test case + terraformOptions := createTerraformOptions(directory.Name()) + defer terraform.Destroy(t, terraformOptions) + terraform.InitAndApply(t, terraformOptions) } func createTerraformOptions(directory string) *terraform.Options { - terraformOptions := &terraform.Options{ - TerraformDir: directory, - NoColor: true, - } + terraformOptions := &terraform.Options{ + TerraformDir: directory, + NoColor: true, + } - return terraformOptions + return terraformOptions } diff --git a/tests/no_create_sg/main.tf b/tests/no_create_sg/main.tf new file mode 100644 index 0000000..01dc140 --- /dev/null +++ b/tests/no_create_sg/main.tf @@ -0,0 +1,17 @@ +provider aws { + region = "us-east-1" +} + +module "no_create_sg" { + source = "../../" + providers = { + aws = aws + } + + create_sg = false + name = "tardigrade-security-group-testing" + vpc_id = null + tags = { + environment = "testing" + } +} diff --git a/tests/no_create_sg/versions.tf b/tests/no_create_sg/versions.tf new file mode 100644 index 0000000..ac97c6a --- /dev/null +++ b/tests/no_create_sg/versions.tf @@ -0,0 +1,4 @@ + +terraform { + required_version = ">= 0.12" +} diff --git a/tests/use_all_variables/main.tf b/tests/use_all_variables/main.tf new file mode 100644 index 0000000..f5bbf5e --- /dev/null +++ b/tests/use_all_variables/main.tf @@ -0,0 +1,46 @@ +provider aws { + region = "us-east-1" +} + +module "vpc" { + source = "github.com/terraform-aws-modules/terraform-aws-vpc?ref=v2.15.0" + providers = { + aws = aws + } + + name = "tardigrade-security-group-testing" + cidr = "10.0.0.0/16" +} + +module "use_all_variables" { + source = "../../" + providers = { + aws = aws + } + + create_sg = true + name = "tardigrade-security-group-testing" + vpc_id = module.vpc.vpc_id + ingress_rules = [ + { + "from_port" = "0", + "to_port" = "0", + "protocol" = "-1", + "cidr_blocks" = ["0.0.0.0/0"] + } + ] + + egress_rules = [ + { + "from_port" = "0", + "to_port" = "0", + "protocol" = "-1", + "cidr_blocks" = ["0.0.0.0/0"] + } + ] + + revoke_rules_on_delete = true + tags = { + environment = "testing" + } +} diff --git a/tests/use_all_variables/versions.tf b/tests/use_all_variables/versions.tf new file mode 100644 index 0000000..ac97c6a --- /dev/null +++ b/tests/use_all_variables/versions.tf @@ -0,0 +1,4 @@ + +terraform { + required_version = ">= 0.12" +} diff --git a/variables.tf b/variables.tf index e044d0c..29a7a99 100644 --- a/variables.tf +++ b/variables.tf @@ -1,45 +1,45 @@ variable "create_sg" { - type = "string" + type = string description = "Toggle controlling whether to create the security group" default = true } variable "name" { description = "Name of the Security Group" - type = "string" + type = string } variable "vpc_id" { description = "VPC ID in which to create the Security Group" - type = "string" + type = string } variable "description" { description = "Description of the Security Group" - type = "string" + type = string default = "Managed by Terraform" } variable "ingress_rules" { description = "A schema list of ingress rules for the Security Group, see " - type = "list" + type = list default = [] } variable "egress_rules" { description = "A schema list of egress rules for the Security Group, see " - type = "list" + type = list default = [] } variable "revoke_rules_on_delete" { description = "Determines whether to forcibly remove rules when destroying the security group" - type = "string" + type = string default = false } variable "tags" { description = "A map of tags for the Security Group" - type = "map" + type = map(string) default = {} } diff --git a/versions.tf b/versions.tf new file mode 100644 index 0000000..ac97c6a --- /dev/null +++ b/versions.tf @@ -0,0 +1,4 @@ + +terraform { + required_version = ">= 0.12" +}