Home > front end >  How do I enable my code runing in a AWS Fargate container to assume an IAM role when connecting to S
How do I enable my code runing in a AWS Fargate container to assume an IAM role when connecting to S

Time:09-28

I am trying to use IAM roles to control access to S3 in my application. However, I don't have all the pieces in place to make this work. When running in AWS, my code is throwing a "missing credentials." exception, so obviously I've missed a step.

I was under the impression that without specifying the credentials, the SDK would default to using the identity of the container, but that doesn't seem to be the case. I assume that either my code is wrong, or the Assume Role policy that I've created isn't specifying the right principal. I just haven't been able to figure out from the docs what I'm supposed to be doing.

My other thought is maybe I need to create a separate role for access to the S3 bucket, and then write some code to assume that role, and use those credentials in my s3 client.

Any help would be appreciated.

I'm using Terraform to set up my infrastructure, and have included the relevant excerpts below. At the end of the post, I've included my Typescript code for accessing S3.

Current configuration

  1. I've defined a role for my ECS Fargate Task
resource "aws_iam_role" "ecs_task_execution_role" {
  name = "ecsTaskExecutionRole"
  assume_role_policy = data.aws_iam_policy_document.ecs_task_execution_role.json
}
  1. I've defined an Assume Role policy for this task
data "aws_iam_policy_document" "ecs_task_execution_role" {
    version = "2012-10-17"
    statement {
        sid = ""
        effect = "Allow"
        actions = ["sts:AssumeRole"]
        
        principals {
            type = "Service"
            identifiers = ["ecs-tasks.amazonaws.com"]
        }
    }
}
  1. I've defined an IAM Policy that governs access to the S3 bucket in question:
resource "aws_iam_policy" "read_write_image_storage" {
    name = "${var.environment}-read-write-image-storage"
    description = "Allows read access to s3 bucket in the ${var.environment} environment"
    
    policy = jsonencode({
      Version = "2012-10-17",
      Statement = [{
        Effect = "Allow",
        Action = [
          "s3:*"
        ],
        Resource = [
          aws_s3_bucket.image_storage.arn,
        ]
     }]
    })
}
  1. I've attached the policy to the role under which my containers are running:
resource "aws_iam_role_policy_attachment" "read_write_image_storage" {
  role = aws_iam_role.ecs_task_execution_role.name
  policy_arn = aws_iam_policy.read_write_image_storage.arn
}
  1. In my node.js code running in the container associated with this task I spin up a default S3 client, and try to use it to access the bucket:
const s3config = {
    region: process.env.AWS_REGION,
};

const s3 = new S3(s3config);

export const putBlob = async (key: string, blob: Buffer) => {
    // save buffer to an AWS S3 bucket
    const params = {
        Bucket: process.env.AWS_ATTACHMENT_STORAGE_BUCKETNAME,
        Key: key,
        Body: blob,
        ContentType: "image/png",
    };
    
    try {
        console.debug("Saving image to S3");
        const result = await s3.upload(params).promise();
    } catch(e) {
        console.error(e.message) // MissingCredentials
        throw 2
    }
}
  1. I've defined the Fargate task to use the role defined in step 1
resource "aws_ecs_task_definition" "webapp" {
  family                   = "webapp-task"
  execution_role_arn       = aws_iam_role.ecs_task_execution_role.arn
  network_mode             = "awsvpc"
  requires_compatibilities = ["FARGATE"]
  cpu                      = "256"
  memory                   = "512"

  container_definitions = jsonencode([
    {
      "name" : "MyContainerDefinition",
      "image" : "MyContainerImage",
      "cpu" : 256,
      "memory" : 512,
      "essential" : true,
      "portMappings" : [
        {
          "containerPort" : 80,
          "hostPort" : 80,
          "protocol" : "tcp"
        }
      ],
    }
  ])
}```

CodePudding user response:

You have to setup task_role_arn. This is different then execution_role_arn.

  • Related