如何通过Terraform为EC2(非ECS)实例绑定IAM角色拉取ECR特定镜像
Hey there! Let's break down exactly how to configure Terraform to bind an IAM role to your EC2 instance—so it can pull specific images from ECR without needing hardcoded credentials. I've tested this setup multiple times, so here's a step-by-step guide that works:
First, we need an IAM role that your EC2 instance can assume, paired with a policy that only allows access to your specific ECR repository. This follows the principle of least privilege, which is always a good practice.
# IAM role granting EC2 permission to assume it resource "aws_iam_role" "ec2_ecr_access_role" { name = "ec2-ecr-pull-role" assume_role_policy = jsonencode({ Version = "2012-10-17" Statement = [ { Action = "sts:AssumeRole" Effect = "Allow" Principal = { Service = "ec2.amazonaws.com" } } ] }) } # Custom policy to pull from a specific ECR repo resource "aws_iam_policy" "ecr_specific_pull_policy" { name = "ecr-specific-pull-policy" description = "Grants permission to pull images from a single ECR repository" policy = jsonencode({ Version = "2012-10-17" Statement = [ { Effect = "Allow" Action = [ "ecr:GetDownloadUrlForLayer", "ecr:BatchGetImage", "ecr:BatchCheckLayerAvailability" ] Resource = "arn:aws:ecr:${var.aws_region}:${var.account_id}:repository/${var.target_ecr_repo}" }, { # GetAuthorizationToken is an account-level action, needs a wildcard resource Effect = "Allow" Action = "ecr:GetAuthorizationToken" Resource = "*" } ] }) } # Attach the policy to the IAM role resource "aws_iam_role_policy_attachment" "ecr_pull_attach" { role = aws_iam_role.ec2_ecr_access_role.name policy_arn = aws_iam_policy.ecr_specific_pull_policy.arn }
Note: Replace the variables (var.aws_region, var.account_id, var.target_ecr_repo) with your actual values, or hardcode them if you prefer.
EC2 instances can't attach IAM roles directly—you need to wrap the role in an instance profile first. This is just an AWS requirement for EC2-IAM integration.
resource "aws_iam_instance_profile" "ec2_ecr_profile" { name = "ec2-ecr-pull-profile" role = aws_iam_role.ec2_ecr_access_role.name }
Now, attach this instance profile to your EC2 instance—whether you're launching a new one or updating an existing one.
For a New EC2 Instance:
Add the iam_instance_profile argument to your aws_instance resource:
resource "aws_instance" "target_ec2" { ami = "ami-0c55b159cbfafe1f0" # Example Amazon Linux 2 AMI (update for your region) instance_type = "t2.micro" iam_instance_profile = aws_iam_instance_profile.ec2_ecr_profile.name # Add your existing config (security groups, tags, etc.) below vpc_security_group_ids = [aws_security_group.ec2_sg.id] tags = { Name = "EC2-with-ECR-Access" } }
For an Existing EC2 Instance:
Use the aws_ec2_instance_profile_association resource to attach the profile without recreating the instance:
resource "aws_ec2_instance_profile_association" "attach_to_existing" { instance_id = "i-1234567890abcdef0" # Replace with your EC2 instance ID iam_instance_profile = aws_iam_instance_profile.ec2_ecr_profile.name }
Once the instance is running, SSH into it and verify you can pull the image. For Amazon Linux 2/2023, the ECR credential helper is pre-installed, so run these commands (replace placeholders with your details):
# Authenticate to ECR (uses the IAM role automatically) aws ecr get-login-password --region your-region | docker login --username AWS --password-stdin your-account-id.dkr.ecr.your-region.amazonaws.com # Pull the specific image docker pull your-account-id.dkr.ecr.your-region.amazonaws.com/your-repo-name:your-tag
If you're using a non-AWS AMI (like vanilla Ubuntu), you'll need to install the AWS CLI and Docker first, but the IAM role will still handle authentication without access keys.
- Least Privilege: Avoid using
Resource = "*"for the ECR pull actions unless you need access to all repos in your account. The setup above locks access to your specific repo. - IMDS Access: Ensure your EC2 instance has access to the Instance Metadata Service (IMDSv2 is recommended)—this is how the instance retrieves the role's temporary credentials.
- AMI Compatibility: Most modern AMIs include the necessary tools, but double-check if you're using a custom AMI.
内容的提问来源于stack exchange,提问作者Ricardo Branco

