이 기사는 다음 기사에 이어집니다:
Active Directory와 IAM Identity Center의 통합 방법에 대한 자세한 내용은 아래 기사를 참조하십시오.
배경
이전에 특정 프로젝트를 위해 AWS를 사용하려는 직원들에게 접근 권한을 부여했습니다. 이번에 다른 프로젝트에서도 AWS 사용을 고려하고 있어, 앞으로는 업무 환경뿐 아니라 각 프로젝트에서도 AWS 사용이 확대될 것으로 예상됩니다.
이미 Active Directory와 IAM Identity Center는 통합된 상태로, 이전과 마찬가지로 접근이 필요한 직원들에게 권한을 부여하기로 했습니다.
과제
이전에는 특별한 권한 제한 없이 AWS에서 사전 정의된 PowerUserAccess 정책을 사용했습니다. 그러나 PowerUserAccess는 강력한 권한을 부여하기 때문에, 이를 계기로 각 사용자의 접근 권한을 최소화하는 엄격한 운용 방식을 도입하게 되었습니다. 우리의 목표는 다음과 같습니다:
- 다른 프로젝트에서 사용 중인 VPC에 대한 변경, 삭제 또는 리소스 배치를 방지.
- VPC가 어떤 프로젝트에서 사용되고 있는지 식별 가능.
- 불필요한 AWS 서비스 사용 제한.
방법
이전 설정에서는 IAM Identity Center에서 권한 세트를 사용해 AWS 계정에 대한 접근 권한을 정의하고 이를 사용자에게 할당했습니다.
이번에는 프로젝트별로 권한 세트를 정의하고, 해당 프로젝트에 속한 사용자에게 할당합니다.
각 권한 세트에서는 태그를 기반으로 사용 가능한 VPC를 제한합니다. 이를 통해 프로젝트별로 접근 권한을 구분할 수 있습니다.
다음은 간략한 예시입니다.
하지만 중요한 점은 User 2와 같이 여러 프로젝트에 속한 직원도 있다는 것입니다.
IAM Identity Center에서는 하나의 사용자에게 여러 권한 세트를 할당하는 것이 가능합니다.
따라서 여러 프로젝트에 참여하는 사용자에게는 다중 접근 권한을 부여합니다.
관리자 단계
Active Directory에서 이미 그룹이 생성되어 있으며, 현재 IAM Identity Center의 사용자 및 그룹 상태는 다음과 같습니다.
이전 권한 세트(PowerUserAccess)를 삭제하고, 새 권한 세트를 생성해 다시 할당하는 방식으로 진행합니다.
이미지
이제 Project B에 속한 사용자에게 부여할 접근 권한을 설정합니다.
권한은 특정 VPC에 대한 생성, 업데이트 및 삭제만 허용하며, 모든 리소스에 대한 읽기 권한을 부여합니다.
권한 세트 생성
사용자 정의 정책과 AWS에서 정의한 ReadOnlyAccess, AmazonEC2FullAccess를 함께 할당합니다.
이전에는 관리 콘솔을 통해 권한 세트를 생성했으나, 이번에는 AWS CLI를 사용합니다.
설명 : AWS 서비스 및 리소스에 대한 읽기 전용 액세스를 제공합니다.
https://docs.aws.amazon.com/ko_kr/aws-managed-policy/latest/reference/ReadOnlyAccess.html
설명: 를 통해 Amazon EC2에 대한 전체 액세스를 제공합니다. AWS Management Console
https://docs.aws.amazon.com/ko_kr/aws-managed-policy/latest/reference/AmazonEC2FullAccess.html
- 다음 AWS CLI 명령어를 실행하여 권한 세트를 생성합니다.
INSTNACE_ARN=$(aws sso-admin list-instances \
--query "Instances[].InstanceArn" \
--output text)
aws sso-admin create-permission-set \
--instance-arn $INSTNACE_ARN \
--name "ProjectB" \
--session-duration "PT1H"
- 다음 AWS CLI 명령어를 실행하여 AWS에서 사전 정의된 ReadOnlyAccess 정책과 AmazonEC2FullAccess 정책을 권한 세트에 연결합니다.
PERMISSIONSET_ARN=$(aws sso-admin list-permission-sets \
--instance-arn $INSTNACE_ARN \
--query "PermissionSets" \
--output text | tr "\t" "\n" |
while read line
do
aws sso-admin describe-permission-set \
--instance-arn $INSTNACE_ARN \
--permission-set-arn ${line} \
--query "PermissionSet.[Name,PermissionSetArn]" \
--output text
done | grep -w "ProjectB" | awk '{print $2}')
aws sso-admin attach-managed-policy-to-permission-set \
--instance-arn $INSTNACE_ARN \
--permission-set-arn $PERMISSIONSET_ARN \
--managed-policy-arn "arn:aws:iam::aws:policy/ReadOnlyAccess"
aws sso-admin attach-managed-policy-to-permission-set \
--instance-arn $INSTNACE_ARN \
--permission-set-arn $PERMISSIONSET_ARN \
--managed-policy-arn "arn:aws:iam::aws:policy/AmazonEC2FullAccess"
- 다음 AWS CLI 명령어를 실행하여 인라인 정책을 연결합니다.
cat << EOF > inline-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyCreateVpc",
"Effect": "Deny",
"Action": [
"ec2:CreateVpc"
],
"Resource": "*",
"Condition": {
"StringNotEqualsIfExists": {
"aws:RequestTag/Project": "ProjectB"
}
}
},
{
"Sid": "DenyChangeTag",
"Effect": "Deny",
"Action": [
"ec2:CreateTags"
],
"Resource": "*",
"Condition": {
"Null": {
"ec2:ResourceTag/Project": "false"
},
"StringNotEquals": {
"ec2:ResourceTag/Project": "ProjectB"
}
}
},
{
"Sid": "DenyModifyAndDelete",
"Effect": "Deny",
"Action": [
"ec2:Delete*",
"ec2:ModifyVpcAttribute"
],
"Resource": "*",
"Condition": {
"StringNotEquals": {
"ec2:ResourceTag/Project": "ProjectB"
}
}
}
]
}
EOF
aws sso-admin put-inline-policy-to-permission-set \
--instance-arn $INSTNACE_ARN \
--permission-set-arn $PERMISSIONSET_ARN \
--inline-policy file://inline-policy.json
- DenyCreateVpc 문장
다음 조건 중 하나라도 충족되면 VPC 생성을 거부합니다:- Project 태그가 지정되지 않은 경우.
- 지정된 Project 태그 값이 ProjectB가 아닌 경우.
- DenyChangeTag 문장
다음 조건이 모두 충족되면 태그 생성을 거부합니다:- 리소스의 Project 태그가 Null이 아닌 경우 (Project 태그가 이미 있는 경우).참고: 이 조건이 없으면 지정된 태그를 가진 VPC 생성도 거부됩니다.
- 리소스의 Project 태그 값이 ProjectB가 아닌 경우.
- DenyModifyAndDelete 문장
Project 태그 값이 ProjectB가 아닌 리소스에 대한 작업을 제한합니다. 포함된 제한 사항은 다음과 같습니다:- VPC 속성 변경 거부.
- 태그 삭제, VPC 삭제 등 작업 거부.
그룹 할당
- 다음 AWS CLI 명령어를 실행하여 그룹에 권한 세트를 할당합니다.
IDENTITYSTORE_ID=$(aws sso-admin list-instances \
--query "Instances[].IdentityStoreId" \
--output text)
GROUP_ID=$(aws identitystore list-groups \
--identity-store-id $IDENTITYSTORE_ID \
--query "Groups[?DisplayName=='ProjectB@corp.awsexample.com'].GroupId" \
--output text)
ACCOUNT_ID=$(aws sso-admin list-instances \
--query "Instances[].OwnerAccountId" \
--output text)
aws sso-admin create-account-assignment \
--instance-arn $INSTNACE_ARN \
--target-id $ACCOUNT_ID \
--target-type AWS_ACCOUNT \
--permission-set-arn $PERMISSIONSET_ARN \
--principal-type GROUP \
--principal-id $GROUP_ID
추가 작업
다른 프로젝트에 대해서도 동일한 방식으로 진행합니다. 위와 동일한 AWS CLI 명령어를 실행하여 ProjectA에 대한 권한 세트를 생성하고 할당합니다.
AWS CLI 명령
# Step1
INSTNACE_ARN=$(aws sso-admin list-instances \
--query "Instances[].InstanceArn" \
--output text)
aws sso-admin create-permission-set \
--instance-arn $INSTNACE_ARN \
--name "ProjectA" \
--session-duration "PT1H"
# Step2
PERMISSIONSET_ARN=$(aws sso-admin list-permission-sets \
--instance-arn $INSTNACE_ARN \
--query "PermissionSets" \
--output text | tr "\t" "\n" |
while read line
do
aws sso-admin describe-permission-set \
--instance-arn $INSTNACE_ARN \
--permission-set-arn ${line} \
--query "PermissionSet.[Name,PermissionSetArn]" \
--output text
done | grep -w "ProjectA" | awk '{print $2}')
aws sso-admin attach-managed-policy-to-permission-set \
--instance-arn $INSTNACE_ARN \
--permission-set-arn $PERMISSIONSET_ARN \
--managed-policy-arn "arn:aws:iam::aws:policy/ReadOnlyAccess"
aws sso-admin attach-managed-policy-to-permission-set \
--instance-arn $INSTNACE_ARN \
--permission-set-arn $PERMISSIONSET_ARN \
--managed-policy-arn "arn:aws:iam::aws:policy/AmazonEC2FullAccess"
# Step3
cat << EOF > inline-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyCreateVpc",
"Effect": "Deny",
"Action": [
"ec2:CreateVpc"
],
"Resource": "*",
"Condition": {
"StringNotEqualsIfExists": {
"aws:RequestTag/Project": "ProjectA"
}
}
},
{
"Sid": "DenyChangeTag",
"Effect": "Deny",
"Action": [
"ec2:CreateTags"
],
"Resource": "*",
"Condition": {
"Null": {
"ec2:ResourceTag/Project": "false"
},
"StringNotEquals": {
"ec2:ResourceTag/Project": "ProjectA"
}
}
},
{
"Sid": "DenyModifyAndDelete",
"Effect": "Deny",
"Action": [
"ec2:Delete*",
"ec2:ModifyVpcAttribute"
],
"Resource": "*",
"Condition": {
"StringNotEquals": {
"ec2:ResourceTag/Project": "ProjectA"
}
}
}
]
}
EOF
aws sso-admin put-inline-policy-to-permission-set \
--instance-arn $INSTNACE_ARN \
--permission-set-arn $PERMISSIONSET_ARN \
--inline-policy file://inline-policy.json
# Step4
IDENTITYSTORE_ID=$(aws sso-admin list-instances \
--query "Instances[].IdentityStoreId" \
--output text)
GROUP_ID=$(aws identitystore list-groups \
--identity-store-id $IDENTITYSTORE_ID \
--query "Groups[?DisplayName=='ProjectA@corp.awsexample.com'].GroupId" \
--output text)
ACCOUNT_ID=$(aws sso-admin list-instances \
--query "Instances[].OwnerAccountId" \
--output text)
aws sso-admin create-account-assignment \
--instance-arn $INSTNACE_ARN \
--target-id $ACCOUNT_ID \
--target-type AWS_ACCOUNT \
--permission-set-arn $PERMISSIONSET_ARN \
--principal-type GROUP \
--principal-id $GROUP_ID
태그 정책 설정
이 단계는 필수는 아니지만, 설정해 두면 유용한 구성입니다.
태그 정책을 설정하면 대소문자만 다른 중복 태그 생성을 방지할 수 있습니다.
참고로 태그를 강제하는 설정은 아니니 주의하시기 바랍니다.aws:TagKeys
조건을 인라인 정책에 포함하여 동일한 효과를 얻을 수 있지만, 인라인 정책이 지나치게 길고 복잡해지는 것을 방지하기 위해 태그 정책을 채택했습니다.
대소문자만 다른 키를 포함한 중복 태그를 방지하려면
https://docs.aws.amazon.com/ko_kr/IAM/latest/UserGuide/access_tags.htmlaws:TagKeys
조건을 사용하여 사용자가 적용할 수 있는 태그 키를 정의하거나 AWS Organizations과(와) 함께 사용할 수 있는 태그 정책을 사용합니다.
- 다음 URL을 통해 조직 내에서 태그 정책을 활성화하세요:
https://us-east-1.console.aws.amazon.com/organizations/v2/home/policies/tag-policy
이미지
- 다음 URL로 이동하여 태그 정책을 생성합니다:
https://us-east-1.console.aws.amazon.com/organizations/v2/home/policies/tag-policy/create- 정책 이름: Project
- 태그 키: Project
- 규정 준수 옵션:
- ☑ 태그 키에 대해 위에서 지정한 대문자를 사용합니다.
- ☑ 이 태그 키에 대해 허용되는 값을 지정합니다.
ProjectA
ProjectB
- 적용할 리소스 유형:
- ☑ 이 태그에 대한 규정 미준수 작업을 방지합니다.
- 모든 옵션 선택.
- ☑ 이 태그에 대한 규정 미준수 작업을 방지합니다.
이미지
- [대상(Target)] 탭에서 해당 계정에 정책을 연결합니다.
이미지
태그 정책은 키와 값 모두에 대해 대소문자를 엄격하게 확인하며, 값은 지정된 옵션으로 제한됩니다. 예시:
키(Key) | 값(Value) | 허용 여부 |
---|---|---|
Project | ProjectC | ❌ 불가 |
ProjecT | ProjectA | ❌ 불가 |
project | ProjectA | ❌ 불가 |
Project | projecta | ❌ 불가 |
Project | ProjectA | ✅ 허용 |
Project | ProjectB | ✅ 허용 |
사용자 측 절차
MFA가 이미 등록된 경우 1단계와 3단계를 건너뛸 수 있습니다.
- Google Authenticator(MFA 인증 앱)를 스마트폰에 설치합니다.
[Google Play / App Store] - 다음 포털 URL에 접속하여 사용자 이름과 비밀번호를 입력합니다.
<Directory ID>
를 실제 디렉토리 ID로 대체하세요.
https://<Directory ID>
.awsapps.com/start - MFA 장치 등록:
- 인증 앱을 선택합니다.
- QR 코드를 표시합니다.
- Google Authenticator를 열고 QR 코드를 스캔합니다.
- 앱에 추가된 AWS SSO 항목에서 표시된 6자리 인증 코드를 입력합니다.
- [계정] 탭에서 해당 프로젝트의 권한 세트를 선택하여 로그인합니다.
이미지
직원들에게 현재 작업 중인 프로젝트에 적합한 권한 세트로 로그인하도록 지시합니다.
프로젝트 간 전환이 번거로울 수 있지만, 브라우저의 시크릿 탭이나 프라이빗 창을 사용하면 동시에 여러 프로젝트에 로그인할 수 있습니다.
현재는 VPC 접근을 제한하고 사용자 권한을 부여했습니다.
하지만 AWS 서비스 사용 범위가 확대되면 더 많은 제한이 필요할 것으로 보입니다.
복잡하지만, 필요할 때마다 인라인 정책을 업데이트할 예정입니다.
추가 정보
IAM 사용자 또는 IAM Identity Center에서 제공하는 ABAC (속성 기반 접근 제어) 를 사용하면 사용자 속성을 기반으로 한 동적 접근 제한이 가능합니다. 관련 공식 문서:
그러나 위 방법으로는 여러 프로젝트에 속한 직원들에게 다중 접근 권한을 부여할 수 없었습니다.
따라서 이번에는 번거롭지만 권한 세트를 여러 개 만들어 대처했습니다.
앞으로도 더 나은 방법을 모색할 예정입니다.