serverless/serverless

Requires capabilities : [CAPABILITY_AUTO_EXPAND]

开放

#11,566 创建于 2022年11月29日

 (6 条评论) (0 个反应) (1 位负责人)JavaScript (5,734 个派生)batch import
cat/deploymentenhancementgood first issuehelp wanted

仓库指标

星标
 (46,915 个星标)
PR 合并指标
 (平均合并 1天 15小时) (30 天内合并 34 个 PR)

描述

Are you certain it's a bug?

  • Yes, it looks like a bug

Is the issue caused by a plugin?

  • It is not a plugin issue

Are you using the latest v3 release?

  • Yes, I'm using the latest v3 release

Is there an existing issue for this?

  • I have searched existing issues, it hasn't been reported yet

Issue description

When running serverless deploy an error occur stating "Requires capabilities : [CAPABILITY_AUTO_EXPAND]" but this should be default behavior is my understanding.

This is when role is specified under the resource part.

Service configuration (serverless.yml) content

service: ${env:CI_PROJECT_NAME, 'clad-region-service-api'}

frameworkVersion: "3"
useDotenv: true

custom:
  baseUrlV1: v1
  pythonRequirements:
    pipCmdExtraArgs: 
      - '--platform manylinux2014_x86_64'
      - "--only-binary=:all:"
    slim: true
    slimPatternsAppendDefaults: false
    slimPatterns:
      - '**/requirements.txt'
  logRetentionInDays: 365  # used to set a global value for all functions
  stackName: ${self:service}-${opt:stage, self:provider.stage}
  customDomain:
    domainName: ${self:custom.config.apidomain}
    certificateName: ${self:custom.config.acmcertificate}
    basePath: region
    stage: ${opt:stage, self:provider.stage}
    createRoute53Record: false
  config: ${file(config.${opt:stage, self:provider.stage}.yml), 'api.clad.devtest.aws.scania.com'}
  dynamoDbTableName: ${env:DYNAMODB_TABLE_NAME, 'clad-region-service-tbl-dev'}
  apiKeyExecutionRole: ${self:service}-${opt:stage, self:provider.stage}-ApiKeyExecutionRole
  iamAuthExecutionRole: ${self:service}-${opt:stage, self:provider.stage}-IamAuthExecutionRole
  associateWaf:
    name: clad-wafv2-public-WebACLPublic
    version: V2

package:
  patterns:
    - '!./**'
    - './python/src/**'
  excludeDevDependencies: false # need to be false to have quick deployments, default value true

