Skip to content

Commit ed92bbc

Browse files
Add component tests (#19)
* Added tests * Update test/component_test.go Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Fix ssm parameter path collisition * Fix verify test * Fix verify test * Added github provider --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
1 parent e0ca330 commit ed92bbc

21 files changed

+1271
-19
lines changed

src/notifications.tf

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -219,22 +219,22 @@ locals {
219219
if key != "ssm_path_prefix" && key != "webhook"
220220
},
221221
{
222-
for key, value in coalesce(local.notifications_notifiers.webhook, {}) :
222+
for key, value in try(local.notifications_notifiers.webhook, {}) :
223223
format("webhook_%s", key) =>
224224
{ for param_name, param_value in value : param_name => param_value if param_value != null }
225225
}
226226
)
227227

228228
## Get paths to read configs for each notifier service
229-
notifications_notifiers_ssm_path = merge(
229+
notifications_notifiers_ssm_path = local.enabled ? merge(
230230
{
231231
for key, value in local.notifications_notifiers_variables :
232232
key => format("%s/%s/", local.notifications_notifiers.ssm_path_prefix, key)
233233
},
234234
{
235235
common = format("%s/common/", local.notifications_notifiers.ssm_path_prefix)
236236
},
237-
)
237+
) : {}
238238

239239
## Read SSM secrets into object for each notifier service
240240
notifications_notifiers_ssm_configs = {

src/provider-github.tf

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,12 @@ variable "ssm_github_app_private_key" {
4343
}
4444

4545
locals {
46-
github_token = local.create_github_webhook ? (
47-
var.github_app_enabled ? null : coalesce(var.github_token_override, try(data.aws_ssm_parameter.github_api_key[0].value, null))
48-
) : ""
46+
github_token = var.github_app_enabled ? null : coalesce(var.github_token_override, try(data.aws_ssm_parameter.github_api_key[0].value, null))
4947
}
5048

5149
# SSM Parameter for PAT Authentication
5250
data "aws_ssm_parameter" "github_api_key" {
53-
count = local.create_github_webhook && !var.github_app_enabled ? 1 : 0
51+
count = !var.github_app_enabled ? 1 : 0
5452
name = var.ssm_github_api_key
5553
with_decryption = true
5654
}
@@ -64,9 +62,9 @@ data "aws_ssm_parameter" "github_app_private_key" {
6462

6563
# We will only need the github provider if we are creating the GitHub webhook with github_repository_webhook.
6664
provider "github" {
67-
base_url = local.create_github_webhook ? var.github_base_url : null
68-
owner = local.create_github_webhook ? var.github_organization : null
69-
token = local.create_github_webhook ? local.github_token : null
65+
base_url = var.github_base_url
66+
owner = var.github_organization
67+
token = local.github_token
7068

7169
dynamic "app_auth" {
7270
for_each = local.create_github_webhook && var.github_app_enabled ? [1] : []

src/provider-helm.tf

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,8 @@ locals {
133133
"--profile", var.kube_exec_auth_aws_profile
134134
] : []
135135

136-
kube_exec_auth_role_arn = coalesce(var.kube_exec_auth_role_arn, module.iam_roles.terraform_role_arn)
137136
exec_role = local.kube_exec_auth_enabled && var.kube_exec_auth_role_arn_enabled ? [
138-
"--role-arn", local.kube_exec_auth_role_arn
137+
"--role-arn", coalesce(var.kube_exec_auth_role_arn, module.iam_roles.terraform_role_arn)
139138
] : []
140139

141140
# Provide dummy configuration for the case where the EKS cluster is not available.

src/remote-state.tf

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module "eks" {
22
source = "cloudposse/stack-config/yaml//modules/remote-state"
3-
version = "1.5.0"
3+
version = "1.8.0"
44

55
component = var.eks_component_name
66

@@ -9,7 +9,7 @@ module "eks" {
99

1010
module "dns_gbl_delegated" {
1111
source = "cloudposse/stack-config/yaml//modules/remote-state"
12-
version = "1.5.0"
12+
version = "1.8.0"
1313

1414
environment = "gbl"
1515
component = "dns-delegated"
@@ -20,7 +20,7 @@ module "dns_gbl_delegated" {
2020
module "saml_sso_providers" {
2121
for_each = local.enabled ? var.saml_sso_providers : {}
2222
source = "cloudposse/stack-config/yaml//modules/remote-state"
23-
version = "1.5.0"
23+
version = "1.8.0"
2424

2525
component = each.value.component
2626
environment = each.value.environment
@@ -32,7 +32,7 @@ module "argocd_repo" {
3232
for_each = local.enabled ? var.argocd_repositories : {}
3333

3434
source = "cloudposse/stack-config/yaml//modules/remote-state"
35-
version = "1.5.0"
35+
version = "1.8.0"
3636

3737
component = each.key
3838
environment = each.value.environment

test/.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
state/
2+
.cache
3+
test/test-suite.json
4+
.atmos
5+
test_suite.yaml

test/component_test.go

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
package test
2+
3+
import (
4+
"testing"
5+
"fmt"
6+
"strings"
7+
"os"
8+
helper "github.com/cloudposse/test-helpers/pkg/atmos/component-helper"
9+
// "github.com/cloudposse/test-helpers/pkg/atmos"
10+
awsTerratest "github.com/gruntwork-io/terratest/modules/aws"
11+
"github.com/stretchr/testify/assert"
12+
"github.com/gruntwork-io/terratest/modules/random"
13+
)
14+
15+
type ComponentSuite struct {
16+
helper.TestSuite
17+
18+
githubOrg string
19+
githubToken string
20+
randomID string
21+
awsRegion string
22+
}
23+
24+
func (s *ComponentSuite) TestEnabledFlag() {
25+
const component = "eks/argocd/disabled"
26+
const stack = "default-test"
27+
const awsRegion = "us-east-2"
28+
29+
randomID := strings.ToLower(random.UniqueId())
30+
namespace := fmt.Sprintf("argocd-%s", randomID)
31+
32+
secretPath := fmt.Sprintf("/argocd/%s/github/api_key", randomID)
33+
defer func() {
34+
awsTerratest.DeleteParameter(s.T(), awsRegion, secretPath)
35+
}()
36+
awsTerratest.PutParameter(s.T(), s.awsRegion, secretPath, "Github API Key", s.githubToken)
37+
38+
inputs := map[string]interface{}{
39+
"kubernetes_namespace": namespace,
40+
"ssm_github_api_key": secretPath,
41+
}
42+
43+
s.VerifyEnabledFlag(component, stack, &inputs)
44+
}
45+
46+
func (s *ComponentSuite) TestBasic() {
47+
const component = "eks/argocd/basic"
48+
const stack = "default-test"
49+
const awsRegion = "us-east-2"
50+
51+
randomID := strings.ToLower(random.UniqueId())
52+
namespace := fmt.Sprintf("argocd-%s", randomID)
53+
54+
secretPath := fmt.Sprintf("/argocd/%s/github/api_key", randomID)
55+
defer func() {
56+
awsTerratest.DeleteParameter(s.T(), awsRegion, secretPath)
57+
}()
58+
awsTerratest.PutParameter(s.T(), s.awsRegion, secretPath, "Github API Key", s.githubToken)
59+
60+
inputs := map[string]interface{}{
61+
"kubernetes_namespace": namespace,
62+
"ssm_github_api_key": secretPath,
63+
}
64+
65+
defer s.DestroyAtmosComponent(s.T(), component, stack, &inputs)
66+
options, _ := s.DeployAtmosComponent(s.T(), component, stack, &inputs)
67+
assert.NotNil(s.T(), options)
68+
69+
options, _ = s.DeployAtmosComponent(s.T(), component, stack, &inputs)
70+
assert.NotNil(s.T(), options)
71+
72+
s.DriftTest(component, stack, &inputs)
73+
}
74+
75+
func (s *ComponentSuite) SetupSuite() {
76+
s.TestSuite.InitConfig()
77+
s.TestSuite.Config.ComponentDestDir = "components/terraform/eks/argocd"
78+
79+
s.githubOrg = "cloudposse-tests"
80+
s.githubOrg = "cloudposse-tests"
81+
s.githubToken = os.Getenv("GITHUB_TOKEN")
82+
if s.githubToken == "" {
83+
s.T().Fatal("GITHUB_TOKEN environment variable must be set")
84+
}
85+
s.randomID = strings.ToLower(random.UniqueId())
86+
s.awsRegion = "us-east-2"
87+
88+
if !s.Config.SkipDeployDependencies {
89+
deployKeyPath := fmt.Sprintf("/argocd/deploy_keys/%s/%s", s.randomID, "%s")
90+
repoName := fmt.Sprintf("argocd-github-repo-%s", s.randomID)
91+
secretPath := fmt.Sprintf("/argocd/%s/github/api_key", s.randomID)
92+
awsTerratest.PutParameter(s.T(), s.awsRegion, secretPath, "Github API Key", s.githubToken)
93+
94+
inputs := map[string]interface{}{
95+
"ssm_github_deploy_key_format": deployKeyPath,
96+
"ssm_github_api_key": secretPath,
97+
"name": repoName,
98+
"github_organization": s.githubOrg,
99+
}
100+
s.AddDependency(s.T(), "argocd-github-repo", "default-test", &inputs)
101+
}
102+
103+
s.TestSuite.SetupSuite()
104+
}
105+
106+
func (s *ComponentSuite) TearDownSuite() {
107+
s.TestSuite.TearDownSuite()
108+
if !s.Config.SkipDestroyDependencies {
109+
secretPath := fmt.Sprintf("/argocd/%s/github/api_key", s.randomID)
110+
awsTerratest.DeleteParameter(s.T(), s.awsRegion, secretPath)
111+
}
112+
}
113+
114+
func TestRunSuite(t *testing.T) {
115+
suite := new(ComponentSuite)
116+
suite.AddDependency(t, "vpc", "default-test", nil)
117+
suite.AddDependency(t, "eks/cluster", "default-test", nil)
118+
119+
subdomain := strings.ToLower(random.UniqueId())
120+
inputs := map[string]interface{}{
121+
"zone_config": []map[string]interface{}{
122+
{
123+
"subdomain": subdomain,
124+
"zone_name": "components.cptest.test-automation.app",
125+
},
126+
},
127+
}
128+
suite.AddDependency(t, "dns-delegated", "default-test", &inputs)
129+
helper.Run(t, suite)
130+
}

test/fixtures/atmos.yaml

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# CLI config is loaded from the following locations (from lowest to highest priority):
2+
# system dir (`/usr/local/etc/atmos` on Linux, `%LOCALAPPDATA%/atmos` on Windows)
3+
# home dir (~/.atmos)
4+
# current directory
5+
# ENV vars
6+
# Command-line arguments
7+
#
8+
# It supports POSIX-style Globs for file names/paths (double-star `**` is supported)
9+
# https://en.wikipedia.org/wiki/Glob_(programming)
10+
11+
# Base path for components, stacks and workflows configurations.
12+
# Can also be set using `ATMOS_BASE_PATH` ENV var, or `--base-path` command-line argument.
13+
# Supports both absolute and relative paths.
14+
# If not provided or is an empty string, `components.terraform.base_path`, `components.helmfile.base_path`, `stacks.base_path` and `workflows.base_path`
15+
# are independent settings (supporting both absolute and relative paths).
16+
# If `base_path` is provided, `components.terraform.base_path`, `components.helmfile.base_path`, `stacks.base_path` and `workflows.base_path`
17+
# are considered paths relative to `base_path`.
18+
base_path: ""
19+
20+
components:
21+
terraform:
22+
# Can also be set using `ATMOS_COMPONENTS_TERRAFORM_BASE_PATH` ENV var, or `--terraform-dir` command-line argument
23+
# Supports both absolute and relative paths
24+
base_path: "components/terraform"
25+
# Can also be set using `ATMOS_COMPONENTS_TERRAFORM_APPLY_AUTO_APPROVE` ENV var
26+
apply_auto_approve: true
27+
# Can also be set using `ATMOS_COMPONENTS_TERRAFORM_DEPLOY_RUN_INIT` ENV var, or `--deploy-run-init` command-line argument
28+
deploy_run_init: true
29+
# Can also be set using `ATMOS_COMPONENTS_TERRAFORM_INIT_RUN_RECONFIGURE` ENV var, or `--init-run-reconfigure` command-line argument
30+
init_run_reconfigure: true
31+
# Can also be set using `ATMOS_COMPONENTS_TERRAFORM_AUTO_GENERATE_BACKEND_FILE` ENV var, or `--auto-generate-backend-file` command-line argument
32+
auto_generate_backend_file: true
33+
34+
stacks:
35+
# Can also be set using `ATMOS_STACKS_BASE_PATH` ENV var, or `--config-dir` and `--stacks-dir` command-line arguments
36+
# Supports both absolute and relative paths
37+
base_path: "stacks"
38+
# Can also be set using `ATMOS_STACKS_INCLUDED_PATHS` ENV var (comma-separated values string)
39+
# Since we are distinguishing stacks based on namespace, and namespace is not part
40+
# of the stack name, we have to set `included_paths` via the ENV var in the Dockerfile
41+
included_paths:
42+
- "orgs/**/*"
43+
44+
# Can also be set using `ATMOS_STACKS_EXCLUDED_PATHS` ENV var (comma-separated values string)
45+
excluded_paths:
46+
- "**/_defaults.yaml"
47+
48+
# Can also be set using `ATMOS_STACKS_NAME_PATTERN` ENV var
49+
name_pattern: "{tenant}-{stage}"
50+
51+
workflows:
52+
# Can also be set using `ATMOS_WORKFLOWS_BASE_PATH` ENV var, or `--workflows-dir` command-line arguments
53+
# Supports both absolute and relative paths
54+
base_path: "stacks/workflows"
55+
56+
# https://github.com/cloudposse/atmos/releases/tag/v1.33.0
57+
logs:
58+
file: "/dev/stdout"
59+
# Supported log levels: Trace, Debug, Info, Warning, Off
60+
level: Info
61+
62+
settings:
63+
# Can also be set using 'ATMOS_SETTINGS_LIST_MERGE_STRATEGY' environment variable, or '--settings-list-merge-strategy' command-line argument
64+
list_merge_strategy: replace
65+
66+
# `Go` templates in Atmos manifests
67+
# https://atmos.tools/core-concepts/stacks/templating
68+
# https://pkg.go.dev/text/template
69+
templates:
70+
settings:
71+
enabled: true
72+
# https://masterminds.github.io/sprig
73+
sprig:
74+
enabled: true
75+
# https://docs.gomplate.ca
76+
gomplate:
77+
enabled: true
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
components:
2+
terraform:
3+
account-map:
4+
metadata:
5+
terraform_workspace: core-gbl-root
6+
vars:
7+
tenant: core
8+
environment: gbl
9+
stage: root
10+
11+
# This remote state is only for Cloud Posse internal use.
12+
# It references the Cloud Posse test organizations actual infrastructure.
13+
# remote_state_backend:
14+
# s3:
15+
# bucket: cptest-core-ue2-root-tfstate-core
16+
# dynamodb_table: cptest-core-ue2-root-tfstate-core-lock
17+
# role_arn: arn:aws:iam::822777368227:role/cptest-core-gbl-root-tfstate-core-ro
18+
# encrypt: true
19+
# key: terraform.tfstate
20+
# acl: bucket-owner-full-control
21+
# region: us-east-2
22+
23+
remote_state_backend_type: static
24+
remote_state_backend:
25+
# This static backend is used for tests that only need to use the account map iam-roles module
26+
# to find the role to assume for Terraform operations. It is configured to use whatever
27+
# the current user's role is, but the environment variable `TEST_ACCOUNT_ID` must be set to
28+
# the account ID of the account that the user is currently assuming a role in.
29+
#
30+
# For some components, this backend is missing important data, and those components
31+
# will need that data added to the backend configuration in order to work properly.
32+
static:
33+
account_info_map: {}
34+
all_accounts: []
35+
aws_partition: aws
36+
full_account_map: {}
37+
iam_role_arn_templates: {}
38+
non_eks_accounts: []
39+
profiles_enabled: false
40+
root_account_aws_name: root
41+
terraform_access_map: {}
42+
terraform_dynamic_role_enabled: false
43+
terraform_role_name_map:
44+
apply: terraform
45+
plan: planner
46+
terraform_roles: {}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
components:
2+
terraform:
3+
argocd-github-repo:
4+
metadata:
5+
component: argocd-github-repo
6+
vars:
7+
enabled: true
8+
github_user: goruha
9+
github_user_email: ci@acme.com
10+
github_organization: cloudposse-tests
11+
github_codeowner_teams:
12+
- "@cloudposse-tests/admin"
13+
permissions:
14+
- team_slug: admin
15+
permission: admin
16+
name: argocd-deploy-non-prod
17+
description: "ArgoCD desired state repository (Non-production) for ACME applications"
18+
environments:
19+
- tenant: mgmt
20+
environment: uw2
21+
stage: sandbox
22+
auto-sync: false
23+
gitignore_entries: []
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
components:
2+
terraform:
3+
dns-delegated:
4+
metadata:
5+
component: dns-delegated
6+
vars:
7+
zone_config:
8+
- subdomain: test
9+
zone_name: example.net
10+
request_acm_certificate: true

0 commit comments

Comments
 (0)