Amazon Web Services 한국 블로그
AWS 관리 계정 내 암호화된 이미지를 내부 멀티 계정 오토 스케일링 그룹 적용하기
대부분 Amazon Web Services (AWS) 고객들은 사내에 복수의 루트 계정을 사용하고 있는데 관리 계정과 팀별 계정으로 나누어 사용하고 있습니다. 클라우드 보안과 규정 준수 측면에서 관리 계정에서 암호화된 표준 머신 이미지(Amazon Machine Image)를 만들고 조직 내 모든 팀별 멀티 계정에서 공유된 머신 이미지를 기반으로 Amazon Elastic Compute Cloud(Amazon EC2) 인스턴스를 기동하는 것은 바람직한 방법입니다. 이 글에서는 관리 계정에서 생성한 암호화된 AMI로 다른 계정의 Amazon EC2 Auto Scaling을 이용해서 가상 서버를 기동하는 방법을 설명합니다.
가상 시나리오
아래의 아키텍처 다이어그램은 관리 계정 A에 암호화된 표준 AMI를 만들고 팀별 계정 B와 C에 해당 AMI로 오토 스케일링 그룹(Auto Scaling Group)을 생성하는 것을 보여주고 있습니다. 이해를 돕기 위해 이 글의 아래에서 설명하는 내용도 이 아키텍처 다이어그램과 같은 가상 시나리오를 기반으로 합니다. 그리고 설정과 관련된 내용에서 관리 계정 A는 AWS 계정 ID(AWS account ID) “999999999999”를, 팀별 계정 B와 C는 각각 AWS 계정 ID “111111111111”과 “222222222222”를 사용하는 것으로 설명하겠습니다.
고객이 관리하는 KMS 키 생성
우선 다른 AWS 계정에서 사용할 수 있도록 암호화된 AMI를 생성하려면 AWS Key Management Service (AWS KMS) 에서 고객이 관리하는 키(Customer Managed Key)를 사용해야 합니다. AWS가 관리하는 키(AWS Managed key)는 해당 AWS 계정 외부에서 사용할 수 없습니다. 아래와 같이 AMI를 생성할 관리 계정의 KMS 메뉴에서 고객이 관리하는 키를 생성합니다.
생성하는 키에 대해 적절한 별칭(Alias)을 부여하고,
키 관리자로 AWS Identity and Access Management (IAM) 사용자(User) 또는 역할(Role)을 지정합니다.
생성하는 키를 사용할 수 있는 권한을 부여하는 곳에서 다른 AWS 계정을 지정합니다. 우리의 가상 시나리오에서 팀별 AWS 계정 B와 C가 해당 키를 사용할 것이므로 2개의 계정을 추가했습니다. 참고로 키가 생성된 이후에도 다른 AWS 계정의 추가가 필요할 경우 이를 수정할 수 있습니다.
Next 버튼을 누르면 마지막 화면에서 키 정책(key policy) 내용이 보일 것입니다. 이곳에서 제일 아래쪽의 Condition 항목을 삭제합니다. 그리고 그 바로 윗줄의 Resource 부분의 제일 마지막 쉼표(,) 도 제거해서 올바른 JSON 형식이 되도록 합니다. 이 부분을 제거하는 이유는 아래에서 다시 설명하겠습니다.
"Condition": {
"Bool": {
"kms:GrantIsForAWSResource": "true"
}
}
작업이 완료되었다면 아래와 같은 형식의 JSON 문자열을 가진 키 정책이 출력되어야 합니다. 참고로 아래의 암호화 AMI 관리 계정 id는 암호화된 AMI를 생성하고 관리할 AWS 계정(본 가상 시나리오의 999999999999)이고 암호화 AMI 사용 계정 id는 암호화된 AMI를 사용해서 오토 스케일링 그룹을 적용할 AWS 계정(본 가상 시나리오의 111111111111, 222222222222)입니다.
{
"Id": "key-consolepolicy-3",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Enable IAM User Permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::암호화 AMI 관리 계정 id:root"
},
"Action": "kms:*",
"Resource": "*"
},
{
"Sid": "Allow access for Key Administrators",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::암호화 AMI 관리 계정 id:user/선택한 IAM user"
},
"Action": [
"kms:Create*",
"kms:Describe*",
"kms:Enable*",
"kms:List*",
"kms:Put*",
"kms:Update*",
"kms:Revoke*",
"kms:Disable*",
"kms:Get*",
"kms:Delete*",
"kms:TagResource",
"kms:UntagResource",
"kms:ScheduleKeyDeletion",
"kms:CancelKeyDeletion"
],
"Resource": "*"
},
{
"Sid": "Allow use of the key",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::암호화 AMI 사용 계정 id:root",
"arn:aws:iam::암호화 AMI 사용 계정 id:root",
]
},
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
],
"Resource": "*"
},
{
"Sid": "Allow attachment of persistent resources",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::암호화 AMI 사용 계정 id:root",
"arn:aws:iam::암호화 AMI 사용 계정 id:root",
]
},
"Action": [
"kms:CreateGrant",
"kms:ListGrants",
"kms:RevokeGrant"
],
"Resource": "*"
}
]
}
위 설정에서 “arn:aws:iam::암호화 AMI 사용 계정 id
:root”에 대한 이해가 필요합니다. 이 의미는 암호화 AMI 사용 계정 id
의 IAM 사용자나 IAM 역할이 암호화 AMI 생성 계정 id의 KMS 서비스에 대해 해당 액션을 수행할 수 있다는 의미가 아니라 암호화 AMI 사용 계정 id
이 자신의 IAM 사용자나 IAM 역할에게 암호화 AMI 사용 계정 id
의 KMS 서비스에 대해 해당 action에 대한 권한 부여를 생성할 수 있는 권한을 부여받았다는 의미입니다. 이러한 이유로 암호화 AMI 사용 계정에서 오토 스케일링 그룹 생성 시 추가로 KMS의 CreateGrant 작업이 필요하게 됩니다.
암호화 AMI 생성 및 공유
암호화된 AMI를 생성하는 것은 일반 AMI를 생성하는 것과 동일한 과정을 따릅니다. 조직의 표준에 맞는 프로그램들이 설치된 EC2를 선택한 후 간단히 생성하거나 EC2 Image Builder를 이용해서 생성할 수 있습니다. 암호화된 AMI를 생생하기 위해서 EBS 선택 시 KMS 키를 위에서 생성한 고객이 관리하는 KMS 키의 별칭으로 선택하면 됩니다. 그리고 AMI를 공유할 AWS 계정을 추가해 줍니다. 본 블로그에서 암호화 AMI를 생성하는 부분은 자세히 다루지 않습니다. Amazon EC2 Image Builder 사용법에 대해서는 여기를 참고하시기 바랍니다. 그리고 생성한 AMI를 다른 계정과 공유하는 방법은 여기를 참고하시기 바랍니다.
공유된 AMI 확인
암호화된 AMI가 다른 계정에 잘 공유되었는지 확인하기 위해서 AMI를 사용할 AWS 계정에서 이를 검색해봅니다. 예를 들어, 팀별 AWS 계정 A와 B로 각각 AWS 관리 콘솔에 로그인 한 후, Launch Instances를 실행해서 My AMIs 아래의 Shared with me에 해당 AMI가 있는지 확인해 봅니다. AMI ID나 AMI 명을 안다면 아래와 같이 간단히 검색할 수 있습니다.
위와 같이 검색되면 관리 계정에서 생성된 AMI가 다른 AWS 계정에 잘 공유되었다는 의미입니다.
오토 스케일링 서비스 역할(Role)에 KMS CreateGrant 적용
위에서 AMI가 공유되었으므로 일반적인 방법과 동일하게 시작 템플릿(Launch template)이나 시작 구성(Launch Configuration)을 생성한 후, 오토 스케일링 그룹을 생성하고 desired capacity를 적용해서 EC2가 기동 되는 액티비티를 확인하면 아래와 같은 오류가 발생합니다.
이러한 오류가 발생하는 이유는 AWS 오토 스케일링 서비스를 이용하는 AWS 팀별 계정이 암호화된 AMI를 생성한 AWS 관리 계정의 “고객이 관리하는 KMS 키”에 엑세스 할 수 있는 권한이 없기 때문입니다. 이 글의 윗부분에서 고객이 관리하는 키를 생성할 때 설정했던 정책의 principal “arn:aws:iam::암호화 AMI 사용 계정 id
:root”는 암호화 AMI 생성 계정의 KMS에 대한 CreateGrant를 할 수 있는 권한을 받은 것이기 때문에 암호화 AMI 사용 계정에서 각각 KMS의 CreateGrant를 실행해서 오토 스케일링 서비스에 필요한 권한을 생성해 주어야 합니다. 또한 암호화 AMI 사용 계정의 IAM 사용자 또는 역할이 암호화 AMI 생성 계정의 키에 대해 kms:CreateGrant를 실행할 수 있는 권한도 있어야 KMS의 CreateGrant 명령을 실행할 수 있습니다. 따라서 암호화 AMI 사용 계정의 IAM 사용자 하나를 골라서 아래와 같은 정책을 부여합니다. 이 작업을 암호화 AMI 사용 계정별로 수행해야 합니다. 먼저 아래의 JSON 구문을 가진 정책을 생성하고 적절한 이름을 부여합니다.
아래의 JSON 구문 작성 시 Resource Arn 값은 암호화 AMI 생성 계정에서 생성한 고객이 관리하는 KMS 키에 대한 arn 값입니다. 따라서 붉은색 이탤릭 문자열
을 자신의 환경에 맞게 수정하시기 바랍니다.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid":"AllowCreationOfGrantForTheKMSKeyinExternalAccount999999999999",
"Effect": "Allow",
"Action": "kms:CreateGrant",
"Resource": "arn:aws:kms:ap-northeast-2:999999999999:key/a7ca5ab7-15aa-4833-b5df-f8d9a6de33fd"
}
]
}
다음으로 정책 이름을 적절히 부여합니다. 저는 임의로 “kms_create-grant-in-account-999999999999”라는 이름으로 정책을 생성했습니다.
정책이 생성되었으므로 이를 원하는 IAM 사용자에게 연결합니다. IAM 메뉴에서 사용자를 선택한 후 권한 추가(Add permissions)를 수행합니다.
앞에서 생성한 정책을 선택하기 위해 Attach existing policies directly를 선택하고, 생성한 정책 명으로 검색한 후, 권한을 추가합니다.
이제 팀별 계정 B, C의 해당 IAM 사용자가 관리 계정 A에서 AMI 암호화를 위해 사용한 고객이 관리하는 KMS 키에 대해 CreateGrant를 할 수 있게 되었습니다. 이제 아래의 CLI 명령어를 이용해서 CreateGrant를 수행합니다. 이 명령을 수행할 때 반드시 정책이 부여된 IAM 사용자로 명령이 수행되도록 CLI 환경을 확인하시기 바랍니다. 아래 명령어에서 붉은색 이탤릭 문자열
은 자신의 환경에 맞는 값으로 변경하시기 바랍니다.
위 명령의 수행 시 “An error occurred (AccessDeniedException) when calling the CreateGrant operation:” 오류가 발생할 경우, 이 글의 윗부분에서 암호화 AMI 생성 계정으로 생성한 고객이 관리하는 KMS 키 정책에서 “kms:GrantIsForAWSResource”: “true” 조건 연산자(Condition) 부분이 삭제되었는지 확인합니다. “kms:GrantIsForAWSResource”의 의미는 “AWS KMS와 통합되는 AWS 서비스만이 해당 액션을 수행할 권한이 있는지 여부를 체크한다.”는 조건을 의미합니다. 우리는 IAM 사용자를 이용해서 KMS의 CreateGrant를 수행할 것이므로 이 조건 연산자가 있으면 오류가 발생하게 됩니다. KMS의 각종 정책 조건 연산자의 의미는 여기를 참고하시기 바랍니다.
정책 생성부터 KMS의 CreateGrant까지의 작업을 암호화 AMI를 사용할 팀별 계정 B, C에 대해 각각 수행합니다.
위 명령이 성공적으로 수행될 경우 아래와 같은 응답을 받게 됩니다.
{
"GrantToken": "token 문자열",
"GrantId": "GrantId 문자열"
}
EC2 오토 스케일링 그룹 적용하기
이제 일반적으로 적용하는 방법과 동일하게 시작 템플릿이나 시작 구성을 생성한 후, 오토 스케일링 그룹을 생성합니다. 생성 시 desired capacity를 적용해서 EC2가 기동 되는 액티비티를 확인해봅니다. 그러면 아래와 같이 오토 스케일링이 정상적으로 작동하는 것을 확인할 수 있습니다. 또는 앞에서 미리 오토 스케일링 그룹을 생성해 두었고 오류가 발생하는 상태였더라도 다시 확인하면 정상적으로 동작하게 됩니다.
마무리
본 글에서는 보안과 규정 준수를 위해 관리 계정으로 사내 표준 암호화 AMI를 관리하면서 다른 계정에서 표준 AMI를 사용해서 오토 스케일링을 적용하는 방법에 대해서 살펴보았습니다. 여러분들도 탄력성을 유지하면서 보안과 규정 준수를 강화하는 방법을 적용해보시기 바랍니다.
– 문종민, AWS 솔루션즈 아키텍트 매니저