Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions smoke_tests/ecs_fargate/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,11 @@ output "cws-only" {
output "logging-only" {
value = module.dd_task_logging_only
}

output "role-parsing-with-path" {
value = module.dd_task_role_parsing_with_path
}

output "role-parsing-without-path" {
value = module.dd_task_role_parsing_without_path
}
66 changes: 66 additions & 0 deletions smoke_tests/ecs_fargate/role-parsing-with-path.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Unless explicitly stated otherwise all files in this repository are licensed
# under the Apache License Version 2.0.
# This product includes software developed at Datadog (https://www.datadoghq.com/).
# Copyright 2025-present Datadog, Inc.

################################################################################
# Task Definition: IAM Role with path in name
################################################################################

# Create IAM roles with paths to test the parsing logic
resource "aws_iam_role" "test_task_role_with_path" {
name = "${var.test_prefix}-task-role-with-path"
path = "/terraform-test/"

assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Principal = {
Service = "ecs-tasks.amazonaws.com"
}
Action = "sts:AssumeRole"
}]
})
}

resource "aws_iam_role" "test_execution_role_with_path" {
name = "${var.test_prefix}-execution-role-with-path"
path = "/terraform-test/"

assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Principal = {
Service = "ecs-tasks.amazonaws.com"
}
Action = "sts:AssumeRole"
}]
})
}

# Attach required policies to execution role
resource "aws_iam_role_policy_attachment" "test_execution_role_policy" {
role = aws_iam_role.test_execution_role_with_path.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
}

module "dd_task_role_parsing_with_path" {
source = "../../modules/ecs_fargate"

# Use roles with paths to test parsing
task_role = aws_iam_role.test_task_role_with_path
execution_role = { arn = aws_iam_role.test_execution_role_with_path.arn }

dd_api_key = var.dd_api_key
dd_site = var.dd_site
dd_service = var.dd_service
dd_essential = true

# Configure Task Definition
family = "${var.test_prefix}-role-parsing-with-path"
container_definitions = jsonencode([])

requires_compatibilities = ["FARGATE"]
}
66 changes: 66 additions & 0 deletions smoke_tests/ecs_fargate/role-parsing-without-path.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Unless explicitly stated otherwise all files in this repository are licensed
# under the Apache License Version 2.0.
# This product includes software developed at Datadog (https://www.datadoghq.com/).
# Copyright 2025-present Datadog, Inc.

################################################################################
# Task Definition: IAM Role without path in name
################################################################################

# Create IAM roles without paths to test the parsing logic
resource "aws_iam_role" "test_task_role_without_path" {
name = "${var.test_prefix}-task-role-without-path"
# No path specified - defaults to "/"

assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Principal = {
Service = "ecs-tasks.amazonaws.com"
}
Action = "sts:AssumeRole"
}]
})
}

resource "aws_iam_role" "test_execution_role_without_path" {
name = "${var.test_prefix}-execution-role-without-path"
# No path specified - defaults to "/"

assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Principal = {
Service = "ecs-tasks.amazonaws.com"
}
Action = "sts:AssumeRole"
}]
})
}

# Attach required policies to execution role
resource "aws_iam_role_policy_attachment" "test_execution_role_policy_no_path" {
role = aws_iam_role.test_execution_role_without_path.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
}

module "dd_task_role_parsing_without_path" {
source = "../../modules/ecs_fargate"

# Use roles without paths to test parsing
task_role = aws_iam_role.test_task_role_without_path
execution_role = { arn = aws_iam_role.test_execution_role_without_path.arn }

dd_api_key = var.dd_api_key
dd_site = var.dd_site
dd_service = var.dd_service
dd_essential = true

# Configure Task Definition
family = "${var.test_prefix}-role-parsing-without-path"
container_definitions = jsonencode([])

requires_compatibilities = ["FARGATE"]
}
73 changes: 73 additions & 0 deletions tests/role_parsing_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// Unless explicitly stated otherwise all files in this repository are licensed
// under the Apache License Version 2.0.
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2025-present Datadog, Inc.

