name: Deploy Options Trading Systems to AWS Lambda
on:
push:
branches:
- main
workflow_dispatch:
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: '3.12'
- name: Install AWS SAM CLI
run: |
pip install aws-sam-cli
# Deploy live trading system
- name: Build and deploy live trading
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
ECR_REPOSITORY: options-trading-system
IMAGE_TAG: ${{ github.sha }}
run: |
cd Enter_Mon_Hold_Till_Fri
docker buildx build \
--cache-from type=registry,ref=$ECR_REGISTRY/$ECR_REPOSITORY:cache-live \
--cache-to type=registry,ref=$ECR_REGISTRY/$ECR_REPOSITORY:cache-live,mode=max \
-t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG \
--push \
--provenance=false .
sam deploy \
--no-confirm-changeset \
--no-fail-on-empty-changeset \
--stack-name options-trading-system \
--capabilities CAPABILITY_IAM \
--region us-east-1 \
--resolve-s3 \
--resolve-image-repos \
--parameter-overrides ImageUri=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
- name: Clean up old ECR images
env:
ECR_REPOSITORY: options-trading-system
run: |
echo "๐งน Cleaning up old Docker images from $ECR_REPOSITORY..."
OLD_IMAGES=$(aws ecr describe-images \
--repository-name $ECR_REPOSITORY \
--region us-east-1 \
--query 'sort_by(imageDetails,&imagePushedAt)[:-3].imageDigest' \
--output text)
if [ -n "$OLD_IMAGES" ]; then
echo "$OLD_IMAGES" | tr '\t' '\n' | while read digest; do
if [ -n "$digest" ]; then
echo " โ Deleting image: $digest"
aws ecr batch-delete-image \
--repository-name $ECR_REPOSITORY \
--image-ids imageDigest=$digest \
--region us-east-1 \
--no-cli-pager || true
fi
done
else
echo " โ
No old images to delete (keeping 3 most recent)"
fi
REMAINING=$(aws ecr describe-images \
--repository-name $ECR_REPOSITORY \
--region us-east-1 \
--query 'length(imageDetails)' \
--output text)
echo "๐ Cleanup complete! $ECR_REPOSITORY now has $REMAINING images"
name: Deploy Sector Rotation System to AWS Lambda
on:
push:
branches:
- main
workflow_dispatch:
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1
- name: Build Docker image
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
ECR_REPOSITORY: etf-trading-system
IMAGE_TAG: ${{ github.sha }}
run: |
cd live_trading
docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: '3.12'
- name: Install AWS SAM CLI
run: |
pip install aws-sam-cli
- name: Deploy with SAM
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
ECR_REPOSITORY: etf-trading-system
IMAGE_TAG: ${{ github.sha }}
run: |
sam deploy \
--no-confirm-changeset \
--no-fail-on-empty-changeset \
--stack-name etf-trading-system \
--capabilities CAPABILITY_IAM \
--region us-east-1 \
--resolve-s3 \
--resolve-image-repos \
--parameter-overrides ImageUri=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
- name: Clean up old ECR images
env:
ECR_REPOSITORY: etf-trading-system
run: |
echo "๐งน Cleaning up old Docker images from $ECR_REPOSITORY..."
OLD_IMAGES=$(aws ecr describe-images \
--repository-name $ECR_REPOSITORY \
--region us-east-1 \
--query 'sort_by(imageDetails,&imagePushedAt)[:-3].imageDigest' \
--output text)
if [ -n "$OLD_IMAGES" ]; then
echo "$OLD_IMAGES" | tr '\t' '\n' | while read digest; do
if [ -n "$digest" ]; then
echo " โ Deleting image: $digest"
aws ecr batch-delete-image \
--repository-name $ECR_REPOSITORY \
--image-ids imageDigest=$digest \
--region us-east-1 \
--no-cli-pager || true
fi
done
else
echo " โ
No old images to delete (keeping 3 most recent)"
fi
REMAINING=$(aws ecr describe-images \
--repository-name $ECR_REPOSITORY \
--region us-east-1 \
--query 'length(imageDetails)' \
--output text)
echo "๐ Cleanup complete! $ECR_REPOSITORY now has $REMAINING images"
These are two valid organizational patterns with different tradeoffs:
| Aspect | Options Trading | Sector Rotation |
|---|---|---|
| Directory Structure |
Self-contained approach: Enter_Mon_Hold_Till_Fri/ โโโ template.yaml โโโ Dockerfile โโโ lambda_function.py |
Separated approach: โโโ template.yaml โโโ live_trading/ โโโ Dockerfile โโโ lambda_function.py |
| Step Organization |
1. Checkout 2. AWS Creds 3. ECR Login 4. Docker Buildx Setup 5. Python Setup 6. SAM Install 7. Build + Deploy (COMBINED) 8. Cleanup |
1. Checkout 2. AWS Creds 3. ECR Login 4. Docker Build (SEPARATE) 5. Python Setup 6. SAM Install 7. SAM Deploy (SEPARATE) 8. Cleanup |
| Docker Tool | docker buildx (advanced) | docker build (standard) |
| Build Directory | Enter_Mon_Hold_Till_Fri/ | live_trading/ |
| SAM Deploy Directory | Enter_Mon_Hold_Till_Fri/ (finds template.yaml there) | Repo root (finds template.yaml there) |
| Docker Push | Integrated with --push flag | Separate docker push command |
| Registry Caching | โ Uses --cache-from/--cache-to | โ No caching |
Philosophy: Everything for this system lives in one subdirectory
Benefits:
Tradeoffs:
Philosophy: Infrastructure config (template) at root, application code in subdirectory
Benefits:
Tradeoffs:
| Feature | Options Trading | Sector Rotation |
|---|---|---|
| Build Command | docker buildx build |
docker build |
| Cache Strategy |
--cache-from type=registry--cache-to type=registry,mode=maxBenefit: Faster builds by reusing layers |
None Impact: Rebuilds from scratch each time |
| Push Method |
Integrated: --push flagBenefit: Single command |
Separate: docker pushImpact: Two commands needed |
| Provenance | --provenance=false |
Default (not specified) |
| Requires Buildx Setup | โ Yes (separate step) | โ No (uses standard Docker) |
In GitHub Actions, every step starts with a fresh shell session at the repository root.
Any cd commands only affect that specific step.
This is why Sector Rotation works: the Docker build step changes directory, but the SAM deploy step starts fresh at the repo root.
| Consideration | Self-Contained (Options) | Root Template (Sector) |
|---|---|---|
| Multiple systems in repo | โ Each system is independent directory | โ ๏ธ Need multiple templates at root or complex template |
| Easy to relocate | โ Copy entire directory | โ ๏ธ Need to move both root template and subdirectory |
| Infrastructure visibility | โ ๏ธ Template buried in subdirectory | โ Template obvious at repo root |
| Build performance | โ Docker buildx with layer caching | Standard build, no caching |
| Step clarity | Single combined step | โ Separate steps, clearer logs |
| Common convention | Less common (but valid) | โ More typical repo structure |
| Pattern | Status | Key Characteristic | Best For |
|---|---|---|---|
| Options Trading (Self-Contained) |
โ WORKS | Everything in subdirectory, single combined step, buildx caching | Multi-system repos where each system should be independent and portable |
| Sector Rotation (Root Template) |
โ WORKS | Template at root, code in subdirectory, separate build/deploy steps | Single-system repos following conventional project structure |
Buildx advantages:
When is buildx overkill?