Skip to content

Commit d829c5b

Browse files
[CONTP-962] Add tests for IAM role names with paths. (#42)
* add tests for iam roles with and without path * chore: pass just arn object to validate both cases. * chore: rename task role path name * chore: terraform fmt * chore: use terraform-test path circumventing ci iam perms * chore: task def comments
1 parent 1542b98 commit d829c5b

File tree

4 files changed

+213
-0
lines changed

4 files changed

+213
-0
lines changed

smoke_tests/ecs_fargate/outputs.tf

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,11 @@ output "cws-only" {
2929
output "logging-only" {
3030
value = module.dd_task_logging_only
3131
}
32+
33+
output "role-parsing-with-path" {
34+
value = module.dd_task_role_parsing_with_path
35+
}
36+
37+
output "role-parsing-without-path" {
38+
value = module.dd_task_role_parsing_without_path
39+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# Unless explicitly stated otherwise all files in this repository are licensed
2+
# under the Apache License Version 2.0.
3+
# This product includes software developed at Datadog (https://www.datadoghq.com/).
4+
# Copyright 2025-present Datadog, Inc.
5+
6+
################################################################################
7+
# Task Definition: IAM Role with path in name
8+
################################################################################
9+
10+
# Create IAM roles with paths to test the parsing logic
11+
resource "aws_iam_role" "test_task_role_with_path" {
12+
name = "${var.test_prefix}-task-role-with-path"
13+
path = "/terraform-test/"
14+
15+
assume_role_policy = jsonencode({
16+
Version = "2012-10-17"
17+
Statement = [{
18+
Effect = "Allow"
19+
Principal = {
20+
Service = "ecs-tasks.amazonaws.com"
21+
}
22+
Action = "sts:AssumeRole"
23+
}]
24+
})
25+
}
26+
27+
resource "aws_iam_role" "test_execution_role_with_path" {
28+
name = "${var.test_prefix}-execution-role-with-path"
29+
path = "/terraform-test/"
30+
31+
assume_role_policy = jsonencode({
32+
Version = "2012-10-17"
33+
Statement = [{
34+
Effect = "Allow"
35+
Principal = {
36+
Service = "ecs-tasks.amazonaws.com"
37+
}
38+
Action = "sts:AssumeRole"
39+
}]
40+
})
41+
}
42+
43+
# Attach required policies to execution role
44+
resource "aws_iam_role_policy_attachment" "test_execution_role_policy" {
45+
role = aws_iam_role.test_execution_role_with_path.name
46+
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
47+
}
48+
49+
module "dd_task_role_parsing_with_path" {
50+
source = "../../modules/ecs_fargate"
51+
52+
# Use roles with paths to test parsing
53+
task_role = aws_iam_role.test_task_role_with_path
54+
execution_role = { arn = aws_iam_role.test_execution_role_with_path.arn }
55+
56+
dd_api_key = var.dd_api_key
57+
dd_site = var.dd_site
58+
dd_service = var.dd_service
59+
dd_essential = true
60+
61+
# Configure Task Definition
62+
family = "${var.test_prefix}-role-parsing-with-path"
63+
container_definitions = jsonencode([])
64+
65+
requires_compatibilities = ["FARGATE"]
66+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# Unless explicitly stated otherwise all files in this repository are licensed
2+
# under the Apache License Version 2.0.
3+
# This product includes software developed at Datadog (https://www.datadoghq.com/).
4+
# Copyright 2025-present Datadog, Inc.
5+
6+
################################################################################
7+
# Task Definition: IAM Role without path in name
8+
################################################################################
9+
10+
# Create IAM roles without paths to test the parsing logic
11+
resource "aws_iam_role" "test_task_role_without_path" {
12+
name = "${var.test_prefix}-task-role-without-path"
13+
# No path specified - defaults to "/"
14+
15+
assume_role_policy = jsonencode({
16+
Version = "2012-10-17"
17+
Statement = [{
18+
Effect = "Allow"
19+
Principal = {
20+
Service = "ecs-tasks.amazonaws.com"
21+
}
22+
Action = "sts:AssumeRole"
23+
}]
24+
})
25+
}
26+
27+
resource "aws_iam_role" "test_execution_role_without_path" {
28+
name = "${var.test_prefix}-execution-role-without-path"
29+
# No path specified - defaults to "/"
30+
31+
assume_role_policy = jsonencode({
32+
Version = "2012-10-17"
33+
Statement = [{
34+
Effect = "Allow"
35+
Principal = {
36+
Service = "ecs-tasks.amazonaws.com"
37+
}
38+
Action = "sts:AssumeRole"
39+
}]
40+
})
41+
}
42+
43+
# Attach required policies to execution role
44+
resource "aws_iam_role_policy_attachment" "test_execution_role_policy_no_path" {
45+
role = aws_iam_role.test_execution_role_without_path.name
46+
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
47+
}
48+
49+
module "dd_task_role_parsing_without_path" {
50+
source = "../../modules/ecs_fargate"
51+
52+
# Use roles without paths to test parsing
53+
task_role = aws_iam_role.test_task_role_without_path
54+
execution_role = { arn = aws_iam_role.test_execution_role_without_path.arn }
55+
56+
dd_api_key = var.dd_api_key
57+
dd_site = var.dd_site
58+
dd_service = var.dd_service
59+
dd_essential = true
60+
61+
# Configure Task Definition
62+
family = "${var.test_prefix}-role-parsing-without-path"
63+
container_definitions = jsonencode([])
64+
65+
requires_compatibilities = ["FARGATE"]
66+
}

tests/role_parsing_test.go

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// Unless explicitly stated otherwise all files in this repository are licensed
2+
// under the Apache License Version 2.0.
3+
// This product includes software developed at Datadog (https://www.datadoghq.com/).
4+
// Copyright 2025-present Datadog, Inc.
5+
6+
package test
7+
8+
import (
9+
"encoding/json"
10+
"log"
11+
"strings"
12+
13+
"github.com/aws/aws-sdk-go-v2/service/ecs/types"
14+
"github.com/gruntwork-io/terratest/modules/terraform"
15+
)
16+
17+
// TestRoleParsingWithPath tests that the module correctly parses role names from ARNs with paths
18+
func (s *ECSFargateSuite) TestRoleParsingWithPath() {
19+
log.Println("TestRoleParsingWithPath: Running test...")
20+
21+
var containers []types.ContainerDefinition
22+
task := terraform.OutputMap(s.T(), s.terraformOptions, "role-parsing-with-path")
23+
24+
s.Equal(s.testPrefix+"-role-parsing-with-path", task["family"], "Unexpected task family name")
25+
26+
err := json.Unmarshal([]byte(task["container_definitions"]), &containers)
27+
s.NoError(err, "Failed to parse container definitions")
28+
29+
s.NotEmpty(task["arn"], "Task definition ARN should not be empty")
30+
s.NotEmpty(task["revision"], "Task definition revision should not be empty")
31+
32+
taskRoleArn := task["task_role_arn"]
33+
s.NotEmpty(taskRoleArn, "Task role ARN should not be empty")
34+
s.Contains(taskRoleArn, "/terraform-test/", "Task role ARN should contain the path '/test-path/'")
35+
s.Contains(taskRoleArn, s.testPrefix+"-task-role-with-path", "Task role ARN should contain the expected role name")
36+
37+
executionRoleArn := task["execution_role_arn"]
38+
s.NotEmpty(executionRoleArn, "Execution role ARN should not be empty")
39+
s.Contains(executionRoleArn, "/terraform-test/", "Execution role ARN should contain the path '/terraform-test/'")
40+
s.Contains(executionRoleArn, s.testPrefix+"-execution-role-with-path", "Execution role ARN should contain the expected role name")
41+
}
42+
43+
// TestRoleParsingWithoutPath tests that the module correctly parses role names from ARNs without paths
44+
func (s *ECSFargateSuite) TestRoleParsingWithoutPath() {
45+
log.Println("TestRoleParsingWithoutPath: Running test...")
46+
47+
var containers []types.ContainerDefinition
48+
task := terraform.OutputMap(s.T(), s.terraformOptions, "role-parsing-without-path")
49+
50+
s.Equal(s.testPrefix+"-role-parsing-without-path", task["family"], "Unexpected task family name")
51+
52+
err := json.Unmarshal([]byte(task["container_definitions"]), &containers)
53+
s.NoError(err, "Failed to parse container definitions")
54+
55+
s.NotEmpty(task["arn"], "Task definition ARN should not be empty")
56+
s.NotEmpty(task["revision"], "Task definition revision should not be empty")
57+
58+
taskRoleArn := task["task_role_arn"]
59+
s.NotEmpty(taskRoleArn, "Task role ARN should not be empty")
60+
s.Contains(taskRoleArn, s.testPrefix+"-task-role-without-path", "Task role ARN should contain the expected role name")
61+
62+
roleArnParts := strings.Split(taskRoleArn, "/")
63+
s.Equal(2, len(roleArnParts), "Role ARN without path should have exactly 2 parts when split by '/'")
64+
s.Contains(roleArnParts[1], s.testPrefix+"-task-role-without-path", "Role name should be the second part after splitting by '/'")
65+
66+
executionRoleArn := task["execution_role_arn"]
67+
s.NotEmpty(executionRoleArn, "Execution role ARN should not be empty")
68+
s.Contains(executionRoleArn, s.testPrefix+"-execution-role-without-path", "Execution role ARN should contain the expected role name")
69+
70+
execRoleArnParts := strings.Split(executionRoleArn, "/")
71+
s.Equal(2, len(execRoleArnParts), "Execution role ARN without path should have exactly 2 parts when split by '/'")
72+
s.Contains(execRoleArnParts[1], s.testPrefix+"-execution-role-without-path", "Execution role name should be the second part after splitting by '/'")
73+
}

0 commit comments

Comments
 (0)