Compose Error: Cannot resolve '${param:xxx}' variable at 'provider.environment.yyyy'

Hello all -

I’m new to serverless. I hope someone can look at this and tell me what’s wrong… been reading and beating my head against the wall all day long. This has got to be something super simple…

Here’s my project definition:

serviceA/
  serverless.yml
infra/
  serverless.yml
serverless-compose.yml

serverless-compose.yml

# serverless-compose.yml
services:
  serviceA:
    path: serviceA
    params:
      region: ${infra.region}
      integrationsTable: ${infra.integrationsTable}
    dependsOn:
      - infra

  infra:
    path: infra

infra/serverless.yml

service: infra

provider:
  name: aws
  runtime: nodejs20.x
  region: us-east-1
  stage: ${opt:stage, 'dev'}
  profile: serverlessUser
custom:
 tables:
    integrationsTable: "${sls:stage}-integrations"

resources:
  Resources:
    IntegrationsTable:
      Type: AWS::DynamoDB::Table
      Properties:
        TableName: ${self:custom.tables.integrationsTable}
        ...
        ...
  Outputs:
    region: ${self:provider.region}
    integrationsTable: ${self:custom.tables.integrationsTable}

serviceA/serverless.yml

service: serviceA

provider:
  name: aws
  runtime: nodejs20.x
  region: ${param:region}
  profile: serverlessUser
  stage: ${opt:stage, 'dev'}
  environment:
    integrationsTable: ${param:integrationsTable}

functions:
  register:
  ...
  ...

From the project directory, when I run sls package, dev, info or deploy I get the following:

Packaging "infra" for stage "dev" (us-east-1)

✔ Service packaged (1s)

✔ Ran package on Service: infra

✖ Serverless Compose failed to run "package" on "serviceA"

✖ Could not resolve the parameter 'region'. Please ensure that it is correctly defined in the Compose configuration and that all dependent services are deployed. If the services are deployed, verify that their state is up to date by running 'deploy' or 'info' command on the Compose file.

When I cd into serviceA directory and try to build from there, it’s the same thing.

It is my understanding per documentation here https://www.serverless.com/framework/docs/guides/compose that Outputs defined in a service are mapped to other services by way of params

Also if I remove the region property in serviceA/serverless.yml, it stops with the same error at integrationsTable

Clearly, my params aren’t communicated to the service. Why?

What am I doing wrong here?

I’d define region (and any other shared params) in the top level file, and refer to it from the two children. Does that work any better ?

1 Like

Thanks for your reply.

I’m not sure I follow. By toplevel are you referring to serverless-compose.yml? Or some sort of shared yml file to be included/referenced in the microservices?

What I’ve figured out this:

You can’t cd into a mircroservice directory and run serverless deploy for example. The params are referenced from a neighboring service and serverless does not move up the directory chain to discover where to find the parameters. This make sense. Though it would be cool if that could be done somehow.

What does work howver is to run serverless deploy --service projectA from the parent directory. This circumvents the error because serverless considers serverless-compose.yml first in this case and resolves everything.

My understanding is you have

toplevel.yml
childA/some.yml
childB/thing.yml

All your variables should be defined in toplevel.yml