Fn::GetAtt not resolving
HoneyryderChuck opened this issue · comments
I've tried to use this lib (very useful, btw) to generate my .env to run migrations in continuous deployment. However, the database is postgresql, which means that getting the address involves a look-up using Fn::GetAtt:
Fn::GetAtt:
- MyDB
- Endpoint.Address
From what I got in the README, it's still to be implemented. Could you share the timeline for the feature, and eventually what's the stumbling block?
Hi - I was interested in the same feature
Having a look through how resolveCloudFormationEnvVariables.js
it doesn't seem easy as there is no AWS API Cloudformation call to replicate the behaviour of what Fn:GetAtt does at stack deployment time?
@arabold I've taken the approach of falling through any unknown CF types to already set env variables here that works for our team.
We then use direnv to set these dynamically into the local shell environment using AWS cli + jq.
So far working well for both
serverless offline start
serverless invoke local -f function
I've also taken a look and it's not straight forward to support GetAtt::
. If you can, you should use Ref: MyDB
instead as that should resolve without issues. You can also try using Fn::ImportValue
as an alternative.
@herebebogans I'm not sure if I'm a fan of falling back to global environment variables. It might have unforeseen consequences as things aren't fully predictable anymore. I wanted to have the .env
file resemble your Lambda configuration as closely as possible.
Does anybody have a suggestion for a decent workaround, until this is implemented? My .env
file currently looks like this
companiesTableName=dev-companies
vehiclesTableName=dev-vehicles
region=eu-west-1
searchIndexEndpoint=[object Object]
The search index is defined like
Resources:
SearchIndex:
Type: AWS::Elasticsearch::Domain
Properties:
And my serverless.yml looks like this
provider:
name: aws
runtime: nodejs8.10
stage: dev
region: eu-west-1
environment:
companiesTableName:
Ref: CompaniesTable
vehiclesTableName:
Ref: VehiclesTable
region: ${self:provider.region}
searchIndexEndpoint:
Fn::GetAtt: [SearchIndex, DomainEndpoint]
And of course I want to have access to it in my lambda functions without hardcoding the endpoint. What's the best solution?
I temporarily solved it like this:
in serverless.yml
custom:
searchIndexEndpoint:
Fn::GetAtt: [SearchIndex, DomainEndpoint]
provider:
searchIndexEndpoint: ${opt:searchIndexEndpoint, self:custom.searchIndexEndpoint}
Then I can do like this when I test locally.
$ sls invoke local -f myFunction --path mocks/myFunction.json --searchIndexEndpoint="some-url.es.amazonaws.com"
v1.4.0 contains a new feature to read environment variables directly from the CloudFormation output. This can work as a workaround to this issue. See the conversation here: #21
Unfortunately, this workaround solution does not work for the new HTTP API in API Gateway.
my config:
custom:
...
apiGatewayEndpointUrl:
Fn::GetAtt: [HttpApi, ApiEndpoint]
#HttpApi is a logical name of a resource that is created by SF under the hood
functions:
createItem:
handler: src/createItem/function.handler
description: Create Item in repository
memorySize: 128
timeout: 5
environment:
tableName: ${self:custom.tableName}
createItemEndpoint: ${self:custom.apiGatewayEndpointUrl}/item
events:
- httpApi:
method: POST
path: /item
Trying to deploy this I get following error
Trying to populate non string value into a string for variable ${self:custom.apiGatewayEndpointUrl}. Please make sure the value of the property is a string.
v2.0.0 (not released to npm
yet) will support Fn::GetAtt
and other intrinsic functions.
https://github.com/arabold/serverless-export-env/tree/v2.0.0
To simplify testing the new version, I've published 2.0.0-alpha.0
as alpha release to npm
:
npm install serverless-export-env@2.0.0-alpha.0 --save-dev
I'm closing this task. Please open a new one (or comment on this one) if your problems are still not solved.