AWS 를 사용한 서버리스 아키텍쳐 적용기(삽질기) (7) - IAM role 세팅
저번 글에서 빠르게 만들면서 AdministratorAccess 정책을 이용해서 권한을 설정해줬습니다.
하지만 AdministratorAccess 는 모든 권한에 접근할 수 있기 때문에 혹시나 잘못되면 과금등에도 손댈 수 있기 때문에
role 변경이 필요해보입니다. 그럼 어떤 권한을 부여해야되는지 알아보도록 하겠습니다.
0. 기존 권한 확인 및 사용된 권한 확인.
AWS에서 IAM Management Console 로 이동해서 왼쪽 메뉴 중에서 '사용자' 를 클릭하면
정의된 사용자를 확인할 수 있습니다.
해당 사용자를 클릭하면 아래와 같이 AdministratorAccess 권한이 설정된 것을 확인할 수 있습니다.
정확하게 어떤 서비스들이 사용되었는지 확인하기 위에 엑세스 관리자를 클릭해 확인해보겠습니다.
다음과 같은 결과를 확인할 수 있습니다.
7개의 서비스를 이용했을 때 AdministratorAccess 권한이 사용된 것을 확인할 수 있습니다.
security token, s3, cloudwatch logs, cloudformation, api gw, lambda, IAM 서비스들이 사용됐네요.
그럼 이 서비스에 해당하는 권한들만 따로 모아서 부여해주면 정상적으로 작동하겠지요 ??
1. 새로운 정책 생성.
위의 서비스들에 대한 권한을 새로 생성해보겠습니다.
좌측에 정책 메뉴를 클릭해서 정책 생성을 클릭해줍니다.
정책 생성 버튼을 누르면 다음과 같은 화면을 확인하실 수 있습니다.
권한 추가 버튼을 눌러 하나씩 추가해줍시다. 그 후 작업은 모든 작업을 체크해주고 리소스도 모두 선택을 체크해 모든 유형의 리소스를 통과시키도록 해줍니다.
아래와 같이 하나씩 해주기는 귀찮고 복잡하니깐 JSON 을 통해 한번에 정의해줍니다.
일단 이렇게 해놓은 뒤 정책을 적용하고 sls deploy를 해보겠습니다.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"cloudformation:*",
"s3:*",
"logs:*",
"iam:*",
"apigateway:*",
"lambda:*"
],
"Resource": [
"*"
]
}
]
}
정책 검토 버튼을 클릭해줍니다.
이름은 적당히 full_serverless_role 로 명명해줍니다.
정책을 생성해줍니다.
아래와 같은 메시지가 출력된다면 정책이 제대로 생성된 것입니다.
2. 정책 적용
다시 사용자로 돌아가 serverless-demo 사용자를 클릭해주고 권한 탭에서 권한 추가 버튼을 눌러줍니다.
아래와 같이 방금 생성한 정책을 체크하고 다음으로 넘어가서 권한을 추가해줍니다.
그 후 AdministratorAccess 정책을 삭제해주면 아래와 같은 화면이 됩니다.
여기까지 끝났으면 이제 제대로 돌아가는지 확인해보겠습니다.
3. 배포
sls deploy -v 명령어를 통해 배포해주겠습니다.
문제없이 배포 완료됩니다. (문제 발생시 다시 차례대로 설정을 진행해주세요.)
curl 명령어를 통해 배포된 api endpoint에 테스트를 해봐도 잘 동작하는 것을 확인할 수 있습니다!!!
cloudwatch에 로그도 제대로 쌓입니다 :)
지금까지 IAM role 변경을 해봤습니다.
4. 세부 설정 및 응용
이제 조금 더 설정을 세부적으로 변경해보겠습니다.
앞서 한 IAM role setting은 serverless framework를 사용할 때 기본적으로 사용하는 권한 이외에도 모든 권한을 포함시켰습니다.
조금 더 필요한 권한 위주로만 세팅하고 region, account, service 도 제한을 두는 role을 설정해주겠습니다.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"cloudformation:Describe*",
"cloudformation:List*",
"cloudformation:Get*",
"cloudformation:CreateStack",
"cloudformation:UpdateStack",
"cloudformation:DeleteStack"
],
"Resource": "arn:aws:cloudformation:<region>:<account_no>:stack/<service_name>*/*"
},
{
"Effect": "Allow",
"Action": [
"cloudformation:ValidateTemplate"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"s3:CreateBucket",
"s3:DeleteBucket",
"s3:Get*",
"s3:List*"
],
"Resource": [
"arn:aws:s3:::*"
]
},
{
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": [
"arn:aws:s3:::*/*"
]
},
{
"Effect": "Allow",
"Action": [
"logs:DescribeLogGroups"
],
"Resource": "arn:aws:logs:<region>:<account_no>:log-group::log-stream:*"
},
{
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:DeleteLogGroup",
"logs:DeleteLogStream",
"logs:DescribeLogStreams",
"logs:FilterLogEvents"
],
"Resource": "arn:aws:logs:<region>:<account_no>:log-group:/aws/lambda/<service_name>*:log-stream:*",
"Effect": "Allow"
},
{
"Effect": "Allow",
"Action": [
"iam:GetRole",
"iam:PassRole",
"iam:CreateRole",
"iam:DeleteRole",
"iam:DetachRolePolicy",
"iam:PutRolePolicy",
"iam:AttachRolePolicy",
"iam:DeleteRolePolicy"
],
"Resource": [
"arn:aws:iam::<account_no>:role/<service_name>*-lambdaRole"
]
},
{
"Effect": "Allow",
"Action": [
"apigateway:GET",
"apigateway:POST",
"apigateway:PUT",
"apigateway:DELETE"
],
"Resource": [
"arn:aws:apigateway:<region>::/restapis"
]
},
{
"Effect": "Allow",
"Action": [
"apigateway:GET",
"apigateway:POST",
"apigateway:PUT",
"apigateway:DELETE"
],
"Resource": [
"arn:aws:apigateway:<region>::/restapis/*"
]
},
{
"Effect": "Allow",
"Action": [
"lambda:GetFunction",
"lambda:CreateFunction",
"lambda:DeleteFunction",
"lambda:UpdateFunctionConfiguration",
"lambda:UpdateFunctionCode",
"lambda:ListVersionsByFunction",
"lambda:PublishVersion",
"lambda:CreateAlias",
"lambda:DeleteAlias",
"lambda:UpdateAlias",
"lambda:GetFunctionConfiguration",
"lambda:AddPermission",
"lambda:RemovePermission",
"lambda:InvokeFunction"
],
"Resource": [
"arn:aws:lambda:*:<account_no>:function:<service_name>*"
]
},
{
"Effect": "Allow",
"Action": [
"ec2:DescribeSecurityGroups",
"ec2:DescribeSubnets",
"ec2:DescribeVpcs"
],
"Resource": [
"*"
]
},
{
"Effect": "Allow",
"Action": [
"events:Put*",
"events:Remove*",
"events:Delete*",
"events:Describe*"
],
"Resource": "arn:aws:events::<account_no>:rule/<service_name>*"
}
]
}
에러가 발생한다...
내용을 읽어보니 apigateway:PATCH 권한이 없어서 생기는 문제입니다.
위로 올라가서 apigateway 권한 Action 들이 쭉 있는곳에 추가해주면 문제해결!
(두군데 다 추가해주셔야 됩니다.)
최종적으로 배포하면 정상적으로 작동합니다!
IAM 에 대해선 다음에 기회가 되면 더 자세히 다루겠습니다. (워낙 양도 많고 들어갈수록 어렵습니다..)
+ 추가.. 나중에 production 모드로 추가배포했는데 배포 오류가 떠서 보니깐 s3 bucket 오류였습니다.
정책에서 "s3:Put*" 한줄 추가해주면 잘 작동합니다.
* 참고
https://www.youtube.com/watch?v=mQqVarM5mOY
https://serverless.com/blog/abcs-of-iam-permissions/
https://github.com/serverless/serverless/issues/1439