introduction
As customers increasingly seek to leverage the power of generative AI (GenAI) and machine learning to deliver cutting-edge applications, the need for flexible, intuitive, and scalable development platforms has never been greater. In this context, Streamlit has emerged as an outstanding tool, allowing developers to easily prototype, build, and deploy GenAI-powered apps with minimal effort. It’s an open-source Python framework designed to simplify the development of custom web applications for data science, machine learning, and GenAI projects. Streamlit allows developers to quickly transform Python scripts into interactive dashboards, LLM-powered chatbots, and web apps using just a few lines of code. Its unique combination of simplicity, interactivity, and speed is the perfect complement to the rapid advances in AI.
When deploying Streamlit applications, customers often face the challenge of ensuring the application is available and able to scale to meet fluctuating demand. To achieve these goals, customers are turning to a serverless approach to deploying Streamlit apps. With serverless applications, you pay only for the resources you need and don’t have to worry about server management or capacity planning.
In this post, you will learn how to automatically deploy containerized serverless Streamlit applications through HashiCorp Terraform, an Infrastructure as Code (IaC) tool that allows users to define and provision infrastructure across cloud platforms. I will explain.
Solution overview
This solution uses AWS Fargate to manage compute and run Streamlit apps on Amazon Elastic Container Service (ECS) clusters across multiple Availability Zones (AZs). Fargate is a serverless, pay-as-you-go compute engine that lets you focus on building apps without managing servers. Fargate relieves you of the undifferentiated heavy lifting that can come with building and maintaining web applications. Additionally, it is often desirable to use a content delivery network (CDN) to ensure low latency for users around the world by caching content in edge locations geographically close to where the users are. Masu.
Let’s focus on two architectures: the Streamlit app hosting architecture and the Streamlit app deployment pipeline.
Streamlit app hosting
In the above architecture, the following flow applies:
- Users access your Streamlit app using the public DNS endpoint of your Amazon CloudFront distribution.
- Using an Internet Gateway (IGW), user requests are routed to a publicly available Application Load Balancer (ALB).
- This ALB has a target group that maps to ECS task nodes that are part of an ECS cluster running in two AZs (us-east-1a and us-east-1b in this example).
- Fargate automatically scales the underlying compute nodes in your ECS cluster based on demand.
Streamlit app deployment pipeline
In the above architecture, the following flow applies:
- Users develop local Streamlit apps and define paths for these assets in module configuration. Then run terraform apply to generate a local .zip file consisting of your Streamlit app directory and upload it to your Amazon S3 bucket (Streamlit assets) using version control. It is configured to trigger the execution of a Streamlit CI/CD pipeline.
- AWS CodePipeline (Streamlit CI/CD pipeline) starts running. The pipeline copies the .zip file from the Streamlit Assets S3 bucket, stores the content in the connected CodePipeline Artifacts S3 bucket, and passes the asset to the AWS CodeBuild project that is also part of the pipeline.
- CodeBuild (Streamlit CodeBuild project) configures a compute/build environment and retrieves Python Docker images from public Amazon ECR repositories. CodeBuild uses Docker to build a new Streamlit app image based on what’s defined in the Dockerfile in your .zip file and pushes the new image to your private ECR repository. tag images
latest
,app_version
(user defined in Terraform), and S3 version ID Extract the .zip file and push the image to ECR. - ECS has task definitions that reference images in ECR. S3 version ID This tag is generated every time a new version of the file is created, so it is always unique. This also acts as a data lineage, so you can link the version of your Streamlit app .zip file in S3 to the version of the image stored in ECR. When a new image is pushed to ECR (along with a unique image tag), the task definition is updated and the ECS service starts a new deployment using the new version of the Streamlit app.
- When a new image is pushed to ECR, the Terraform module
local-exec
The provisioner runs an AWS CLI command that creates a CloudFront revocation. This allows users of the Streamlit app to use new versions without waiting for the time-to-live (TTL) of cached files to expire at the edge location (default 24 hours).
Both of these pipelines are built and packaged into Terraform modules that can be efficiently reused with just a few lines of code.
Both of these pipelines are built and packaged into Terraform modules that can be efficiently reused with just a few lines of code.
Prerequisites
This solution requires the following prerequisites:
- AWS account. If you don’t have an account, please create one.
- Terraform v1.0.0 or later is installed.
- Python v3.8 or later installed.
- Streamlit app. If you don’t already have a Streamlit project, you can download this app directory as the sample Streamlit app for this post and save it to your local folder.
The folder structure will look like this:
terraform_streamlit_folder
├── README.md
└── app # Streamlit app directory
├── home.py # Streamlit app entry point
├── Dockerfile # Dockerfile
└── pages/ # Streamlit pages
Create and initialize a Terraform project
In the same folder where the Streamlit app is saved, in the example above terraform_streamlit_folder
Let’s create and initialize a new Terraform project.
- In any terminal, create a new file named main.tf by running the following command on a Unix/Linux machine or the equivalent command on a Windows machine.
touch main.tf
- Please open
main.tf
Create a file and add the following code.module "serverless-streamlit-app" { source = "aws-ia/serverless-streamlit-app/aws" app_name = "streamlit-app" app_version = "v1.1.0" path_to_app_dir = "./app" # Replace with path to your app }
This code utilizes a module block with the source pointing to the Terraform module and the appropriate input variables passed. When Terraform encounters a module block, it uses source to load and process that module’s configuration file. The Serverless Streamlit App Terraform module has many optional input variables. If you have existing resources, such as an existing VPC, subnet, or security group, that you want to reuse instead of deploying new resources, you can reference the existing resources using input variables in the module. However, in this post, we will deploy all the resources for the above architecture from scratch. All you need to do here is define a source that references the module hosted in the Terraform registry.
app_name
Used as a prefix for naming resources.app_version
Used to track changes to the app.path_to_app_dir
This is the path to the local directory where your Streamlit app’s assets are stored. - Save the file.
- To initialize the Terraform working directory, run the following command in Terminal:
terraform init
The output includes a success message similar to the following:
"Terraform has been successfully initialized"
Output CloudFront URL
To easily access the Cloudfront URL of a deployed Streamlit application, you can add the URL as a Terraform output.
- In Terminal, create a new file named .
outputs.tf
Run the following command on a Unix/Linux machine or the equivalent command on a Windows machine.touch outputs.tf
- Please open
outputs.tf
Create a file and add the following code.output "streamlit_cloudfront_distribution_url" { value = module.serverless-streamlit-app.streamlit_cloudfront_distribution_url }
- Save the file.
Your folder structure should now look like this:terraform_streamlit_folder ├── README.md ├── app # Streamlit app directory │ ├── home.py # Streamlit app entry point │ ├── Dockerfile # Dockerfile │ └── pages/ # Streamlit pages │ ├── main.tf # Terraform Code (where you call the module) └── outputs.tf # Outputs definition
Deploy the solution
Now, using Terraform, main.tf
file.
- Apply the infrastructure deployment by running the following command in your terminal: This includes hosting your Streamlit application using ECS and CloudFront, and the pipeline used to push updates.
terraform apply
When the apply command finishes running, you’ll see Terraform output in your terminal.
- Move to.
streamlit_cloudfront_distribution_url
Check out Streamlit applications hosted on AWS. - If you have made changes to the Streamlit codebase, you can go ahead and rerun it.
terraform apply
Push new changes to your cloud environment.
When you update your Streamlit codebase, the CodePipeline and CodeBuild processes are started to automatically update your Streamlit application with new changes. CodePipeline automates the entire software release process, managing stages such as source acquisition, build, testing, and deployment. Integrate with AWS services and third-party tools, such as GitHub and Jenkins, for greater automation, speed, and security. CodeBuild focuses on automating code compilation, testing, and packaging, supports multiple languages and custom Docker environments, and integrates with CodePipeline for scalable and secure builds. With this CI/CD pipeline, all you need to do when making changes to your code is terraform apply
Update your cloud environment. For an example buildspec, see Repository Examples.
Complete examples of deploying infrastructure with and without existing resources can be found in our GitHub repository.
cleaning
If you no longer need the resources deployed in this post, you can clean them up using the Terraform destroy command. Just run terraform destroy
. This will remove all the resources you deployed using Terraform in this post.
conclusion
Building serverless Streamlit applications using Terraform on AWS provides a powerful combination of scalability, efficiency, and automation. As you continue to build and improve your Streamlit application, Terraform’s flexibility allows your infrastructure to seamlessly evolve to support rapid innovation and agile development. Streamlit and Terraform give you the tools to create dynamic serverless applications that easily scale and work reliably in the cloud.
author