Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Severless does not seem to handle using a shared api gateway v2 defined in the same CF stack #13178

Copy link
Copy link
@maciejewiczow

Description

@maciejewiczow
Issue body actions

Issue description

I am trying to share an API Gateway V2 between all the functions in the serverless file. When I tried using provider.httpApi.apiId["Fn::ImportValue"] with an export name defined in the same serverless.yml in resources.Resources.Outputs it failed with an error saying that it cannot resolve the export. When I modified the config to be as in the issue context, the deployment succeeds, CF stack is marked as CREATE_COMPLETE or UPDATE_COMPLETE in the AWS console, but serverless deploy fails with an error seen in the issue context. This is pretty annoying because I have to swallow this error in my github actions pipeline, and also the command does not print the stack outputs when it errors out, which is another problem I need to solve now.

Also the command serverless deploy prints the following warning at the beginning when ran:

[!] Invalid configuration encountered
  at 'provider.httpApi.id': must have required property 'Fn::ImportValue'
  at 'provider.httpApi.id': unrecognized property 'Ref'

Context

Service Overview

  • Serverless Framework Version: 4.27.0
  • Service Config File: serverless.yml
  • Service Name: recipe-scraper
  • Service App: recipe-scraper
  • Service Runtime: python3.13
  • Service Stage: prod
  • Service Region: eu-north-1
  • Error Code: UNABLE_TO_RESOLVE_HTTP_API_ID

Service Path

[REDACTED]

Command

deploy --param recipeTTL=5d,recipeReadyNotificationBody=Ready,recipeReadyNotificationTitle=Recipe,aiBaseUrl=https://api.openai.com/v1,promptIdPL=[REDACTED],maxAiParseRetryCount=4,promptIdEN=[REDACTED],domainName=[REDACTED],aiModelName=gpt-5-nano,--verbose true

Error Message

Could not resolve provider.httpApi.id parameter. Expected params.ApiId to be a string

Error Stacktrace

