security credential, IAM role
AWS 의 instance에서 IAM role 사용
AWS의 instance에서 IAM role 을 사용할 수 있다. 예를 들어 EC2에서 s3를 사용할때 access key 를 발급받고, 그것을 instance 에 넣고, 그것을 application 이 사용하게 된다. 그런데 이 IAM role 을 사용하면, 실제적으로 application 이 access key 를 사용하는 것과 비슷하게 주기적으로 refresh 되는 security token 을 사용하게 된다.
그래서 IAM 을 사용하는 것은 이전에 access key 를 만들고, 그것을 넣어주는 작업을 좀 더 간편하게 해준다.
+-------------------------------------------+
| EC2 instance |
| - iam/security-credentials/<role-name> |
| +-------------+ |
| | Application | |
| +-------------+ |
+----------|---^----------------------------+
| | |
| | V
| | +---------+ +------------+
| | | Profile |---> | IAM role |
role name | | +---------+ | + policy |
| | | + policy |
| | +------------+
V |
+------------------------------+
| Security Token Service(STS) |
+------------------------------+
- IAM role에 policy 를 만들어서 permission 을 명시하게 된다. resource-level 로 permission들을 적용할 수 있다.
- IAM role 을 만들때 trusted entities 에 이 role을 사용할 수 있는 aws service 를 정의해주게 된다.
- 이 IAM role을 ’instance의 profile’에 할당할 수 있다. 이 profile 은 1개의 IAM role 만 담을 수 있다.
- 현재 run 하고 있는 instance 에도 attach 할 수 있다.
- IAM console에서 IAM role 을 만들면, IAM console 은 instance profile 을 자동으로 생성한다.
- 이 IAM role 에 policy 가 있다. 이 policy 에 어떤 action/resource 에 어떤 permission 이 허락되는지를 표시하게 된다.
- instance 에 있는 application 은 STS 에다가 security credential 을 retrieve 한다.(아래 AssumeRole api 참고)
- application 에서 사용하는 AWS SDK 에서 이 작업을 해주게 된다.
- instance metadata item(
iam/security-credentials/<role-name>
) 을 보고 해당하는 security credential 을 retrieve 한다. - 이러한 security credentials은 임시적이며 자동으로 교체된다. 이전 credential이 만료되기 최소 5분 전에 새 credential을 사용할 수 있게 한다.
Retrieve instance metadata - Amazon Elastic Compute Cloud : aws는
http://169.254.169.254/latest/meta-data/
에 각 instance 들의 meta-data들이 있다.
security credential 을 요청하는 command
아래는 s3access 라는 IAM role 에 대한 security credential 을 요청하는 command이다.
# s3access 라는 IAM role 에 대한 security credential 을 요청하는 command
#
TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` \
&& curl -H "X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/meta-data/iam/security-credentials/s3access
{
"Code" : "Success",
"LastUpdated" : "2012-04-26T16:39:16Z",
"Type" : "AWS-HMAC",
"AccessKeyId" : "ASIAIOSFODNN7EXAMPLE",
"SecretAccessKey" : "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
"Token" : "token",
"Expiration" : "2017-05-17T15:09:54Z"
}
만약 instance 에서 AWS SDK를 사용해서 application 을 만들었다면, AWS SDK 가 자동으로 credential 들을 ec2 instance metadata service 로 부터 가져가서 사용하게 된다. (iam/security-credentials/<role-name>
)
AssumeRole api
이 api 는 STS(security token service) 에서 제공한다.
이 api 를 호출하면 credential 을 return 해준다.
- boto - AWS: Boto3: AssumeRole example which includes role usage - Stack Overflow
- Switching to an IAM role (AWS API) - AWS Identity and Access Management
- Requesting temporary security credentials - AWS Identity and Access Management
sts_client = boto3.client('sts')
assumed_role_object=sts_client.assume_role(
RoleArn="arn:aws:iam::account-of-role-to-assume:role/name-of-role",
RoleSessionName="AssumeRoleSession1"
)
credentials=assumed_role_object['Credentials']
s3_resource=boto3.resource(
's3',
aws_access_key_id=credentials['AccessKeyId'],
aws_secret_access_key=credentials['SecretAccessKey'],
aws_session_token=credentials['SessionToken'],
)
terraform code
terraform 으로 구성하면 아래와 같다.
설명:
- ec2 가 사용할 수 있는 IAM role 을 만들고,
- 그 role 에 s3 mycorp-myapp bucket 을 사용할 수 있는 권한을 준다.
- 그리고 instance profile 을 이용해서 ec2 에 attach 한다.
// ----------------------------
//
// IAM Role
//
// ----------------------------
resource "aws_iam_role" "tf-myapp-s3" {
name = "myapp-s3"
assume_role_policy = jsonencode({
Version = "2012-10-17",
Statement = [
{
Sid = "exmyapp"
Action = "sts:AssumeRole",
Effect = "Allow",
Principal = {
// entities that can use this role
Service = "ec2.amazonaws.com"
}
}
]
})
tags = {
Name = "my-app"
}
}
resource "aws_iam_role_policy" "tf-myapp-s3" {
name = "myapp-s3"
role = aws_iam_role.tf-myapp-s3.name
policy = jsonencode({
Version = "2012-10-17",
Statement = [
{
Action = "s3:ListBucket",
Effect = "Allow",
Resource = [
"arn:aws:s3:::mycorp-myapp",
"arn:aws:s3:::mycorp-myapp/*"
],
},
{
Action = [
"s3:DeleteBucket",
],
Effect = "Deny",
Resource = [
"arn:aws:s3:::mycorp-myapp",
]
}
]
})
}
// ----------------------------
//
// instance profile
//
// ----------------------------
resource "aws_iam_instance_profile" "tf-myapp-s3" {
name = "myapp-s3"
role = aws_iam_role.tf-myapp-s3.name
}
// ----------------------------
//
// EC2
//
// ----------------------------
resource "aws_instance" "tf-myapp" {
...
iam_instance_profile = aws_iam_instance_profile.tf-myapp-s3.name
...
}
댓글 없음:
댓글 쓰기