provider:
  name: aws
  deploymentMethod: direct # Can not set this to direct. Getting error about auto_expand
  runtime: python3.9
  timeout: 30
  logs:
    restApi: false
  stackTags:
    GitLabCommitSHA: ${env:CI_COMMIT_SHA, 'local-sls-deployment'}
  environment:
    PYTHONPATH: ${env:PYTHONPATH, 'python/src'}
    LOG_LEVEL: ${env:LOG_LEVEL, 'DEFAULT'}
    LOG_LEVEL_BOTOCORE: ${env:LOG_LEVEL_BOTOCORE, 'DEFAULT'}
    DYNAMODB_TABLE_NAME: ${self:custom.dynamoDbTableName}
    JWT_PROVIDER_URL: ${env:JWT_PROVIDER_URL, ''}
    AUTHORIZED_FG_CLIENTS: ${env:AUTHORIZED_FG_CLIENTS, 'clad_test'}
    COGNITO_USER_POOL_ID: ${env:COGNITO_USER_POOL_ID, 'eu-west-1_usWPsvCHv'}
    COGNITO_USER_POOL_AWS_ACCOUNT_NUMBER: ${env:COGNITO_USER_POOL_AWS_ACCOUNT_NUMBER, '123'}
    ENVIRONMENT_STAGE: ${env:ENVIRONMENT_STAGE, 'dev'}
    IAM_ROLE_ALLOWED_ACCOUNT: ${env:IAM_ROLE_ALLOWED_ACCOUNT, '123'}
    INFOSEC_ACCOUNT: ${env:INFOSEC_ACCOUNT, '123'}
  iam:
    role:
      statements:
        - Effect: Allow
          Action:
            - dynamodb:Query
            - dynamodb:Scan
            - dynamodb:GetItem
            - dynamodb:DeleteItem
            - dynamodb:UpdateItem
            - dynamodb:PutItem
            - dynamodb:DescribeTable
          Resource:
            - "arn:aws:dynamodb:${opt:region, self:provider.region}:*:table/${self:custom.dynamoDbTableName}"
        - Effect: Allow
          Action:
            - apigateway:POST
            - apigateway:PUT
            - apigateway:PATCH
            - apigateway:DELETE
            - apigateway:GET
            - apigateway:HEAD
            - apigateway:OPTIONS
          Resource:
            - "arn:aws:apigateway:${opt:region, self:provider.region}::/apikeys/*"
            - "arn:aws:apigateway:${opt:region, self:provider.region}::/*"
        - Effect: Allow
          Action:
            - execute-api:Invoke
          Resource:
            - "arn:aws:execute-api:${opt:region, self:provider.region}:*:*"
        - Effect: Allow
          Action:
            - ec2:DescribeRegions
          Resource:
            - '*'
        - Effect: Allow
          Action:
            - cognito-idp:ListUsersInGroup
            - cognito-idp:ListUsers
          Resource: 
            'Fn::ImportValue': 'clad-cognito-userpool-CladUserPoolArn'
        - Effect: Allow
          Action: sts:AssumeRole
          Resource: 
            - arn:aws:iam::${aws:accountId}:role/clad-account-service-aws-api-${opt:stage, self:provider.stage}-IamAuthExecutionRole
            - arn:aws:iam::${aws:accountId}:role/clad-ipam-service-${opt:stage, self:provider.stage}-IamAuthExecutionRole
        
  apiGateway:
    resourcePolicy:
      - Effect: Allow
        Principal: "*"
        Action: execute-api:Invoke
        Resource:
          - execute-api:/*/GET/v1/cognito/region/account/*
          - execute-api:/*/PUT/v1/cognito/region/account/*

      - Effect: Allow
        Principal: "*"
        Action: execute-api:Invoke
        Resource:
          - execute-api:/*/GET/${self:custom.baseUrlV1}/fg/region
          - execute-api:/*/GET/${self:custom.baseUrlV1}/fg/region/account
          - execute-api:/*/POST/${self:custom.baseUrlV1}/fg/region/account
          - execute-api:/*/GET/${self:custom.baseUrlV1}/fg/region/account/*
          - execute-api:/*/PUT/${self:custom.baseUrlV1}/fg/region/account/*
        Condition:
          IpAddress:
            'Fn::Transform':
              Name: 'AWS::Include'
              Parameters:
                Location: s3://clad-masked-resourcepolicy-${sls:stage}/FederationGatewayIpFilter.yml

      - Effect: Allow
        Principal: "*"
        Action: execute-api:Invoke
        Resource:
          - execute-api:/*/*/*
        Condition:
          IpAddress:
            'Fn::Transform':
              Name: 'AWS::Include'
              Parameters:
                Location: s3://clad-masked-resourcepolicy-${sls:stage}/CognitoIpFilter.yml

      - Effect: Allow
        Principal:
          AWS:
            - "${aws:accountId}" # Could be none?
        Action: execute-api:Invoke
        Resource:
          - execute-api:/*/*/*

plugins:
  - serverless-python-requirements
  - serverless-plugin-log-retention
  - serverless-domain-manager
  - serverless-associate-waf

functions:
  get_supported_regions:
    handler: region.get_supported_regions
    events:
      - http:  
          path: ${self:custom.baseUrlV1}/region
          method: get
          cors: true
          authorizer:
            type: AWS_IAM

  get_supported_regions_fg:
    handler: region.get_supported_regions_fg
    events:
      - http:
          path: ${self:custom.baseUrlV1}/fg/region
          method: get
          cors: true
          authorizer: 
            name: jwt_authenticator
            type: request

  get_supported_regions_cognito:
    handler: region_cognito.get_supported_regions_cognito
    events:
      - http:
          path: ${self:custom.baseUrlV1}/cognito/region
          method: get
          cors: true
          authorizer:
            name: CognitoCladAuthorizer
            type: COGNITO_USER_POOLS
            arn: 
              'Fn::ImportValue': 'clad-cognito-userpool-CladUserPoolArn'

  get_specific_account_and_region:
    handler: region.get_specific_account_and_region
    events:
      - http:
          path: ${self:custom.baseUrlV1}/region/account/{account_id}/region/{region_id}
          method: get
          cors: true
          authorizer:
            type: AWS_IAM
          request:
            parameters:
              paths:
                account_id: true

  get_specific_account: 
    handler: region.get_specific_account
    events:
      - http:  
          path: ${self:custom.baseUrlV1}/region/account/{account_id}
          method: get
          cors: true
          authorizer:
            type: AWS_IAM
          request:
            parameters:
              paths:
                account_id: true

  get_specific_account_fg:
    handler: region.get_specific_account_fg
    events:
      - http:
          path: ${self:custom.baseUrlV1}/fg/region/account/{account_id}
          method: get
          cors: true
          authorizer: 
            name: jwt_authenticator
            type: request
          request:
            parameters:
              paths:
                account_id: true

  get_specific_account_cognito:
    handler: region_cognito.get_specific_account_cognito
    events:
      - http:
          path: ${self:custom.baseUrlV1}/cognito/region/account/{account_id}
          method: get
          cors: true
          authorizer:
            name: CognitoCladAuthorizer
            type: COGNITO_USER_POOLS
            arn:
              'Fn::ImportValue': 'clad-cognito-userpool-CladUserPoolArn'
          request:
            parameters:
              paths:
                account_id: true

  get_all:
    handler: region.get_all
    # layers:
    #   - ${cf:clad-lambda-layer-cryptography-patch-${opt:stage}.ContentLambdaLayerQualifiedArn}
    events:
      - http:
          path: ${self:custom.baseUrlV1}/region/account/
          method: get
          cors: true
          authorizer: aws_iam

  get_all_fg:
    handler: region.get_all_fg
    events:
      - http:
          path: ${self:custom.baseUrlV1}/fg/region/account/
          method: get
          cors: true
          authorizer: 
            name: jwt_authenticator
            type: request

  create:
    handler: region.create
    events:
      - http:  
          path: ${self:custom.baseUrlV1}/region/account/
          method: post
          cors: true
          authorizer: aws_iam

  create_fg:
    handler: region.create_fg
    events:
      - http:
          path: ${self:custom.baseUrlV1}/fg/region/account/
          method: post
          cors: true
          authorizer: 
            name: jwt_authenticator
            type: request

  update:
    handler: region.update
    events:
      - http: 
          path: ${self:custom.baseUrlV1}/region/account/{account_id}
          method: put
          cors: true
          request:
            parameters:
              paths:
                account_id: true
          authorizer: aws_iam

  update_fg:
    handler: region.update_fg
    events:
      - http:
          path: ${self:custom.baseUrlV1}/fg/region/account/{account_id}
          method: put
          cors: true
          request:
            parameters:
              paths:
                account_id: true
          authorizer: 
            name: jwt_authenticator
            type: request

  update_availabilityzones_cognito:
    handler: availabilityzones.update_availabilityzones_cognito
    events:
      - http:
          path: ${self:custom.baseUrlV1}/cognito/region/account/{account_id}/{region}/vpc/availabilityzones
          method: put
          cors: true
          authorizer:
            name: CognitoCladAuthorizer
            type: COGNITO_USER_POOLS
            arn: 
              'Fn::ImportValue': 'clad-cognito-userpool-CladUserPoolArn'
          request:
            parameters:
              paths:
                account_id: true
                region: true

  create_vpc_cognito:
    handler: vpc.create_vpc_cognito
    events:
      - http:
          path: ${self:custom.baseUrlV1}/cognito/region/account/{account_id}/{region}/vpc
          method: post
          cors: true
          authorizer:
            name: CognitoCladAuthorizer
            type: COGNITO_USER_POOLS
            arn: 
              'Fn::ImportValue': 'clad-cognito-userpool-CladUserPoolArn'
          request:
            parameters:
              paths:
                account_id: true
                region: true
  
  delete_vpc:
    handler: vpc.delete_vpc
    events:
      - http:
          path: ${self:custom.baseUrlV1}/region/account/{account_id}/{region}/vpc
          method: put
          cors: true
          request:
            parameters:
              paths:
                account_id: true
                region: true
          authorizer: aws_iam

  delete_vpc_cognito:
    handler: vpc.delete_vpc_cognito
    events:
      - http:
          path: ${self:custom.baseUrlV1}/cognito/region/account/{account_id}/{region}/vpc
          method: put
          cors: true
          authorizer:
            name: CognitoCladAuthorizer
            type: COGNITO_USER_POOLS
            arn: 
              'Fn::ImportValue': 'clad-cognito-userpool-CladUserPoolArn'
          request:
            parameters:
              paths:
                account_id: true
                region: true

  jwt_authenticator:
    handler: clad_auth_utilities.jwt.jwt_authenticator

resources:
  Resources:
    ApiKeyExecutionRole:
      Type: AWS::IAM::Role
      Properties:
        Path: /
        RoleName: ${self:custom.apiKeyExecutionRole}
        AssumeRolePolicyDocument:
          Version: '2012-10-17'
          Statement:
            - Effect: Allow
              Principal:
                AWS:
                  - '${aws:accountId}'                 # The stage (DEV / PROD) account it self
                  - '${self:provider.environment.IAM_ROLE_ALLOWED_ACCOUNT}'   # The allowed account (DEV / PROD) account
                  - '${self:provider.environment.INFOSEC_ACCOUNT}'            # infosec- dev or prod account
              Action: sts:AssumeRole
        ManagedPolicyArns:    
          - !Ref ApiKeyExecutionRolePolicy

    ApiKeyExecutionRolePolicy:
      Type: AWS::IAM::ManagedPolicy
      Properties:
        ManagedPolicyName: ${self:custom.apiKeyExecutionRole}-Policy
        PolicyDocument:
          Version: '2012-10-17'
          Statement:
            # Needed to get query stage (dev/prod)
            - Effect: Allow
              Action:
                - 'cloudformation:DescribeStacks'
              Resource:
                - 'arn:aws:cloudformation:${opt:region, self:provider.region}:${aws:accountId}:stack/${self:custom.stackName}*'
                - 'arn:aws:cloudformation:${opt:region, self:provider.region}:${aws:accountId}:stack/${self:custom.stackName}/*'
            # Needed to retrieve API Key and Url
            - Effect: Allow
              Action:
                - 'cloudformation:ListExports'
              Resource:
                - '*'
            - Effect: Allow
              Action:
                - 'apigateway:GET'
              Resource:
                - 'arn:aws:apigateway:${opt:region, self:provider.region}::/apikeys/*'
                # - 'arn:aws:execute-api:${opt:region, self:provider.region}:${aws:accountId}:*/${opt:stage}/*/*'

    IamAuthExecutionRole:
      Type: AWS::IAM::Role
      Properties:
        Path: /
        RoleName: ${self:custom.iamAuthExecutionRole}
        AssumeRolePolicyDocument:
          Version: '2012-10-17'
          Statement:
            - Effect: Allow
              Principal:
                AWS:
                  - '${aws:accountId}'                 # The stage (DEV / PROD) account it self
                  - '${self:provider.environment.IAM_ROLE_ALLOWED_ACCOUNT}'   # The allowed account (DEV / PROD) account
                  - '${self:provider.environment.INFOSEC_ACCOUNT}'            # infosec- dev or prod account
              Action: sts:AssumeRole
        ManagedPolicyArns:    
          - !Ref IamAuthExecutionRolePolicy

    IamAuthExecutionRolePolicy:
      Type: AWS::IAM::ManagedPolicy
      Properties:
        ManagedPolicyName: ${self:custom.iamAuthExecutionRole}-Policy
        PolicyDocument:
          Version: '2012-10-17'
          Statement:
            - Effect: Allow
              Action:
                - 'execute-api:Invoke'
              Resource:
                - 'arn:aws:execute-api:${opt:region, self:provider.region}:${aws:accountId}:*/${opt:stage}/GET/v1/region'
                - 'arn:aws:execute-api:${opt:region, self:provider.region}:${aws:accountId}:*/${opt:stage}/*/*'

  Outputs:
    ApiGatewayRestApi:
      Description: Endpoint for this API
      Value:
        Fn::Join:
          - ''
          - - 'https://'
            - Fn::Join:
                - '.'
                - - Ref: ApiGatewayRestApi
                  - 'execute-api'
                  - ${opt:region, self:provider.region}
                  - 'amazonaws'
                  - 'com'
            - '/'
            - ${opt:stage, self:provider.stage}
      Export:
        Name: ${self:custom.stackName}-ApiEndpoint

Command name and used flags

sls deploy -s dev -r eu-west-1

Command output

✖ Stack clad-region-service-api-dev failed to deploy (113s)
Environment: darwin, node 14.16.0, framework 3.25.1, plugin 6.2.2, SDK 4.3.2
Credentials: Local, "scania-clad-dev" profile
Docs:        docs.serverless.com
Support:     forum.serverless.com
Bugs:        github.com/serverless/serverless/issues

Error:
Requires capabilities : [CAPABILITY_AUTO_EXPAND]

Environment information

Framework Core: 3.25.1
Plugin: 6.2.2
SDK: 4.3.2

贡献者指南