Declaring resources in multiple files in Serverless framework - serverless-framework

Is there any way to split the resource definitions in serverless framework into multiple files? Something like:
resources:
- ${resources/base.yml}
- ${resources/foo.yml}
I have been trying multiple combinations but I keep getting errors about references not being found.

Even though dashmug's answer is correct, I found that the way I was trying to make it work was quite close to a valid solution too. As explained in this github comment it is possible to reference other files in the resources section:
resources:
- ${file(resources/first-cf-resources.yml)}
- ${file(resources/second-cf-resources.yml)}
Provided that each those files defines a "Resources" key of its own, like:
---
Resources:
MyCFResource:
Type:.....
What I didn't manage is to have a mixed approach such as:
resources:
- ${file(resources/first-cf-resources.yml)}
- ${file(resources/second-cf-resources.yml)}
SomeResource:
Type: ...
So I just have a resources/base.yml for that instead.

I can't comment but I'd like to extend Jesuspc's answer.
There is a way to achieve that 'mixed' approach, in serverless.yml:
resources:
- ${file(resources/first-cf-resources.yml)}
- ${file(resources/second-cf-resources.yml)}
- Resources:
SomeResource:
Type: ...
In this case files first-cf-resources.yml and second-cf-resources.yml must have the next structure:
Resources:
SomeResourceA:
...
AnotherResourceB:
...

Take note that the resources property has to be an object containing a Resources property, NOT an array of resources like what you wanted in your code snippet.
So, to use external file references, you can do something like...
resources
Resources:
UsersTable: ${file(../resources/base.yml):UsersTable}
FooTable: ${file(../resources/foo.yml):FooTable}
Reference: Reference variables in other files

Related

Define variables per folder in dbt

I'm trying to have a structure to run a dbt project, where I have multiple entities (bank, names, cars). I'm going to have exactly the same code for them all.
Based on that, I'm trying to have several folder with the same code, where I can define inside the dbt_project.yamlfile. The idea is something like this:
vars:
db_name: 'db_official'
staging:
bank: 'variable_bank'
car: 'variable_car'
name: 'variable_name'
The variable "db_name" works. So, my the two problems I'm having are:
How to have this structure inside the the yaml file?
How to reference this structure inside each file?
(extra) Any other ideas how to handle this?
Thanks!
vars are basically globals. They can be scoped to your whole project, or to a package within your project, but not more specifically than that (they share a flat namespace). See the docs.
I would pull out the common code into a macro, then call that macro from each model file, passing in the unique values as string literals in the model file:
-- models/staging/bank.sql
{{ my_model_template('variable_bank') }}
-- models/staging/car.sql
{{ my_model_template('variable_car') }}

Combine properties in serverless.yml

I have a custom section in serverless.common.yml, which is common to all the services. Some services use some additional properties in their serverless.yml appart from the defined in the file mentioned before.
My idea would be to perform something like:
custom:
- ${file(../serverless.common.yml):custom}
- myServiceCustomProperty: 1
But this does not work. Any idea about how can I achieve that behaviour?
Thank you
- ${file(../serverless.common.yml):custom} is going to dump the array from common so that wont merge. With this approach you need to add each property from the common/custom section individually:
custom:
- foo: ${file(../serverless.common.yml):custom.foo}
- myServiceCustomProperty: 1
or
custom: ${file(../serverless.common.yml):custom}
Alternatively if your setup is complex you can write a serverless.js file instead which allows JS processing. I personally use that to programically merge a dozen yml file - for example when I run sls offline I want to add/remove a bunch of stuff so that's a pretty powerful approach.

Using variables in Serverless resource name

In my serverless.yml I have:
public-function:
handler: function.Handler
I want to parametrise the public-function line but I'm not sure how to do this. I know I can add a name: attribute to the function and use the ${} syntax documented at https://www.serverless.com/framework/docs/providers/aws/guide/variables/ but this only half solves my problem as public-function is used by Serverless as a basis for the names of other resources which I also want to have parametrised names.
Is there some way of using variables in the resource name?
The declared function key (i.e. public-function) is only a reference in the stack. There is no reason to change it at build time as the name is arbitrary.
If you want to customise the details of the deployed function, change its configuration.
For example, change the name of the function to something else using environment variables:
functions:
main:
handler: function.Handler
name: ${self:provider.stage}-${env:FUNCTION_NAME}
If you are exporting the resource to another stack, you can define the export name like so:
resources:
Outputs:
MainFunction:
Value:
Fn::GetAtt: [MainLambdaFunction, Arn]
Export:
Name: ${self:provider.stage}-${env:CUSTOM_EXPORT_NAME}
The stage scoping to both of these examples is recommended but not required; you can name your functions, resources, and outputs anything you want.

How to make resource in Serverless Framework reusable?

I am trying to set up my serverless.yml file with only an API Gateway, and there are several resources that I need to reuse throughout the file, and I'd like to not copy and paste the same lines of code per resource like 100 times.
For example, I want to reuse TestId resource below and dynamically pass in the Ref under ParentId so I can reuse the resource for multiple parent resources. How can I do that?
TestResource:
Type: AWS::ApiGateway::Resource
Properties:
ParentId:
Fn::GetAtt:
- TestApi
- RootResourceId
PathPart: test
RestApiId:
Ref: TestApi
TestId:
Type: AWS::ApiGateway::Resource
Properties:
ParentId:
Ref: TestResource
PathPart: '{id}'
RestApiId:
Ref: TestApi
Ideally I would want the resuable TestId resource in a separate file and then reference it, and also pass in the dynamic value that I want to insert in. Something like:
TestId: ${file(testid.yml):TestId} somehow override the TestId.Properties.ParentId.Ref: <somevalue>
Does anyone know if this is possible?
In case you are using NodeJs (if not maybe something like this exists in your programming language), I think you should take a look at this plugin : https://www.npmjs.com/package/yamlinc
It allow to compose YAML files using $include tag.
Hope this helps you.

Multiple identical named Resource-Files in a VB.NET project

Related: What could cause Visual Studio / C# error MSB3105: Duplicate resources
I'd like to have multiple identical named resource files in my project, all separated via the Namespace. The following setup:
Project
- Namespace1 [also a Folder]
- MyResourceFile.resx
- Namespace2.SubNamespace1 [two folders]
- MyResourceFile.resx
This is easily possible by setting Namespace-property of the resource files to the correct namespaces. Unfortunately this will bring the compiler to a halt:
The item obj\x86\Debug\Project.MyResourceFile.resx was specified more than once in the "Resources" parameter. Duplicate items are not supported by the "Resources" parameter.
As it seems, Resource-Files are compiled into a file called ProjectNameSpace.Filename.resx, which is a problem if you want to have multiple identical named resource files in different namespaces.
Does somebody know how I can change that behavior?
The reason why I want this is because I want to store SQl-Statements in resource files. The datalayer of my application is hidden behind interfaces which allow multiple implementations, therefor I thought of the following structure:
Project
- ModuleNamespace
- IData.vb
- Datas
- MySQL
- Data.vb (Implementation of IData)
- Queries.resx
- SQLite
- Data.vb
- Queries.resx
- and so on...
I would have added those queries to a simple class-file and used that, but in that Project I'm using VB.NET...which adds a little pain to have a string span multiple lines...