Изменить роль IAM для лямбды в шаблоне CloudFormation в проекте CodeStar?
Как я могу изменить роль IAM для лямбда-функции в шаблоне CloudFormation проекта AWS CodeStar?
Я создал проект AWS CodeStar (веб-сервис, на основе Lambda, Node.js). По умолчанию AWS CodeStar генерирует следующее CloudFormation:
AWSTemplateFormatVersion: 2010-09-09
Transform:
- AWS::Serverless-2016-10-31
- AWS::CodeStar
Parameters:
ProjectId:
Type: String
Description: AWS CodeStar projectID used to associate new resources to team members
Resources:
HelloWorld:
Type: AWS::Serverless::Function
Properties:
Handler: index.handler
Runtime: nodejs4.3
Role:
Fn::ImportValue:
!Join ['-', [!Ref 'ProjectId', !Ref 'AWS::Region', 'LambdaTrustRole']]
Events:
GetEvent:
Type: Api
Properties:
Path: /
Method: get
PostEvent:
Type: Api
Properties:
Path: /
Method: post
Теперь я хотел бы заменить эту роль собственной ролью, потому что мне нужно добавить политики для функции Lambda для доступа к другим ресурсам AWS. В то же время я также удалил шлюз API, потому что позже добавлю планировщик для запуска лямбда-вызовов:
AWSTemplateFormatVersion: 2010-09-09
Transform:
- AWS::Serverless-2016-10-31
- AWS::CodeStar
Parameters:
ProjectId:
Type: String
Description: AWS CodeStar projectID used to associate new resources to team members
Resources:
HelloWorld:
Type: AWS::Serverless::Function
Properties:
Handler: index.handler
Runtime: nodejs4.3
Role: !Ref HelloWorldLambdaRole
HelloWorldLambdaRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Однако, когда я фиксирую и отправляю эти изменения, AWS CodePipeline не может обновить шаблон CloudFormation:
CREATE_FAILED AWS::IAM::Role EchoLambdaRole API: iam:CreateRole User: arn:aws:sts::[accountId]:assumed-role/CodeStarWorker-[projectId]-CloudFormation/AWSCloudFormation is not authorized to perform: iam:CreateRole on resource: arn:aws:iam::[accountId]:role/awscodestar-[projectId]-lambda-HelloWorldLambdaRole-ABCDEF123456
На основании этого отзыва я делаю вывод, что CodeStarWorker-[projectId]-CloudFormation/AWSCloudFormation
роль не авторизована для создания ролей IAM. Однако эта роль скрыта от моего шаблона CloudFormation, и, насколько я понимаю, она настраивается CodeStar автоматически. Как администратор учетной записи AWS, я мог бы просто отредактировать соответствующую политику, но, по-моему, это не способ решить эту проблему.
Редактировать:
Я проверил конфигурацию IAM в своей учетной записи. Была создана aws-codestar-service-роль, и она связана с AWSCodeStarServiceRole
политика, которая имеет следующий оператор (среди других операторов, см. ссылку для деталей):
{
"Sid": "ProjectWorkerRoles",
"Effect": "Allow",
"Action": [
"iam:AttachRolePolicy",
"iam:CreateRole",
"iam:DeleteRole",
"iam:DeleteRolePolicy",
"iam:DetachRolePolicy",
"iam:GetRole",
"iam:PassRole",
"iam:PutRolePolicy",
"iam:SetDefaultPolicyVersion",
"iam:CreatePolicy",
"iam:DeletePolicy",
"iam:AddRoleToInstanceProfile",
"iam:CreateInstanceProfile",
"iam:DeleteInstanceProfile",
"iam:RemoveRoleFromInstanceProfile"
],
"Resource": [
"arn:aws:iam::*:role/CodeStarWorker*",
"arn:aws:iam::*:policy/CodeStarWorker*",
"arn:aws:iam::*:instance-profile/awscodestar-*"
]
},
Также есть CodeStarWorker-[projectId]-CloudFormation
роль, которая имеет встроенную политику с именем CodeStarWorkerCloudFormationRolePolicy
со следующей конфигурацией:
{
"Statement": [
{
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:GetObjectVersion"
],
"Resource": [
"arn:aws:s3:::aws-chargeodestar-eu-west-1-[accountId]-[projectId]-pipeline",
"arn:aws:s3:::aws-codestar-eu-west-1-[accountId]-[projectId]-pipeline/*"
],
"Effect": "Allow"
},
{
"Action": [
"codestar:SyncResources",
"lambda:CreateFunction",
"lambda:DeleteFunction",
"lambda:AddPermission",
"lambda:UpdateFunction",
"lambda:UpdateFunctionCode",
"lambda:GetFunctionConfiguration",
"lambda:UpdateFunctionConfiguration",
"lambda:RemovePermission",
"apigateway:*",
"dynamodb:CreateTable",
"dynamodb:DeleteTable",
"dynamodb:DescribeTable",
"kinesis:CreateStream",
"kinesis:DeleteStream",
"kinesis:DescribeStream",
"sns:CreateTopic",
"sns:DeleteTopic",
"sns:ListTopics",
"sns:GetTopicAttributes",
"sns:SetTopicAttributes",
"s3:CreateBucket",
"s3:DeleteBucket"
],
"Resource": "*",
"Effect": "Allow"
},
{
"Action": [
"iam:PassRole"
],
"Resource": [
"arn:aws:iam::[accountId]:role/CodeStarWorker-[projectId]-Lambda"
],
"Effect": "Allow"
},
{
"Action": [
"cloudformation:CreateChangeSet"
],
"Resource": [
"arn:aws:cloudformation:eu-west-1:aws:transform/Serverless-2016-10-31",
"arn:aws:cloudformation:eu-west-1:aws:transform/CodeStar"
],
"Effect": "Allow"
}
]
}
Так как я создал проект, CodeStar_[projectId]_Owner
политика была напрямую привязана к моему пользователю.
Изменить 2:
Несмотря на мою собственную рекомендацию, я попытался обновить встроенную CodeStarWorkerCloudFormationRolePolicy
из CodeStarWorker-[projectId]-CloudFormation
роль, добавив следующее заявление о политике:
{
"Action": [
"iam:AttachRolePolicy",
"iam:CreateRole",
"iam:DeleteRole",
"iam:DetachRolePolicy",
"iam:GetRole",
"iam:PassRole"
],
"Resource": [
"arn:aws:iam::699602212296:role/awscodestar-[projectId]-*"
],
"Effect": "Allow"
}
Однако это вызвало следующую ошибку в CloudFormation:
CREATE_FAILED AWS::CodeStar::SyncResources SyncResources123456789012 com.amazon.coral.service.InternalFailure
1 ответ
Служба CodeStar использует служебную роль под названием aws-codestar-service-role со следующим утверждением. Вы можете изменить эту роль службы, если она позволяет динамическим рабочим ролям проекта наследовать действие по созданию роли IAM. В противном случае CodeStar может перезаписать ваши изменения.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ProjectStack",
"Effect": "Allow",
"Action": [
"cloudformation:*Stack*",
"cloudformation:GetTemplate"
],
"Resource": [
"arn:aws:cloudformation:*:*:stack/awscodestar-*",
"arn:aws:cloudformation:*:*:stack/awseb-*"
]
},
{
"Sid": "ProjectStackTemplate",
"Effect": "Allow",
"Action": [
"cloudformation:GetTemplateSummary",
"cloudformation:DescribeChangeSet"
],
"Resource": "*"
},
{
"Sid": "ProjectQuickstarts",
"Effect": "Allow",
"Action": [
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::awscodestar-*/*"
]
},
{
"Sid": "ProjectS3Buckets",
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": [
"arn:aws:s3:::aws-codestar-*",
"arn:aws:s3:::aws-codestar-*/*",
"arn:aws:s3:::elasticbeanstalk-*",
"arn:aws:s3:::elasticbeanstalk-*/*"
]
},
{
"Sid": "ProjectServices",
"Effect": "Allow",
"Action": [
"codestar:*Project",
"codestar:*Resource*",
"codestar:List*",
"codestar:Describe*",
"codestar:Get*",
"codestar:AssociateTeamMember",
"codecommit:*",
"codepipeline:*",
"codedeploy:*",
"codebuild:*",
"ec2:RunInstances",
"autoscaling:*",
"cloudwatch:Put*",
"ec2:*",
"elasticbeanstalk:*",
"elasticloadbalancing:*",
"iam:ListRoles",
"logs:*",
"sns:*"
],
"Resource": "*"
},
{
"Sid": "ProjectWorkerRoles",
"Effect": "Allow",
"Action": [
"iam:AttachRolePolicy",
"iam:CreateRole",
"iam:DeleteRole",
"iam:DeleteRolePolicy",
"iam:DetachRolePolicy",
"iam:GetRole",
"iam:PassRole",
"iam:PutRolePolicy",
"iam:SetDefaultPolicyVersion",
"iam:CreatePolicy",
"iam:DeletePolicy",
"iam:AddRoleToInstanceProfile",
"iam:CreateInstanceProfile",
"iam:DeleteInstanceProfile",
"iam:RemoveRoleFromInstanceProfile"
],
"Resource": [
"arn:aws:iam::*:role/CodeStarWorker*",
"arn:aws:iam::*:policy/CodeStarWorker*",
"arn:aws:iam::*:instance-profile/awscodestar-*"
]
},
{
"Sid": "ProjectTeamMembers",
"Effect": "Allow",
"Action": [
"iam:AttachUserPolicy",
"iam:DetachUserPolicy"
],
"Resource": "*",
"Condition": {
"ArnEquals": {
"iam:PolicyArn": [
"arn:aws:iam::*:policy/CodeStar_*"
]
}
}
},
{
"Sid": "ProjectRoles",
"Effect": "Allow",
"Action": [
"iam:CreatePolicy",
"iam:DeletePolicy",
"iam:CreatePolicyVersion",
"iam:DeletePolicyVersion",
"iam:ListEntitiesForPolicy",
"iam:ListPolicyVersions"
],
"Resource": [
"arn:aws:iam::*:policy/CodeStar_*"
]
},
{
"Sid": "InspectServiceRole",
"Effect": "Allow",
"Action": [
"iam:ListAttachedRolePolicies"
],
"Resource": [
"arn:aws:iam::*:role/aws-codestar-service-role"
]
}
]
}
Также см. http://docs.aws.amazon.com/codestar/latest/userguide/access-permissions.html но, как вы уже догадались, он относительно новый, и документы не охватывают ваш вариант использования.
Я полагаю, что ответ заключается в том, что CodeStar кажется несовместимым с соглашением об именах, которое используется для создания ролей в различных ситуациях. Если при создании роли вы предоставляете имя с префиксом CodeStar-[projectId]*
это будет соответствовать политике IAM роли CodeStarWorker-[projectId]-CloudFormation. т. е. включить `RoleName:!Sub 'CodeStar-${ProjectId}-....'.
Дополнительная информация Когда я столкнулся с той же ошибкой, я также собирался обновить политику IAM, а затем заметил границу разрешений в политике IAM роли CodeStarWorker-[projectId]-CloudFormation. Сравните роль в ошибке с существующей ролью:
Роль в ошибке: awscodestar-[projectId]-lambda-HelloWorldLambdaRole-ABCDEF123456
,
Роль, созданная CodeStar, пример кода: CodeStar-[projectId]-Execution
В качестве дополнительного примечания, это сбивает с толку, если вы пришли в CodeStar с помощью SAM CLI, так как с CLI вы можете указать лямбда-функцию без роли, и SAM создаст ее для вас, например:
$ sam init --name test_sam
$ cat test_sam/template.yml
HelloWorldFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: hello-world/
Handler: app.lambdaHandler
Runtime: nodejs8.10
Environment:
Variables:
PARAM1: VALUE
Events:
HelloWorld:
Type: Api
Properties:
Path: /hello
Method: get
Однако в CodeStar это не сработает, и кажется, что вам нужно следовать примеру CodeStar и указать ресурс функции, а также роль с правильным префиксом имени! например
Resources:
HelloWorld:
Type: AWS::Serverless::Function
Properties:
Handler: index.handler
Runtime: python3.7
Role:
Fn::GetAtt:
- LambdaExecutionRole
- Arn
Events:
GetEvent:
Type: Api
Properties:
Path: /
Method: get
LambdaExecutionRole:
Description: Creating service role in IAM for AWS Lambda
Type: AWS::IAM::Role
Properties:
RoleName: !Sub 'CodeStar-${ProjectId}-Execution${Stage}'
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service: [lambda.amazonaws.com]
Action: sts:AssumeRole
Path: /
ManagedPolicyArns:
- ....