From ff9a5aef27aed58464aaef910c475aa963166c05 Mon Sep 17 00:00:00 2001 From: matttrach Date: Tue, 23 Jan 2024 13:36:08 -0600 Subject: [PATCH] feature!: add the ability to explicitly skip parts of the module Signed-off-by: matttrach --- examples/basic/outputs.tf | 4 -- examples/basic/versions.tf | 2 +- examples/override/outputs.tf | 4 -- examples/override/versions.tf | 2 +- examples/personal/outputs.tf | 4 -- examples/personal/versions.tf | 2 +- examples/project/outputs.tf | 4 -- examples/project/versions.tf | 2 +- examples/sgip/main.tf | 16 +++++ examples/sgip/outputs.tf | 15 +++++ examples/sgip/variables.tf | 6 ++ examples/sgip/versions.tf | 17 +++++ examples/skipsecuritygroup/main.tf | 16 +++++ examples/skipsecuritygroup/outputs.tf | 15 +++++ examples/skipsecuritygroup/variables.tf | 6 ++ examples/skipsecuritygroup/versions.tf | 17 +++++ examples/skipssh/main.tf | 16 +++++ examples/skipssh/outputs.tf | 15 +++++ examples/skipssh/variables.tf | 6 ++ examples/skipssh/versions.tf | 17 +++++ examples/skipsubnet/main.tf | 16 +++++ examples/skipsubnet/outputs.tf | 15 +++++ examples/skipsubnet/variables.tf | 6 ++ examples/skipsubnet/versions.tf | 17 +++++ examples/skipvpc/main.tf | 10 +++ examples/skipvpc/outputs.tf | 15 +++++ examples/skipvpc/variables.tf | 6 ++ examples/skipvpc/versions.tf | 17 +++++ examples/specifyip/main.tf | 21 +++---- examples/specifyip/outputs.tf | 12 ++-- examples/specifyip/versions.tf | 2 +- main.tf | 27 +++++--- outputs.tf | 84 ++++++++++++++++++++----- terraform.md | 6 -- tests/sgip_test.go | 29 +++++++++ tests/skip_test.go | 80 +++++++++++++++++++++++ tests/specifyip_test.go | 3 +- variables.tf | 24 +++++++ 38 files changed, 500 insertions(+), 76 deletions(-) create mode 100644 examples/sgip/main.tf create mode 100644 examples/sgip/outputs.tf create mode 100644 examples/sgip/variables.tf create mode 100644 examples/sgip/versions.tf create mode 100644 examples/skipsecuritygroup/main.tf create mode 100644 examples/skipsecuritygroup/outputs.tf create mode 100644 examples/skipsecuritygroup/variables.tf create mode 100644 examples/skipsecuritygroup/versions.tf create mode 100644 examples/skipssh/main.tf create mode 100644 examples/skipssh/outputs.tf create mode 100644 examples/skipssh/variables.tf create mode 100644 examples/skipssh/versions.tf create mode 100644 examples/skipsubnet/main.tf create mode 100644 examples/skipsubnet/outputs.tf create mode 100644 examples/skipsubnet/variables.tf create mode 100644 examples/skipsubnet/versions.tf create mode 100644 examples/skipvpc/main.tf create mode 100644 examples/skipvpc/outputs.tf create mode 100644 examples/skipvpc/variables.tf create mode 100644 examples/skipvpc/versions.tf create mode 100644 tests/sgip_test.go create mode 100644 tests/skip_test.go diff --git a/examples/basic/outputs.tf b/examples/basic/outputs.tf index 6ba84f6..cf40a9f 100644 --- a/examples/basic/outputs.tf +++ b/examples/basic/outputs.tf @@ -6,10 +6,6 @@ output "subnet" { value = module.TestBasic.subnet } -output "cidr" { - value = module.TestBasic.cidr -} - output "security_group" { value = module.TestBasic.security_group } diff --git a/examples/basic/versions.tf b/examples/basic/versions.tf index 43a2f01..d4e5dec 100644 --- a/examples/basic/versions.tf +++ b/examples/basic/versions.tf @@ -1,5 +1,5 @@ terraform { - required_version = ">= 1.2.0" + required_version = ">= 1.2.0, < 1.6" required_providers { local = { source = "hashicorp/local" diff --git a/examples/override/outputs.tf b/examples/override/outputs.tf index 9b98a3d..c01b69a 100644 --- a/examples/override/outputs.tf +++ b/examples/override/outputs.tf @@ -6,10 +6,6 @@ output "subnet" { value = module.TestOverride.subnet } -output "cidr" { - value = module.TestOverride.cidr -} - output "security_group" { value = module.TestOverride.security_group } diff --git a/examples/override/versions.tf b/examples/override/versions.tf index 43a2f01..d4e5dec 100644 --- a/examples/override/versions.tf +++ b/examples/override/versions.tf @@ -1,5 +1,5 @@ terraform { - required_version = ">= 1.2.0" + required_version = ">= 1.2.0, < 1.6" required_providers { local = { source = "hashicorp/local" diff --git a/examples/personal/outputs.tf b/examples/personal/outputs.tf index f82ab55..b286a70 100644 --- a/examples/personal/outputs.tf +++ b/examples/personal/outputs.tf @@ -6,10 +6,6 @@ output "subnet" { value = module.TestPersonal.subnet } -output "cidr" { - value = module.TestPersonal.cidr -} - output "security_group" { value = module.TestPersonal.security_group } diff --git a/examples/personal/versions.tf b/examples/personal/versions.tf index 43a2f01..d4e5dec 100644 --- a/examples/personal/versions.tf +++ b/examples/personal/versions.tf @@ -1,5 +1,5 @@ terraform { - required_version = ">= 1.2.0" + required_version = ">= 1.2.0, < 1.6" required_providers { local = { source = "hashicorp/local" diff --git a/examples/project/outputs.tf b/examples/project/outputs.tf index 3650f74..551aa73 100644 --- a/examples/project/outputs.tf +++ b/examples/project/outputs.tf @@ -6,10 +6,6 @@ output "subnet" { value = module.TestProject.subnet } -output "cidr" { - value = module.TestProject.cidr -} - output "security_group" { value = module.TestProject.security_group } diff --git a/examples/project/versions.tf b/examples/project/versions.tf index 43a2f01..d4e5dec 100644 --- a/examples/project/versions.tf +++ b/examples/project/versions.tf @@ -1,5 +1,5 @@ terraform { - required_version = ">= 1.2.0" + required_version = ">= 1.2.0, < 1.6" required_providers { local = { source = "hashicorp/local" diff --git a/examples/sgip/main.tf b/examples/sgip/main.tf new file mode 100644 index 0000000..1d369e3 --- /dev/null +++ b/examples/sgip/main.tf @@ -0,0 +1,16 @@ + +locals { + identifier = "sgip" +} + +module "this" { + source = "../../" + owner = "terraform-ci@suse.com" + vpc_name = "terraform-aws-access-${local.identifier}" + vpc_cidr = "10.0.255.0/24" # gives 256 usable addresses from .1 to .254, but AWS reserves .1 to .4 and .255, leaving .5 to .254 + skip_subnet = true + security_group_name = "terraform-aws-access-${local.identifier}" + security_group_type = "specific" + security_group_ip = "192.168.1.1" + skip_ssh = true +} diff --git a/examples/sgip/outputs.tf b/examples/sgip/outputs.tf new file mode 100644 index 0000000..a8a8e2e --- /dev/null +++ b/examples/sgip/outputs.tf @@ -0,0 +1,15 @@ +output "vpc" { + value = module.this.vpc +} + +output "subnet" { + value = module.this.subnet +} + +output "security_group" { + value = module.this.security_group +} + +output "ssh_key" { + value = module.this.ssh_key +} diff --git a/examples/sgip/variables.tf b/examples/sgip/variables.tf new file mode 100644 index 0000000..63d0a70 --- /dev/null +++ b/examples/sgip/variables.tf @@ -0,0 +1,6 @@ +variable "key" { + type = string +} +variable "key_name" { + type = string +} diff --git a/examples/sgip/versions.tf b/examples/sgip/versions.tf new file mode 100644 index 0000000..d4e5dec --- /dev/null +++ b/examples/sgip/versions.tf @@ -0,0 +1,17 @@ +terraform { + required_version = ">= 1.2.0, < 1.6" + required_providers { + local = { + source = "hashicorp/local" + version = ">= 2.4" + } + aws = { + source = "hashicorp/aws" + version = ">= 5.11" + } + http = { + source = "hashicorp/http" + version = ">= 3.4" + } + } +} \ No newline at end of file diff --git a/examples/skipsecuritygroup/main.tf b/examples/skipsecuritygroup/main.tf new file mode 100644 index 0000000..3e3544a --- /dev/null +++ b/examples/skipsecuritygroup/main.tf @@ -0,0 +1,16 @@ +locals { + identifier = "skipsg" +} +# vpc, subnet, and ssh key +module "this" { + source = "../../" + owner = "terraform-ci@suse.com" + vpc_name = "terraform-aws-access-${local.identifier}" + vpc_cidr = "10.0.255.0/24" # gives 256 usable addresses from .1 to .254, but AWS reserves .1 to .4 and .255, leaving .5 to .254 + subnet_name = "terraform-aws-access-${local.identifier}" + subnet_cidr = "10.0.255.224/28" # gives 14 usable addresses from .225 to .238, but AWS reserves .225 to .227 and .238, leaving .227 to .237 + availability_zone = "us-west-1b" # check what availability zones are available in your region before setting this + skip_security_group = true + public_ssh_key = var.key + ssh_key_name = var.key_name +} diff --git a/examples/skipsecuritygroup/outputs.tf b/examples/skipsecuritygroup/outputs.tf new file mode 100644 index 0000000..a8a8e2e --- /dev/null +++ b/examples/skipsecuritygroup/outputs.tf @@ -0,0 +1,15 @@ +output "vpc" { + value = module.this.vpc +} + +output "subnet" { + value = module.this.subnet +} + +output "security_group" { + value = module.this.security_group +} + +output "ssh_key" { + value = module.this.ssh_key +} diff --git a/examples/skipsecuritygroup/variables.tf b/examples/skipsecuritygroup/variables.tf new file mode 100644 index 0000000..63d0a70 --- /dev/null +++ b/examples/skipsecuritygroup/variables.tf @@ -0,0 +1,6 @@ +variable "key" { + type = string +} +variable "key_name" { + type = string +} diff --git a/examples/skipsecuritygroup/versions.tf b/examples/skipsecuritygroup/versions.tf new file mode 100644 index 0000000..d4e5dec --- /dev/null +++ b/examples/skipsecuritygroup/versions.tf @@ -0,0 +1,17 @@ +terraform { + required_version = ">= 1.2.0, < 1.6" + required_providers { + local = { + source = "hashicorp/local" + version = ">= 2.4" + } + aws = { + source = "hashicorp/aws" + version = ">= 5.11" + } + http = { + source = "hashicorp/http" + version = ">= 3.4" + } + } +} \ No newline at end of file diff --git a/examples/skipssh/main.tf b/examples/skipssh/main.tf new file mode 100644 index 0000000..970924b --- /dev/null +++ b/examples/skipssh/main.tf @@ -0,0 +1,16 @@ +locals { + identifier = "skipssh" +} +# generate vpc, subnet, and security group, skip ssh keypair +module "this" { + source = "../../" + owner = "terraform-ci@suse.com" + vpc_name = "terraform-aws-access-${local.identifier}" + vpc_cidr = "10.0.255.0/24" # gives 256 usable addresses from .1 to .254, but AWS reserves .1 to .4 and .255, leaving .5 to .254 + subnet_name = "terraform-aws-access-${local.identifier}" + subnet_cidr = "10.0.255.224/28" # gives 14 usable addresses from .225 to .238, but AWS reserves .225 to .227 and .238, leaving .227 to .237 + availability_zone = "us-west-1b" # check what availability zones are available in your region before setting this + security_group_name = "terraform-aws-access-test-${local.identifier}" + security_group_type = "egress" + skip_ssh = true +} diff --git a/examples/skipssh/outputs.tf b/examples/skipssh/outputs.tf new file mode 100644 index 0000000..a8a8e2e --- /dev/null +++ b/examples/skipssh/outputs.tf @@ -0,0 +1,15 @@ +output "vpc" { + value = module.this.vpc +} + +output "subnet" { + value = module.this.subnet +} + +output "security_group" { + value = module.this.security_group +} + +output "ssh_key" { + value = module.this.ssh_key +} diff --git a/examples/skipssh/variables.tf b/examples/skipssh/variables.tf new file mode 100644 index 0000000..63d0a70 --- /dev/null +++ b/examples/skipssh/variables.tf @@ -0,0 +1,6 @@ +variable "key" { + type = string +} +variable "key_name" { + type = string +} diff --git a/examples/skipssh/versions.tf b/examples/skipssh/versions.tf new file mode 100644 index 0000000..d4e5dec --- /dev/null +++ b/examples/skipssh/versions.tf @@ -0,0 +1,17 @@ +terraform { + required_version = ">= 1.2.0, < 1.6" + required_providers { + local = { + source = "hashicorp/local" + version = ">= 2.4" + } + aws = { + source = "hashicorp/aws" + version = ">= 5.11" + } + http = { + source = "hashicorp/http" + version = ">= 3.4" + } + } +} \ No newline at end of file diff --git a/examples/skipsubnet/main.tf b/examples/skipsubnet/main.tf new file mode 100644 index 0000000..f35763a --- /dev/null +++ b/examples/skipsubnet/main.tf @@ -0,0 +1,16 @@ +locals { + identifier = "skipsubnet" +} +# generate vpc, security group, and ssh key +module "this" { + source = "../../" + owner = "terraform-ci@suse.com" + vpc_name = "terraform-aws-access-${local.identifier}" + vpc_cidr = "10.0.255.0/24" # gives 256 usable addresses from .1 to .254, but AWS reserves .1 to .4 and .255, leaving .5 to .254 + skip_subnet = true + security_group_name = "terraform-aws-access-${local.identifier}" + security_group_type = "specific" + security_group_ip = "192.168.0.1" + public_ssh_key = var.key + ssh_key_name = var.key_name +} diff --git a/examples/skipsubnet/outputs.tf b/examples/skipsubnet/outputs.tf new file mode 100644 index 0000000..a8a8e2e --- /dev/null +++ b/examples/skipsubnet/outputs.tf @@ -0,0 +1,15 @@ +output "vpc" { + value = module.this.vpc +} + +output "subnet" { + value = module.this.subnet +} + +output "security_group" { + value = module.this.security_group +} + +output "ssh_key" { + value = module.this.ssh_key +} diff --git a/examples/skipsubnet/variables.tf b/examples/skipsubnet/variables.tf new file mode 100644 index 0000000..63d0a70 --- /dev/null +++ b/examples/skipsubnet/variables.tf @@ -0,0 +1,6 @@ +variable "key" { + type = string +} +variable "key_name" { + type = string +} diff --git a/examples/skipsubnet/versions.tf b/examples/skipsubnet/versions.tf new file mode 100644 index 0000000..d4e5dec --- /dev/null +++ b/examples/skipsubnet/versions.tf @@ -0,0 +1,17 @@ +terraform { + required_version = ">= 1.2.0, < 1.6" + required_providers { + local = { + source = "hashicorp/local" + version = ">= 2.4" + } + aws = { + source = "hashicorp/aws" + version = ">= 5.11" + } + http = { + source = "hashicorp/http" + version = ">= 3.4" + } + } +} \ No newline at end of file diff --git a/examples/skipvpc/main.tf b/examples/skipvpc/main.tf new file mode 100644 index 0000000..e41686a --- /dev/null +++ b/examples/skipvpc/main.tf @@ -0,0 +1,10 @@ +# generate ssh key only +module "this" { + source = "../../" + owner = "terraform-ci@suse.com" + skip_vpc = true + skip_subnet = true # without a vpc selected or created subnet can't be created + skip_security_group = true # without a vpc selected of created security group can't be created + public_ssh_key = var.key + ssh_key_name = var.key_name +} diff --git a/examples/skipvpc/outputs.tf b/examples/skipvpc/outputs.tf new file mode 100644 index 0000000..a8a8e2e --- /dev/null +++ b/examples/skipvpc/outputs.tf @@ -0,0 +1,15 @@ +output "vpc" { + value = module.this.vpc +} + +output "subnet" { + value = module.this.subnet +} + +output "security_group" { + value = module.this.security_group +} + +output "ssh_key" { + value = module.this.ssh_key +} diff --git a/examples/skipvpc/variables.tf b/examples/skipvpc/variables.tf new file mode 100644 index 0000000..63d0a70 --- /dev/null +++ b/examples/skipvpc/variables.tf @@ -0,0 +1,6 @@ +variable "key" { + type = string +} +variable "key_name" { + type = string +} diff --git a/examples/skipvpc/versions.tf b/examples/skipvpc/versions.tf new file mode 100644 index 0000000..d4e5dec --- /dev/null +++ b/examples/skipvpc/versions.tf @@ -0,0 +1,17 @@ +terraform { + required_version = ">= 1.2.0, < 1.6" + required_providers { + local = { + source = "hashicorp/local" + version = ">= 2.4" + } + aws = { + source = "hashicorp/aws" + version = ">= 5.11" + } + http = { + source = "hashicorp/http" + version = ">= 3.4" + } + } +} \ No newline at end of file diff --git a/examples/specifyip/main.tf b/examples/specifyip/main.tf index acdd4c0..8e74cf3 100644 --- a/examples/specifyip/main.tf +++ b/examples/specifyip/main.tf @@ -1,21 +1,18 @@ -# this is given for reference, in most cases you will want to set the region using environment variables -# provider "aws" { -# region = "us-west-1" -# } +locals { + identifier = "specifyip" +} -# AWS reserves the first four IP addresses and the last IP address in any CIDR block for its own use (cumulatively) -module "TestBasic" { +module "this" { source = "../../" owner = "terraform-ci@suse.com" - vpc_name = "terraform-aws-access-test-basic" + vpc_name = "terraform-aws-access-${local.identifier}" vpc_cidr = "10.0.255.0/24" # gives 256 usable addresses from .1 to .254, but AWS reserves .1 to .4 and .255, leaving .5 to .254 - subnet_name = "terraform-aws-access-test-basic" + subnet_name = "terraform-aws-access-${local.identifier}" subnet_cidr = "10.0.255.224/28" # gives 14 usable addresses from .225 to .238, but AWS reserves .225 to .227 and .238, leaving .227 to .237 availability_zone = "us-west-1b" # check what availability zones are available in your region before setting this - security_group_name = "terraform-aws-access-test-basic" + security_group_name = "terraform-aws-access-${local.identifier}" security_group_type = "egress" security_group_ip = chomp(var.ip) - public_ssh_key = var.key # I don't normally recommend this, but it allows tests to supply their own key - ssh_key_name = var.key_name # A lot of troubleshooting during critical times can be saved by hard coding variables in root modules - # root modules should be secured properly (including the state), and should represent your running infrastructure + public_ssh_key = var.key + ssh_key_name = var.key_name } diff --git a/examples/specifyip/outputs.tf b/examples/specifyip/outputs.tf index 6ba84f6..a8a8e2e 100644 --- a/examples/specifyip/outputs.tf +++ b/examples/specifyip/outputs.tf @@ -1,19 +1,15 @@ output "vpc" { - value = module.TestBasic.vpc + value = module.this.vpc } output "subnet" { - value = module.TestBasic.subnet -} - -output "cidr" { - value = module.TestBasic.cidr + value = module.this.subnet } output "security_group" { - value = module.TestBasic.security_group + value = module.this.security_group } output "ssh_key" { - value = module.TestBasic.ssh_key + value = module.this.ssh_key } diff --git a/examples/specifyip/versions.tf b/examples/specifyip/versions.tf index 43a2f01..d4e5dec 100644 --- a/examples/specifyip/versions.tf +++ b/examples/specifyip/versions.tf @@ -1,5 +1,5 @@ terraform { - required_version = ">= 1.2.0" + required_version = ">= 1.2.0, < 1.6" required_providers { local = { source = "hashicorp/local" diff --git a/main.tf b/main.tf index 559e738..36df290 100644 --- a/main.tf +++ b/main.tf @@ -3,21 +3,24 @@ locals { owner = var.owner vpc_name = var.vpc_name - vpc_cidr = var.vpc_cidr # create when cidr is given, otherwise select with name + vpc_cidr = var.vpc_cidr # create when cidr is given, otherwise select with name or skip + skip_vpc = var.skip_vpc # both subnet and security group need a vpc, but vpc is not necessary for ssh key subnet_name = var.subnet_name - subnet_cidr = var.subnet_cidr # create when cidr is given, otherwise select with name + subnet_cidr = var.subnet_cidr # create when cidr is given, otherwise select with name or skip subnet_availability_zone = var.availability_zone # only used when creating + skip_subnet = var.skip_subnet # if using the "specific" security group type you can skip subnet creation security_group_name = var.security_group_name - security_group_type = var.security_group_type # create when type is given, otherwise select with name + security_group_type = var.security_group_type # create when type is given, otherwise select with name or skip security_group_ip = var.security_group_ip + ipinfo_ip = chomp(can(data.http.my_public_ip[0].response_body) ? data.http.my_public_ip[0].response_body : "127.0.0.1") + ip = (local.security_group_ip == "" ? local.ipinfo_ip : local.security_group_ip) + skip_security_group = var.skip_security_group # no objects in this module depend on security group being created, skip if wanted ssh_key_name = var.ssh_key_name public_ssh_key = var.public_ssh_key # create when public key is given, otherwise select with name - - ipinfo_ip = (can(chomp(data.http.my_public_ip[0].response_body)) ? chomp(data.http.my_public_ip[0].response_body) : "") - ip = (local.security_group_ip == "" ? local.ipinfo_ip : local.security_group_ip) + skip_ssh = var.skip_ssh # no objects in this module depend on ssh key being created, skip if wanted } data "http" "my_public_ip" { @@ -26,32 +29,36 @@ data "http" "my_public_ip" { } module "vpc" { + count = (local.skip_vpc ? 0 : 1) source = "./modules/vpc" name = local.vpc_name cidr = local.vpc_cidr } module "subnet" { + count = (local.skip_subnet ? 0 : 1) source = "./modules/subnet" name = local.subnet_name cidr = local.subnet_cidr - vpc_id = module.vpc.id + vpc_id = module.vpc[0].id owner = local.owner availability_zone = local.subnet_availability_zone } module "security_group" { + count = (local.skip_security_group ? 0 : 1) source = "./modules/security_group" name = local.security_group_name ip = local.ip - cidr = module.subnet.cidr + cidr = (can(module.subnet[0].cidr) ? module.subnet[0].cidr : "") owner = local.owner type = local.security_group_type - vpc_id = module.vpc.id - vpc_cidr = module.vpc.vpc.cidr_block + vpc_id = module.vpc[0].id + vpc_cidr = module.vpc[0].vpc.cidr_block } module "ssh_key" { + count = (local.skip_ssh ? 0 : 1) source = "./modules/ssh_key" name = local.ssh_key_name public_key = local.public_ssh_key diff --git a/outputs.tf b/outputs.tf index c1d16fe..2e66d0a 100644 --- a/outputs.tf +++ b/outputs.tf @@ -1,40 +1,90 @@ output "vpc" { - value = module.vpc.vpc + value = (can(module.vpc[0].vpc) ? { + id = module.vpc[0].vpc.id + arn = module.vpc[0].vpc.arn + cidr_block = module.vpc[0].vpc.cidr_block + ipv6_cidr_block = module.vpc[0].vpc.ipv6_cidr_block + main_route_table_id = module.vpc[0].vpc.main_route_table_id + tags = module.vpc[0].vpc.tags + } : { + id = "" + arn = "" + cidr_block = "" + ipv6_cidr_block = "" + main_route_table_id = "" + tags = tomap({ "" = "" }) + }) description = <<-EOT The VPC object from AWS. EOT } output "subnet" { - value = module.subnet.subnet + value = (can(module.subnet[0].subnet) ? { + id = module.subnet[0].subnet.id + arn = module.subnet[0].subnet.arn + availability_zone = module.subnet[0].subnet.availability_zone + availability_zone_id = module.subnet[0].subnet.availability_zone_id + cidr_block = module.subnet[0].subnet.cidr_block + ipv6_cidr_block = module.subnet[0].subnet.ipv6_cidr_block + vpc_id = module.subnet[0].subnet.vpc_id + tags = module.subnet[0].subnet.tags + } : { + # no object found, but output types are normal + id = "" + arn = "" + availability_zone = "" + availability_zone_id = "" + cidr_block = "" + ipv6_cidr_block = "" + vpc_id = "" + tags = tomap({ "" = "" }) + }) description = <<-EOT The subnet object from AWS. EOT } -output "cidr" { - value = module.subnet.cidr - description = <<-EOT - The CIDR block of the subnet. - EOT -} - output "security_group" { - value = module.security_group.security_group + value = (can(module.security_group[0].security_group) ? { + id = module.security_group[0].security_group.id + arn = module.security_group[0].security_group.arn + name = module.security_group[0].security_group.name + vpc_id = module.security_group[0].security_group.vpc_id + tags = module.security_group[0].security_group.tags + } : { + # no object found, but output types are normal + id = "" + arn = "" + name = "" + vpc_id = "" + tags = tomap({ "" = "" }) + }) description = <<-EOT The security group object from AWS. EOT } -output "security_group_name" { - value = module.security_group.name - description = <<-EOT - The name of the security group. - EOT -} output "ssh_key" { - value = module.ssh_key.ssh_key + value = (can(module.ssh_key[0].ssh_key) ? { + id = module.ssh_key[0].ssh_key.id + arn = module.ssh_key[0].ssh_key.arn + key_name = module.ssh_key[0].ssh_key.key_name + key_pair_id = module.ssh_key[0].ssh_key.key_pair_id + key_type = module.ssh_key[0].ssh_key.key_type + public_key = module.ssh_key[0].ssh_key.public_key + tags = module.ssh_key[0].ssh_key.tags + } : { + # no object found, but output types are normal + id = "" + arn = "" + key_name = "" + key_pair_id = "" + key_type = "" + public_key = "" + tags = tomap({ "" = "" }) + }) description = <<-EOT The SSH key object from AWS. EOT diff --git a/terraform.md b/terraform.md index b5012b0..35008a5 100644 --- a/terraform.md +++ b/terraform.md @@ -89,12 +89,6 @@ Selector files like this allow users to choose a configuration that makes sense Most commonly, this is used for server configurations, but may also occur in other places like ami selection or higher level abstractions. Generally this should provide some examples of working configurations so that users do not need to scour provider documentation. -## Select if Not Creating - -Forcing the user to select a resource if they are not creating it allows outputs to be normalized, which allows easier construction of modules at a higher level. -If a "server" implementation module always returns information about a server, even when the information isn't necessary, then the composing module can just treat it like any other implementation of that module. -This provides a separation of concerns around data and logic allowing for less work adapting to specific implementations. - ## Idempotent Modules Terraform state allows modules to be idempotent within their context by default, diff --git a/tests/sgip_test.go b/tests/sgip_test.go new file mode 100644 index 0000000..b09408d --- /dev/null +++ b/tests/sgip_test.go @@ -0,0 +1,29 @@ +package test + +import ( + "fmt" + "testing" + + "github.com/gruntwork-io/terratest/modules/random" + "github.com/gruntwork-io/terratest/modules/ssh" + "github.com/gruntwork-io/terratest/modules/terraform" +) + +// generate a security group without generating a subnet, specifying an ip +func TestSgip(t *testing.T) { + t.Parallel() + uniqueID := random.UniqueId() + directory := "sgip" + region := "us-west-1" + + keyPair := ssh.GenerateRSAKeyPair(t, 2048) + keyPairName := fmt.Sprintf("terraform-aws-access-%s-%s", directory, uniqueID) + terraformVars := map[string]interface{}{ + "key_name": keyPairName, + "key": keyPair.PublicKey, + } + terraformOptions := setup(t, directory, region, terraformVars) + defer teardown(t, directory) + defer terraform.Destroy(t, terraformOptions) + terraform.InitAndApply(t, terraformOptions) +} diff --git a/tests/skip_test.go b/tests/skip_test.go new file mode 100644 index 0000000..e48290b --- /dev/null +++ b/tests/skip_test.go @@ -0,0 +1,80 @@ +package test + +import ( + "fmt" + "testing" + + "github.com/gruntwork-io/terratest/modules/random" + "github.com/gruntwork-io/terratest/modules/ssh" + "github.com/gruntwork-io/terratest/modules/terraform" +) + +func TestSkipVpc(t *testing.T) { + t.Parallel() + uniqueID := random.UniqueId() + directory := "skipvpc" + region := "us-west-1" + + keyPair := ssh.GenerateRSAKeyPair(t, 2048) + keyPairName := fmt.Sprintf("terraform-aws-access-%s-%s", directory, uniqueID) + terraformVars := map[string]interface{}{ + "key_name": keyPairName, + "key": keyPair.PublicKey, + } + terraformOptions := setup(t, directory, region, terraformVars) + defer teardown(t, directory) + defer terraform.Destroy(t, terraformOptions) + terraform.InitAndApply(t, terraformOptions) +} + +func TestSkipSubnet(t *testing.T) { + t.Parallel() + uniqueID := random.UniqueId() + directory := "skipsubnet" + region := "us-west-1" + + keyPair := ssh.GenerateRSAKeyPair(t, 2048) + keyPairName := fmt.Sprintf("terraform-aws-access-%s-%s", directory, uniqueID) + terraformVars := map[string]interface{}{ + "key_name": keyPairName, + "key": keyPair.PublicKey, + } + terraformOptions := setup(t, directory, region, terraformVars) + defer teardown(t, directory) + defer terraform.Destroy(t, terraformOptions) + terraform.InitAndApply(t, terraformOptions) +} +func TestSkipSecurityGroup(t *testing.T) { + t.Parallel() + uniqueID := random.UniqueId() + directory := "skipsecuritygroup" + region := "us-west-1" + + keyPair := ssh.GenerateRSAKeyPair(t, 2048) + keyPairName := fmt.Sprintf("terraform-aws-access-%s-%s", directory, uniqueID) + terraformVars := map[string]interface{}{ + "key_name": keyPairName, + "key": keyPair.PublicKey, + } + terraformOptions := setup(t, directory, region, terraformVars) + defer teardown(t, directory) + defer terraform.Destroy(t, terraformOptions) + terraform.InitAndApply(t, terraformOptions) +} +func TestSkipSsh(t *testing.T) { + t.Parallel() + uniqueID := random.UniqueId() + directory := "skipssh" + region := "us-west-1" + + keyPair := ssh.GenerateRSAKeyPair(t, 2048) + keyPairName := fmt.Sprintf("terraform-aws-access-%s-%s", directory, uniqueID) + terraformVars := map[string]interface{}{ + "key_name": keyPairName, + "key": keyPair.PublicKey, + } + terraformOptions := setup(t, directory, region, terraformVars) + defer teardown(t, directory) + defer terraform.Destroy(t, terraformOptions) + terraform.InitAndApply(t, terraformOptions) +} diff --git a/tests/specifyip_test.go b/tests/specifyip_test.go index d62ba2f..1754280 100644 --- a/tests/specifyip_test.go +++ b/tests/specifyip_test.go @@ -11,7 +11,6 @@ import ( "github.com/gruntwork-io/terratest/modules/terraform" ) -// this test generates all objects, no overrides func TestIp(t *testing.T) { t.Parallel() uniqueID := random.UniqueId() @@ -20,7 +19,7 @@ func TestIp(t *testing.T) { ip := GetOutboundIP().String() keyPair := ssh.GenerateRSAKeyPair(t, 2048) - keyPairName := fmt.Sprintf("terraform-aws-access-test-%s-%s", directory, uniqueID) + keyPairName := fmt.Sprintf("terraform-aws-access-%s-%s", directory, uniqueID) terraformVars := map[string]interface{}{ "key_name": keyPairName, "key": keyPair.PublicKey, diff --git a/variables.tf b/variables.tf index 03beedd..d50455d 100644 --- a/variables.tf +++ b/variables.tf @@ -15,6 +15,7 @@ variable "vpc_name" { This is required. If a cidr is specified, then a VPC will be created. EOT + default = "" } variable "vpc_cidr" { type = string @@ -30,6 +31,11 @@ variable "vpc_cidr" { EOT default = "" } +variable "skip_vpc" { + type = bool + description = "Skip vpc generation, use with care." + default = false +} # subnet variable "subnet_name" { type = string @@ -44,6 +50,7 @@ variable "subnet_name" { If you override the creation of the VPC and the creation of the subnet, this module won't attempt to associate the subnet to the VPC. EOT + default = "" } variable "subnet_cidr" { type = string @@ -70,6 +77,11 @@ variable "availability_zone" { EOT default = "" } +variable "skip_subnet" { + type = bool + description = "Skip subnet generation, use with care." + default = false +} # security group variable "security_group_name" { type = string @@ -79,6 +91,7 @@ variable "security_group_name" { If you would like to create a security group please specify the type of security group you would like to create. The types are located in modules/security_group/types.tf. EOT + default = "" } variable "security_group_type" { type = string @@ -100,6 +113,11 @@ variable "security_group_ip" { EOT default = "" } +variable "skip_security_group" { + type = bool + description = "Skip security group generation, use with care." + default = false +} # ssh key variable "ssh_key_name" { @@ -110,6 +128,7 @@ variable "ssh_key_name" { If you would like to create an ssh key pair, please specify the public_ssh_key. If the public_ssh_key variable is not specified, then this module will attempt to find an ssh key with the given name. EOT + default = "" } variable "public_ssh_key" { type = string @@ -120,3 +139,8 @@ variable "public_ssh_key" { EOT default = "" } +variable "skip_ssh" { + type = bool + description = "Skip ssh key generation, use with care." + default = false +} \ No newline at end of file