실행 중인 EC2 인스턴스에 IAM Role 연결하는 방법 (재시작 없이)
EC2 인스턴스를 시작할 때 IAM Role 연결을 빠뜨리는 건 생각보다 자주 있는 실수다. 인스턴스가 이미 프로덕션 트래픽을 받고 있는 상황에서 재시작 없이 IAM Role을 붙일 수 있는지 확인하는 것이 급선무가 된다. 다행히 AWS는 실행 중인 EC2 인스턴스에 IAM Role을 연결하거나 교체하는 기능을 지원한다.
TL;DR — IAM Role을 EC2에 연결하는 핵심 요약
| 상황 | 방법 | 재시작 필요 여부 |
|---|---|---|
| IAM Role이 없는 인스턴스에 최초 연결 | associate-iam-instance-profile | 불필요 |
| 기존 IAM Role을 다른 Role로 교체 | replace-iam-instance-profile-association | 불필요 |
| 연결된 IAM Role 제거 | disassociate-iam-instance-profile | 불필요 |
IAM Role이 EC2에 연결되는 구조 이해
IAM Role을 EC2에 직접 붙이는 게 아니다. 중간에 Instance Profile이라는 컨테이너가 존재한다. IAM Role을 생성하면 AWS 콘솔에서는 자동으로 동일한 이름의 Instance Profile이 함께 생성되지만, AWS CLI나 CloudFormation으로 Role을 만들면 Instance Profile은 별도로 생성해야 한다. EC2 인스턴스에 실제로 연결되는 것은 IAM Role이 아니라 Instance Profile이다.
Instance Profile은 IAM Role을 EC2 인스턴스에 전달하는 봉투라고 생각하면 된다. 봉투(Instance Profile) 없이는 Role을 인스턴스에 넣을 수 없다.
인스턴스가 Role의 임시 자격증명을 얻는 경로는 EC2 메타데이터 서비스(IMDSv2)를 통해서다. 인스턴스 내부 애플리케이션이 http://169.254.169.254/latest/meta-data/iam/security-credentials/에 접근하면 STS가 발급한 임시 키를 받아온다. Role을 교체하면 다음 갱신 사이클에 새 자격증명이 자동으로 반영된다.
권한 정책 포함"] --> Profile["Instance Profile
Role 컨테이너"] Profile --> EC2["EC2 Instance"] EC2 --> IMDS["IMDS 169.254.169.254"] IMDS --> STS["AWS STS
임시 자격증명 발급"] STS --> App["애플리케이션
SDK / CLI"]
- IAM Role: 실제 권한 정책이 붙어 있는 객체
- Instance Profile: IAM Role을 EC2에 전달하는 컨테이너. 1:1 관계
- EC2 Instance: Instance Profile을 통해 Role을 참조
- IMDS(메타데이터 서비스): 인스턴스 내부에서 임시 자격증명을 조회하는 엔드포인트
- STS: 임시 자격증명(AccessKeyId, SecretAccessKey, SessionToken)을 발급
사전 조건 — IAM Role과 Instance Profile 준비
AWS 콘솔에서 IAM Role을 생성했다면 Instance Profile은 자동으로 만들어진다. CLI로 직접 생성했다면 아래 순서를 따른다.
1단계: IAM Role 생성 (EC2 신뢰 정책 포함)
EC2가 Role을 Assume할 수 있도록 신뢰 정책에 ec2.amazonaws.com을 명시해야 한다. 이 설정이 빠지면 인스턴스가 자격증명을 받지 못한다.
# trust-policy.json 파일 생성
cat > trust-policy.json <<'EOF'
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
# IAM Role 생성
aws iam create-role \
--role-name MyEC2Role \
--assume-role-policy-document file://trust-policy.json
2단계: Instance Profile 생성 및 Role 연결
CLI로 Role을 만든 경우 Instance Profile이 자동 생성되지 않는다. 반드시 별도로 생성하고 Role을 추가해야 한다.
# Instance Profile 생성
aws iam create-instance-profile \
--instance-profile-name MyEC2InstanceProfile
# Instance Profile에 Role 추가
aws iam add-role-to-instance-profile \
--instance-profile-name MyEC2InstanceProfile \
--role-name MyEC2Role
3단계: 권한 정책 연결
Role에 실제 권한 정책을 붙인다. 아래는 S3 읽기 권한을 예시로 사용한다.
aws iam attach-role-policy \
--role-name MyEC2Role \
--policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
실행 중인 EC2 인스턴스에 IAM Role 연결하는 방법
인스턴스가 실행 중(running)이든 중지 상태(stopped)이든 관계없이 IAM Role을 연결할 수 있다. 재시작은 필요하지 않다.
4단계: Instance Profile 연결 (최초 연결)
인스턴스에 기존에 연결된 Instance Profile이 없는 경우 associate-iam-instance-profile을 사용한다. 인스턴스 ID는 EC2 콘솔 또는 CLI로 확인한다.
# 인스턴스 ID 확인 (Name 태그 기준)
aws ec2 describe-instances \
--filters 'Name=tag:Name,Values=MyInstance' \
--query 'Reservations[*].Instances[*].InstanceId' \
--output text
# Instance Profile 연결
aws ec2 associate-iam-instance-profile \
--instance-id i-1234567890abcdef0 \
--iam-instance-profile Name=MyEC2InstanceProfile
5단계: 연결 상태 확인
연결 후 상태가 associated로 표시되는지 확인한다. Association ID는 이후 교체 또는 제거 시 필요하다.
aws ec2 describe-iam-instance-profile-associations \
--filters 'Name=instance-id,Values=i-1234567890abcdef0'
출력 예시에서 State: associated와 AssociationId 값을 확인한다. AssociationId는 iip-assoc-로 시작하는 문자열이다.
기존 IAM Role을 다른 Role로 교체하는 방법
이미 Instance Profile이 연결된 인스턴스에 다른 Role을 적용해야 할 때는 replace-iam-instance-profile-association을 사용한다. 이 명령은 Association ID가 필요하다 — 5단계에서 확인한 값을 사용한다.
- 기존 Association을 먼저 조회해 AssociationId를 확인한다
- replace 명령으로 새 Instance Profile로 교체한다
- 교체 후 State가
associated로 전환되는지 확인한다 - 인스턴스 내부에서 IMDS를 통해 새 자격증명이 반영됐는지 검증한다
# Association ID 조회
ASSOC_ID=$(aws ec2 describe-iam-instance-profile-associations \
--filters 'Name=instance-id,Values=i-1234567890abcdef0' \
--query 'IamInstanceProfileAssociations[0].AssociationId' \
--output text)
echo "Association ID: $ASSOC_ID"
# Instance Profile 교체
aws ec2 replace-iam-instance-profile-association \
--association-id "$ASSOC_ID" \
--iam-instance-profile Name=MyNewEC2InstanceProfile
인스턴스 내부에서 자격증명 반영 확인
Role 교체 후 인스턴스 내부 애플리케이션이 새 자격증명을 사용하는지 확인해야 한다. AWS SDK는 자격증명을 캐시하기 때문에 교체 직후 즉시 반영되지 않을 수 있다 — SDK가 다음 갱신 사이클에 새 자격증명을 가져온다.
인스턴스에 SSH로 접속한 뒤 아래 명령으로 현재 적용된 Role을 확인한다.
# IMDSv2 토큰 발급
TOKEN=$(curl -s -X PUT 'http://169.254.169.254/latest/api/token' \
-H 'X-aws-ec2-metadata-token-ttl-seconds: 21600')
# 현재 연결된 IAM Role 이름 확인
curl -s -H "X-aws-ec2-metadata-token: $TOKEN" \
http://169.254.169.254/latest/meta-data/iam/security-credentials/
# 실제 자격증명 확인 (Role 이름을 위 결과로 대체)
curl -s -H "X-aws-ec2-metadata-token: $TOKEN" \
http://169.254.169.254/latest/meta-data/iam/security-credentials/MyEC2Role
출력에서 Expiration 필드가 있고 Code: Success가 확인되면 자격증명이 정상적으로 발급된 것이다.
실제 운영에서 마주치는 실수 — 진단 패턴
증상: 인스턴스에 Role을 붙였는데 애플리케이션에서 계속 Unable to locate credentials 오류가 난다.
처음엔 IAM 정책 문제라고 생각하고 권한을 추가하거나 Role을 재생성한다. 그래도 안 된다. 콘솔에서 보면 인스턴스에 Role이 분명히 붙어 있다.
실제 원인은 두 가지 중 하나였다. 첫째, CLI로 Role을 만들었는데 Instance Profile 생성을 빠뜨린 경우다. 콘솔에서는 Role 이름이 Instance Profile 이름과 동일하게 보여서 헷갈린다. 둘째, IMDSv2가 활성화된 인스턴스에서 애플리케이션이 IMDSv1 방식(토큰 없이)으로 메타데이터를 조회하는 경우다. IMDSv2는 PUT 요청으로 토큰을 먼저 발급받아야 한다.
Instance Profile 존재 여부는 아래 명령으로 확인한다.
# Instance Profile이 실제로 존재하는지 확인
aws iam get-instance-profile \
--instance-profile-name MyEC2InstanceProfile
# Instance Profile에 Role이 연결됐는지 확인
aws iam get-instance-profile \
--instance-profile-name MyEC2InstanceProfile \
--query 'InstanceProfile.Roles[*].RoleName' \
--output text
IMDSv2 강제 여부는 아래로 확인한다.
aws ec2 describe-instances \
--instance-ids i-1234567890abcdef0 \
--query 'Reservations[*].Instances[*].MetadataOptions' \
--output json
HttpTokens: required면 IMDSv2가 강제 적용된 상태다. 이 경우 애플리케이션이 사용하는 AWS SDK 버전이 IMDSv2를 지원하는지 확인해야 한다. 최신 AWS SDK는 IMDSv2를 자동으로 처리한다.
이 작업에 필요한 IAM 권한
IAM Role을 EC2에 연결하는 작업 자체에도 권한이 필요하다. 운영자 계정 또는 자동화 Role에 아래 권한이 있어야 한다.
🔽 IAM 정책 예시 (클릭하여 펼치기)
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "EC2InstanceProfileAssociation",
"Effect": "Allow",
"Action": [
"ec2:AssociateIamInstanceProfile",
"ec2:ReplaceIamInstanceProfileAssociation",
"ec2:DisassociateIamInstanceProfile",
"ec2:DescribeIamInstanceProfileAssociations",
"ec2:DescribeInstances"
],
"Resource": "*"
},
{
"Sid": "IAMInstanceProfileRead",
"Effect": "Allow",
"Action": [
"iam:GetInstanceProfile",
"iam:ListInstanceProfiles"
],
"Resource": "*"
},
{
"Sid": "IAMPassRole",
"Effect": "Allow",
"Action": "iam:PassRole",
"Resource": "arn:aws:iam::123456789012:role/MyEC2Role"
}
]
}
iam:PassRole은 특히 중요하다. 이 권한이 없으면 associate-iam-instance-profile 명령이 AccessDenied로 실패한다. iam:PassRole의 Resource는 연결하려는 Role의 ARN으로 제한하는 것이 최소 권한 원칙에 맞다.
IAM Role을 EC2에 연결하는 전체 흐름 정리
EC2 신뢰 정책 포함"] --> B{"생성 방법"} B -->|"콘솔"| C["Instance Profile 자동 생성"] B -->|"CLI / IaC"| D["Instance Profile 수동 생성 필수"] D --> E["add-role-to-instance-profile"] C --> F["associate-iam-instance-profile"] E --> F F --> G["연결 상태 확인
describe-iam-instance-profile-associations"] G --> H{"교체 필요?"} H -->|"Yes"| I["replace-iam-instance-profile-association"] H -->|"No"| J["IMDS 자격증명 검증"] I --> J J --> K["완료"]
- IAM Role 생성 시 EC2 신뢰 정책 포함 여부 확인
- CLI로 생성한 경우 Instance Profile 별도 생성 필수
- Instance Profile에 Role 추가 후 EC2에 연결
- 연결 상태 확인 및 IMDS를 통한 자격증명 검증
- 교체가 필요한 경우 AssociationId 조회 후 replace 명령 실행
마무리 및 다음 단계
실행 중인 EC2 인스턴스에 IAM Role을 연결하거나 교체하는 작업은 재시작 없이 가능하다. 핵심은 IAM Role과 Instance Profile의 관계를 이해하고, CLI로 Role을 생성했다면 Instance Profile을 반드시 별도로 만들어야 한다는 점이다.
다음 단계로 고려할 사항:
- IMDSv2 전용 설정(
HttpTokens: required)을 기본값으로 적용해 메타데이터 서비스 보안을 강화한다 - EC2 인스턴스에 부여하는 Role은 최소 권한 원칙을 적용하고, 불필요한 관리형 정책 대신 인라인 정책 또는 범위가 제한된 정책을 사용한다
- AWS Config 규칙
ec2-instance-profile-attached를 활성화해 Instance Profile이 없는 인스턴스를 자동으로 감지한다
관련 AWS 공식 문서: Amazon EC2의 IAM 역할, associate-iam-instance-profile CLI 레퍼런스
용어 정리 (Glossary)
| 용어 | 설명 |
|---|---|
| IAM Role | AWS 서비스나 사용자가 임시로 권한을 위임받기 위한 IAM 객체. EC2에서는 Instance Profile을 통해 연결된다. |
| Instance Profile | IAM Role을 EC2 인스턴스에 전달하기 위한 컨테이너. Role과 1:1 관계이며, 콘솔에서는 자동 생성되지만 CLI에서는 별도 생성이 필요하다. |
| IMDS (Instance Metadata Service) | EC2 인스턴스 내부에서 메타데이터와 IAM 임시 자격증명을 조회하는 링크로컬 HTTP 엔드포인트(169.254.169.254). |
| IMDSv2 | 토큰 기반 세션 방식의 메타데이터 서비스. SSRF 공격에 대한 보안을 강화한 버전. |
| iam:PassRole | IAM Role을 AWS 서비스(EC2 등)에 전달할 수 있는 권한. 이 권한 없이는 Instance Profile 연결이 불가능하다. |
댓글
댓글 쓰기