Fix diagram formatting in README.md #10
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI/CD Pipeline | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| workflow_dispatch: | |
| inputs: | |
| deploy: | |
| description: 'Deploy to ECS' | |
| required: true | |
| default: 'false' | |
| type: choice | |
| options: | |
| - 'true' | |
| - 'false' | |
| destroy: | |
| description: 'Destroy infrastructure' | |
| required: false | |
| default: 'false' | |
| type: choice | |
| options: | |
| - 'true' | |
| - 'false' | |
| env: | |
| AWS_REGION: us-west-2 | |
| TF_VERSION: 1.6.0 | |
| GO_VERSION: '1.24' | |
| TF_STATE_BUCKET: xds-controller-tfstate-820537372947 | |
| jobs: | |
| # ========================================================================== | |
| # Build and Test | |
| # ========================================================================== | |
| build: | |
| name: Build and Test | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Go | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version: ${{ env.GO_VERSION }} | |
| - name: Cache Go modules | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/go/pkg/mod | |
| key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} | |
| restore-keys: | | |
| ${{ runner.os }}-go- | |
| - name: Download dependencies | |
| run: | | |
| cd ${{ github.workspace }} | |
| GOPROXY=direct go mod download | |
| - name: Build xDS Controller | |
| run: | | |
| GOPROXY=direct go build -v ./... | |
| - name: Run tests | |
| run: | | |
| GOPROXY=direct go test -v -race ./... | |
| - name: Build mock service | |
| run: | | |
| cd mock-service | |
| GOPROXY=direct go build -v . | |
| # ========================================================================== | |
| # Build and Push Docker Images | |
| # ========================================================================== | |
| docker: | |
| name: Build and Push Docker Images | |
| runs-on: ubuntu-latest | |
| needs: build | |
| if: github.event_name == 'push' || github.event.inputs.deploy == 'true' | |
| outputs: | |
| xds_image: ${{ steps.build-xds.outputs.image }} | |
| mock_image: ${{ steps.build-mock.outputs.image }} | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Configure AWS credentials | |
| uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
| aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
| aws-region: ${{ env.AWS_REGION }} | |
| - name: Login to Amazon ECR | |
| id: login-ecr | |
| uses: aws-actions/amazon-ecr-login@v2 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| # Initialize Terraform to get ECR URLs | |
| - name: Setup Terraform | |
| uses: hashicorp/setup-terraform@v3 | |
| with: | |
| terraform_version: ${{ env.TF_VERSION }} | |
| terraform_wrapper: false | |
| - name: Create Terraform state bucket if not exists | |
| run: | | |
| if ! aws s3api head-bucket --bucket ${{ env.TF_STATE_BUCKET }} 2>/dev/null; then | |
| echo "Creating S3 bucket for Terraform state..." | |
| aws s3api create-bucket \ | |
| --bucket ${{ env.TF_STATE_BUCKET }} \ | |
| --region ${{ env.AWS_REGION }} \ | |
| --create-bucket-configuration LocationConstraint=${{ env.AWS_REGION }} | |
| aws s3api put-bucket-versioning \ | |
| --bucket ${{ env.TF_STATE_BUCKET }} \ | |
| --versioning-configuration Status=Enabled | |
| else | |
| echo "Terraform state bucket already exists" | |
| fi | |
| - name: Terraform Init | |
| working-directory: infrastructure | |
| run: terraform init | |
| - name: Get ECR URLs | |
| id: ecr-urls | |
| working-directory: infrastructure | |
| run: | | |
| # Check if state exists and has ECR resources | |
| if terraform state list 2>/dev/null | grep -q "aws_ecr_repository"; then | |
| echo "ECR repositories exist in state, getting URLs..." | |
| XDS_ECR=$(terraform output -raw ecr_xds_controller_url) | |
| MOCK_ECR=$(terraform output -raw ecr_mock_service_url) | |
| else | |
| # ECR doesn't exist yet, create repos | |
| echo "Creating ECR repositories..." | |
| terraform apply -target=aws_ecr_repository.xds_controller -target=aws_ecr_repository.mock_service -auto-approve | |
| XDS_ECR=$(terraform output -raw ecr_xds_controller_url) | |
| MOCK_ECR=$(terraform output -raw ecr_mock_service_url) | |
| fi | |
| echo "xds_ecr=$XDS_ECR" >> $GITHUB_OUTPUT | |
| echo "mock_ecr=$MOCK_ECR" >> $GITHUB_OUTPUT | |
| - name: Build and push xDS Controller image | |
| id: build-xds | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: . | |
| file: deployments/docker/Dockerfile | |
| push: true | |
| tags: | | |
| ${{ steps.ecr-urls.outputs.xds_ecr }}:latest | |
| ${{ steps.ecr-urls.outputs.xds_ecr }}:${{ github.sha }} | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| - name: Build and push mock service image | |
| id: build-mock | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: mock-service | |
| file: mock-service/Dockerfile | |
| push: true | |
| tags: | | |
| ${{ steps.ecr-urls.outputs.mock_ecr }}:latest | |
| ${{ steps.ecr-urls.outputs.mock_ecr }}:${{ github.sha }} | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| - name: Output image tags | |
| run: | | |
| echo "xDS Controller image: ${{ steps.ecr-urls.outputs.xds_ecr }}:${{ github.sha }}" | |
| echo "Mock service image: ${{ steps.ecr-urls.outputs.mock_ecr }}:${{ github.sha }}" | |
| # ========================================================================== | |
| # Deploy Infrastructure | |
| # ========================================================================== | |
| deploy: | |
| name: Deploy Infrastructure | |
| runs-on: ubuntu-latest | |
| needs: docker | |
| if: github.event_name == 'push' || github.event.inputs.deploy == 'true' | |
| environment: production | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Configure AWS credentials | |
| uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
| aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
| aws-region: ${{ env.AWS_REGION }} | |
| - name: Setup Terraform | |
| uses: hashicorp/setup-terraform@v3 | |
| with: | |
| terraform_version: ${{ env.TF_VERSION }} | |
| - name: Create Terraform state bucket if not exists | |
| run: | | |
| if ! aws s3api head-bucket --bucket ${{ env.TF_STATE_BUCKET }} 2>/dev/null; then | |
| echo "Creating S3 bucket for Terraform state..." | |
| aws s3api create-bucket \ | |
| --bucket ${{ env.TF_STATE_BUCKET }} \ | |
| --region ${{ env.AWS_REGION }} \ | |
| --create-bucket-configuration LocationConstraint=${{ env.AWS_REGION }} | |
| aws s3api put-bucket-versioning \ | |
| --bucket ${{ env.TF_STATE_BUCKET }} \ | |
| --versioning-configuration Status=Enabled | |
| else | |
| echo "Terraform state bucket already exists" | |
| fi | |
| - name: Terraform Init | |
| working-directory: infrastructure | |
| run: terraform init | |
| - name: Terraform Plan | |
| working-directory: infrastructure | |
| run: terraform plan -out=tfplan | |
| - name: Terraform Apply | |
| working-directory: infrastructure | |
| run: terraform apply -auto-approve tfplan | |
| - name: Get outputs | |
| id: tf-outputs | |
| working-directory: infrastructure | |
| run: | | |
| echo "alb_url=$(terraform output -raw alb_url)" >> $GITHUB_OUTPUT | |
| echo "cluster_name=$(terraform output -raw ecs_cluster_name)" >> $GITHUB_OUTPUT | |
| - name: Wait for services to stabilize | |
| run: | | |
| echo "Waiting for ECS services to stabilize..." | |
| sleep 120 | |
| - name: Run smoke tests | |
| run: | | |
| ALB_URL="${{ steps.tf-outputs.outputs.alb_url }}" | |
| echo "Testing ALB at: $ALB_URL" | |
| # Test each mock tenant | |
| for i in 1 2 3; do | |
| HOSTNAME="tenant-${i}.test.local" | |
| echo "Testing $HOSTNAME..." | |
| RESPONSE=$(curl -sf -H "Host: $HOSTNAME" "$ALB_URL/" || echo "FAILED") | |
| echo "Response: $RESPONSE" | |
| if echo "$RESPONSE" | grep -q "tenant-${i}"; then | |
| echo "✓ $HOSTNAME routing works!" | |
| else | |
| echo "✗ $HOSTNAME routing failed!" | |
| fi | |
| done | |
| - name: Print test commands | |
| working-directory: infrastructure | |
| run: | | |
| echo "=== Deployment Complete ===" | |
| echo "" | |
| terraform output test_commands | |
| echo "" | |
| echo "ALB URL: ${{ steps.tf-outputs.outputs.alb_url }}" | |
| # ========================================================================== | |
| # Destroy Infrastructure (manual trigger only) | |
| # ========================================================================== | |
| destroy: | |
| name: Destroy Infrastructure | |
| runs-on: ubuntu-latest | |
| if: github.event.inputs.destroy == 'true' | |
| environment: production | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Configure AWS credentials | |
| uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
| aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
| aws-region: ${{ env.AWS_REGION }} | |
| - name: Setup Terraform | |
| uses: hashicorp/setup-terraform@v3 | |
| with: | |
| terraform_version: ${{ env.TF_VERSION }} | |
| - name: Create Terraform state bucket if not exists | |
| run: | | |
| if ! aws s3api head-bucket --bucket ${{ env.TF_STATE_BUCKET }} 2>/dev/null; then | |
| echo "Creating S3 bucket for Terraform state..." | |
| aws s3api create-bucket \ | |
| --bucket ${{ env.TF_STATE_BUCKET }} \ | |
| --region ${{ env.AWS_REGION }} \ | |
| --create-bucket-configuration LocationConstraint=${{ env.AWS_REGION }} | |
| aws s3api put-bucket-versioning \ | |
| --bucket ${{ env.TF_STATE_BUCKET }} \ | |
| --versioning-configuration Status=Enabled | |
| else | |
| echo "Terraform state bucket already exists" | |
| fi | |
| - name: Terraform Init | |
| working-directory: infrastructure | |
| run: terraform init | |
| - name: Terraform Destroy | |
| working-directory: infrastructure | |
| run: terraform destroy -auto-approve |