Skip to content

Commit 7ab272c

Browse files
Fix: var.enabled for Parameter Read, Testing Suite Overhaul (cloudposse#33)
Co-authored-by: cloudpossebot <[email protected]>
1 parent 712156c commit 7ab272c

File tree

8 files changed

+142
-24
lines changed

8 files changed

+142
-24
lines changed

README.md

+11-4
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,9 @@ This example creates a new `String` parameter called `/cp/prod/app/database/mast
109109

110110
```hcl
111111
module "store_write" {
112-
source = "git::https://github.com/cloudposse/terraform-aws-ssm-parameter-store?ref=master"
112+
source = "cloudposse/ssm-parameter-store/aws"
113+
# Cloud Posse recommends pinning every module to a specific version
114+
# version = "x.x.x"
113115
114116
parameter_write = [
115117
{
@@ -131,7 +133,10 @@ This example reads a value from the parameter store with the name `/cp/prod/app/
131133

132134
```hcl
133135
module "store_read" {
134-
source = "git::https://github.com/cloudposse/terraform-aws-ssm-parameter-store?ref=master"
136+
source = "cloudposse/ssm-parameter-store/aws"
137+
# Cloud Posse recommends pinning every module to a specific version
138+
# version = "x.x.x"
139+
135140
parameter_read = ["/cp/prod/app/database/master_password"]
136141
}
137142
```
@@ -367,8 +372,8 @@ Check out [our other projects][github], [follow us on twitter][twitter], [apply
367372
### Contributors
368373

369374
<!-- markdownlint-disable -->
370-
| [![Erik Osterman][osterman_avatar]][osterman_homepage]<br/>[Erik Osterman][osterman_homepage] | [![Andriy Knysh][aknysh_avatar]][aknysh_homepage]<br/>[Andriy Knysh][aknysh_homepage] | [![Jamie Nelson][Jamie-BitFlight_avatar]][Jamie-BitFlight_homepage]<br/>[Jamie Nelson][Jamie-BitFlight_homepage] | [![Matt Gowie][Gowiem_avatar]][Gowiem_homepage]<br/>[Matt Gowie][Gowiem_homepage] |
371-
|---|---|---|---|
375+
| [![Erik Osterman][osterman_avatar]][osterman_homepage]<br/>[Erik Osterman][osterman_homepage] | [![Andriy Knysh][aknysh_avatar]][aknysh_homepage]<br/>[Andriy Knysh][aknysh_homepage] | [![Jamie Nelson][Jamie-BitFlight_avatar]][Jamie-BitFlight_homepage]<br/>[Jamie Nelson][Jamie-BitFlight_homepage] | [![Matt Gowie][Gowiem_avatar]][Gowiem_homepage]<br/>[Matt Gowie][Gowiem_homepage] | [![Yonatan Koren][korenyoni_avatar]][korenyoni_homepage]<br/>[Yonatan Koren][korenyoni_homepage] |
376+
|---|---|---|---|---|
372377
<!-- markdownlint-restore -->
373378

374379
[osterman_homepage]: https://github.com/osterman
@@ -379,6 +384,8 @@ Check out [our other projects][github], [follow us on twitter][twitter], [apply
379384
[Jamie-BitFlight_avatar]: https://img.cloudposse.com/150x150/https://github.com/Jamie-BitFlight.png
380385
[Gowiem_homepage]: https://github.com/Gowiem
381386
[Gowiem_avatar]: https://img.cloudposse.com/150x150/https://github.com/Gowiem.png
387+
[korenyoni_homepage]: https://github.com/korenyoni
388+
[korenyoni_avatar]: https://img.cloudposse.com/150x150/https://github.com/korenyoni.png
382389

383390
[![README Footer][readme_footer_img]][readme_footer_link]
384391
[![Beacon][beacon]][website]

README.yaml

+9-2
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,9 @@ usage: |2-
4949
5050
```hcl
5151
module "store_write" {
52-
source = "git::https://github.com/cloudposse/terraform-aws-ssm-parameter-store?ref=master"
52+
source = "cloudposse/ssm-parameter-store/aws"
53+
# Cloud Posse recommends pinning every module to a specific version
54+
# version = "x.x.x"
5355
5456
parameter_write = [
5557
{
@@ -71,7 +73,10 @@ usage: |2-
7173
7274
```hcl
7375
module "store_read" {
74-
source = "git::https://github.com/cloudposse/terraform-aws-ssm-parameter-store?ref=master"
76+
source = "cloudposse/ssm-parameter-store/aws"
77+
# Cloud Posse recommends pinning every module to a specific version
78+
# version = "x.x.x"
79+
7580
parameter_read = ["/cp/prod/app/database/master_password"]
7681
}
7782
```
@@ -88,3 +93,5 @@ contributors:
8893
github: "Jamie-BitFlight"
8994
- name: "Matt Gowie"
9095
github: "Gowiem"
96+
- name: "Yonatan Koren"
97+
github: "korenyoni"

examples/complete/fixtures.us-east-2.tfvars

+4
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,7 @@ parameter_write = [
3131
description = "Company name"
3232
}
3333
]
34+
35+
//parameter_read= [
36+
// "/production/test/master/preexisting_key_${rand_id}"
37+
//]

examples/complete/main.tf

+15-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ provider "aws" {
44

55
module "kms_key" {
66
source = "cloudposse/kms-key/aws"
7-
version = "0.9.0"
7+
version = "0.11.0"
88
description = "terraform-aws-ssm-parameter-store test KMS key"
99
deletion_window_in_days = 10
1010
enable_key_rotation = true
@@ -16,7 +16,21 @@ module "kms_key" {
1616
module "store" {
1717
source = "../../"
1818
parameter_write = var.parameter_write
19+
parameter_read = var.parameter_read
1920
kms_arn = module.kms_key.key_arn
2021

2122
context = module.this.context
23+
24+
depends_on = [
25+
aws_ssm_parameter.preexisting_parameter
26+
]
2227
}
28+
29+
# This resource is used to test var.parameter_read in both enabled and disabled contexts.
30+
# The value is hardcoded because it is referenced in examples_complete_test.go
31+
resource "aws_ssm_parameter" "preexisting_parameter" {
32+
count = length(var.parameter_read)
33+
name = element(var.parameter_read, count.index)
34+
type = "SecureString"
35+
value = "preexisting_value"
36+
}

examples/complete/variables.tf

+6
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,9 @@ variable "parameter_write" {
77
type = list(map(string))
88
description = "List of maps with the parameter values to write to SSM Parameter Store"
99
}
10+
11+
variable "parameter_read" {
12+
type = list(string)
13+
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."
14+
default = []
15+
}

main.tf

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
locals {
2-
parameter_write = module.this.enabled ? { for e in var.parameter_write : e.name => merge(var.parameter_write_defaults, e) } : {}
2+
enabled = module.this.enabled
3+
parameter_write = local.enabled ? { for e in var.parameter_write : e.name => merge(var.parameter_write_defaults, e) } : {}
4+
parameter_read = local.enabled ? var.parameter_read : []
35
}
46

57
data "aws_ssm_parameter" "read" {
6-
count = module.this.enabled ? length(var.parameter_read) : 0
7-
name = element(var.parameter_read, count.index)
8+
count = length(local.parameter_read)
9+
name = element(local.parameter_read, count.index)
810
}
911

1012
resource "aws_ssm_parameter" "default" {
@@ -19,5 +21,4 @@ resource "aws_ssm_parameter" "default" {
1921
overwrite = each.value.overwrite
2022
allowed_pattern = each.value.allowed_pattern
2123
tags = var.tags
22-
2324
}

outputs.tf

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Splitting and joining, and then compacting a list to get a normalised list
22
locals {
3-
name_list = compact(concat(keys(local.parameter_write), var.parameter_read))
3+
name_list = compact(concat(keys(local.parameter_write), local.parameter_read))
44

55
value_list = compact(
66
concat(

test/src/examples_complete_test.go

+91-12
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,122 @@
11
package test
22

33
import (
4-
"strings"
4+
"fmt"
5+
"math/rand"
6+
"strconv"
57
"testing"
8+
"time"
69

710
"github.com/gruntwork-io/terratest/modules/terraform"
811
"github.com/stretchr/testify/assert"
912
)
1013

14+
const preExistingKeyFormat = "/production/test/master/preexisting_key_%s"
15+
1116
// Test the Terraform module in examples/complete using Terratest.
1217
func TestExamplesComplete(t *testing.T) {
18+
terraformOptions := &terraform.Options{
19+
// The path to where our Terraform code is located
20+
TerraformDir: "../../examples/complete",
21+
Upgrade: true,
22+
// Variables to pass to our Terraform code using -var-file options
23+
VarFiles: []string{"fixtures.us-east-2.tfvars"},
24+
}
25+
26+
terraform.Init(t, terraformOptions)
27+
// Run tests in parallel
28+
t.Run("Disabled", testExamplesCompleteDisabled)
29+
t.Run("Enabled", testExamplesCompleteEnabled)
30+
}
31+
32+
func testExamplesCompleteDisabled(t *testing.T) {
1333
t.Parallel()
1434

35+
attributes := []string{strconv.Itoa(rand.Intn(100000))}
36+
preExistingKeyName := fmt.Sprintf(preExistingKeyFormat, attributes[0])
37+
1538
terraformOptions := &terraform.Options{
1639
// The path to where our Terraform code is located
1740
TerraformDir: "../../examples/complete",
1841
Upgrade: true,
42+
EnvVars: map[string]string{
43+
"TF_CLI_ARGS": "-state=terraform-disabled-test.tfstate",
44+
},
1945
// Variables to pass to our Terraform code using -var-file options
2046
VarFiles: []string{"fixtures.us-east-2.tfvars"},
47+
Vars: map[string]interface{}{
48+
"enabled": false,
49+
"attributes": attributes,
50+
"parameter_read": []string{
51+
preExistingKeyName,
52+
},
53+
},
2154
}
2255

2356
// At the end of the test, run `terraform destroy` to clean up any resources that were created
2457
defer terraform.Destroy(t, terraformOptions)
2558

26-
// This will run `terraform init` and `terraform apply` and fail the test if there are any errors
27-
terraform.InitAndApply(t, terraformOptions)
59+
// This will run `terraform apply` and fail the test if there are any errors
60+
terraform.Apply(t, terraformOptions)
2861

2962
// Run `terraform output` to get the value of an output variable
30-
output := terraform.Output(t, terraformOptions, "map")
63+
output := terraform.OutputMap(t, terraformOptions, "map")
64+
assert.Equal(t, len(output), 0, "There should be no outputs when the module is disabled.")
65+
}
3166

32-
key1Result := strings.Contains(output, "/production/test/master/company")
33-
value1Result := strings.Contains(output, "Amazon")
34-
key2Result := strings.Contains(output, "/production/test/master/users")
35-
value2Result := strings.Contains(output, "John,Todd")
67+
func testExamplesCompleteEnabled(t *testing.T) {
68+
t.Parallel()
69+
70+
rand.Seed(time.Now().UnixNano() + 1) // give a slightly different seed than the other parallel test
71+
attributes := []string{strconv.Itoa(rand.Intn(100000))}
72+
preExistingKeyName := fmt.Sprintf(preExistingKeyFormat, attributes[0])
73+
74+
terraformOptions := &terraform.Options{
75+
// The path to where our Terraform code is located
76+
TerraformDir: "../../examples/complete",
77+
Upgrade: true,
78+
EnvVars: map[string]string{
79+
"TF_CLI_ARGS": "-state=terraform-enabled-test.tfstate",
80+
},
81+
// Variables to pass to our Terraform code using -var-file options
82+
VarFiles: []string{"fixtures.us-east-2.tfvars"},
83+
Vars: map[string]interface{}{
84+
"attributes": attributes,
85+
"parameter_read": []string{
86+
preExistingKeyName,
87+
},
88+
},
89+
}
90+
91+
// At the end of the test, run `terraform destroy` to clean up any resources that were created
92+
defer terraform.Destroy(t, terraformOptions)
93+
94+
// This will run `terraform apply` and fail the test if there are any errors
95+
terraform.Apply(t, terraformOptions)
96+
97+
// Run `terraform output` to get the value of an output variable
98+
output := terraform.OutputMap(t, terraformOptions, "map")
99+
100+
// Expected values for created parameters
101+
key1 := "/production/test/master/company"
102+
value1 := "Amazon"
103+
key2 := "/production/test/master/users"
104+
value2 := "John,Todd"
105+
106+
// Expected values for preexisting parameters
107+
key3 := preExistingKeyName
108+
value3 := "preexisting_value"
36109

37110
// Verify we're getting back the outputs we expect
38-
assert.True(t, key1Result, "The 'map' output should contain the /production/test/master/company key")
39-
assert.True(t, value1Result, "The /production/test/master/company key's value should be 'Amazon'")
111+
containsErrorMessageFormat := "The 'map' output should contain the %s key"
112+
equalsErrorMessageFormat := "The %s's value should be '%s'"
113+
114+
assert.Contains(t, output, key1, fmt.Sprintf(containsErrorMessageFormat, key1))
115+
assert.Equal(t, value1 ,output[key1], fmt.Sprintf(equalsErrorMessageFormat, key1, value1))
116+
117+
assert.Contains(t, output, key2, fmt.Sprintf(containsErrorMessageFormat, key2))
118+
assert.Equal(t, value2 ,output[key2], fmt.Sprintf(equalsErrorMessageFormat, key2, value2))
40119

41-
assert.True(t, key2Result, "The 'map' output should contain the /production/test/master/users key")
42-
assert.True(t, value2Result, "The /production/test/master/users key's value should be 'John,Todd'")
120+
assert.Contains(t, output, key3, fmt.Sprintf(containsErrorMessageFormat, key3))
121+
assert.Equal(t, value3 ,output[key3], fmt.Sprintf(equalsErrorMessageFormat, key3, value3))
43122
}

0 commit comments

Comments
 (0)