How to Create Service Roles for AWS Glue, Lambda, ECS, and Step Functions
Create service roles by defining trust policies that allow service principals (glue.amazonaws.com, lambda.amazonaws.com, ecs.amazonaws.com, states.amazonaws.com) to assume the role, attach AWS-managed policies like AWSGlueServiceRole or AWSLambdaBasicExecutionRole, and add inline permissions for specific resource access using the AWS CLI or IAM console.
The Agent Toolkit for AWS provides comprehensive IAM guidance for creating service roles that enable AWS workloads to run securely. According to the repository's IAM management references in skills/core-skills/aws-iam/references/aws-iam-role-management.md, every service role requires a trust policy, AWS-managed permissions, and service-specific inline policies. This guide walks through the exact configurations needed for Glue, Lambda, ECS, and Step Functions.
Prerequisites for Creating Service Roles
Before creating any service role, ensure you have the necessary IAM permissions and understand the naming conventions.
- Required IAM permissions: You must have
iam:CreateRole,iam:PutRolePolicy, andiam:PassRolepermissions on the target account - Naming convention: Use clear, service-specific names like
MyApp-Glue-ServiceRoleorMyApp-Lambda-ExecRole - Trust policy security: Always include the
aws:SourceAccountcondition key in trust policies to prevent confused-deputy attacks
AWS Glue Service Role
AWS Glue ETL jobs require a service role that can access the Data Catalog, underlying data sources, and S3 Tables for data lake operations.
Required Permissions
According to skills/specialized-skills/storage-skills/creating-data-lake-table/references/table-creation-glue-etl.md, a Glue service role requires:
- Managed policy:
AWSGlueServiceRole - Inline permissions:
glue:GetCatalog,glue:GetDatabase,glue:GetTable,glue:passConnection - Data lake permissions:
s3tables:*for S3 Tables integration
Trust Policy
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "glue.amazonaws.com"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"aws:SourceAccount": "<ACCOUNT_ID>"
}
}
}
]
}
AWS Lambda Execution Role
Lambda functions assume an execution role to interact with AWS services and write logs to CloudWatch.
Required Permissions
- Managed policy:
AWSLambdaBasicExecutionRole(provides CloudWatch Logs access) - Additional permissions: Resource-specific policies for services your function accesses (e.g., S3, DynamoDB)
Trust Policy
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"aws:SourceAccount": "<ACCOUNT_ID>"
}
}
}
]
}
Amazon ECS Roles
ECS workloads require three distinct role types: the service role for the control plane, the task execution role for container management, and the task role for application code.
ECS Service Role
The service role allows the ECS control plane to manage cluster resources.
- Managed policy:
AmazonECSServiceRolePolicy - Trust principal:
ecs.amazonaws.com
ECS Task Execution Role
The task execution role enables ECS to pull container images and write logs to CloudWatch.
- Managed policy:
AmazonECSTaskExecutionRolePolicy - Additional permissions:
ecr:GetAuthorizationToken,logs:CreateLogStream, S3 access as needed - Trust principal:
ecs-tasks.amazonaws.com
ECS Task Role
The task role grants permissions to the application code running inside the container.
- Policy type: Custom inline policy based on workload requirements
- Common permissions: DynamoDB access, S3 operations, or other AWS API calls your containerized application requires
Trust Policy for Service Role
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ecs.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
AWS Step Functions Execution Role
Step Functions state machines require an execution role that permits the service to invoke other AWS services on your behalf.
Required Permissions
- Managed policy:
AWSStepFunctionsFullAccess(or a custom least-privilege policy) - Service permissions: Permissions for every service the workflow calls, such as
lambda:InvokeFunction,glue:StartJobRun, orecs:RunTask
Trust Policy
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "states.amazonaws.com"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"aws:SourceAccount": "<ACCOUNT_ID>"
}
}
}
]
}
CLI Examples for Creating Service Roles
Use the following AWS CLI commands to create and configure each service role. Replace <ACCOUNT_ID> with your AWS account ID.
Create a Glue ETL Service Role
# Create the role with Glue trust policy
aws iam create-role \
--role-name MyApp-Glue-ServiceRole \
--assume-role-policy-document file://<(cat <<'EOF'
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {"Service": "glue.amazonaws.com"},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {"aws:SourceAccount": "<ACCOUNT_ID>"}
}
}
]
}
EOF
)
# Attach AWS managed policy
aws iam attach-role-policy \
--role-name MyApp-Glue-ServiceRole \
--policy-arn arn:aws:iam::aws:policy/service-role/AWSGlueServiceRole
# Add S3 Tables inline permissions
aws iam put-role-policy \
--role-name MyApp-Glue-ServiceRole \
--policy-name S3TablesAccess \
--policy-document file://<(cat <<'EOF'
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3tables:GetTableBucket",
"s3tables:CreateTable"
],
"Resource": "*"
}
]
}
EOF
)
Create a Lambda Execution Role
aws iam create-role \
--role-name MyApp-Lambda-ExecRole \
--assume-role-policy-document file://<(cat <<'EOF'
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {"Service": "lambda.amazonaws.com"},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {"aws:SourceAccount": "<ACCOUNT_ID>"}
}
}
]
}
EOF
)
aws iam attach-role-policy \
--role-name MyApp-Lambda-ExecRole \
--policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Create ECS Service and Task Roles
# ECS Service Role (control plane)
aws iam create-role \
--role-name MyApp-ECS-ServiceRole \
--assume-role-policy-document file://<(cat <<'EOF'
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {"Service": "ecs.amazonaws.com"},
"Action": "sts:AssumeRole"
}
]
}
EOF
)
aws iam attach-role-policy \
--role-name MyApp-ECS-ServiceRole \
--policy-arn arn:aws:iam::aws:policy/service-role/AmazonECSServiceRolePolicy
# ECS Task Execution Role
aws iam create-role \
--role-name MyApp-ECS-TaskExecRole \
--assume-role-policy-document file://<(cat <<'EOF'
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {"Service": "ecs-tasks.amazonaws.com"},
"Action": "sts:AssumeRole"
}
]
}
EOF
)
aws iam attach-role-policy \
--role-name MyApp-ECS-TaskExecRole \
--policy-arn arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy
Create a Step Functions Execution Role
aws iam create-role \
--role-name MyApp-States-ExecRole \
--assume-role-policy-document file://<(cat <<'EOF'
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {"Service": "states.amazonaws.com"},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {"aws:SourceAccount": "<ACCOUNT_ID>"}
}
}
]
}
EOF
)
# Add permissions for Lambda and Glue integration
aws iam put-role-policy \
--role-name MyApp-States-ExecRole \
--policy-name StateMachinePermissions \
--policy-document file://<(cat <<'EOF'
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["lambda:InvokeFunction"],
"Resource": "arn:aws:lambda:*:*:<ACCOUNT_ID>:function:*"
},
{
"Effect": "Allow",
"Action": ["glue:StartJobRun"],
"Resource": "arn:aws:glue:*:*:<ACCOUNT_ID>:job/*"
}
]
}
EOF
)
Summary
- Trust policies must allow the specific service principal (e.g.,
glue.amazonaws.com,lambda.amazonaws.com) to assume the role usingsts:AssumeRole - AWS-managed policies provide baseline permissions:
AWSGlueServiceRolefor Glue,AWSLambdaBasicExecutionRolefor Lambda,AmazonECSServiceRolePolicyandAmazonECSTaskExecutionRolePolicyfor ECS - Security conditions should include
aws:SourceAccountin trust policies to prevent confused-deputy attacks across accounts - Inline policies extend managed policies with specific resource permissions, such as S3 Tables access for Glue ETL jobs or service invocation permissions for Step Functions
- ECS requires three roles: a service role for the control plane, a task execution role for container management, and a task role for application permissions
Frequently Asked Questions
What is the difference between an ECS task execution role and a task role?
The task execution role (ecs-tasks.amazonaws.com principal) grants permissions to the ECS agent to pull container images from ECR, write logs to CloudWatch, and access secrets. The task role (ecs-tasks.amazonaws.com principal in the task definition) grants permissions to the application code running inside the container. According to the Agent Toolkit for AWS IAM guidance, the task execution role uses AmazonECSTaskExecutionRolePolicy, while the task role requires a custom policy based on your application's AWS API usage.
Why do I need the aws:SourceAccount condition in trust policies?
The aws:SourceAccount condition prevents the confused-deputy problem, where a service might be tricked into accessing resources in a different account. By specifying StringEquals: {aws:SourceAccount: "<ACCOUNT_ID>"}, you ensure that only resources in your specific AWS account can assume the role through that service principal. This security control is emphasized in skills/core-skills/aws-iam/references/aws-iam-role-management.md as a best practice for all service roles.
Can I use the same IAM role for multiple AWS services?
While technically possible, using the same role across multiple services violates the principle of least privilege. Each service (Glue, Lambda, ECS, Step Functions) requires different permissions and trust relationships. The Agent Toolkit reference implementations recommend creating service-specific roles (e.g., MyApp-Glue-ServiceRole, MyApp-Lambda-ExecRole) to minimize blast radius and maintain clear audit trails for each service's access patterns.
How do I validate that my service role has the correct permissions?
Use the IAM policy simulator (aws iam simulate-principal-policy) to test whether your role can perform specific actions before deploying. Additionally, verify the trust relationship with aws iam get-role --role-name <ROLE_NAME> to confirm the service principal is correctly configured. For Glue-specific validation, reference skills/specialized-skills/storage-skills/creating-data-lake-table/references/table-creation-glue-etl.md to ensure you have included glue:GetCatalog, glue:GetDatabase, and S3 Tables permissions for data lake workloads.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →