This project is dedicated to providing an all-encompassing solution for hosting Streamlit applications on AWS by leveraging AWS CloudFormation and a robust Continuous Integration/Continuous Deployment (CI/CD) pipeline. By combining the power of infrastructure as code and automated deployment workflows, developers can effortlessly host and update their Streamlit apps, ensuring a seamless and efficient user experience.
This repository provides base code for Streamlit application's and is not production ready. It is your responsibility as a developer to test and vet the application according to your security guidlines.
- Developer manually deploys codepipeline.yaml stack, infrastructure.yaml is deployed as nested stack.
- Lambda triggers the CodeBuild project.
- The CodeBuild project zip's this repository content into app.zip file.
- CodeBuild copies app.zip into S3 bucket.
- app.zip PUT event triggers the CodePipeline and triggers the CodeBuild stage.
- This CodeBuild is responsible for creating a container image using the DockerFile and pushing this image into ECR.
- Deploy stage is trigged.
- Cloudformation stage deploys the deploy.yaml stack. This stack takes the new docker image URI as input. This stage creates the Hello world app. Follow steps here.
- After successfull creation of deploy.yaml stack, Cloudfront invalidate cache stage is triggered.
- Developer Customize's the Web App, zip's new content and uploads it into Amazon S3. This triggers the CodePipeline which results in new Docker image. These docker images replaces the old Fargate tasks. Follow steps here to customize app.
Note
Steps 2, 3 and 4 are run only once when Codepipeline.yaml is created. To Trigger the changes to the Streamlit web applicaiton manually follow steps here.
An AWS Account, to deploy the infrastructure. You can find more instructions to create your account here.
- Steps to Deploy Hello World App
- Steps to Customize Web App
- Streamlit Secrets Management
- Invoking AWS Services from Web App
- Clean Up
git clone https://github.com/aws-samples/aws-streamlit-deploy-cicd.git
Step 2️⃣ Open the CloudFormation console.
Create a CloudFormation Stack using the codepipeline.yaml file.
After the successful completion of CodePipeline, the deploy.yaml
cloudFormation stack is deployed. Get the CloudFront URL from the Output
of the stack named <StackName>deploy<EnvironmentName>
. Paste it in the browser to view the Hellow World app.
In order to customize the web app change the content of app.py
file.
Caution
- Do not rename the
app.py
file - Make sure to declare all packages in requirements.txt
First commit all changes
git add .
git commit -m "All Changes"
Then zip the current repository using the following command:
git archive --format=zip --output=app.zip HEAD
This will create an app.zip
file.
Upload the zip file into CodeS3Bucket
either using S3 management console or AWS CLI.
aws s3 cp app.zip s3://<CodeS3Bucket-Name>
Important
You have access to CodeS3Bucket name from Outputs
of codepipeline.yaml
cloudFormation stack
Repeat Step 2
and Step 3
with modified content.
Important
It is crucial to .gitignore files containing confidential information
Tip
- For the purpose of simplicity we are using AWS Systems Manager Parameter Store. However, when dealing with sensitive secrets such as Database credentials, the best practice is to use AWS Secrets Manager.
- If you decide to use AWS Secrets Manager for storing credentials make sure to follow stops here to give Fargate appropriate permissions.
To get more information about creating secure parameters using SSM Parameter store visit link.
Caution
- Start the parameter path with /streamlitapp
- Use SecureString parameter type while creating the parameters to encrypt the parameters
from boto3.session import Session
ssm = Session().client("ssm")
USERNAME = ssm.get_parameter(Name='/streamlitapp/EnvironmentName/USERNAME',WithDecryption=True)["Parameter"]["Value"]
Important
Replace EnvironmentName with value passed in infrastructure.yaml
Inorder to give permission to the web app to invoke AWS services add appropriate policies to StreamlitECSTaskRole-<EnvironmentName>
.
For instance, if you want to invoke Anthropic Claude V2 Bedrock model from the Streamlit app add the following policy to StreamlitECSTaskRole-<EnvironmentName>
:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Statement1",
"Effect": "Allow",
"Action": [
"bedrock:InvokeModel"
],
"Resource": [
"arn:aws:bedrock:us-east-1::foundation-model/anthropic.claude-v2"
]
}
]
}
For invoking Bedrock Agents from Streamlit app add the following policy to StreamlitECSTaskRole-<EnvironmentName>
:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Statement1",
"Effect": "Allow",
"Action": [
"bedrock:InvokeAgent"
],
"Resource": [
"arn:aws:bedrock:{Region}:{Account}:agent-alias/{AgentId}/{AgentAliasId}"
]
}
]
}
Caution
Replace {Region}, {Account}, {AgentId}, and {AgentAliasId} with valid values in the above policy
- Open the CloudFormation console.
- Select the stack
codepipeline.yaml
you created then click Delete twice. Wait for the stack to be deleted. - Delete the nested stack
<StackName>-Infra-<StackId>
created bycodepipeline.yaml
. Please ensure that you refrain from deleting this stack if there are any additional web deployments utilizing this repository within the specified region of your current work environment. - Delete the role
StreamlitCfnRole-<EnvironmentName>
manually.
See CONTRIBUTING for more information.
This library is licensed under the MIT-0 License. See the LICENSE file.