Sure, you can only manage AWS cloud components with Serverless. But why you, when Terraform was designed to do it better? By default, they do not integrate. Follow this guide to learn how to bridge between Serverless and Terraform in 3 ways to handle infrastructure work more efficiently.
Dear Cloud Providers, What are Terraform and Serverless good for?
Terraform Is an “infrastructure as code” tool used to manage the lifecycle of cloud components. You write code that defines the cloud infrastructure, then Terraform maps it to actual resources like databases, virtual networks, event buses and so on.
The framework without servers Is a command line tool that can handle a cloud infrastructure (just like Terraform) but serves as a place where you create code. Once the code is deployed, no server interacts with cloud components to execute business logic. However, it is not without its drawbacks.
Separation of dependence
Imagine you have multiple applications where everyone has to interact with cloud components to get their work done. Moreover, each of them may sometimes need to change some part of the infrastructure.
Suppose you have cloud component settings associated with application A. Now, whenever application B, C or D needs to change the cloud infrastructure, you will need to make changes to application A.
It is really inconvenient and completely contrary to the principle of sole responsibility.
The solution here is to create a separate entity that will only retain the definition of the cloud infrastructure. It is best to list it in a tool for this very purpose – like Terraform.
Which tool is better for dealing with state change?
Because Terraform acts as an “infrastructure as code,” it can create an execution plan before changes are approved. When you’re not sure what will happen after the infrastructure setup is deployed, you can ask Terraform to simulate changes.
Unfortunately, the Serverless Framework does not support this out-of-the-box mechanism. In order for you to have it, it will require a detour. Let’s go for a clean solution – let me show you how to combine the two tools.
Why Terraform and Serverless fusion is a problem
Suppose you have an application written on the Serverless Framework where a single lambda must be executed each time a record is added to DynamoDB. It can look something like this.
Configuration for the Serverless Framework application
Dummy therapist
I used CloudFormation Fn::GetAtt
Function to tell lambda which DynamoDB stream he should subscribe to. The function returns a value of a attribute StreamArn
From the resource ExampleTable
.
run serverless deploy
At the system terminal and to AWS console -> Lambda -> Functions -> blog-post-dev-hello
. See that our Lambda was successfully created and subscribed to the DynamoDB stream.
![](https://tsh.io/wp-content/uploads/2021/12/2.-Lambda-subscribe.png)
The serverless framework was able to resolve Fn::GetAtt: [ExampleTable, StreamArn]
Without any problems because we wrote the cloud and function components in the same app.
Now, let’s move our DynamoDB setting to the Terraform application. First, we will delete our current app to avoid later collisions by executing serverless remove
. We then create a new Terraform app with one file.
But what about our Serverless Framework app?
As you can see, we’ve lost the logical name of ExampleTable
And we can not use Fn::GetAtt
at all. What can we do?
The Dirty Way: Use Encoded Values
The simplest solution is DynamoDB hard code to stream ARN. so! Deploy your infrastructure. In your Terraform application, follow terraform init
and terraform apply
. Now you can go to AWS console -> DynamoDB -> Tables -> example_table -> Exports and streams
There you will find our DynamoDB ARN stream.
![](https://tsh.io/wp-content/uploads/2021/12/4.-Dynamo-stream-ARN.png)
Let’s copy this entry and paste it serverless.yml
.
Then, we can deploy the Serverless Framework application with serverless deploy
See the lambda subscribe again to the DynamoDB stream.
But hold on! We had to perform many more steps to get the same solution offered by Serverless Framework. Is there a better way to do this?
The standard way: work with the system administrator’s parameter database
A simpler solution to automatically inject DynamoDB ARN – just as the serverless framework does – is to use AWS ‘Systems Manager Parameter Store. This service is a simple container with the aim of storing configuration data of your applications. Let’s take advantage of it!
Add the following code to the Terraform app.
I set a new Store parameter name there /blog-post/example-table-stream-arn
And the value of the DynamoDB ARN as stream aws_dynamodb_table.this.stream_arn
. Let’s see how I built this entry.
aws_dynamodb_table
Is a kind of resource, this
Is the name of a resource, and stream_arn
Is one of the many features that this resource reveals. You can find the whole list of these features In Terraform’s documentation.
Okay, now that you know what else, launch a layout with terraform apply
. Check if the resource is created by switching to AWS console -> Systems Manager -> Parameter Store -> /blog-post/example-table-stream-arn
.
![](https://tsh.io/wp-content/uploads/2021/12/5.-Parameter-store.png)
Now, you need to tell the Serverless Framework application how to retrieve this data. Serverless provides a series of special variables that are resolved to different values after deployment. One of these variables relates to the administrator database: ${ssm:NAME_OF_PARAMETER_STORE}
Add the syntax to the Serverless Framework application.
Deploy the app with serverless deploy
And saw that the lambda function was successfully registered to the DynamoDB stream again.
Nice! Now you know how to solve the problem using the admin database. But, surprise, there is another approach you can use! Let’s look at another scenario.
The Exotic Way: Connecting via AWS CloudFormation Outputs
Imagine you have to announce the infrastructure using an original CloudFormation template. The template is exactly the same template used to announce the infrastructure within the Serverless Framework.
Because of the limitations of the CloudFormation template, you lose access to resource attributes. Now you can not use resource.resource_name.resource_attribute
To bring the ARN current. Remove the issue using CloudFormation Outputs.
The outputs are an optional section in the CloudFormation templates where you can declare values that will be used as cross-references. This means you can choose which features of our infrastructure we want to be easily removable.
Adding DynamoDB’s ARN stream to the output section looks like this.
Now, remove the current Terraform app to prevent Stem condition Between creating a new database and removing the old one. run terraform destroy
. Then, you can deploy our beauty safely terraform apply
.
Now refer to the CloudFormation Outputs variable in the Serverless Framework application. cf:STACK_NAME.OUTPUT_KEY
He syntaxed it. In our case, it should look like this.
Slice it with serverless deploy
, After all, the lambda function is again registered to the DynamoDB stream.
Remember the 3 ways
You may find other approaches to connecting the Serverless Framework with Terraform. During the development of a large spacecraft project, I relied on the three described in the guide:
- Hard coding of ARN DynamoDB stream
- Retrieving data from the AWS systems manager parameter store
- Connect through CloudFormation ports to a serverless framework
I hope they will serve you as they served me. Utilize them well and successfully 🙂