package test

import (
"encoding/json"
"log"
"strings"

"github.com/aws/aws-sdk-go-v2/service/ecs/types"
"github.com/gruntwork-io/terratest/modules/terraform"
)

// TestRoleParsingWithPath tests that the module correctly parses role names from ARNs with paths
func (s *ECSFargateSuite) TestRoleParsingWithPath() {
log.Println("TestRoleParsingWithPath: Running test...")

var containers []types.ContainerDefinition
task := terraform.OutputMap(s.T(), s.terraformOptions, "role-parsing-with-path")

s.Equal(s.testPrefix+"-role-parsing-with-path", task["family"], "Unexpected task family name")

err := json.Unmarshal([]byte(task["container_definitions"]), &containers)
s.NoError(err, "Failed to parse container definitions")

s.NotEmpty(task["arn"], "Task definition ARN should not be empty")
s.NotEmpty(task["revision"], "Task definition revision should not be empty")

taskRoleArn := task["task_role_arn"]
s.NotEmpty(taskRoleArn, "Task role ARN should not be empty")
s.Contains(taskRoleArn, "/terraform-test/", "Task role ARN should contain the path '/test-path/'")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: expected role path

Suggested change
s.Contains(taskRoleArn, "/terraform-test/", "Task role ARN should contain the path '/test-path/'")
s.Contains(taskRoleArn, "/terraform-test/", "Task role ARN should contain the path '/terraform-test/'")

s.Contains(taskRoleArn, s.testPrefix+"-task-role-with-path", "Task role ARN should contain the expected role name")

executionRoleArn := task["execution_role_arn"]
s.NotEmpty(executionRoleArn, "Execution role ARN should not be empty")
s.Contains(executionRoleArn, "/terraform-test/", "Execution role ARN should contain the path '/terraform-test/'")
s.Contains(executionRoleArn, s.testPrefix+"-execution-role-with-path", "Execution role ARN should contain the expected role name")
}

// TestRoleParsingWithoutPath tests that the module correctly parses role names from ARNs without paths
func (s *ECSFargateSuite) TestRoleParsingWithoutPath() {
log.Println("TestRoleParsingWithoutPath: Running test...")

var containers []types.ContainerDefinition
task := terraform.OutputMap(s.T(), s.terraformOptions, "role-parsing-without-path")

s.Equal(s.testPrefix+"-role-parsing-without-path", task["family"], "Unexpected task family name")

err := json.Unmarshal([]byte(task["container_definitions"]), &containers)
s.NoError(err, "Failed to parse container definitions")

s.NotEmpty(task["arn"], "Task definition ARN should not be empty")
s.NotEmpty(task["revision"], "Task definition revision should not be empty")

taskRoleArn := task["task_role_arn"]
s.NotEmpty(taskRoleArn, "Task role ARN should not be empty")
s.Contains(taskRoleArn, s.testPrefix+"-task-role-without-path", "Task role ARN should contain the expected role name")

roleArnParts := strings.Split(taskRoleArn, "/")
s.Equal(2, len(roleArnParts), "Role ARN without path should have exactly 2 parts when split by '/'")
s.Contains(roleArnParts[1], s.testPrefix+"-task-role-without-path", "Role name should be the second part after splitting by '/'")

executionRoleArn := task["execution_role_arn"]
s.NotEmpty(executionRoleArn, "Execution role ARN should not be empty")
s.Contains(executionRoleArn, s.testPrefix+"-execution-role-without-path", "Execution role ARN should contain the expected role name")

execRoleArnParts := strings.Split(executionRoleArn, "/")
s.Equal(2, len(execRoleArnParts), "Execution role ARN without path should have exactly 2 parts when split by '/'")
s.Contains(execRoleArnParts[1], s.testPrefix+"-execution-role-without-path", "Execution role name should be the second part after splitting by '/'")
}