AWS CLI & Deployment
AWS CLI essentials, IAM roles for CI/CD, and deploying to EC2, ECS Fargate, and Lambda
Knowledge Debt detected
You can study this freely — but your score may plateau if these foundations have gaps. The Mastery badge requires them to be solid.
Explanation
The AWS CLI lets you manage all AWS resources from the command line — essential for scripts, CI/CD, and local development.
Setup:
bash pip install awscli aws configure # AWS Access Key ID: AKIA... # AWS Secret Access Key: ... # Default region: us-east-1 # Default output format: json `` Never use root account credentials. Create an IAM user with minimum required permissions.
Essential CLI commands:
bash # S3 aws s3 ls # list buckets aws s3 cp local.txt s3://my-bucket/ # upload file aws s3 sync dist/ s3://my-bucket/ --delete # sync directory # EC2 aws ec2 describe-instances aws ec2 start-instances --instance-ids i-1234 aws ec2 stop-instances --instance-ids i-1234 # ECR (container registry) aws ecr get-login-password | docker login --username AWS --password-stdin 123456789.dkr.ecr.us-east-1.amazonaws.com # ECS aws ecs update-service --cluster prod --service api --force-new-deployment
Three deployment targets:
| Target | Best for | Overhead | |---|---|---| | EC2 | Full control, stateful, long-running | High — manage OS, patching, scaling | | ECS (Fargate) | Dockerized apps, no server management | Medium — manage tasks/services | | Lambda | Event-driven, short-lived functions | Minimal — just the function code |
Deploying a Docker app to ECS Fargate:
bash # 1. Build and push to ECR docker build -t my-api . docker tag my-api:latest 123456789.dkr.ecr.us-east-1.amazonaws.com/my-api:latest docker push 123456789.dkr.ecr.us-east-1.amazonaws.com/my-api:latest # 2. Trigger rolling deployment aws ecs update-service --cluster production --service api-service --force-new-deployment
IAM roles for deployment (best practice):
- Never use long-lived access keys in production servers
- EC2/ECS/Lambda: attach an IAM role → credentials are injected and auto-rotate
- GitHub Actions: use OIDC → assume an IAM role per workflow run (no stored secrets)
Secrets Manager for sensitive config:
bash aws secretsmanager create-secret --name prod/api/database-url --secret-string "postgresql://user:pass@host/db" python import boto3 secret = boto3.client("secretsmanager").get_secret_value( SecretId="prod/api/database-url" )
Examples
GitHub Actions → ECR → ECS with OIDC
OIDC provides temporary per-run credentials — no long-lived AWS keys stored in GitHub Secrets
# .github/workflows/deploy.yml
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
id-token: write # required for OIDC
contents: read
steps:
- uses: actions/checkout@v4
- name: Configure AWS credentials (OIDC)
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789:role/github-deploy-role
aws-region: us-east-1
- name: Login to ECR
run: |
aws ecr get-login-password | docker login --username AWS --password-stdin 123456789.dkr.ecr.us-east-1.amazonaws.com
- name: Build, tag, push
run: |
IMAGE=123456789.dkr.ecr.us-east-1.amazonaws.com/my-api
docker build -t $IMAGE:${{ github.sha }} .
docker push $IMAGE:${{ github.sha }}
- name: Deploy to ECS
run: |
aws ecs update-service --cluster prod --service api --force-new-deploymentFastAPI on Lambda via Mangum
Mangum lets you run a full FastAPI app on Lambda with no code changes — ideal for low-traffic or cost-sensitive APIs
# Mangum adapts ASGI (FastAPI) to the Lambda event/context format
# pip install fastapi mangum
from fastapi import FastAPI
from mangum import Mangum
app = FastAPI()
@app.get("/")
def root():
return {"message": "Hello from Lambda"}
handler = Mangum(app) # Lambda calls handler(event, context)
# Deploy
zip -r function.zip . -x "*.pyc" "__pycache__/*"
aws lambda update-function-code --function-name my-api --zip-file fileb://function.zip
# Expose via Function URL (no API Gateway needed)
aws lambda create-function-url-config --function-name my-api --auth-type NONEHow well did you understand this?