From 441baf326fc7e5a1fd5b7a0f74b6a0a63980a3d0 Mon Sep 17 00:00:00 2001 From: Fabrizio Siciliano Date: Tue, 7 Jul 2026 15:40:37 +0200 Subject: [PATCH] feat(terraform): build and manage ECS images from configuration files --- .github/workflows/deploy-data.yml | 85 ++++++++++++++++--- litellm/proxy/proxy_config.yaml | 7 +- .../litellm/aws/config/prod/terraform.tfvars | 1 - terraform/litellm/aws/ecr.tf | 39 +++++++++ terraform/litellm/aws/outputs.tf | 20 +++++ 5 files changed, 135 insertions(+), 17 deletions(-) create mode 100644 terraform/litellm/aws/ecr.tf diff --git a/.github/workflows/deploy-data.yml b/.github/workflows/deploy-data.yml index 36380ebe85f..ab06acd3bb1 100644 --- a/.github/workflows/deploy-data.yml +++ b/.github/workflows/deploy-data.yml @@ -8,47 +8,112 @@ on: permissions: id-token: write - contents: read + contents: read defaults: run: shell: bash working-directory: ./terraform/litellm/aws/ +env: + AWS_REGION: eu-central-1 + IMAGE_TAG: ${{ github.sha }} jobs: terraform: name: Terraform Deploy runs-on: ubuntu-latest - + steps: - name: Checkout Code - uses: actions/checkout@v4 + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 - name: Configure AWS credentials - uses: aws-actions/configure-aws-credentials@v4 + uses: aws-actions/configure-aws-credentials@7474bc4690e29a8392af63c5b98e7449536d5c3a # v4.3.1 with: audience: sts.amazonaws.com role-to-assume: arn:aws:iam::${{ vars.AWS_ACCOUNT_ID }}:role/github-oidc-provider-role role-session-name: github-actions - aws-region: eu-central-1 + aws-region: ${{ env.AWS_REGION }} - name: Setup Terraform - uses: hashicorp/setup-terraform@v3 + uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3.1.2 with: terraform_version: "1.15.7" + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0 + - name: Terraform Init run: terraform init -backend-config=config/prod/backend.tfbackend - - name: Terraform Validate run: terraform validate - - name: Terraform Plan - run: terraform plan -var-file=config/prod/terraform.tfvars -out=tfplan + - name: Bootstrap ECR repositories + run: | + terraform apply -auto-approve \ + -var-file=config/prod/terraform.tfvars \ + -target=aws_ecr_repository.gateway \ + -target=aws_ecr_repository.backend \ + -target=aws_ecr_repository.ui \ + -target=aws_ecr_repository.migrations + + - name: Read ECR repository URLs + id: ecr + run: | + { + echo "gateway_repo=$(terraform output -raw gateway_ecr_repository_url)" + echo "backend_repo=$(terraform output -raw backend_ecr_repository_url)" + echo "ui_repo=$(terraform output -raw ui_ecr_repository_url)" + echo "migrations_repo=$(terraform output -raw migrations_ecr_repository_url)" + } >> "$GITHUB_OUTPUT" + + - name: Login to Amazon ECR + uses: aws-actions/amazon-ecr-login@4625ce35226a7557230889aae2f52eb50ec3dcda # v2.0.1 + + - name: Build and push gateway image + uses: docker/build-push-action@0adf9959216b96bec444f325f1e493d4aa344497 # v6.14.0 + with: + context: . + file: ./gateway/Dockerfile + push: true + tags: ${{ steps.ecr.outputs.gateway_repo }}:${{ env.IMAGE_TAG }} + - name: Build and push backend image + uses: docker/build-push-action@0adf9959216b96bec444f325f1e493d4aa344497 # v6.14.0 + with: + context: . + file: ./backend/Dockerfile + push: true + tags: ${{ steps.ecr.outputs.backend_repo }}:${{ env.IMAGE_TAG }} + + - name: Build and push UI image + uses: docker/build-push-action@0adf9959216b96bec444f325f1e493d4aa344497 # v6.14.0 + with: + context: . + file: ./ui/Dockerfile + push: true + tags: ${{ steps.ecr.outputs.ui_repo }}:${{ env.IMAGE_TAG }} + + - name: Build and push migrations image + uses: docker/build-push-action@0adf9959216b96bec444f325f1e493d4aa344497 # v6.14.0 + with: + context: . + file: ./migrations/Dockerfile + push: true + tags: ${{ steps.ecr.outputs.migrations_repo }}:${{ env.IMAGE_TAG }} + + - name: Terraform Plan + run: | + terraform plan \ + -var-file=config/prod/terraform.tfvars \ + -var="gateway_image=${{ steps.ecr.outputs.gateway_repo }}:${IMAGE_TAG}" \ + -var="backend_image=${{ steps.ecr.outputs.backend_repo }}:${IMAGE_TAG}" \ + -var="ui_image=${{ steps.ecr.outputs.ui_repo }}:${IMAGE_TAG}" \ + -var="migrations_image=${{ steps.ecr.outputs.migrations_repo }}:${IMAGE_TAG}" \ + -out=tfplan - name: Terraform Apply if: github.ref == 'refs/heads/datareply/prod' - run: terraform apply -auto-approve tfplan \ No newline at end of file + run: terraform apply -auto-approve tfplan diff --git a/litellm/proxy/proxy_config.yaml b/litellm/proxy/proxy_config.yaml index a4dd6fa98cd..8fbf0cc0a8c 100644 --- a/litellm/proxy/proxy_config.yaml +++ b/litellm/proxy/proxy_config.yaml @@ -51,18 +51,13 @@ mcp_servers: general_settings: master_key: sk-1234 store_model_in_db: false - alerting: ["email", "slack_budget_alerts", "slack"] + enforce_email_prefix_on_key_alias: true # LiteLLM Settings litellm_settings: - callbacks: ["smtp_email"] - ui_theme_config: - logo_url: "https://www.reply.com/favicon.ico" - favicon_url: "https://www.reply.com/favicon.ico" # Enable MCP Semantic Tool Filter mcp_semantic_tool_filter: enabled: true embedding_model: "text-embedding-3-small" top_k: 5 similarity_threshold: 0.3 - diff --git a/terraform/litellm/aws/config/prod/terraform.tfvars b/terraform/litellm/aws/config/prod/terraform.tfvars index b7c6d94ab76..3a1b1fb34b8 100644 --- a/terraform/litellm/aws/config/prod/terraform.tfvars +++ b/terraform/litellm/aws/config/prod/terraform.tfvars @@ -10,7 +10,6 @@ route53_zone_id = "Z046271219OMVB01WCCVM" s3_force_destroy = false skip_final_snapshot = false - # ---------- proxy_config (mirrors helm gateway.config.proxy_config) ---------- proxy_config = { model_list = [ diff --git a/terraform/litellm/aws/ecr.tf b/terraform/litellm/aws/ecr.tf new file mode 100644 index 00000000000..00a028dc167 --- /dev/null +++ b/terraform/litellm/aws/ecr.tf @@ -0,0 +1,39 @@ +resource "aws_ecr_repository" "gateway" { + name = "${local.name}-gateway" + + image_scanning_configuration { + scan_on_push = true + } + + tags = local.tags +} + +resource "aws_ecr_repository" "backend" { + name = "${local.name}-backend" + + image_scanning_configuration { + scan_on_push = true + } + + tags = local.tags +} + +resource "aws_ecr_repository" "ui" { + name = "${local.name}-ui" + + image_scanning_configuration { + scan_on_push = true + } + + tags = local.tags +} + +resource "aws_ecr_repository" "migrations" { + name = "${local.name}-migrations" + + image_scanning_configuration { + scan_on_push = true + } + + tags = local.tags +} diff --git a/terraform/litellm/aws/outputs.tf b/terraform/litellm/aws/outputs.tf index 9f7d908dbe6..8a9ea8e45ad 100644 --- a/terraform/litellm/aws/outputs.tf +++ b/terraform/litellm/aws/outputs.tf @@ -33,6 +33,26 @@ output "s3_bucket" { value = aws_s3_bucket.this.bucket } +output "gateway_ecr_repository_url" { + description = "ECR repository URL for the gateway image." + value = aws_ecr_repository.gateway.repository_url +} + +output "backend_ecr_repository_url" { + description = "ECR repository URL for the backend image." + value = aws_ecr_repository.backend.repository_url +} + +output "ui_ecr_repository_url" { + description = "ECR repository URL for the UI image." + value = aws_ecr_repository.ui.repository_url +} + +output "migrations_ecr_repository_url" { + description = "ECR repository URL for the migrations image." + value = aws_ecr_repository.migrations.repository_url +} + output "master_key_secret_arn" { description = "Secrets Manager ARN holding LITELLM_MASTER_KEY. Fetch with `aws secretsmanager get-secret-value --secret-id `." value = aws_secretsmanager_secret.master_key.arn