#11611·serverless

Validator reports invalid configuration for !If function

Author: karmaniverousCreated Dec 15, 2022Updated Jun 23, 2026
Labelsgood first issueenhancementhelp wantedcat/aws-event-api-gateway

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

I'm using !If in a valid configuration that works perfectly when deployed but generates a config warning on deployment. Full description here

Service configuration (serverless.yml) content

service: ${env:SERVICE_NAME}
frameworkVersion: '3'

plugins:
  - serverless-domain-manager
  - serverless-offline

params:
  default:
    apiBasePath: ${env:API_VERSION}-${env:ENV}
    authSubdomain: ${env:AUTH_SUBDOMAIN_TOKEN}-${env:API_VERSION}-${env:ENV}
  prod:
    apiBasePath: ${env:API_VERSION}
    authSubdomain: ${env:AUTH_SUBDOMAIN_TOKEN}-${env:API_VERSION}

provider:
  apiGateway:
    disableDefaultEndpoint: true
  apiName: ${self:provider.stackName}
  endpointType: EDGE
  iam:
    role:
      # name:
      statements:
        - Effect: Allow
          Action:
            - cognito-idp:AdminInitiateAuth
            - cognito-idp:AdminCreateUser
            - cognito-idp:AdminSetUserPassword
          Resource: '*'
  memorySize: 128
  name: aws
  region: us-east-1
  runtime: nodejs18.x
  stackName: ${env:SERVICE_NAME}-${env:API_VERSION}-${env:ENV}
  stage: ${env:API_VERSION}-${env:ENV}
  timeout: 5

custom:
  customDomain:
    domainName: ${env:API_SUBDOMAIN}.${env:ROOT_DOMAIN}
    basePath: ${param:apiBasePath}
    certificateArn: ${env:CERTIFICATE_ARN}

functions:
  hello:
    handler: api/open/hello.get
    description: GET /hello
    events:
      - http:
          path: hello
          method: get
          cors: true
    # name: ${self:provider.stage}

  secure-hello:
    handler: api/secure/hello.get
    description: GET /secure-hello
    events:
      - http:
          path: secure-hello
          method: get
          cors: true
          authorizer:
            name: UserPoolAuthorizer
            type: COGNITO_USER_POOLS
            arn: !If
              - CreateUserPool
              - !GetAtt UserPool.Arn
              - ${env:COGNITO_USER_POOL_ARN}
            claims:
              - email

resources:
  Conditions:
    CreateUserPool: !Equals ['${env:COGNITO_USER_POOL_ARN}', '*']
    CreateIdentityProviderGoogle: !And
      - !Condition CreateUserPool
      - !Not
        - !Or
          - !Equals ['${env:GOOGLE_CLIENT_ID}', '*']
          - !Equals ['${env:GOOGLE_CLIENT_SECRET}', '*']

  Resources:
    GatewayResponseDefault4XX:
      Type: 'AWS::ApiGateway::GatewayResponse'
      Properties:
        ResponseParameters:
          gatewayresponse.header.Access-Control-Allow-Origin: "'*'"
          gatewayresponse.header.Access-Control-Allow-Headers: "'*'"
        ResponseType: DEFAULT_4XX
        RestApiId:
          Ref: 'ApiGatewayRestApi'

    UserPool:
      Type: AWS::Cognito::UserPool
      Condition: CreateUserPool
      Properties:
        AutoVerifiedAttributes: ['email']
        Schema:
          - Name: email
            Mutable: true
            Required: true
        UsernameConfiguration:
          CaseSensitive: false
        UserPoolName: ${self:provider.stackName}

    UserPoolIdentityProviderGoogle:
      Type: AWS::Cognito::UserPoolIdentityProvider
      Condition: CreateIdentityProviderGoogle
      Properties:
        UserPoolId: !Ref UserPool
        ProviderName: Google
        ProviderDetails:
          client_id: '${env:GOOGLE_CLIENT_ID}'
          client_secret: '${env:GOOGLE_CLIENT_SECRET}'
          authorize_scopes: 'profile email openid'
        ProviderType: Google
        AttributeMapping:
          email: email

    UserClient:
      Type: AWS::Cognito::UserPoolClient
      Condition: CreateUserPool
      Properties:
        AllowedOAuthFlows:
          - code
        AllowedOAuthFlowsUserPoolClient: true
        AllowedOAuthScopes:
          - email
          - openid
          - profile
        CallbackURLs:
          - 'https://${env:ROOT_DOMAIN}/api/auth/callback/cognito'
          - 'https://${env:WEB_SUBDOMAIN_PROD}.${env:ROOT_DOMAIN}/api/auth/callback/cognito'
          - 'https://${env:WEB_SUBDOMAIN_PREVIEW}.${env:ROOT_DOMAIN}/api/auth/callback/cognito'
          - 'http://localhost:${env:WEB_LOCALHOST_PORT}/api/auth/callback/cognito'
        ClientName: web-app
        GenerateSecret: true
        LogoutURLs:
          - 'https://${env:ROOT_DOMAIN}'
          - 'https://${env:WEB_SUBDOMAIN_PROD}.${env:ROOT_DOMAIN}'
          - 'https://${env:WEB_SUBDOMAIN_PREVIEW}.${env:ROOT_DOMAIN}'
          - 'http://localhost:${env:WEB_LOCALHOST_PORT}'
        SupportedIdentityProviders:
          - COGNITO
          - !If
            - CreateIdentityProviderGoogle
            - Google
            - Ref: AWS::NoValue
        UserPoolId: !Ref UserPool

    UserPoolDomain:
      Type: AWS::Cognito::UserPoolDomain
      Condition: CreateUserPool
      Properties:
        CustomDomainConfig:
          CertificateArn: ${env:CERTIFICATE_ARN}
        Domain: ${param:authSubdomain}.${env:ROOT_DOMAIN}
        UserPoolId: !Ref UserPool

    UserPoolAlias:
      Type: AWS::Route53::RecordSetGroup
      Condition: CreateUserPool
      Properties:
        HostedZoneName: '${env:ROOT_DOMAIN}.'
        RecordSets:
          - Name: ${param:authSubdomain}.${env:ROOT_DOMAIN}.
            ResourceRecords:
              - !GetAtt UserPoolDomain.CloudFrontDistribution
            TTL: '300'
            Type: CNAME

Command name and used flags

serverless deploy --verbose

Command output

Warning: Invalid configuration encountered
  at 'functions.secure-hello.events.0.http.authorizer.arn': unsupported object format

Learn more about configuration validation here: http://slss.io/configuration-validation

Environment information

Framework Core: 3.25.1 (local) 3.25.1 (global)
Plugin: 6.2.2
SDK: 4.3.2