Skip to content

Commit 6b6bc1e

Browse files
authored
chore(ci): deploy server via cdk (#86)
## What I'm changing Use CDK to handle deploying server ## How I did it Add construct for ECS cluster & service
1 parent 187ba19 commit 6b6bc1e

File tree

8 files changed

+266
-90
lines changed

8 files changed

+266
-90
lines changed

.dockerignore

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,53 @@
1+
# Rust build artifacts
12
target/
2-
.github/
3-
LICENSE
4-
README.md
5-
Dockerfile
3+
**/*.rs.bk
4+
Cargo.lock
5+
6+
# Git and version control
7+
.git/
8+
.gitignore
9+
10+
# IDE and editor files
11+
.vscode/
12+
.idea/
13+
*.swp
14+
*.swo
15+
*~
16+
17+
# OS generated files
18+
.DS_Store
19+
.DS_Store?
20+
._*
21+
.Spotlight-V100
22+
.Trashes
23+
ehthumbs.db
24+
Thumbs.db
25+
26+
# Documentation and scripts
27+
docs/
28+
*.md
629
scripts/
30+
deploy/
31+
32+
# CI/CD
33+
.github/
34+
.github/workflows/
35+
36+
# AWS CDK
37+
cdk.out/
38+
*.d.ts
39+
*.js.map
40+
41+
# Node modules (if any)
42+
node_modules/
43+
npm-debug.log*
44+
yarn-debug.log*
45+
yarn-error.log*
46+
47+
# Logs
48+
*.log
49+
50+
# Environment files
51+
.env
52+
.env.local
53+
.env.*.local

.github/workflows/dev-deploy.yaml

Lines changed: 2 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -15,45 +15,11 @@ concurrency:
1515
cancel-in-progress: false
1616

1717
jobs:
18-
deploy-proxy:
19-
runs-on: ubuntu-latest
20-
environment: development
21-
steps:
22-
- uses: actions/[email protected]
23-
- name: Set up Docker Buildx
24-
uses: docker/setup-buildx-action@v3
25-
- name: Configure AWS Credentials
26-
uses: aws-actions/configure-aws-credentials@v4
27-
with:
28-
aws-region: us-east-1
29-
role-to-assume: ${{ vars.DEPLOY_ROLE_ARN }}
30-
- name: Login to Amazon ECR
31-
id: login-ecr
32-
uses: aws-actions/amazon-ecr-login@v2
33-
- name: Build, tag, and push docker image to Amazon ECR
34-
env:
35-
REGISTRY: ${{ steps.login-ecr.outputs.registry }}
36-
REPOSITORY: source-data-proxy
37-
IMAGE_TAG: ${{ github.sha }}
38-
run: |
39-
docker buildx build -t $REGISTRY/$REPOSITORY:$IMAGE_TAG --push .
40-
- name: Render Amazon ECS task definition
41-
id: render-data-proxy-container
42-
uses: aws-actions/amazon-ecs-render-task-definition@v1
43-
with:
44-
task-definition-family: source-data-proxy
45-
container-name: source-data-proxy
46-
image: 417712557820.dkr.ecr.us-east-1.amazonaws.com/source-data-proxy:${{ github.sha }}
47-
- name: Deploy to Amazon ECS service
48-
uses: aws-actions/amazon-ecs-deploy-task-definition@v2
49-
with:
50-
task-definition: ${{ steps.render-data-proxy-container.outputs.task-definition }}
51-
service: source-data-proxy
52-
cluster: SourceCooperative-Dev
53-
5418
deploy-cdk:
5519
runs-on: ubuntu-latest
5620
environment: development
21+
env:
22+
STAGE: dev
5723
defaults:
5824
run:
5925
working-directory: ./deploy

.github/workflows/prod-deploy.yaml

Lines changed: 2 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -14,51 +14,11 @@ concurrency:
1414
cancel-in-progress: false
1515

1616
jobs:
17-
deploy-proxy:
18-
runs-on: ubuntu-latest
19-
environment: production
20-
steps:
21-
- id: latest
22-
uses: thebritican/fetch-latest-release@a36ee8ee464da77ba3e499ed6b75e3530e10f9bc # v2.0.0
23-
with:
24-
github_token: ${{ secrets.GITHUB_TOKEN }}
25-
- uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
26-
with:
27-
ref: ${{ steps.latest.outputs.tag_name }}
28-
- name: Set up Docker Buildx
29-
uses: docker/setup-buildx-action@v3
30-
- name: Configure AWS Credentials
31-
uses: aws-actions/configure-aws-credentials@v4
32-
with:
33-
aws-region: us-west-2
34-
role-to-assume: ${{ vars.DEPLOY_ROLE_ARN }}
35-
- name: Login to Amazon ECR
36-
id: login-ecr
37-
uses: aws-actions/amazon-ecr-login@v2
38-
- name: Build, tag, and push docker image to Amazon ECR
39-
env:
40-
REGISTRY: ${{ steps.login-ecr.outputs.registry }}
41-
REPOSITORY: source-data-proxy
42-
IMAGE_TAG: ${{ steps.latest.outputs.tag_name }}
43-
run: |
44-
docker buildx build -t $REGISTRY/$REPOSITORY:$IMAGE_TAG --push .
45-
- name: Render Amazon ECS task definition
46-
id: render-data-proxy-container
47-
uses: aws-actions/amazon-ecs-render-task-definition@v1
48-
with:
49-
task-definition-family: source-data-proxy
50-
container-name: source-data-proxy
51-
image: 417712557820.dkr.ecr.us-west-2.amazonaws.com/source-data-proxy:${{ steps.latest.outputs.tag_name }}
52-
- name: Deploy to Amazon ECS service
53-
uses: aws-actions/amazon-ecs-deploy-task-definition@v2
54-
with:
55-
task-definition: ${{ steps.render-data-proxy-container.outputs.task-definition }}
56-
service: source-data-proxy
57-
cluster: SourceCooperative-Prod
58-
5917
deploy-cdk:
6018
runs-on: ubuntu-latest
6119
environment: production
20+
env:
21+
STAGE: prod
6222
defaults:
6323
run:
6424
working-directory: ./deploy

Dockerfile

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,48 @@
1-
FROM rust:1.80.1
2-
ADD . /app
1+
# Build stage - target x86_64 for ECS Fargate compatibility
2+
FROM --platform=linux/amd64 rust:1.82.0 AS builder
3+
4+
# Set environment variables for consistent builds
5+
ENV CARGO_TARGET_DIR=/app/target
6+
ENV RUSTFLAGS="-C target-cpu=x86-64"
7+
8+
# Copy source code
9+
COPY . /app
310
WORKDIR /app
4-
RUN cargo build --release
5-
ENTRYPOINT ["cargo", "run", "--release"]
11+
12+
# Add x86_64 target and build
13+
RUN rustup target add x86_64-unknown-linux-gnu
14+
RUN cargo build --release --target x86_64-unknown-linux-gnu
15+
16+
# Runtime stage - minimal Debian image
17+
FROM --platform=linux/amd64 debian:bookworm-slim AS runtime
18+
19+
# Install runtime dependencies (ca-certificates for HTTPS requests)
20+
RUN apt-get update && \
21+
apt-get install -y --no-install-recommends \
22+
ca-certificates \
23+
curl \
24+
&& rm -rf /var/lib/apt/lists/*
25+
26+
# Create app user for security
27+
RUN groupadd -r appuser && useradd -r -g appuser appuser
28+
29+
# Copy the built binary from builder stage
30+
COPY --from=builder /app/target/x86_64-unknown-linux-gnu/release/source-data-proxy /app/source-data-proxy
31+
32+
# Set proper permissions
33+
RUN chown appuser:appuser /app/source-data-proxy && \
34+
chmod +x /app/source-data-proxy
35+
36+
# Switch to non-root user
37+
USER appuser
38+
39+
# Set working directory and expose port
40+
WORKDIR /app
41+
EXPOSE 8080
42+
43+
# Health check endpoint
44+
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
45+
CMD curl -f http://localhost:8080/health || exit 1
46+
47+
# Run the binary directly
48+
ENTRYPOINT ["/app/source-data-proxy"]

deploy/bin/deploy.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,33 @@
11
#!/usr/bin/env node
22
import * as cdk from "aws-cdk-lib";
33
import { DataProxyStack } from "../lib/data-proxy-stack";
4+
import { Tags } from "aws-cdk-lib";
45

56
const stage = process.env.STAGE || "dev";
6-
77
const vpcId = process.env.VPC_ID;
88
if (!vpcId) {
99
throw new Error("VPC_ID is not set");
1010
}
11+
const certificateArn = process.env.CERTIFICATE_ARN;
12+
if (!certificateArn) {
13+
throw new Error("CERTIFICATE_ARN is not set");
14+
}
15+
const taskCount = process.env.TASK_COUNT || 1;
16+
const sourceApiUrl = process.env.SOURCE_API_URL || "https://s2.source.coop";
1117

1218
const app = new cdk.App();
13-
new DataProxyStack(app, `DataProxy-${stage}`, {
19+
const stack = new DataProxyStack(app, `DataProxy-${stage}`, {
1420
vpcId,
1521
proxyDomain: `vercel-api-${stage}.internal`,
22+
proxyDesiredCount: Number(taskCount),
23+
sourceApiUrl,
1624
env: {
1725
account: process.env.AWS_ACCOUNT_ID,
1826
region: process.env.AWS_REGION,
1927
},
28+
certificateArn,
29+
});
30+
31+
Tags.of(stack).add("Cfn-Stack", stack.stackName, {
32+
applyToLaunchedInstances: true,
2033
});

deploy/lib/data-proxy-stack.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,15 @@ import * as cdk from "aws-cdk-lib";
22
import { aws_ec2 as ec2 } from "aws-cdk-lib";
33
import { Construct } from "constructs";
44
import { VercelApiProxy } from "./vercel-api-proxy";
5+
import { SourceDataProxy } from "./source-data-proxy";
6+
import { VpcEndpoints } from "./vpc-endpoints";
57

68
interface DataProxyStackProps extends cdk.StackProps {
79
vpcId: string;
810
proxyDomain: string;
11+
sourceApiUrl: string;
12+
proxyDesiredCount: number;
13+
certificateArn: string;
914
}
1015

1116
export class DataProxyStack extends cdk.Stack {
@@ -14,9 +19,21 @@ export class DataProxyStack extends cdk.Stack {
1419

1520
const vpc = ec2.Vpc.fromLookup(this, "vpc", { vpcId: props.vpcId });
1621

17-
new VercelApiProxy(this, "vercel-api-proxy", {
22+
// Create Vercel API proxy (existing functionality)
23+
const vercelApiProxy = new VercelApiProxy(this, "vercel-api-proxy", {
1824
vpc,
1925
proxyDomain: props.proxyDomain,
2026
});
27+
28+
new SourceDataProxy(this, "source-data-proxy", {
29+
vpc,
30+
environment: {
31+
RUST_LOG: "info",
32+
SOURCE_API_PROXY_URL: vercelApiProxy.url,
33+
SOURCE_API_URL: props.sourceApiUrl,
34+
},
35+
desiredCount: props.proxyDesiredCount,
36+
certificateArn: props.certificateArn,
37+
});
2138
}
2239
}

0 commit comments

Comments
 (0)