serverless / compose

Orchestrate Serverless Framework in monorepos
https://serverless.com/framework/docs/guides/compose
MIT License
111 stars 15 forks source link

Params not being resolved properly #96

Closed r-token closed 2 years ago

r-token commented 2 years ago

I’m having issues with params I set within the serverless-compose.yml file.

Scenario: I output ARNs from various services and reference them in other services within the IAM role statements block.

However, when deploying my services with Compose, I get an error that says Resource ${services/my-service.MyOutput} must be in ARN format or "*".

This was working fine when I used CloudFormation imports via Fn::ImportValue from each service. But when trying to use Compose’s params, it looks like the param is not being resolved to the actual ARN. It’s just showing as the literal param value of ${services/my-service.MyOutput}

My guess is that this is happening because all of my services live within a services directory, not at the root (where the compose file is). If that's all it is, I can move my serverless-compose.yml file to inside the services directory for now. Does the serverless-compose.yml file need to live at the same level as the services themselves?

Example:

# serverless-compose.yml (at project root)

services:
  my-service:
    path: services/my-service

  my-second-service:
    path: services/my-second-service
    params:
      tableOne: ${services/my-service.TableOneArn}
      tableTwo: ${services/my-service.TableTwoArn}
    dependsOn:
      my-service
# serverless.yml for my-second-service (at services/my-second-service)

provider:
  iam:
    role:
      statements:
        - Effect: "Allow"
          Action:
            - dynamodb:GetItem
            - dynamodb:PutItem
          Resource:
            - ${param:tableOne}
            - ${param:tableTwo}

Deploying this with Compose will return an error that says Resource ${services/my-service.TableOneArn} must be in ARN format or "*"

r-token commented 2 years ago

My guess is that this is happening because all of my services live within a services directory, not at the root (where the compose file is). If that's all it is, I can move my serverless-compose.yml file to inside the services directory for now. Does the serverless-compose.yml file need to live at the same level as the services themselves?

This was indeed the problem. Moving the serverless-compose.yml file to inside the services directory and adjusting the params to just be ${service.output} instead of ${services/service.output} resolved this.

If you're open to it and it's a feasible possibility, I can create an RFC that outlines my request for the serverless-compose.yml file be able to reference services that live in a different directory. I assume this may be a heavier lift than I think, as it would probably require work on the Stage Parameters feature as well. Let me know what you think.

pgrzesik commented 2 years ago

Hey @r-token - I don't think you need to move the serverless-compose.yml file. When referencing outputs of services, you should reference the service via its identifier (so it your case my-service, my-second-service), not its path, so for example in the first case, instead of

params:
      tableOne: ${services/my-service.TableOneArn}

it should be

params:
      tableOne: ${my-service.TableOneArn}
r-token commented 2 years ago

Ah, that worked! Oddly enough, that's originally how I had it set up, but I was getting errors back then that said the outputs couldn't be found at each service. I must've had something else configured incorrectly at that point.

Everything's looking great now. Thank you! This is such a boost for our monorepo.

mnapoli commented 2 years ago

Glad to see this resolved! Should we close this issue?

r-token commented 2 years ago

My issue was resolved, so that sounds good to me.