DEV Community

Cover image for The ambiguous export/import of resources between cross AWS stacks using serverless ('' o)
Ahmed Zeno
Ahmed Zeno

Posted on

The ambiguous export/import of resources between cross AWS stacks using serverless ('' o)

SO i exported my resources from stack A and i wanna use it in Stack B and precisely i wanna pass it to my lambda function …mmm what to do

Will first i've tried what the aws console saying about this
U can have a quick look its kinda helpful to understand the basic principles behind the cross stack shared resources :

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-importvalue.html

Unfortunately this is didn't work for me so i checked the 2nd option which is trying to list all exported resources(variables) inside my cloudformation stack using the aws sdk inside my lambda and you could do that using the following code

const aws = require('aws-sdk')

var params = {
NextToken: ''
};
var cloudformation = new AWS.CloudFormation();
cloudformation.listExports(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log("cloudformation ",data); // successful response
});

But this was a bad solution too much things to display and too much thing to expose

..mm what is next

So what would be the right way to do that ?

First let me explain the situation we are importing resources called UserPool that is being exported to the cloud formation from another repo and another stack

Like this
.
.

userPool:
production:
Fn::ImportValue : yourProjectName-production-UserPool
staging:
Fn::ImportValue : yourProjectName-staging-UserPool
other:
Fn::ImportValue : yourProjectName-dev-UserPool
.
.

This is located in file cognito.yml and inside our serverless.yml we have a custom variable to reference it.

Like this

.
.
userPool: ${file(./config/resources/cognito.yml):userPool}
.
.

Now, the problem was to be able to pass this user pool id to a Lambda function
To do some stuff there

The api was defined in the serverless.yml file as following, and using the static pool id was working probaly
.
.
list-owners:
memorySize: 1024
timeout: 5
environment:
COGNITO_POOL_ID: ‘static_pool_id’
handler: src/api/get-owners.list
alarms:
- errorOccur
events:
- http:
path: ‘/path’
method: get
cors:
origin: '*'
headers: ${self:custom.list-headers}
allowCredentials: false
authorizer: ${self:custom.authorizer}
.
.
Now if use what the aws console suggested in the documentation it will the environment should look like this
environment:
COGNITO_POOL_ID: Fn::ImportValue: userPool //sharedValueToImport

But this will return you an object value like this [object object]

And the reason is because the different levels of the objects inside the .yml file

So the solution was to define a short hand to my cognito.yml file inside my custom functions

So inside the serverless.yml

And under custom i added

userPoolExportKey: ${file(./config/resources/cognito.yml):userPoolExportKey}

And when on the api that I wanted to pass it the cognito pool id based on the environment

I used it this way

list-owners:
memorySize: 1024
timeout: 5
environment:
COGNITO_POOL: ${cf:${self:custom.userPoolExportKey.${self:provider.stage}, self:custom.userPoolExportKey.other}}
handler: src/api/get-owners.list
alarms:

  • errorOccur events:
    • http: path: owners method: get cors: origin: '*' headers: ${self:custom.list-headers} allowCredentials: false authorizer: ${self:custom.authorizer}

And inside the Lambda handler, you can get the COGNITO_POOL from process.env.COGNITO_POOL

Top comments (0)