This is continuing from Part One of getting set up using Pulumi.
Software testing is generally meant to verify if one’s system is working as intended without any gaps or errors.
When it comes to the deployment of cloud infrastructure, there are quite a number of things that can go wrong. For instance, provisioning resources that handle sensitive data without specific access restrictions, or creating a resource with the intention of performing one task but not having it quite work as intended.
Thankfully, it is possible to perform tests in such situations with Pulumi.
Pulumi is an Infrastructure as Code (IaC) tool that leverages general-purpose programming languages for provisioning cloud resources with multi-cloud support. Owing to its conducive implementation, integrating with other infrastructure or configuration management tools is a simple task.
In this article, we’ll look into creating a serverless function with Pulumi’s SDK and then explore how to perform tests on the program.
Pulumi program setup and deployment.
The function we’ll create will get invoked when new entries are added to a DynamoDB table. On invocation, the function will get the text content and call the AWS Polly service for converting the text-to-speech, and then store the audio file in an S3 bucket.
Before we can write the program, the SDK needs to be installed. Follow their quick start guide here.
Python is the language we will use to write the program and perform tests. To install python if you don’t have it already, the instructions can be followed from this link.
Once the SDK and the language runtime is installed, inside an empty directory execute this command
If there are multiple AWS profiles configured with your AWS CLI, you can specify the profile that should be used by Pulumi for deployments by running,
The Pulumi program goes inside the ‘__main__.py’ file. Replace the contents of that file with this code.
In the root of your directory, create a python file that will contain the code for the function’s handler. (Be sure to match the handler value for the lambda object in the above program to the file name you create).
You can deploy the program to AWS by just executing
Based on how the program is written, Pulumi will automatically provision to reach the resource’s desired state.
Once the deployment is successful, insert any random text data into the dynamoDB table, ensuring that the content is entered against a ‘text’ attribute because the handler function is programmed to look for one. The converted text-to-speech mp3 file will be present in the bucket specified when the function finishes executing.
Testing with Pulumi:
Since these programs can be written in general-purpose programming languages, Pulumi makes it possible to take advantage of native testing frameworks for running automated tests. Pulumi supports three styles of performing automated tests for cloud programs.
The nature of these tests is to evaluate the behavior of your code in isolation. Running in-memory, the external dependencies for these tests are replaced by mocks. They are authored in the same language as the Pulumi program. The focus of these tests is not on the behavior of the cloud resources but rather on their inputs.
For instance, we can create unit tests for the above program that verify three things.
- Lambdas should have a minimum timeout of 30 sec.
- Buckets to have ‘bucket’ parameter. Meaning that bucket’s auto-naming by Pulumi should be disabled.
- DynamoDB table should have ‘stream_view_type’ attribute value as ‘NEW_IMAGE’
At the project root, make a copy of the above Pulumi program into another file. Inside a new python file place the following unit tests code.
Alter the program’s values such that tests fail. Utilizing the python’s built-in test framework, unit test, we’ll execute these tests by running the command
These tests are executed while the resources are being deployed. They are based on Pulumi’s offering called CrossGuard (Policy as code). While Policy as Code and Property Testing both use the same technology, the goals and workflows are different. As opposed to unit testing, property tests can evaluate real values returned from the cloud provider instead of the mocked ones. Property tests are limited to Node.js and Python only.
To implement property testing, create a folder ‘tests’ at project root. Create ‘__main__.py’ and ‘PulumiPolicy.yaml’ inside that folder. Install pulumi’s policy pack library by running
Add this to PulumiPolicy.yaml.
Place this inside the __main__.py of the ‘tests’ folder.
These tests verify two items: the dynamoDB table must have streams enabled for the lambda function to get invoked, and the policy attached to the lambda role must have permissions for S3 and Polly services.
To run these tests, execute
It’s only when the tests pass that deployment will proceed. This way you can ensure the created resources on the cloud are compliant with your project’s requirements.
This form of testing runs the program in combination with Pulumi CLI to deploy the resources to an ephemeral environment. After running tests on the created infrastructure, the resources are destroyed. The prime responsibility of these tests is to ensure that the project is deployed to the expected state, and the programmed logic works as intended. The duration for these tests is considerably longer (in minutes) in comparison to the above variations.
Pulumi has an extensive set of integration tests written in Go. You can utilize their Go test framework irrespective of the language your Pulumi program is written in. Although, presently, support for integration tests for other languages from Pulumi aren’t available. If you would like to explore, there is a community developed framework for python called Pitfall.
By utilizing Pulumi’s testing concepts, you can ensure that the provisioning of resources is in line with your project’s requirements and the system works as intended. Migration to Pulumi for programs created with other tools is certainly possible by following their strategy from this doc. Not only that, but Pulumi also has a tool, tf2pulumi, that converts the IaC code written for Terraform in HCL (HashiCorp Configuration Language) to a Pulumi program. They also have integrations for any continuous integration/continuous delivery (CI/CD) system. Writing infrastructure deployment programs with Pulumi is simplified because you have the option to choose the language for creating the program.