qalis
qalis

Reputation: 1543

Serverless Framework - environment variables from file and manual

I have Serverless Framework function for AWS Lambda. I have secrets in AWS Secrets Manager (SSM) Parameter Store and other environment variables in local .yml files, for separate deployments (dev, stg, prod).

How can I use environment variables from both file and SSM?

Only secrets work:

functions:
  kinesisEvents:
    handler: kinesis_events_processing.lambda_handler
    name: kinesis-events-${self:provider.stage}
    package: {}
    maximumRetryAttempts: 2
    events:
      - stream:
          type: kinesis
          ... # omitted a few things
    environment:
      DB_PASSWORD: ${ssm:/${self:provider.stage}/db/db_password}
      API_KEY: ${ssm:/${self:provider.stage}/api/internal_api_key}

And only file also works:

functions:
  kinesisEvents:
    ... # as above
    environment:
      ${file(${self:provider.stage}.yml):}

But how can I combine those, so I have all those variables set as env vars in final deployment? I tried this, but it does not work and throws error during deploy:

functions:
  kinesisEvents:
    ... # as above
    environment:
      DB_PASSWORD: ${ssm:/${self:provider.stage}/db/db_password}
      API_KEY: ${ssm:/${self:provider.stage}/api/internal_api_key}
      ${file(${self:provider.stage}.yml):}

Upvotes: 1

Views: 1919

Answers (2)

gvanto
gvanto

Reputation: 2083

I tried @qalis's answer but getting (in BitBucket build pipeline): "Cannot parse "serverless.yml": cannot merge mappings; the provided source object is unacceptable in "/opt/atlassian/pipelines/agent/build/serverless.yml" (12:5)"

service: {project}-14-dkr

env_vars: &env_vars
  ${file(./config/serverless/config.${self:provider.stage}.json):}

provider:
  name: aws
  stage: ${opt:stage, 'local'}
  region: eu-west-1
  environment:
    <<: *env_vars
    RUNTIME_AWS_ACCESS_KEY_ID: ${param:runtimeAwsAccessKeyId}
    RUNTIME_AWS_SECRET_ACCESS_KEY: ${param:runtimeAwsSecretAccessKey}

Upvotes: 0

qalis
qalis

Reputation: 1543

I found answers here, here and here. Basically, Serverless Framework has no particular support for this feature. However, it supports extended YAML syntax, which has anchor and dictionary merging capabilities.

So first I unpack the env vars from YAML config file, at the top of the file, and anchor it with &env_vars (like a variable for referencing, but in YAML):

env_vars: &env_vars
  ${file(${self:provider.stage}.yml):}

functions:
  ...

And then I use it, unpacking this dictionary:

    environment:
      <<: *env_vars
      DB_PASSWORD: ${ssm:/${self:provider.stage}/db/db_password}
      API_KEY: ${ssm:/${self:provider.stage}/api/internal_api_key}

Upvotes: 2

Related Questions