Getting Started¶
This guide will walk you through deploying your first containerized web application using gds-idea-cdk-constructs.
Prerequisites¶
Before using this library, ensure you have:
- AWS Account - With credentials configured for your environment
- AWS CDK v2 - Installed and bootstrapped in your target account and region
- Docker - Installed and running on your local machine
- Python 3.11+ - This library requires Python 3.11 or later
Existing AWS Infrastructure¶
This library assumes you have the following infrastructure already deployed:
- VPC - Virtual Private Cloud for networking
- Route 53 Hosted Zone - Parent domain for your applications
- S3 Bucket - For ALB access logs
- Cognito User Pool (optional) - For authentication
- WAF Web ACL - For security
The DeploymentConfig class automatically looks up these resources based on your AWS account.
Installation¶
Install from the GDS IDEA PyPI index:
Your First Application¶
1. Project Setup¶
Create a new CDK project:
Install the library:
2. Create Your Application Code¶
Create a simple Streamlit app:
# app.py
import streamlit as st
st.title("Hello GDS Idea!")
st.write("This is my first deployed application.")
Create a Dockerfile:
# Dockerfile
FROM python:3.11-slim
WORKDIR /app
RUN pip install streamlit
COPY app.py .
EXPOSE 8501
CMD ["streamlit", "run", "app.py", "--server.port=8501", "--server.address=0.0.0.0"]
3. Create CDK Stack¶
Edit your app.py (or create a new one):
#!/usr/bin/env python3
import os
import aws_cdk as cdk
from gds_idea_cdk_constructs.config import DeploymentConfig, AppConfig
from gds_idea_cdk_constructs.web_app import WebApp, AuthType
app = cdk.App()
# Configure environment from AWS credentials
cdk_env = cdk.Environment(
account=os.environ.get("CDK_DEFAULT_ACCOUNT"),
region=os.environ.get("CDK_DEFAULT_REGION", "eu-west-2"),
)
# Deployment config automatically looks up infrastructure
deployment_config = DeploymentConfig(cdk_env)
# Configure your application
app_config = AppConfig(
app_name="my-web-app",
framework="streamlit",
)
# Create the stack
WebApp(
app,
deployment_config=deployment_config,
app_config=app_config,
authentication=AuthType.INTERNAL_ACCESS, # Requires login
docker_context_path=".",
dockerfile_path="Dockerfile",
)
app.synth()
4. Deploy¶
Set your AWS profile and deploy:
The deployment will: 1. Build your Docker image 2. Push it to ECR 3. Create all AWS resources 4. Output your application URL
Configuration Options¶
Custom Container Properties¶
If you need to change the default parameters of the container, or pass envs initiate
a WebAppContainerProperties object. All parameters have sensible defaults.
from gds_idea_cdk_constructs.web_app import WebAppContainerProperties
container_props = WebAppContainerProperties(
cpu=512, # 0.5 vCPU
memory_limit_mib=1024, # 1 GB RAM
desired_count=2, # Run 2 tasks
container_port=8501, # Streamlit default
health_check_path="/_stcore/health",
environment_variables={
"LOG_LEVEL": "INFO",
"APP_ENV": "production",
},
)
WebApp(
app,
deployment_config=deployment_config,
app_config=app_config,
container_props=container_props,
# ... other parameters
)
Custom IAM Role¶
You can create a custom IAM role to pass to the container, For example if you have a backend stack that creates s3/database etc and need the app to access them.
from aws_cdk import Stack
from constructs import Construct
import aws_cdk.aws_iam as iam
class MyBackEnd(Stack):
def __init__(self, scope: Construct, construct_id: str, **kwargs):
super().__init__(scope, construct_id, **kwargs)
# ... creation of backend
# Create custom role
self.task_role = iam.Role(
self,
"CustomTaskRole",
assumed_by=iam.ServicePrincipal("ecs-tasks.amazonaws.com"),
)
# Grant S3 access
task_role.add_to_policy(
iam.PolicyStatement(
actions=["s3:GetObject", "s3:PutObject"],
resources=["arn:aws:s3:::my-bucket/*"],
)
)
backend = MyBackEnd(app, "MyBackEnd")
WebApp(
app,
deployment_config=deployment_config,
app_config=app_config,
task_role=backend.task_role, # Use custom role
# ... other parameters
)
Or if you need to simply add additional permissions for example the ability to call bedrock, add them to the automatically generated role.
web_app = WebApp(
app,
deployment_config=deployment_config,
app_config=app_config,
# ... other parameters
)
web_app.task_role.add_to_policy(...)
Environment Configuration¶
The library automatically configures resources based on your active AWS account. Environment-specific values (VPC, domain, Cognito user pool, WAF, etc.) are fetched from AWS Systems Manager Parameter Store at synth time. Three parameters are fetched and merged:
/gds-idea-auth— domain, Cognito, WAF config/gds-idea-ecs— ECS cluster config/gds-idea-vpc— VPC and subnet config
These parameters are managed by Terraform and shared within each AWS account. You do not need to create them manually.
Development Environment¶
Account ID: 992382722318
- Developers can assume task roles for local testing
Production Environment¶
Account ID: 588077357019
- Stricter security policies
- No developer assume role access
Framework Support¶
The library automatically configures health check paths for common frameworks:
- Streamlit:
/_stcore/health - Dash:
/health - FastAPI:
/health - Other:
/health(default)
Override with AppConfig:
Cross-Account Data Access¶
If your application needs to access data in the production account when deployed to the development environment (e.g., querying Athena or reading S3), enable cross-account access:
WebApp(
app,
deployment_config=deployment_config,
app_config=app_config,
cross_account_access=True, # Enable cross-account role assumption in dev
# ... other parameters
)
When enabled and deploying to a non-production environment, the construct automatically:
- Grants the task role
sts:AssumeRolepermission on the cross-account role - Injects
CROSS_ACCOUNT_ROLE_ARNas a container environment variable
Your application code can then use this environment variable to create a boto3 session that assumes the cross-account role:
import os
import boto3
def get_session():
role_arn = os.getenv("CROSS_ACCOUNT_ROLE_ARN")
if role_arn:
sts = boto3.client("sts")
creds = sts.assume_role(RoleArn=role_arn, RoleSessionName="app")["Credentials"]
return boto3.Session(
aws_access_key_id=creds["AccessKeyId"],
aws_secret_access_key=creds["SecretAccessKey"],
aws_session_token=creds["SessionToken"],
)
return boto3.Session()
In production, CROSS_ACCOUNT_ROLE_ARN is not set, so the default session (using the
task role's direct permissions) is used. No code changes needed between environments.
Next Steps¶
- API Reference - Detailed API documentation
- Authentication Guide - Configure authentication strategies
- Contributing - Contribute to the project