at file:///[REDACTED - windows user docs dir]/.serverless/releases/4.27.0/package/dist/sf-core.js:1117:3845
at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
at async Promise.all (index 1)
at async aws:info:gatherData (file:///[REDACTED - windows user docs dir]/.serverless/releases/4.27.0/package/dist/sf-core.js:1117:12599)
at async PluginManager.runHooks (file:///[REDACTED - windows user docs dir]/.serverless/releases/4.27.0/package/dist/sf-core.js:1372:11105)
at async PluginManager.invoke (file:///[REDACTED - windows user docs dir]/.serverless/releases/4.27.0/package/dist/sf-core.js:1372:11874)
at async PluginManager.spawn (file:///[REDACTED - windows user docs dir]/.serverless/releases/4.27.0/package/dist/sf-core.js:1372:12236)
at async PluginManager.runHooks (file:///[REDACTED - windows user docs dir]/.serverless/releases/4.27.0/package/dist/sf-core.js:1372:11105)
at async PluginManager.invoke (file:///[REDACTED - windows user docs dir]/.serverless/releases/4.27.0/package/dist/sf-core.js:1372:11874)
at async PluginManager.run (file:///[REDACTED - windows user docs dir]/.serverless/releases/4.27.0/package/dist/sf-core.js:1372:12607)
at async Serverless.run (file:///[REDACTED - windows user docs dir]/.serverless/releases/4.27.0/package/dist/sf-core.js:1379:10524)
at async runFramework (file:///[REDACTED - windows user docs dir]/.serverless/releases/4.27.0/package/dist/sf-core.js:1406:1781)
at async TraditionalRunner.run (file:///[REDACTED - windows user docs dir]/.serverless/releases/4.27.0/package/dist/sf-core.js:1402:28508)
at async route (file:///[REDACTED - windows user docs dir]/.serverless/releases/4.27.0/package/dist/sf-core.js:1577:2848)
at async Object.run (file:///[REDACTED - windows user docs dir]/.serverless/releases/4.27.0/package/dist/sf-core.js:1578:3876)
at async run2 (file:///[REDACTED - windows user docs dir]/.serverless/releases/4.27.0/package/dist/sf-core.js:1578:5030)

Service Config

org: maciejcorp
app: recipe-scraper
service: recipe-scraper
provider:
  name: aws
  runtime: python3.13
  stage: prod
  region: eu-north-1
  architecture: arm64
  httpApi:
    id: !Ref Gateway
  layers:
    - !Ref SharedLambdaLayer
functions:
  # endpoint handlers
  get-recipe:
    handler: functions/get_recipe/handler.handler
    environment:
      DYNAMO_USER_QUOTA_TABLE_NAME: !ImportValue RecipeScraperPermanentResourcesProd-UserQuotaTableName
      RECIPES_TABLE_NAME: !ImportValue RecipeScraperPermanentResourcesProd-RecipesTableName
    events:
      - httpApi:
          path: /recipe/{recipeId}
          method: get
          authorizer:
            type: jwt
            id:
              Ref: ApiGatewayAuthorizer
    iam:
      inheritStatements: true
      role:
        statements:
          - Effect: Allow
            Action:
              - dynamodb:GetItem
              - dynamodb:PutItem
              - dynamodb:Query
            Resource:
              - !ImportValue RecipeScraperPermanentResourcesProd-RecipesTableArn
              - !ImportValue RecipeScraperPermanentResourcesProd-UserQuotaTableArn
  scrape-recipe:
    handler: functions/scrape_recipe/handler.handler
    events:
      - httpApi:
          path: /recipe/scrape
          method: post
          authorizer:
            type: jwt
            id:
              Ref: ApiGatewayAuthorizer
    iam:
      inheritStatements: true
      role:
        statements:
          - Effect: Allow
            Action:
              - dynamodb:GetItem
              - dynamodb:PutItem
              - dynamodb:Query
            Resource:
              - !ImportValue RecipeScraperPermanentResourcesProd-RecipesTableArn
              - !ImportValue RecipeScraperPermanentResourcesProd-UserQuotaTableArn
          - Effect: Allow
            Action:
              - states:StartExecution
            Resource: ${self:resources.Outputs.ProcessIngredientsStepFn.Value}
          - Effect: Allow
            Action:
              - sns:CreatePlatformEndpoint
            Resource: ${env:SNS_ANDROID_PLATFORM_APPLICATION_ARN}
    environment:
      DYNAMO_USER_QUOTA_TABLE_NAME: !ImportValue RecipeScraperPermanentResourcesProd-UserQuotaTableName
      RECIPES_TABLE_NAME: !ImportValue RecipeScraperPermanentResourcesProd-RecipesTableName
      PROCESS_INGREDIENTS_STEP_FN_ARN: ${self:resources.Outputs.ProcessIngredientsStepFn.Value}
      RECIPE_TTL: ${param:recipeTTL}
      SNS_PLARFORM_APPLICATION_ARN__ANDROID: ${env:SNS_ANDROID_PLATFORM_APPLICATION_ARN}
  parse-result-webhook:
    handler: functions/parse_result_webhook/handler.handler
    events:
      - httpApi:
          path: /ai/webhook
          method: post
    environment:
      DYNAMO_RESPONSES_TABLE_NAME: !ImportValue RecipeScraperPermanentResourcesProd-OpenAiResponsesTableName
      AI__API_KEY: ${env:AI_API_KEY}
      AI__BASE_URL: ${param:aiBaseUrl}
      AI__WEBHOOK_SECRET: ${env:AI_WEBHOOK_SECRET}
    iam:
      inheritStatements: true
      role:
        statements:
          - Effect: Allow
            Action:
              - dynamodb:GetItem
            Resource: !ImportValue RecipeScraperPermanentResourcesProd-OpenAiResponsesTableArn
          - Effect: Allow
            Action:
              - states:SendTaskSuccess
              - states:SendTaskFailure
            Resource: ${self:resources.Outputs.ProcessIngredientsStepFn.Value}
  # iternal processing
  assemble-recipe:
    handler: functions/assemble_recipe/handler.handler
    environment:
      RECIPES_TABLE_NAME: !ImportValue RecipeScraperPermanentResourcesProd-RecipesTableName
      NOTIFICATION__BODY: ${param:recipeReadyNotificationBody}
      NOTIFICATION__TITLE: ${param:recipeReadyNotificationTitle}
    iam:
      inheritStatements: true
      role:
        statements:
          - Effect: Allow
            Action:
              - dynamodb:GetItem
              - dynamodb:PutItem
            Resource: !ImportValue RecipeScraperPermanentResourcesProd-RecipesTableArn
          - Effect: Allow
            Action:
              - sns:Publish
              - sns:DeleteEndpoint
            Resource: ${env:SNS_ANDROID_PLATFORM_APPLICATION_ARN}
  parse-ingredient-start:
    handler: functions/parse_ingredient_start/handler.handler
    environment:
      AI__API_KEY: ${env:AI_API_KEY}
      AI__BASE_URL: ${param:aiBaseUrl}
      AI__MODEL_NAME: ${param:aiModelName}
      PROMPT_ID__PL: ${param:promptIdPL}
      PROMPT_ID__EN: ${param:promptIdEN}
      DYNAMO_RESPONSES_TABLE_NAME: !ImportValue RecipeScraperPermanentResourcesProd-OpenAiResponsesTableName
    iam:
      inheritStatements: true
      role:
        statements:
          - Effect: Allow
            Action:
              - dynamodb:PutItem
            Resource: !ImportValue RecipeScraperPermanentResourcesProd-OpenAiResponsesTableArn
  parse-ingredient-success:
    handler: functions/parse_ingredient_success/handler.handler
    environment:
      AI__API_KEY: ${env:AI_API_KEY}
      AI__BASE_URL: ${param:aiBaseUrl}
      MAX_RETRY_COUNT: ${param:maxAiParseRetryCount}
      DYNAMO_RESPONSES_TABLE_NAME: !ImportValue RecipeScraperPermanentResourcesProd-OpenAiResponsesTableName
    iam:
      inheritStatements: true
      role:
        statements:
          - Effect: Allow
            Action:
              - dynamodb:GetItem
              - dynamodb:DeleteItem
            Resource: !ImportValue RecipeScraperPermanentResourcesProd-OpenAiResponsesTableArn
  parse-ingredient-fail:
    handler: functions/parse_ingredient_fail/handler.handler
    environment:
      DYNAMO_RESPONSES_TABLE_NAME: !ImportValue RecipeScraperPermanentResourcesProd-OpenAiResponsesTableName
    iam:
      inheritStatements: true
      role:
        statements:
          - Effect: Allow
            Action:
              - dynamodb:DeleteItem
            Resource: !ImportValue RecipeScraperPermanentResourcesProd-OpenAiResponsesTableArn
  parse-ingr-prep-retry:
    handler: functions/parse_ingredient_prepare_for_retry/handler.handler
    environment:
      DYNAMO_RESPONSES_TABLE_NAME: !ImportValue RecipeScraperPermanentResourcesProd-OpenAiResponsesTableName
    iam:
      inheritStatements: true
      role:
        statements:
          - Effect: Allow
            Action:
              - dynamodb:GetItem
            Resource: !ImportValue RecipeScraperPermanentResourcesProd-OpenAiResponsesTableArn
# used within processIngredients state machine definition file
custom:
  parseIngredientStartFnName: !Ref ParseDashingredientDashstartLambdaFunction
  parseIngredientFailFnName: !Ref ParseDashingredientDashfailLambdaFunction
  parseIngredientSuccessFnName: !Ref ParseDashingredientDashsuccessLambdaFunction
  assembleRecipeFnName: !Ref AssembleDashrecipeLambdaFunction
  parseIngredientFailNotificationSNSTopic: !ImportValue RecipeScraperPermanentResourcesProd-OutOfCreditsAdminNotificationsTopic
  prepareForRetryFunctionArn: !Ref ParseDashingrDashprepDashretryLambdaFunction
  pythonRequirements:
    useUv: true
    dockerizePip: non-linux
  customDomain:
    domainName: ${param:domainName}
    stage: prod
    basePath: prod
    createRoute53Record: false
    createRoute53IPv6Record: false
    endpointType: REGIONAL
    apiType: http
    autoDomain: true
    certificateArn: ${env:DOMAIN_CERTIFICATE_ARN}
stepFunctions:
  stateMachines:
    processIngredients:
      name: ProcessIngredients
      definition: ${file(functions/process_ingredients/stateMachine.asl.yml)}
layers:
  shared:
    path: lib
    compatibleArchitectures:
      - arm64
    compatibleRuntimes:
      - python3.13
resources:
  Description: "CloudFormation functions template for ${self:service}"
  Resources:
    Gateway:
      Type: AWS::ApiGatewayV2::Api
      Properties:
        Name: Gateway
        ProtocolType: HTTP
        DisableExecuteApiEndpoint: true
      DeletionPolicy: Retain
      UpdateReplacePolicy: Retain
    GatewayStage:
      Type: AWS::ApiGatewayV2::Stage
      Properties:
        ApiId: !Ref Gateway
        StageName: prod
        AutoDeploy: true
    GatewayDomainMapping:
      Type: AWS::ApiGatewayV2::ApiMapping
      Properties:
        ApiId: !Ref Gateway
        DomainName: ${param:domainName}
        Stage: prod
      DependsOn: GatewayStage
    ApiGatewayAuthorizer:
      Type: AWS::ApiGatewayV2::Authorizer
      Properties:
        AuthorizerResultTtlInSeconds: 0
        IdentitySource:
          - $request.header.Authorization
        Name: cognito-authorizer
        ApiId: !Ref Gateway
        AuthorizerType: JWT
        JwtConfiguration:
          Audience:
            - Fn::ImportValue: RecipeScraperCognitoProd-UserPoolClient
          Issuer:
            Fn::Join:
              - ""
              - - "https://cognito-idp."
                - "${opt:region, self:provider.region}"
                - ".amazonaws.com/"
                - Fn::ImportValue: RecipeScraperCognitoProd-UserPool
  Outputs:
    ProcessIngredientsStepFn:
      Value: !Ref ProcessIngredients
    Gateway:
      Value: !Ref Gateway
      Export:
        Name: !Sub "${AWS::StackName}-Gateway"
    ApiEndpoint:
      Value: !GetAtt Gateway.ApiEndpoint
      Export:
        Name: !Sub "${AWS::StackName}-ApiEndpoint"
plugins:
  - serverless-step-functions
  - serverless-domain-manager
Reactions are currently unavailable

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions

    Morty Proxy This is a proxified and sanitized view of the page, visit original site.