Изменить роль 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:
        -  ....
Другие вопросы по тегам