The Stripe samples are great ways to see how to build payments into your web app. This article will show you how to use Terraform, a popular infrastructure-as-code software tool, to deploy a Stripe sample to AWS.
But why use Terraform? Terraform lets you provision API objects with specific attributes, such as EC2 instances, Lambda functions, etc. through a declarative configuration language. It’s also very flexible: it can simultaneously manage multiple different providers, as opposed to CloudFormation, which is only limited to AWS. You can even write your own Terraform provider for any API, and publish it to the open-sourced Terraform Registry!
Before you begin
- You will need an AWS account with Identity and Access Management (IAM) credentials. Specifically, you will need an AWS Access Key ID and Secret Access Key (refer to the “Programmatic access” section of the AWS security credentials documentation for detailed instructions on how to retrieve them).
- You will also need a Stripe account.
- Follow the instructions to install Terraform.
- Clone the terraform-checkout-one-time-payments repository to walk through the example steps. (This repository builds off of the original checkout-one-time-payments Stripe sample repository.) You will have to follow the steps for running locally.
- [Important] The steps in this tutorial assume that you are running the Stripe sample with HTML and a JavaScript (Node) server implementation. So when you clone and configure the sample, be sure to choose these options.
High-level overview
We will use Terraform to provision many necessary AWS resources to host the app, which have been defined in main.tf
in the terraform-checkout-one-time-payments repository. At a high level, we are creating a Lambda function that will handle API queries and connect to the AWS API Gateway service, which will also display the frontend of the app. Each of these resources is defined in its own resource
block, like so:
resource "aws_api_gateway_rest_api" "expressapi" {
body = jsonencode({
openapi = "3.0.1"
info = {
title = "ExpressApi"
version = "1.0"
}
paths = ...
})
binary_media_types = [ "*/*" ]
name = "ExpressApi"
}
resource "aws_lambda_function" "expresslambdafunction" {
...
}
// ... other resources
In addition to the new main.tf
file, the other major difference between the deployment tutorial repository and the original checkout-one-time-payments repository is the restructuring of the code directory tree. This is necessary for webpack to build and bundle the application.
Deploying with Terraform
Step 1
Run npm build
to initiate the build process and create the dist
folder, which will come in handy in the next step.
Step 2
Now we need to prepare the code to be uploaded to the AWS Lambda function. Create one zip file containing all of the contents in the dist
directory, but do not zip the dist
directory itself. Name it whatever you’d like; running the Terraform script will later prompt you to input the name of the zip file you’d like to upload into Lambda. An example Linux command that you could run to do this would be:
cd dist && zip -r ../out.zip .
This will create a zip file titled out.zip
in the root folder.
Step 3
You are almost ready to initialize terraform! Before you continue, you will first have to use your IAM credentials to authenticate the Terraform AWS provider. Retrieve your AWS Access Key ID and Secret Access Key (refer to the “Programmatic access” section of the AWS security credentials documentation for detailed instructions). Then, in a .env
file, correspondingly set the AWS_ACCESS_KEY_ID
and AWS_SECRET_ACCESS_KEY
.
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
Step 4
Now you can begin using Terraform commands!
While you are in the root directory, run terraform
init
, which will download the necessary providers and initialize Terraform.
Step 5
Then, apply the AWS configurations using terraform apply
. This will create all of the needed AWS resources for deployment.
Step 6
Enter the name of the zip file you created in the previous step when the Terraform CLI prompts you to do so. This will kick off the process of creating an API Gateway, Lambda function, and IAM roles. Once finished, it will output a few URLs:
lambda_function_console_url
: The URL to the created Lambda function overview
api_gateway_console_url
: The API Gateway console, where you can view all created API Gateway REST APIs — the newly created one will be called “ExpressApi” if you didn’t rename it inmain.tf
api_url
: The API endpoint itself where you can try out the Stripe sample
Step 7
At this point, you should be almost done, however, the DOMAIN
environment variable still needs to be set so that the app will know which URL to redirect to once finishing the payments flow.
Unfortunately, the DOMAIN
cannot be known ahead of time before provisioning the API endpoint URL, and there is no way (yet) to declare using the output URL as the input to the Lambda function in Terraform. So, to get around this, paste the URL after the first call to terraform apply
as the DOMAIN
environment variable in main.tf
.
Navigate to main.tf
, copy the value of api_url
and paste it as the DOMAIN
environment variable under the "aws_lambda_function" "expresslambdafunction"
resource, then copy the rest of the environment variables from server/.env
. Run terraform apply
again to update with these changes.
The app should now be ready! Visit the api_url
to view the running app.
Wrap up
In this article, you learned how to deploy an existing Stripe sample application to AWS by using the checkout-one-time-payments sample as a walkthrough. You also initialized (terraform init
) and ran (terraform apply
) a Terraform script (main.tf
) to automatically provision the resources needed for the deployment.
This tutorial just scratches the surface of what you can do with Terraform. For further exploration, consider these resources:
- Official Terraform Tutorials: learn about CLI commands, the Terraform Configuration Language syntax, writing modules, provisioning infrastructure, and Terraform state
- Terraform Registry: browse the different resources types that existing providers can provision for you today
An official Terraform provider for the Stripe API is also currently in the works. We hope to publish it to the Terraform Registry soon. This will allow you to define and manage Stripe objects in your own Terraform files. A great use case for this would be creating and maintaining your webhook endpoints.
We’d also love to hear what you think of this tutorial and if there are other interesting ways that you use Terraform!
About the author
Erika Tan is an intern at Stripe on the Sandboxes team. Her favorite hobbies outside of work are reading and trying new restaurants.
Top comments (0)