Hello,
Event if the “provider.name” is set, I get the error “Error: Invalid service configuration: “provider.name” property is missing” when I try to deploy my stack.
import type { Serverless } from "serverless/aws";
/**
* Authorizer with Cognito User Pool
*/
export const authorizer = {
name: 'test-back-${sls:stage}-authorizer',
type: 'COGNITO_USER_POOLS',
arn: { 'Fn::GetAtt': [ 'cognitoUserPool', 'Arn' ] }
}
const serverlessConfig: Partial<Serverless> = {
service: 'test-auth',
provider: {
name: "aws",
runtime: "nodejs16.x",
memorySize: 128,
stage: "${opt:stage, 'dev'}",
logRetentionInDays: 14,
environment: {
API_ENV: "${sls:stage}",
NODE_OPTIONS: "--enable-source-maps",
},
region: "eu-west-1",
stackTags: {
project: "test-back",
},
apiName: '${opt:stage}-test-back',
apiGateway: {
minimumCompressionSize: 1024,
metrics: false,
// @ts-ignore
restApiId: {
Ref: 'ApiGateway',
},
// @ts-ignore
restApiRootResourceId: {
'Fn::GetAtt': ['ApiGateway', 'RootResourceId']
},
description: "test-back",
},
},
custom: {
esbuild: {
bundle: true,
// @ts-ignore
minify: '${sls:stage}' === 'prod' ? true : false,
packager: "pnpm",
sourcemap: true,
exclude: ["aws-sdk"],
},
apiGatewayCaching: {
enabled: true,
},
"serverless-offline": {
lambdaPort: 3000,
httpPort: 3001,
},
},
/**
* Example functions with Cognito Authorizer
*/
functions: {
getHello: {
handler: 'getHello/index.handler',
events: [
{
http: {
method: 'get',
path: 'auth/getHello',
authorizer: ({ 'Ref' : 'apiGatewayAuthorizer' } as unknown) as string,
cors: true,
},
},
],
},
},
resources: {
Resources: {
/**
* Base Api Gateway
*/
ApiGateway: {
Type: 'AWS::ApiGateway::RestApi',
Properties: {
Name: '${opt:stage}-test-back',
},
},
/**
* Cognito - User Pool
* https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cognito-userpool.html
*/
cognitoUserPool: {
Type: 'AWS::Cognito::UserPool',
Properties: {
UserPoolName: 'test-back-${sls:stage}-user-pool',
MfaConfiguration: 'OPTIONAL',
UsernameAttributes: [ 'email' ],
AutoVerifiedAttributes: [ 'email' ],
Policies: {
PasswordPolicy: {
MinimumLength: 8,
RequireLowercase: true,
RequireNumbers: true,
RequireSymbols: true,
RequireUppercase: true
}
}
}
},
/**
* Cognito - User Pool Client
* https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cognito-userpoolclient.html
*/
cognitoUserPoolClient: {
Type: 'AWS::Cognito::UserPoolClient',
Properties: {
ClientName: 'test-back-${sls:stage}-user-pool-client',
GenerateSecret: false,
UserPoolId: { 'Ref': 'cognitoUserPool' },
AccessTokenValidity: 8,
IdTokenValidity: 8,
RefreshTokenValidity: 7,
TokenValidityUnits: {
AccessToken : 'hours',
IdToken : 'hours',
RefreshToken : 'days'
},
ExplicitAuthFlows: [
'ALLOW_CUSTOM_AUTH',
'ALLOW_REFRESH_TOKEN_AUTH',
'ALLOW_USER_SRP_AUTH'
],
EnableTokenRevocation: true,
PreventUserExistenceErrors: 'ENABLED',
}
},
/**
* Cognito - Identity
* https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cognito-identitypool.html
*/
cognitoIdentityPool: {
Type: 'AWS::Cognito::IdentityPool',
Properties: {
IdentityPoolName: 'test-back-${sls:stage}-cognito-identity-pool',
AllowUnauthenticatedIdentities: false,
CognitoIdentityProviders: [
{
ClientId: { Ref: 'cognitoUserPoolClient' },
ProviderName: { 'Fn::GetAtt': ['cognitoUserPool', 'ProviderName'] }
}
]
}
},
/**
* Cognito - Base Roles: Authorized and Unauthorized
* https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cognito-identitypoolroleattachment.html
*/
cognitoIdentityPoolRoles: {
Type: 'AWS::Cognito::IdentityPoolRoleAttachment',
Properties: {
IdentityPoolId: { Ref: 'cognitoIdentityPool' },
Roles: {
authenticated: {
'Fn::GetAtt':[ 'cognitoAuthenticatedRole', 'Arn' ]
},
unauthenticated: {
'Fn::GetAtt': [ 'cognitoUnauthenticatedRole', 'Arn' ]
}
}
}
},
/**
* Cognito Roles
* https://docs.aws.amazon.com/fr_fr/AWSCloudFormation/latest/UserGuide/aws-resource-iam-role.html
*/
cognitoAuthenticatedRole: {
Type: 'AWS::IAM::Role',
Properties: {
RoleName: 'test-back-${sls:stage}-cognito-authorized-role',
Path: '/',
AssumeRolePolicyDocument: {
Version: '2012-10-17',
Statement: [
{
Effect: 'Allow',
Principal: {
Federated: 'cognito-identity.amazonaws.com'
},
Action: [
'sts:AssumeRoleWithWebIdentity'
],
Condition: {
StringEquals: {
'cognito-identity.amazonaws.com:aud': { 'Ref': 'cognitoIdentityPool' }
},
'ForAnyValue:StringLike': {
'cognito-identity.amazonaws.com:amr': 'authenticated'
}
}
}
]
},
Policies: [
{
PolicyName: 'test-back-${sls:stage}-cognito-authorized-policy',
PolicyDocument: {
Version: '2012-10-17',
Statement: [
{
Effect: 'Allow',
Action: [
'mobileanalytics:PutEvents',
'cognito-sync:*',
'cognito-identity:*'
],
Resource: '*'
},
{
Effect: 'Allow',
Action: [
'execute-api:Invoke'
],
Resource: '*' // @TOUP: better security to change to API / lambda that request need to access
}
]
}
}
]
}
},
cognitoUnauthenticatedRole: {
Type: 'AWS::IAM::Role',
Properties: {
RoleName: 'test-back-${sls:stage}-cognito-unauthorized-role',
Path: '/',
AssumeRolePolicyDocument: {
Version: '2012-10-17',
Statement: [
{
Effect: 'Allow',
Principal: {
Federated: 'cognito-identity.amazonaws.com'
},
Action: [
'sts:AssumeRoleWithWebIdentity'
],
Condition: {
'StringEquals': {
'cognito-identity.amazonaws.com:aud': { 'Ref': 'cognitoIdentityPool' }
},
'ForAnyValue:StringLike': {
'cognito-identity.amazonaws.com:amr': 'unauthenticated'
}
}
}
]
},
Policies: [
{
PolicyName: 'test-back-${sls:stage}-cognito-unauthorized-policy',
PolicyDocument: {
Version: '2012-10-17',
Statement: [
{
Effect: 'Allow',
Action: [
'mobileanalytics:PutEvents',
'cognito-sync:*',
'cognito-identity:*'
],
Resource: '*'
}
]
}
}
]
}
},
/**
* API Gateway
* https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-authorizer.html
*/
apiGatewayAuthorizer: {
Type: 'AWS::ApiGateway::Authorizer',
Properties: {
name: 'test-back-${sls:stage}-authorizer',
type: 'COGNITO_USER_POOLS',
IdentitySource: 'method.request.header.Authorization',
// IdentityValidationExpression: Bearer (.*) // reject mal formated Authorization header
// AuthorizerResultTtlInSeconds: // change default 300 TTL cache settings
ProviderARNs: [
{ 'Ref': 'cognitoUserPool' }
],
RestApiId: {
'Fn::ImportValue': '${opt:stage}-ApiGateway-restApiId'
}
}
}
},
Outputs: {
apiGatewayAuthorizerId: {
Value: {
Ref: 'apiGatewayAuthorizer',
},
Export: {
Name: '${opt:stage}-ApiGateway-AuthorizerId',
},
},
},
}
};
module.exports = {serverlessConfig, authorizer};
Environment:
- darwin,
- node 16.17.0,
- framework 3.22.0 (local) 3.22.0v (global),
- plugin 6.2.2,
- SDK 4.3.2