diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml new file mode 100644 index 00000000..0a33508f --- /dev/null +++ b/.github/workflows/cicd.yml @@ -0,0 +1,38 @@ +name: Build and Push Docker Image to ECR + +on: + push: + branches: + - main # Runs when code is pushed to the main branch + +jobs: + build-and-push: + runs-on: ubuntu-latest + + steps: + - name: Checkout Code + uses: actions/checkout@v3 + + - name: Set Up AWS CLI + uses: aws-actions/configure-aws-credentials@v1 + with: + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-region: ${{ secrets.AWS_REGION }} + + - name: Login to Amazon ECR + run: | + aws ecr get-login-password --region ${{ secrets.AWS_REGION }} | docker login --username AWS --password-stdin ${{ secrets.ECR_REGISTRY }} + + - name: Build and Tag Docker Image + run: | + IMAGE_TAG=$(git rev-parse --short HEAD) + docker build -t ${{ secrets.ECR_REPO }}:$IMAGE_TAG -f fastapi-service/Dockerfile fastapi-service/ + docker tag ${{ secrets.ECR_REPO }}:$IMAGE_TAG ${{ secrets.ECR_REGISTRY }}/${{ secrets.ECR_REPO }}:$IMAGE_TAG + docker tag ${{ secrets.ECR_REPO }}:$IMAGE_TAG ${{ secrets.ECR_REGISTRY }}/${{ secrets.ECR_REPO }}:latest + + - name: Push Docker Image to ECR + run: | + IMAGE_TAG=$(git rev-parse --short HEAD) + docker push ${{ secrets.ECR_REGISTRY }}/${{ secrets.ECR_REPO }}:$IMAGE_TAG + docker push ${{ secrets.ECR_REGISTRY }}/${{ secrets.ECR_REPO }}:latest diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..99f7ee23 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,20 @@ +# Use a lightweight Python image +FROM python:3.9-slim + +# Set the working directory +WORKDIR /app + +# Copy only the necessary files first +COPY requirements.txt . + +# Install dependencies +RUN pip install --no-cache-dir -r requirements.txt + +# Copy the FastAPI application files +COPY . . + +# Expose the application port +EXPOSE 8000 + +# Run the FastAPI application using Uvicorn +CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"] diff --git a/fastapi-service/Dockerfile b/fastapi-service/Dockerfile new file mode 100644 index 00000000..0f531652 --- /dev/null +++ b/fastapi-service/Dockerfile @@ -0,0 +1,5 @@ +FROM python:3.9-slim +WORKDIR /app +COPY . /app +RUN pip install fastapi uvicorn +CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"] diff --git a/fastapi-service/deployment.yaml b/fastapi-service/deployment.yaml new file mode 100644 index 00000000..a1a484e5 --- /dev/null +++ b/fastapi-service/deployment.yaml @@ -0,0 +1,20 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: fastapi-service +spec: + replicas: 2 + selector: + matchLabels: + app: fastapi-service + template: + metadata: + labels: + app: fastapi-service + spec: + containers: + - name: fastapi-service + image: 503147168047.dkr.ecr.ap-south-1.amazonaws.com/fastapi-service:latest # Updated with ECR details + ports: + - containerPort: 8000 + imagePullPolicy: Always # Ensures the latest image is pulled on deployment diff --git a/fastapi-service/main.py b/fastapi-service/main.py new file mode 100644 index 00000000..9628872d --- /dev/null +++ b/fastapi-service/main.py @@ -0,0 +1,7 @@ +from fastapi import FastAPI + +app = FastAPI() + +@app.get("/") +def read_root(): + return {"message": "Hello from FastAPI in Kubernetes!"} diff --git a/fastapi-service/service.yaml b/fastapi-service/service.yaml new file mode 100644 index 00000000..4896bdbf --- /dev/null +++ b/fastapi-service/service.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Service +metadata: + name: fastapi-service +spec: + selector: + app: fastapi-service + ports: + - protocol: TCP + port: 80 + targetPort: 8000 + type: LoadBalancer # Exposes service externally diff --git a/main.py b/main.py new file mode 100644 index 00000000..3c7e3763 --- /dev/null +++ b/main.py @@ -0,0 +1,19 @@ +from fastapi import FastAPI + +# Create a FastAPI instance +app = FastAPI() + +# Define a root endpoint +@app.get("/") +def read_root(): + return {"message": "Hello from FastAPI running on Kubernetes!"} + +# Example endpoint with a parameter +@app.get("/items/{item_id}") +def read_item(item_id: int, q: str = None): + return {"item_id": item_id, "query": q} + +# Health check endpoint (useful for Kubernetes readiness and liveness probes) +@app.get("/health") +def health_check(): + return {"status": "healthy"} diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 00000000..97dc7cd8 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +fastapi +uvicorn diff --git a/test.txt b/test.txt new file mode 100644 index 00000000..45b983be --- /dev/null +++ b/test.txt @@ -0,0 +1 @@ +hi