Skip to content

fix: Ensure var.region is passed through aws_region data source #329

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jul 31, 2025

Conversation

tvon
Copy link
Contributor

@tvon tvon commented Jul 31, 2025

Description

Update the ECSTasksAssumeRole policy to use the region variable in the assume role condition. This is to configure the policy for the region the service is deployed to.

Motivation and Context

When applying with a provider configured for us-east-1 and creating a cluster in eu-west-1 the assume role policy is generated as follows:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "ECSTasksAssumeRole",
            "Effect": "Allow",
            "Principal": {
                "Service": "ecs-tasks.amazonaws.com"
            },
            "Action": "sts:AssumeRole",
            "Condition": {
                "StringEquals": {
                    "aws:SourceAccount": "XXXXXXXXXXXX"
                },
                "ArnLike": {
                    "aws:SourceArn": "arn:aws:ecs:us-east-1:XXXXXXXXXXXX:*"
                }
            }
        }
    ]
}

Note the ArnLike is arn:aws:ecs:us-east-1:XXXXXXXXXXXX when it should match the region of the created service, e.g. arn:aws:ecs:eu-west-1:XXXXXXXXXXXX

With the incorrect region, the task deployment fails with the following (via service events in the AWS Console) :

service [ex-fargate](https://eu-west-1.console.aws.amazon.com/ecs/v2/clusters/ex-fargate/services/ex-fargate?region=eu-west-1) failed to launch a task with (error ECS was unable to assume the role 'arn:aws:iam::XXXXXXXXXXXX:role/ex-fargate-20250731185936604400000004' that was provided for this task. Please verify that the role being passed has the proper trust relationship and permissions and that your IAM user has permissions to pass this role.).

Updating the aws:SourceArn with the correct region resolves the issue.

Breaking Changes

None that I am aware of.

How Has This Been Tested?

  • I have updated at least one of the examples/* to demonstrate and validate my change(s)
  • I have tested and validated these changes using one or more of the provided examples/* projects
  • I have executed pre-commit run -a on my pull request

tvon added 4 commits July 31, 2025 12:03
Given var.region can be null, add another try() to check for a provided value
before falling back to current region.
@tvon tvon changed the title Use provided region in aws:SourceArn condition fix: Use provided region in aws:SourceArn condition Jul 31, 2025
@tvon
Copy link
Contributor Author

tvon commented Jul 31, 2025

The examples do not seem to exercise the enhanced region support in the v6 provider, so I locally modified the examples/fargate/main.tf as follows:

provider "aws" {
  region = local.region
}

locals {
  # The region we are executing Terraform against.
  region = "us-east-1"

  # The region we are building ECS resources in.
  target_region = "eu-west-1"

  name     = "ex-${basename(path.cwd)}"
  vpc_cidr = "10.0.0.0/16"
  azs      = slice(data.aws_availability_zones.available.names, 0, 3)

  container_name = "ecsdemo-frontend"
  container_port = 3000

  tags = {
    Name       = local.name
    Example    = local.name
    Repository = "https://github.com/terraform-aws-modules/terraform-aws-ecs"
  }
}

################################################################################
# Cluster
################################################################################

module "ecs_cluster" {
  source = "../../modules/cluster"

  region = local.target_region

  name = local.name

  # Capacity provider
  default_capacity_provider_strategy = {
    FARGATE = {
      weight = 50
      base   = 20
    }
    FARGATE_SPOT = {
      weight = 50
    }
  }

  tags = local.tags
}

################################################################################
# Service
################################################################################

module "ecs_service" {
  source = "../../modules/service"

  region = local.target_region

  name        = local.name
  cluster_arn = module.ecs_cluster.arn

  cpu    = 1024
  memory = 4096

  # Enables ECS Exec
  enable_execute_command = true

  # Container definition(s)
  container_definitions = {

    (local.container_name) = {
      cpu       = 512
      memory    = 1024
      essential = true
      image     = "public.ecr.aws/aws-containers/ecsdemo-frontend:776fd50"
      portMappings = [
        {
          name          = local.container_name
          containerPort = local.container_port
          hostPort      = local.container_port
          protocol      = "tcp"
        }
      ]

      # Example image used requires access to write to root filesystem
      readonlyRootFilesystem = false
      memoryReservation      = 100
    }
  }

  subnet_ids = module.vpc.private_subnets

  security_group_egress_rules = {
    all = {
      ip_protocol = "-1"
      cidr_ipv4   = "0.0.0.0/0"
    }
  }

  tags = local.tags
}


#
#  Setup VPC
#
#  terraform-aws-modules/vpc does not fully support specifying the region so use
#  the provider alias method to create a VPC in a different region.
#

provider "aws" {
  alias  = "eu-east-1"
  region = local.target_region
}

data "aws_availability_zones" "available" {
  provider = aws.eu-east-1
}

module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "~> 6.0"

  providers = {
    aws = aws.eu-east-1
  }

  name = local.name
  cidr = local.vpc_cidr

  azs             = local.azs
  private_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 4, k)]
  public_subnets  = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 48)]

  enable_nat_gateway = true
  single_nat_gateway = true

  tags = local.tags
}

Prior to the change in this PR the service fails to start with a ECS was unable to assume the role error, with the changes in this PR the task launches successfully.

@tvon
Copy link
Contributor Author

tvon commented Jul 31, 2025

I can add a cross-region example, I'm not sure how else to address a demo.

@tvon tvon requested a review from bryantbiggs July 31, 2025 19:32
@bryantbiggs
Copy link
Member

ok thank you - curious, why use the region in that way instead of just setting it on the provider and let everything else inherit it?

@bryantbiggs bryantbiggs changed the title fix: Use provided region in aws:SourceArn condition fix: Ensure var.region is passed through aws_region data source Jul 31, 2025
@bryantbiggs bryantbiggs merged commit 9a7f9b5 into terraform-aws-modules:master Jul 31, 2025
13 checks passed
antonbabenko pushed a commit that referenced this pull request Jul 31, 2025
## [6.1.3](v6.1.2...v6.1.3) (2025-07-31)

### Bug Fixes

* Ensure `var.region` is passed through `aws_region` data source ([#329](#329)) ([9a7f9b5](9a7f9b5))
@antonbabenko
Copy link
Member

This PR is included in version 6.1.3 🎉

@tvon
Copy link
Contributor Author

tvon commented Jul 31, 2025

ok thank you - curious, why use the region in that way instead of just setting it on the provider and let everything else inherit it?

We have resources spread across a few regions and there is enough interdependence to put them all in one terraform workspace.

@bryantbiggs
Copy link
Member

I would advise against doing that

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants