<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: 🚀 Vu Dao 🚀 </title>
    <description>The latest articles on Forem by 🚀 Vu Dao 🚀  (@vumdao).</description>
    <link>https://forem.com/vumdao</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F512906%2F83cde530-e04d-4510-90e4-d73bd4d1e7bd.png</url>
      <title>Forem: 🚀 Vu Dao 🚀 </title>
      <link>https://forem.com/vumdao</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/vumdao"/>
    <language>en</language>
    <item>
      <title>CI Load Test for http-echo using Kind and k6</title>
      <dc:creator>🚀 Vu Dao 🚀 </dc:creator>
      <pubDate>Sat, 10 Jan 2026 03:48:41 +0000</pubDate>
      <link>https://forem.com/vumdao/ci-load-test-for-http-echo-using-kind-and-k6-4nab</link>
      <guid>https://forem.com/vumdao/ci-load-test-for-http-echo-using-kind-and-k6-4nab</guid>
      <description>&lt;h2&gt;
  
  
  Assignment
&lt;/h2&gt;

&lt;p&gt;Build a CI Load Test for &lt;code&gt;http-echo&lt;/code&gt; applications using Kind (Kubernetes in Docker) and the k6 load testing tool.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution Overview
&lt;/h2&gt;

&lt;p&gt;This project implements a comprehensive load testing solution using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Kind&lt;/strong&gt;: Creates a multi-node Kubernetes cluster for realistic testing environments&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NGINX Ingress Controller&lt;/strong&gt;: Routes HTTP requests to different services based on hostnames&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;k6&lt;/strong&gt;: Performs load testing with detailed metrics and performance analysis&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Architecture
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────┐    ┌──────────────────┐    ┌─────────────────┐
│   k6 Load Test  │───▶│  NGINX Ingress   │───▶│  http-echo apps │
│                 │    │   Controller     │    │                 │
│ - foo.localhost │    │                  │    │ - foo service   │
│ - bar.localhost │    │  (Port 80/443)   │    │ - bar service   │
└─────────────────┘    └──────────────────┘    └─────────────────┘
                                │
                                ▼
                       ┌──────────────────┐
                       │   Kind Cluster   │
                       │                  │
                       │ - Control plane  │
                       │ - Worker node    │
                       └──────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Project Structure
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kind-http-echo-test/
├── README.md                   # This documentation
├── kind-config.yaml           # Kind cluster configuration
├── k8s/                       # Kubernetes manifests
│   ├── http-echo-foo.yaml     # Foo service deployment
│   └── http-echo-bar.yaml     # Bar service deployment
└── loadtest/                  # Load testing scripts
    └── load-test.js           # k6 load test script
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Ensure you have the following tools installed in your CI environment:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.docker.com/get-docker/" rel="noopener noreferrer"&gt;Docker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kind.sigs.k8s.io/docs/user/quick-start/#installation" rel="noopener noreferrer"&gt;Kind&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kubernetes.io/docs/tasks/tools/" rel="noopener noreferrer"&gt;kubectl&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://k6.io/docs/get-started/installation/" rel="noopener noreferrer"&gt;k6&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  CI Workflow
&lt;/h2&gt;

&lt;p&gt;This project is designed for automated CI/CD pipelines that trigger on each pull request to the default branch. The workflow consists of four main stages executed sequentially:&lt;/p&gt;

&lt;h3&gt;
  
  
  Stage 1: Environment Setup
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Purpose&lt;/strong&gt;: Prepare the CI runner with all necessary tools and dependencies, supporting both AMD64 and ARM64 agents.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Activities&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Checkout the source code from the repository&lt;/li&gt;
&lt;li&gt;Install k6 load testing tool via package manager&lt;/li&gt;
&lt;li&gt;Download and install Kind for local Kubernetes clusters&lt;/li&gt;
&lt;li&gt;Set up kubectl for cluster management&lt;/li&gt;
&lt;li&gt;Configure necessary permissions and environment variables&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Stage 2: Cluster Provisioning
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Purpose&lt;/strong&gt;: Create and configure a complete Kubernetes environment for testing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Activities&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a multi-node Kind cluster using the project configuration&lt;/li&gt;
&lt;li&gt;Install NGINX Ingress Controller for request routing&lt;/li&gt;
&lt;li&gt;Wait for all control plane components to become ready&lt;/li&gt;
&lt;li&gt;Deploy the http-echo applications (foo and bar services)&lt;/li&gt;
&lt;li&gt;Verify all pods are running and services are accessible&lt;/li&gt;
&lt;li&gt;Configure ingress rules for hostname-based routing&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Stage 3: Load Testing
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Purpose&lt;/strong&gt;: Execute comprehensive load testing against the deployed services.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Activities&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Verify endpoint availability with health checks&lt;/li&gt;
&lt;li&gt;Execute k6 load test script with predefined scenarios&lt;/li&gt;
&lt;li&gt;Monitor real-time performance metrics during testing&lt;/li&gt;
&lt;li&gt;Generate detailed test results in JSON format&lt;/li&gt;
&lt;li&gt;Track custom metrics for both foo and bar services&lt;/li&gt;
&lt;li&gt;Capture response times, error rates, and throughput data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Test Configuration&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ramp-up&lt;/strong&gt;: 10s to reach target load&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sustained load&lt;/strong&gt;: 30s at peak virtual users&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ramp-down&lt;/strong&gt;: 10s to zero load&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance thresholds&lt;/strong&gt;: P95 &amp;lt; 500ms, Error rate &amp;lt; 10%&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Stage 4: Results Analysis
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Purpose&lt;/strong&gt;: Validate performance requirements and clean up resources.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Activities&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Parse JSON test results for key performance indicators&lt;/li&gt;
&lt;li&gt;Validate against predefined performance thresholds&lt;/li&gt;
&lt;li&gt;Generate human-readable test summary&lt;/li&gt;
&lt;li&gt;Fail the pipeline if performance criteria are not met&lt;/li&gt;
&lt;li&gt;Upload test artifacts for later analysis&lt;/li&gt;
&lt;li&gt;Clean up the Kind cluster to free resources&lt;/li&gt;
&lt;li&gt;Provide detailed feedback on test outcomes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Success Criteria&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;All requests complete successfully (&amp;lt; 10% error rate)&lt;/li&gt;
&lt;li&gt;Response times meet SLA requirements (P95 &amp;lt; 500ms)&lt;/li&gt;
&lt;li&gt;Both services perform within acceptable ranges&lt;/li&gt;
&lt;li&gt;No infrastructure errors during testing&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🚀 Load Testing Configuration
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="//loadtest/load-test.js"&gt;load-test.js&lt;/a&gt; script provides comprehensive load testing capabilities with the following configuration:&lt;/p&gt;

&lt;h3&gt;
  
  
  📊 Test Execution Stages
&lt;/h3&gt;

&lt;p&gt;The load test follows a three-phase approach for realistic performance assessment:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Phase&lt;/th&gt;
&lt;th&gt;Duration&lt;/th&gt;
&lt;th&gt;Virtual Users&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;🔼 &lt;strong&gt;Ramp-up&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10 seconds&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0 → 10 users&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Gradual load increase to target capacity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🎯 &lt;strong&gt;Sustained Load&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;30 seconds&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;20 users&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Peak performance evaluation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🔽 &lt;strong&gt;Ramp-down&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10 seconds&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;20 → 0 users&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Graceful load reduction&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  ⚡ Performance Thresholds
&lt;/h3&gt;

&lt;p&gt;Critical performance criteria that must be met for test success:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Response Time&lt;/strong&gt;: 📈 95% of requests must complete under &lt;strong&gt;500ms&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Error Rate&lt;/strong&gt;: ❌ Must remain below &lt;strong&gt;10%&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Service Availability&lt;/strong&gt;: ✅ Both foo and bar services must be responsive&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  📈 Custom Metrics &amp;amp; Monitoring
&lt;/h3&gt;

&lt;p&gt;Advanced monitoring capabilities for detailed performance analysis:&lt;/p&gt;

&lt;h4&gt;
  
  
  🎯 Host-Specific Metrics
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Per-host Response Times&lt;/strong&gt;: Individual performance tracking for &lt;code&gt;foo&lt;/code&gt; and &lt;code&gt;bar&lt;/code&gt; services&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Load Distribution&lt;/strong&gt;: Ensures balanced traffic across both deployments&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Service Health&lt;/strong&gt;: Real-time availability monitoring&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  🔍 Real-Time Tracking
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Error Rate Monitoring&lt;/strong&gt;: Continuous failure rate assessment&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Request Distribution&lt;/strong&gt;: Balanced load verification across services&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance Degradation&lt;/strong&gt;: Early detection of performance issues&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  📋 Test Results &amp;amp; Output
&lt;/h3&gt;

&lt;p&gt;Comprehensive reporting for performance analysis:&lt;/p&gt;

&lt;h4&gt;
  
  
  🖥️ Console Output
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Real-time metrics display during test execution&lt;/li&gt;
&lt;li&gt;Live performance indicators and alerts&lt;/li&gt;
&lt;li&gt;Immediate feedback on test progress&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  📄 Detailed Reports
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;JSON Report&lt;/strong&gt;: Machine-readable results saved as &lt;a href="//loadtest-results.json"&gt;&lt;code&gt;loadtest-results.json&lt;/code&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Per-Host Breakdown&lt;/strong&gt;: Individual service performance analysis&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Threshold Validation&lt;/strong&gt;: Pass/fail status for each performance criterion&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  📊 Key Metrics Captured
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Request rate (requests/second)&lt;/li&gt;
&lt;li&gt;Response time percentiles (P90, P95, P99)&lt;/li&gt;
&lt;li&gt;Error distribution by service&lt;/li&gt;
&lt;li&gt;Host-specific performance characteristics&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  📊 Monitoring and Metrics
&lt;/h2&gt;

&lt;h3&gt;
  
  
  k6 Metrics Collection
&lt;/h3&gt;

&lt;p&gt;Comprehensive performance data captured during load testing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Request Rate&lt;/strong&gt;: Requests per second across all endpoints&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Response Time&lt;/strong&gt;: Average, minimum, maximum, P90, and P95 percentiles&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Error Rate&lt;/strong&gt;: Percentage of failed requests with detailed error categorization&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Host-specific Metrics&lt;/strong&gt;: Individual performance analysis per service (foo/bar)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  📋 Sample Test Results
&lt;/h3&gt;

&lt;p&gt;Example output from a successful load testing execution:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Total Requests"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;450&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Requests/sec"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"9.00"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Request Duration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"avg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"25.34ms"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"min"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"10.12ms"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"max"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"89.45ms"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"p90"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"45.67ms"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"p95"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"52.34ms"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Failed Requests"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0.00%"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Foo Host Duration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"avg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"24.56ms"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"p90"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"44.23ms"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"p95"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"51.12ms"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Bar Host Duration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"avg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"26.12ms"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"p90"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"47.11ms"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"p95"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"53.56ms"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  📝 Project Completion Notes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  💡 Development Experience
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;GitHub Copilot Integration&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Successfully leveraged GitHub Copilot (GPT-4.1) to generate code with the following prompts:&lt;/li&gt;
&lt;li&gt;Create a Kind configuration for a Kubernetes cluster with 2 nodes, adding taints to the control-plane node to ensure only the ingress-nginx controller is deployed on it&lt;/li&gt;
&lt;li&gt;Add a step for deploying an Ingress controller to handle incoming HTTP requests in the CI workflow&lt;/li&gt;
&lt;li&gt;Create 2 http-echo deployments using the &lt;code&gt;hashicorp/http-echo:1.0&lt;/code&gt; image, one serving a "bar" response and another serving a "foo" response. Configure cluster/ingress routing to send traffic for the "bar" hostname to the bar deployment and "foo" hostname to the foo deployment on the local cluster (routing both &lt;a href="http://foo.localhost" rel="noopener noreferrer"&gt;http://foo.localhost&lt;/a&gt; and &lt;a href="http://bar.localhost" rel="noopener noreferrer"&gt;http://bar.localhost&lt;/a&gt;), where ingress rules are based on the request's host header&lt;/li&gt;
&lt;li&gt;Generate randomized traffic loads for both bar and foo hosts and capture load testing results using k6&lt;/li&gt;
&lt;li&gt;Add a CI workflow step at the beginning to modify &lt;code&gt;/etc/hosts&lt;/code&gt;, aliasing &lt;code&gt;foo.localhost&lt;/code&gt; and &lt;code&gt;bar.localhost&lt;/code&gt; to &lt;code&gt;127.0.0.1&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Create a CI workflow that triggers on each pull request to the master branch&lt;/li&gt;
&lt;li&gt;Use Github-copilot (Claude Sonnet 4) to write this document&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;strong&gt;Kind Learning Curve&lt;/strong&gt;: This was my first experience with Kind (Kubernetes in Docker). I spent considerable time understanding how Kind works, particularly the configuration required to expose services to localhost for external access and testing.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;strong&gt;Time Investment&lt;/strong&gt;: The complete project took approximately 5 hours to complete, including research, implementation, testing, and documentation.&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;




&lt;p&gt;Source: &lt;a href="https://github.com/vumdao/kind-http-echo-test" rel="noopener noreferrer"&gt;https://github.com/vumdao/kind-http-echo-test&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ref: Goodnotes Take Home Assignment - DevOps Engineering&lt;/p&gt;

&lt;p&gt;Note: The solution did not meet the team's expectations.&lt;/p&gt;

</description>
      <category>simflexcloud</category>
      <category>k8s</category>
      <category>kind</category>
      <category>k6</category>
    </item>
    <item>
      <title>Self-Hosted N8N on AWS ECS with AWS CDK Typescript</title>
      <dc:creator>🚀 Vu Dao 🚀 </dc:creator>
      <pubDate>Thu, 18 Dec 2025 16:04:34 +0000</pubDate>
      <link>https://forem.com/aws-builders/self-hosted-n8n-on-aws-ecs-with-aws-cdk-typescript-l6d</link>
      <guid>https://forem.com/aws-builders/self-hosted-n8n-on-aws-ecs-with-aws-cdk-typescript-l6d</guid>
      <description>&lt;h2&gt;
  
  
  📋 Abstract
&lt;/h2&gt;

&lt;p&gt;This repository provides Infrastructure as Code (IaC) solution for deploying a self-hosted N8N workflow automation platform on AWS using the AWS Cloud Development Kit (CDK). The solution implements a scalable, cost-optimized, and highly available architecture leveraging AWS ECS Fargate, PostgreSQL RDS database instance, and ElastiCache Redis for queue management.&lt;/p&gt;

&lt;h2&gt;
  
  
  📑 Table of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;🏗️ Architecture Overview&lt;/li&gt;
&lt;li&gt;🔍 Deep-Dive the Solution&lt;/li&gt;
&lt;li&gt;
🚀 Deploy CDK Stack and Test

&lt;ul&gt;
&lt;li&gt;📋 Prerequisites&lt;/li&gt;
&lt;li&gt;⚙️ Environment Setup&lt;/li&gt;
&lt;li&gt;🚀 Deployment Steps&lt;/li&gt;
&lt;li&gt;✅ Verify Deployment&lt;/li&gt;
&lt;li&gt;🧪 Testing N8N Workflows&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;🧹 Cleanup Stack&lt;/li&gt;

&lt;li&gt;🎉 Conclusion&lt;/li&gt;

&lt;li&gt;📚 References&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  🏗️ Architecture Overview
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyqou0xyoqrqxqf5s8ye5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyqou0xyoqrqxqf5s8ye5.png" alt="Architecture Flow" width="800" height="301"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Components:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;VPC with Multi-AZ Subnets&lt;/strong&gt;: Isolated network with public, private, and isolated subnets across multiple availability zones&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Network Load Balancer (NLB)&lt;/strong&gt;: Distributes HTTPS traffic to N8N main service instances&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ECS Fargate Cluster&lt;/strong&gt;: Runs containerized N8N services with auto-scaling capabilities&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RDS PostgreSQL&lt;/strong&gt;: Multi-AZ managed database for workflow data persistence&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ElastiCache Redis&lt;/strong&gt;: In-memory cache for BullMQ job queue management&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AWS Cloud Map&lt;/strong&gt;: Service discovery for internal service-to-service communication&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🔍 Deep-Dive the Solution
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fvumdao%2Faws-cdk-self-hosted-n8n-infra%2Fraw%2Fmaster%2Fdocs%2Fimages%2Fdiagram.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fvumdao%2Faws-cdk-self-hosted-n8n-infra%2Fraw%2Fmaster%2Fdocs%2Fimages%2Fdiagram.png" alt="Detailed Architecture Diagram" width="800" height="333"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 Deploy CDK Stack and Test
&lt;/h2&gt;

&lt;h3&gt;
  
  
  📋 Prerequisites
&lt;/h3&gt;

&lt;p&gt;Before deploying, ensure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AWS CLI installed and configured (&lt;code&gt;aws configure&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Node.js 16+ and pnpm installed&lt;/li&gt;
&lt;li&gt;AWS CDK CLI installed (&lt;code&gt;npm install -g aws-cdk&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;An AWS account with appropriate permissions&lt;/li&gt;
&lt;li&gt;A Route53 hosted zone (optional, for custom domain)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ⚙️ Environment Setup
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Clone the repository:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/vumdao/aws-cdk-self-hosted-n8n-infra
&lt;span class="nb"&gt;cd &lt;/span&gt;aws-cdk-self-hosted-n8n-infra
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Install dependencies:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Configure environment variables:&lt;/strong&gt; Create a &lt;code&gt;.env&lt;/code&gt; file in the root directory:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CDK_DEFAULT_ACCOUNT=your-aws-account-id
CDK_DEFAULT_REGION=your-aws-region
HOSTED_ZONE_NAME=example.com
HOSTED_ZONE_ID=Z1234567890ABC
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🚀 Deployment Steps
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Synthesize CloudFormation template:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm run synth
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Review the changes:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm run diff
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Deploy the stack:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm run deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ✅ Verify Deployment
&lt;/h3&gt;

&lt;p&gt;After successful deployment, verify the resources in AWS Console:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. ECS Cluster:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flsliw30796u1me5csgks.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flsliw30796u1me5csgks.png" alt="ECS Cluster" width="800" height="296"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The ECS cluster shows both N8N services running with the configured task definitions and capacity providers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Main Service:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvkravfj7hoia20gndyt6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvkravfj7hoia20gndyt6.png" alt="Main Service" width="800" height="351"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The N8N main service displays running tasks, auto-scaling configuration, and health status.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Worker Service:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1m1wrmci0guk9pdwadkl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1m1wrmci0guk9pdwadkl.png" alt="Worker Service" width="800" height="350"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The worker service shows active workers processing queued jobs with concurrency settings.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Network Load Balancer:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft48xq8zl8f138ncvchme.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft48xq8zl8f138ncvchme.png" alt="NLB" width="800" height="347"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The NLB shows the listener configuration and DNS name which is used to create alias record in route53.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Target Group:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx7a3x1lcp2gne0za5634.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx7a3x1lcp2gne0za5634.png" alt="Target Group" width="800" height="319"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The target group displays registered ECS tasks with health check status and routing configuration.&lt;/p&gt;

&lt;h3&gt;
  
  
  🧪 Testing N8N Workflows
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Access N8N UI:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Navigate to your NLB DNS name or custom domain (if configured):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://n8n.simflexcloud.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8w1nhkxy8jg6znfexoco.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8w1nhkxy8jg6znfexoco.png" alt="N8N Interface" width="800" height="388"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The N8N interface shows the workflow editor where you can create, test, and monitor automation workflows.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Create a Test Workflow:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Example workflow: Send an inspirational quote from internet to Slack daily&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Verify Execution:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff7morbamppz952vppe8z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff7morbamppz952vppe8z.png" alt="Slack Integration" width="781" height="627"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Slack integration demonstrates successful workflow execution with the message being delivered to the configured Slack channel.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧹 Cleanup Stack
&lt;/h2&gt;

&lt;p&gt;To avoid ongoing AWS charges, destroy all resources:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Destroy the CDK stack&lt;/span&gt;
pnpm run destroy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🎉 Conclusion
&lt;/h2&gt;

&lt;p&gt;This CDK solution provides a scalable, and cost-optimized infrastructure as code (AWS CDK) for running N8N on AWS ECS.&lt;/p&gt;




&lt;h2&gt;
  
  
  📚 References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/azmimengu/aws-cdk-self-hosted-n8n-infra" rel="noopener noreferrer"&gt;https://github.com/azmimengu/aws-cdk-self-hosted-n8n-infra&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>simflexcloud</category>
      <category>cdk</category>
      <category>ecs</category>
      <category>n8n</category>
    </item>
    <item>
      <title>ClamAV (Anti-Virus) as a REST application on AWS ECS</title>
      <dc:creator>🚀 Vu Dao 🚀 </dc:creator>
      <pubDate>Tue, 09 Dec 2025 15:50:59 +0000</pubDate>
      <link>https://forem.com/aws-builders/clamav-anti-virus-as-a-rest-application-on-aws-ecs-1d0e</link>
      <guid>https://forem.com/aws-builders/clamav-anti-virus-as-a-rest-application-on-aws-ecs-1d0e</guid>
      <description>&lt;h2&gt;
  
  
  📋 Abstract
&lt;/h2&gt;

&lt;p&gt;This project provides an AWS CDK solution for automated virus scanning of S3 objects using ClamAV. It addresses the performance limitations of serverless ClamAV implementations by running ClamAV daemon (&lt;code&gt;clamd&lt;/code&gt;) as a containerized REST API on AWS ECS Fargate. This architecture eliminates the 15-30 second cold start delay associated with loading ClamAV libraries in Lambda functions, enabling near-instant scan results.&lt;/p&gt;

&lt;p&gt;The solution uses a hybrid approach: ECS Fargate hosts the persistent ClamAV daemon service, while Lambda functions handle S3 event processing and orchestration. Files uploaded to monitored S3 buckets trigger Lambda functions that call the ClamAV REST API, which performs fast scans using the pre-loaded daemon. Results are published to SNS topics for downstream processing.&lt;/p&gt;

&lt;h2&gt;
  
  
  📚 Table of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;📋 Abstract&lt;/li&gt;
&lt;li&gt;📚 Table of Contents&lt;/li&gt;
&lt;li&gt;⚠️ Opening Problems&lt;/li&gt;
&lt;li&gt;
🏗️ Architecture Overview

&lt;ul&gt;
&lt;li&gt;💻 Infrastructure as Code with AWS CDK&lt;/li&gt;
&lt;li&gt;🔧 Core Infrastructure&lt;/li&gt;
&lt;li&gt;📦 Application Components&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

🔍 Deep-dive the Solution

&lt;ul&gt;
&lt;li&gt;🛡️ 1. ClamAV REST API on ECS Fargate&lt;/li&gt;
&lt;li&gt;📢 2. Result Notification System&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

🚀 Deploy CDK Stack and Test

&lt;ul&gt;
&lt;li&gt;✅ Prerequisites&lt;/li&gt;
&lt;li&gt;📥 Installation and Deployment&lt;/li&gt;
&lt;li&gt;🧪 Testing the Solution&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;🧹 Cleanup Stack&lt;/li&gt;

&lt;li&gt;🎯 Conclusion&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  ⚠️ Opening Problems
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://github.com/awslabs/cdk-serverless-clamscan" rel="noopener noreferrer"&gt;cdk-serverless-clamscan&lt;/a&gt; project provides a serverless solution for scanning S3 objects with ClamAV using AWS Lambda. While this approach offers simplicity and automatic scaling, it suffers from a critical performance limitation:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cold Start Delay:&lt;/strong&gt; Lambda functions must load the entire ClamAV scanning library on each lambda invocation, resulting in &lt;strong&gt;15-30 second delays&lt;/strong&gt; before scanning can begin. This makes the solution impractical for time-sensitive workloads or high-volume scanning scenarios.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Solution:&lt;/strong&gt; As suggested in the &lt;a href="https://github.com/Cisco-Talos/clamav/issues/849#issuecomment-1472640852" rel="noopener noreferrer"&gt;ClamAV GitHub discussion&lt;/a&gt;, using &lt;code&gt;clamd&lt;/code&gt; (ClamAV daemon) as a persistent service significantly improves performance. The daemon pre-loads virus definitions into memory and remains running, allowing scans via &lt;code&gt;clamdscan&lt;/code&gt; to execute instantly without initialization overhead.&lt;/p&gt;

&lt;p&gt;This project implements that recommendation by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Running &lt;code&gt;clamd&lt;/code&gt; as a containerized REST API on AWS ECS Fargate&lt;/li&gt;
&lt;li&gt;Using Lambda functions to orchestrate S3 event processing&lt;/li&gt;
&lt;li&gt;Calling the persistent ClamAV API for near-instant scan results&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🏗️ Architecture Overview
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fctuyo3jeftj6mb0d7sd5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fctuyo3jeftj6mb0d7sd5.png" alt="Architecture Flow" width="681" height="761"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  💻 Infrastructure as Code with AWS CDK
&lt;/h3&gt;

&lt;p&gt;This project uses &lt;strong&gt;AWS CDK (Cloud Development Kit)&lt;/strong&gt; with TypeScript to define and provision all infrastructure resources.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CDK Project Structure:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/
├── bin/main.ts                          # CDK app entry point
├── lib/
│   ├── stacks/
│   │   └── s3-clamav-scan-stack.ts     # Main stack orchestration
│   ├── constructs/
│   │   ├── ecs-cluster-provider/       # ECS cluster, NLB, ClamAV service
│   │   └── s3-serverless-clamscan/     # Lambda scanner, SNS, SQS
│   └── shared/
│       ├── environment.ts               # Environment configurations
│       └── constants.ts                 # Shared constants
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fvumdao%2Fcdk-clamav-rest-api-on-aws-ecs%2Fraw%2Fmaster%2Fdocs%2Fimages%2Fdiagram.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fvumdao%2Fcdk-clamav-rest-api-on-aws-ecs%2Fraw%2Fmaster%2Fdocs%2Fimages%2Fdiagram.png" alt="Infrastructure Diagram" width="800" height="578"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The solution consists of the following components:&lt;/p&gt;

&lt;h3&gt;
  
  
  🔧 Core Infrastructure
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;VPC with Multi-AZ Configuration&lt;/strong&gt;: Isolated network with public, private-isolated, and private-with-egress subnets&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ECS Fargate Cluster&lt;/strong&gt;: Hosts the ClamAV REST API containers with Fargate Spot for cost optimization&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Network Load Balancer (NLB)&lt;/strong&gt;: Internal load balancer for distributing traffic to ClamAV API containers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;S3 Gateway Endpoint&lt;/strong&gt;: Direct S3 access from private subnets without NAT gateway costs&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  📦 Application Components
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ClamAV REST API&lt;/strong&gt;: Flask-based API running in Docker containers with &lt;code&gt;clamd&lt;/code&gt;, &lt;code&gt;nginx&lt;/code&gt;, and &lt;code&gt;uwsgi&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lambda Scanner Function&lt;/strong&gt;: Python function triggered by S3 events to orchestrate scanning&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;S3 Upload Bucket event trigger&lt;/strong&gt;: Monitored bucket where files are uploaded for scanning&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SNS Topics&lt;/strong&gt;: Separate topics for clean and infected file notifications&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SQS Error Queue&lt;/strong&gt;: Dead letter queue for failed scan operations with retry logic&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🔍 Deep-dive the Solution
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🛡️ 1. ClamAV REST API on ECS Fargate
&lt;/h3&gt;

&lt;p&gt;The ClamAV API is containerized and runs on ECS Fargate, providing a scalable and persistent scanning service.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Docker Container Components:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="c"&gt;# Key components from Dockerfile&lt;/span&gt;
- Base: python:3.14-bookworm
- ClamAV packages: clamav, clamav-daemon
- Web stack: nginx, uwsgi, Flask
- Process manager: supervisor
- Fresh virus definitions via freshclam
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;API Endpoints:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;GET /&lt;/code&gt; - Health check endpoint (returns "OK")&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;POST /scan_file&lt;/code&gt; - Scan endpoint accepting JSON payload with S3 bucket and key&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  📢 2. Result Notification System
&lt;/h3&gt;

&lt;p&gt;The solution uses SNS topics to notify downstream systems of scan results:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SNS Topics:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;clamav-clean-topic&lt;/code&gt;: Notifications for clean files&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;clamav-infected-topic&lt;/code&gt;: Notifications for infected files&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Message Format:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"input_bucket"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bucket-name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"input_key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"path/to/file.pdf"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"CLEAN"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"INFECTED"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Scanning bucket-name/path/to/file.pdf&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;ClamAV output&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Use Cases:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Clean Files&lt;/strong&gt;: Trigger downstream processing (e.g., move to processed bucket, extract metadata)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Infected Files&lt;/strong&gt;: Quarantine, alert security team, delete, or move to isolated bucket&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integration&lt;/strong&gt;: Subscribe Lambda, SQS, email, or other services to topics&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🚀 Deploy CDK Stack and Test
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ✅ Prerequisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;AWS account with appropriate permissions&lt;/li&gt;
&lt;li&gt;AWS CDK CLI installed (&lt;code&gt;npm install -g aws-cdk&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Node.js 16+ and pnpm package manager&lt;/li&gt;
&lt;li&gt;Docker for building container images&lt;/li&gt;
&lt;li&gt;AWS CLI configured with credentials&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  📥 Installation and Deployment
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Clone the repository:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/vumdao/cdk-clamav-rest-api-on-aws-ecs.git
&lt;span class="nb"&gt;cd &lt;/span&gt;cdk-clamav-rest-api-on-aws-ecs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Install dependencies:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Deploy the stack:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm run deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Build and push Docker image to ECR:&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;During the cdk deployment, build and push the ClamAV API Docker image:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Navigate to the Dockerfile directory&lt;/span&gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;src/lib/constructs/s3-serverless-clamscan/clamd-api

&lt;span class="c"&gt;# Build the Docker image&lt;/span&gt;
docker build &lt;span class="nt"&gt;-t&lt;/span&gt; simflexcloud/clamav-api &lt;span class="nb"&gt;.&lt;/span&gt;

&lt;span class="c"&gt;# Authenticate Docker to your ECR registry (replace region and account ID)&lt;/span&gt;
aws ecr get-login-password &lt;span class="nt"&gt;--region&lt;/span&gt; ap-southeast-1 | docker login &lt;span class="nt"&gt;--username&lt;/span&gt; AWS &lt;span class="nt"&gt;--password-stdin&lt;/span&gt; 123456789012.dkr.ecr.ap-southeast-1.amazonaws.com

&lt;span class="c"&gt;# Tag the image for ECR&lt;/span&gt;
docker tag simflexcloud/clamav-api:latest 123456789012.dkr.ecr.ap-southeast-1.amazonaws.com/simflexcloud/clamav-api:latest

&lt;span class="c"&gt;# Push the image to ECR&lt;/span&gt;
docker push 123456789012.dkr.ecr.ap-southeast-1.amazonaws.com/simflexcloud/clamav-api:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Expected Output:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;✅  S3ClamAvStack

Outputs:
S3ClamAvStack.EcsClusterProviderclamav-apiEndpoint = nlb-xxxx.elb.ap-southeast-1.amazonaws.com:5000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdf499mcq3dzgg2wmkiaq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdf499mcq3dzgg2wmkiaq.png" alt="S3 Event Trigger lambda function" width="800" height="322"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  🧪 Testing the Solution
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Test with clean file:&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdm4xvjoqv6n8hfakl4tm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdm4xvjoqv6n8hfakl4tm.png" alt="Upload clean file" width="800" height="350"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6zhvkvd6ef7p6dc8mkk9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6zhvkvd6ef7p6dc8mkk9.png" alt="Scan result" width="800" height="349"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Test with the EICAR test virus&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxzyhhmebltp78cqc6o7f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxzyhhmebltp78cqc6o7f.png" alt="Upload virus file" width="800" height="326"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk3pd5elwlzub3ke6vhek.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk3pd5elwlzub3ke6vhek.png" alt="Scan result" width="800" height="411"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🧹 Cleanup Stack
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Destroy the CDK stack:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm run destroy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🎯 Conclusion
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;This solution successfully addresses the performance limitations of serverless ClamAV implementations by leveraging a persistent &lt;code&gt;clamd&lt;/code&gt; daemon running on ECS Fargate. Key achievements include:&lt;/li&gt;
&lt;li&gt;This architecture demonstrates how combining AWS managed services (ECS Fargate, Lambda, S3) with open-source tools (ClamAV) can create production-ready solutions that overcome the limitations of purely serverless approaches while maintaining operational simplicity and cost efficiency&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>simflexcloud</category>
      <category>cdk</category>
      <category>ecs</category>
      <category>clamav</category>
    </item>
    <item>
      <title>CDK AWS Aurora PostgreSQL Limitless</title>
      <dc:creator>🚀 Vu Dao 🚀 </dc:creator>
      <pubDate>Sat, 18 Jan 2025 16:04:02 +0000</pubDate>
      <link>https://forem.com/aws-builders/cdk-aws-aurora-postgresql-limitless-74n</link>
      <guid>https://forem.com/aws-builders/cdk-aws-aurora-postgresql-limitless-74n</guid>
      <description>&lt;h2&gt;
  
  
  Abstract
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The Amazon Aurora PostgreSQL Limitless Database is now generally available, offering an advanced solution to scale your Aurora cluster seamlessly. This technology enables millions of write transactions per second and supports petabytes of data, all while maintaining the simplicity of operating a single database instance.&lt;/li&gt;
&lt;li&gt;This post outlines a structured approach to creating an Amazon Aurora PostgreSQL Limitless Database using the AWS Cloud Development Kit (CDK) in TypeScript for demontration of Amazon Aurora PostgreSQL Limitless Database&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Table Of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Deploying Aurora PostgreSQL Limitless Database Using AWS CDK&lt;/li&gt;
&lt;li&gt;Test&lt;/li&gt;
&lt;li&gt;Check workload and scaling&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🚀 Deploying Aurora PostgreSQL Limitless Database Using AWS CDK &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The structure includes VPC, Aurora PostgreSQL Limitless Database with one shard group, secret manager for storing RDS credential, EC2 as bastion-host for access database in private network&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzuuv2o8qudkzedtj6j4z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzuuv2o8qudkzedtj6j4z.png" alt="alt text" width="800" height="1311"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Source code: &lt;a href="https://github.com/vumdao/cdk-aurora-postgres-limitless" rel="noopener noreferrer"&gt;https://github.com/vumdao/cdk-aurora-postgres-limitless&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  src
  ├── bin
  │   └── main.ts
  └── lib
      ├── cluster.ts
      └── shared
          ├── constants.ts
          ├── environment.ts
          ├── index.ts
          └── tagging.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Adjust &lt;code&gt;CDK_DEFAULT_REGION&lt;/code&gt; and &lt;code&gt;CDK_DEFAULT_ACCOUNT&lt;/code&gt; in &lt;code&gt;src/lib/shared/constants&lt;/code&gt; to yours&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Adjust the max&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  serverlessV2MaxCapacity: 64, // Adjust this for your test.
  serverlessV2MinCapacity: 16, // Minimum allow is 16
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Deploy
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  ✗ cdk ls
  AuroraPostgresLimitlessClusterStack

  ✗ cdk deploy AuroraPostgresLimitlessClusterStack
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🚀 Test &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Cluster created&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F826v0j5i6onm5rfh22ab.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F826v0j5i6onm5rfh22ab.png" alt="alt text" width="800" height="266"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to &lt;code&gt;sample_sql&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  cd sample_sql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Create E-Commerce sample schema's standard tables
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  \i create_standard_tables_ec_sample_schema.sql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Convert E-Commerce sample schema's standard tables to limitless tables
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  \i convert_standard_tables_to_limitless_ec_sample_schema.sql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Load data into the orders and orderdetails tables using &lt;code&gt;pgbench&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  pgbench  -n --client=500 --jobs=100 --progress=60 --transactions=2000  -f insert_orders_orderdetails_ec_sample_schema.sql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr2f4w2sho310r1m9kxxd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr2f4w2sho310r1m9kxxd.png" alt="alt text" width="800" height="103"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 Check workload and scaling &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Performance insight&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwtynaqgxa5msogdyr9jq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwtynaqgxa5msogdyr9jq.png" alt="alt text" width="800" height="379"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cloudwatch metrics&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb5unndf6r9dxmp96zwjl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb5unndf6r9dxmp96zwjl.png" alt="alt text" width="800" height="379"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Query limitless table&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq3nnmgbevqtwbl0gdjt9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq3nnmgbevqtwbl0gdjt9.png" alt="alt text" width="800" height="358"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Query database tables&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnforjj178sdjgcyuijbx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnforjj178sdjgcyuijbx.png" alt="alt text" width="646" height="639"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 Cleanup
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Destroy resources to avoid cost
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  cdk destroy AuroraPostgresLimitlessClusterStack
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🚀 Conclusion
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Give Aurora PostgreSQL Limitless Database a try by using AWS CDK to provision cluster faster and in secure way&lt;/li&gt;
&lt;li&gt;Remember to adjust the query size and time of running to avoid huge cost&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;References:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/franckpachot/series/29542"&gt;Aurora Limitless Series' Articles&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/aws-samples/sample-schemas-for-amazon-aurora-postgresql-limitless-database" rel="noopener noreferrer"&gt;Sample-schemas-for-amazon-aurora-postgresql-limitless-database&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>simflexcloud</category>
      <category>cdk</category>
      <category>ecs</category>
      <category>fargate</category>
    </item>
    <item>
      <title>ECS service-to-service communication</title>
      <dc:creator>🚀 Vu Dao 🚀 </dc:creator>
      <pubDate>Mon, 22 Jul 2024 16:02:27 +0000</pubDate>
      <link>https://forem.com/aws-builders/ecs-service-to-service-communication-4clk</link>
      <guid>https://forem.com/aws-builders/ecs-service-to-service-communication-4clk</guid>
      <description>&lt;h2&gt;
  
  
  Abstract
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Interconnect Amazon ECS services&lt;/strong&gt;: Applications that run in Amazon ECS tasks often need to connect to other applications that run in Amazon ECS services. If you need an application to connect to other applications that run in Amazon ECS services, Amazon ECS provides the following ways to do this without a load balancer:

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/AmazonECS/latest/developerguide/service-connect.html" rel="noopener noreferrer"&gt;Amazon ECS Service Connect&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/AmazonECS/latest/developerguide/service-discovery.html" rel="noopener noreferrer"&gt;Amazon ECS service discovery&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  🚀 Amazon ECS Service Connect &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Amazon ECS Service Connect enables easy communication between microservices and across Amazon Virtual Private Clouds (Amazon VPCs) by leveraging AWS Cloud Map namespaces and logical service names. This allows you to seamlessly distribute traffic between your Amazon ECS tasks without having to deploy, configure, and maintain load balancers.&lt;/li&gt;
&lt;li&gt;We recommend Service Connect, which provides Amazon ECS configuration for service discovery, connectivity, and traffic monitoring. With Service Connect, your applications can use short names and standard ports to connect to Amazon ECS services in the same cluster, other clusters, including across VPCs in the same AWS Region&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fecs-service-connect-cdk%2Frefs%2Fheads%2Fmaster%2Fdocs%2Fimages%2Fserviceconnect.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fecs-service-connect-cdk%2Frefs%2Fheads%2Fmaster%2Fdocs%2Fimages%2Fserviceconnect.png%3Fraw%3Dtrue" width="800" height="521"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 AWS ECS Service Connect vs Service Discovery &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Service Connect offers a significant advantage over plain Cloud Map for service discovery by providing faster failover when service instances go down. With DNS-based lookup in Cloud Map, the client may take some time (depending on the TTL settings) to recognize that it needs a new IP address when a service goes down. This delay can be exacerbated if the client library caches the same IP address for an extended period, or if the client's retry logic repeatedly attempts to connect to the same IP address after a failure.&lt;/li&gt;
&lt;li&gt;Service Connect, on the other hand, introduces a sidecar "proxy" container that intercepts outgoing connections and routes them to the correct destinations. Instead of relying on potentially stale DNS entries, the sidecar uses API calls to Cloud Map to look up the IP address of a healthy service instance in real-time. This method provides the standard benefits of a service mesh, like Envoy, with the added advantage that Service Connect manages the sidecar for you. For a more detailed discussion of these benefits, see the guide on migrating existing Amazon ECS services from service discovery to Amazon ECS Service Connect.&lt;/li&gt;
&lt;li&gt;Since Service Connect doesn't rely on DNS, it avoids registering even private DNS entries. Instead, it registers endpoints with Cloud Map that are privately discoverable only through API calls. There currently appears to be no option to configure Service Connect to register service names in DNS.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🚀 Deploying Sample Yelb Application for service connect with Amazon ECS and AWS CDK Typescript &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The Yelb application used in this demo was adapated from Massimo Re Ferrè's original application &lt;a href="https://github.com/mreferre/yelb" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fecs-service-connect-cdk%2Frefs%2Fheads%2Fmaster%2Fdocs%2Fimages%2Fyelb-architecture.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fecs-service-connect-cdk%2Frefs%2Fheads%2Fmaster%2Fdocs%2Fimages%2Fyelb-architecture.png%3Fraw%3Dtrue" width="800" height="448"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  📖 &lt;strong&gt;Solution overview&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fecs-service-connect-cdk%2Frefs%2Fheads%2Fmaster%2Fdocs%2Fimages%2Fsolution-architect.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fecs-service-connect-cdk%2Frefs%2Fheads%2Fmaster%2Fdocs%2Fimages%2Fsolution-architect.png%3Fraw%3Dtrue" width="800" height="624"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  📖 CDK Stacks
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fecs-service-connect-cdk%2Frefs%2Fheads%2Fmaster%2Fdocs%2Fimages%2Fdiagram.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fecs-service-connect-cdk%2Frefs%2Fheads%2Fmaster%2Fdocs%2Fimages%2Fdiagram.png%3Fraw%3Dtrue" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 Walkthrough &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Prerequisites: For this walkthrough, you’ll need the following prerequisites

&lt;ul&gt;
&lt;li&gt;AWS account&lt;/li&gt;
&lt;li&gt;AWS CDK CLI&lt;/li&gt;
&lt;li&gt;CDK bootstrap on the target region&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://projen.io" rel="noopener noreferrer"&gt;Projen&lt;/a&gt; - Configuration management&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://pnpm.io" rel="noopener noreferrer"&gt;pNpm&lt;/a&gt; - Fast, disk space efficient package manager&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;1. Initial setup&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Clone project sample
git clone git@github.com:vumdao/ecs-service-connect-cdk.git &amp;amp;&amp;amp; cd ecs-service-connect-cdk

# Install node modules
pnpm install

# Update your AWS account in `src/lib/shared/constants.ts` at `CDK_DEFAULT_ACCOUNT` and target region in `src/lib/shared/environment.ts` at `devEnv`
sed -i 's/123456789012/234567890123/g' src/lib/shared/constants.ts
sed -i 's/region: .*,/region: "us-west-2",/g' src/lib/shared/environment.ts

# Update Hosted zone name and zone ID in `src/lib/shared/constants.ts` with yours AWS hosted zone to create domain for yelb application eg. yelb.simflexcloud.com
# export const SIMFLEXCLOUD_ZONE_NAME = 'simflexcloud.com';
# export const SIMFLEXCLOUD_ZONE_ID = 'ZZZZZZZSSSSSSAAAA';

# Get CDK stack
cdk ls

# Deploy CDK
cdk deploy EcsBlueprintsStack --require-approval never
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Explore created resources&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Cloudformation Stack&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fecs-service-connect-cdk%2Frefs%2Fheads%2Fmaster%2Fdocs%2Fimages%2Fcfn-stack.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fecs-service-connect-cdk%2Frefs%2Fheads%2Fmaster%2Fdocs%2Fimages%2Fcfn-stack.png%3Fraw%3Dtrue" width="800" height="424"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ECS Cluster&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fecs-service-connect-cdk%2Frefs%2Fheads%2Fmaster%2Fdocs%2Fimages%2Fcluster.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fecs-service-connect-cdk%2Frefs%2Fheads%2Fmaster%2Fdocs%2Fimages%2Fcluster.png%3Fraw%3Dtrue" width="800" height="374"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Yelb database with client service connect&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fecs-service-connect-cdk%2Frefs%2Fheads%2Fmaster%2Fdocs%2Fimages%2Fdb.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fecs-service-connect-cdk%2Frefs%2Fheads%2Fmaster%2Fdocs%2Fimages%2Fdb.png%3Fraw%3Dtrue" width="800" height="442"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Yelb redis with client service connect&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fecs-service-connect-cdk%2Frefs%2Fheads%2Fmaster%2Fdocs%2Fimages%2Fredis.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fecs-service-connect-cdk%2Frefs%2Fheads%2Fmaster%2Fdocs%2Fimages%2Fredis.png%3Fraw%3Dtrue" width="800" height="442"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Yelb appserver with client and api-call service connect&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fecs-service-connect-cdk%2Frefs%2Fheads%2Fmaster%2Fdocs%2Fimages%2Fapp-server.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fecs-service-connect-cdk%2Frefs%2Fheads%2Fmaster%2Fdocs%2Fimages%2Fapp-server.png%3Fraw%3Dtrue" width="800" height="366"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Yelb appserver task with service-connect side-car (this agent is required for all services which enabled service connect)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fecs-service-connect-cdk%2Frefs%2Fheads%2Fmaster%2Fdocs%2Fimages%2Fapp-server-tasks.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fecs-service-connect-cdk%2Frefs%2Fheads%2Fmaster%2Fdocs%2Fimages%2Fapp-server-tasks.png%3Fraw%3Dtrue" width="800" height="389"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;appserver autoscaling group with CPU Utilization track&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fecs-service-connect-cdk%2Frefs%2Fheads%2Fmaster%2Fdocs%2Fimages%2Fapp-server-autoscaling.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fecs-service-connect-cdk%2Frefs%2Fheads%2Fmaster%2Fdocs%2Fimages%2Fapp-server-autoscaling.png%3Fraw%3Dtrue" width="800" height="232"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Yelb UI with client service connect&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fecs-service-connect-cdk%2Frefs%2Fheads%2Fmaster%2Fdocs%2Fimages%2Fui.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fecs-service-connect-cdk%2Frefs%2Fheads%2Fmaster%2Fdocs%2Fimages%2Fui.png%3Fraw%3Dtrue" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Application load balancer to forward requests to yelb-ui target group&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fecs-service-connect-cdk%2Frefs%2Fheads%2Fmaster%2Fdocs%2Fimages%2Falb.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fecs-service-connect-cdk%2Frefs%2Fheads%2Fmaster%2Fdocs%2Fimages%2Falb.png%3Fraw%3Dtrue" width="800" height="445"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Target group of yelb-ui&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fecs-service-connect-cdk%2Frefs%2Fheads%2Fmaster%2Fdocs%2Fimages%2Ftarget-group.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fecs-service-connect-cdk%2Frefs%2Fheads%2Fmaster%2Fdocs%2Fimages%2Ftarget-group.png%3Fraw%3Dtrue" width="800" height="410"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Cloud map service with namespace used by ECS service connect&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fecs-service-connect-cdk%2Frefs%2Fheads%2Fmaster%2Fdocs%2Fimages%2Fcloudmap-services.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fecs-service-connect-cdk%2Frefs%2Fheads%2Fmaster%2Fdocs%2Fimages%2Fcloudmap-services.png%3Fraw%3Dtrue" width="800" height="369"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Cloud map namespace&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fecs-service-connect-cdk%2Frefs%2Fheads%2Fmaster%2Fdocs%2Fimages%2Fnamespace.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fecs-service-connect-cdk%2Frefs%2Fheads%2Fmaster%2Fdocs%2Fimages%2Fnamespace.png%3Fraw%3Dtrue" width="800" height="385"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🚀 Cleaning up &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;To avoid charges, clean up the resources created in this post by running &lt;code&gt;cdk destroy&lt;/code&gt; or go to cloudformation and delete the stack&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fecs-service-connect-cdk%2Frefs%2Fheads%2Fmaster%2Fdocs%2Fimages%2Fcfn-destroy.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fecs-service-connect-cdk%2Frefs%2Fheads%2Fmaster%2Fdocs%2Fimages%2Fcfn-destroy.png%3Fraw%3Dtrue" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 Conclusion &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;With this walkthrough, you can easily deploy ecs-service-connect-yelb-sample-app using AWS CDK typescript to demonstrate ECS service-to-service communication using ECS service connect&lt;/li&gt;
&lt;li&gt;Cloudmap creates private hosted zone automatically when creating namespace, we can delete it as we don't rely on private hosted zone when using service connect&lt;/li&gt;
&lt;li&gt;Regarding the pricing for ECS Service Connect, AWS Cloud Map usage is entirely free when utilised by Service Connect. This includes service discovery, connectivity, and telemetry generated within the ECS console and CloudWatch by Service Connect. The only charges incurred are for the compute resources utilised. ECS Service Connect introduces a new container (Service Connect proxy) to each new task upon initiation. Consequently, you are only billed for the CPU and memory allocated to this sidecar proxy container.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/aws-samples/ecs-service-connect-yelb-sample-app" rel="noopener noreferrer"&gt;https://github.com/aws-samples/ecs-service-connect-yelb-sample-app&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/blogs/containers/proactive-scaling-of-amazon-ecs-services-using-amazon-ecs-service-connect-metrics/" rel="noopener noreferrer"&gt;https://aws.amazon.com/blogs/containers/proactive-scaling-of-amazon-ecs-services-using-amazon-ecs-service-connect-metrics/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/mreferre/yelb" rel="noopener noreferrer"&gt;https://github.com/mreferre/yelb&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>simflexcloud</category>
      <category>cdk</category>
      <category>ecs</category>
      <category>fargate</category>
    </item>
    <item>
      <title>Empowering Amazon CodeCatalyst: Workflows as Code with CodeCatalyst-Blueprints</title>
      <dc:creator>🚀 Vu Dao 🚀 </dc:creator>
      <pubDate>Tue, 30 Jan 2024 17:04:28 +0000</pubDate>
      <link>https://forem.com/aws-builders/empowering-amazon-codecatalyst-workflows-as-code-with-codecatalyst-blueprints-4bgm</link>
      <guid>https://forem.com/aws-builders/empowering-amazon-codecatalyst-workflows-as-code-with-codecatalyst-blueprints-4bgm</guid>
      <description>&lt;h2&gt;
  
  
  Abstract
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;This blog introduces how to optimize workflow management within the Amazon ecosystem using &lt;a href="https://github.com/aws/codecatalyst-blueprints"&gt;codecatalyst-blueprints&lt;/a&gt;. By employing a &lt;code&gt;blueprint.ts&lt;/code&gt; file, developers can succinctly express workflows as code, promoting readability and collaboration without CodeCatalyst Enterprise tier&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Table Of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Blueprints introduction&lt;/li&gt;
&lt;li&gt;Init Blueprint project using Projen&lt;/li&gt;
&lt;li&gt;&lt;a href="//#Write-blueprint.ts-to-build-worksflow"&gt;Write blueprint.ts to build worksflow&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Generate workflow yaml file&lt;/li&gt;
&lt;li&gt;Workflows Runs&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🚀 &lt;strong&gt;Blueprints introduction&lt;/strong&gt; &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Blueprints are code generators used to create and maintain projects in Amazon CodeCatalyst. You can build your own blueprint (Custom Blueprints) today by upgrading to the CodeCatalyst Enterprise tier. An integral aspect of Blueprints involves workflow generation. Disregarding the CodeCatalyst Enterprise tier, we can utilize this feature to create CodeCatalyst workflows as code, utilizing the preferred programming language, such as Typescript.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🚀 &lt;strong&gt;Init Blueprint project using Projen&lt;/strong&gt; &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;We cannot use &lt;a href="https://projen.io"&gt;Projen&lt;/a&gt; to init a blueprint project as AWS CDK or CDK8S, but we can do a trick by init TypeScript project and then update &lt;code&gt;.projenrc.ts&lt;/code&gt; as &lt;a href="https://github.com/aws/codecatalyst-blueprints/blob/main/packages/blueprints/blueprint/.projenrc.ts"&gt;ProjenBlueprint&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;While we cannot directly use &lt;a href="https://projen.io"&gt;Projen&lt;/a&gt; to initialize a blueprint project such as AWS CDK or CDK8S, we can employ a workaround. Initialize a TypeScript project first, and then update the &lt;code&gt;.projenrc.ts&lt;/code&gt; file using &lt;a href="https://github.com/aws/codecatalyst-blueprints/blob/main/packages/blueprints/blueprint/.projenrc.ts"&gt;&lt;code&gt;ProjenBlueprint&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To initialize a TypeScript project using Projen, you can use the following command&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  ➜  projen new typescript --no-git --projenrc-ts --github false --dev-deps "@amazon-codecatalyst/blueprint-util.projen-blueprint" "@amazon-codecatalyst/blueprint-util.cli"
  👾 Project definition file was created at /private/tmp/blueprint/.projenrc.ts
  👾 Installing dependencies...
  👾 install | yarn install --check-files
  yarn install v1.22.19
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Override the &lt;code&gt;.projenrc.ts&lt;/code&gt; with the following code
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  import { ProjenBlueprint } from '@amazon-codecatalyst/blueprint-util.projen-blueprint';

  const project = new ProjenBlueprint({
    name: 'cdk-todo-web-app',
    defaultReleaseBranch: 'main',
    projenrcTs: true,
    sampleCode: false,
    github: false,
    tsconfig: {
      compilerOptions: {
        esModuleInterop: true,
        noImplicitAny: false,
      },
    },
    deps: [
      'projen',
      '@amazon-codecatalyst/blueprints.blueprint',
      '@amazon-codecatalyst/blueprint-component.workflows',
      '@amazon-codecatalyst/blueprint-component.source-repositories',
      '@amazon-codecatalyst/blueprint-component.dev-environments',
      '@amazon-codecatalyst/blueprint-component.environments',
    ],
    devDeps: [
      'ts-node@^10',
      'typescript',
      '@amazon-codecatalyst/blueprint-util.projen-blueprint',
      '@amazon-codecatalyst/blueprint-util.cli',
    ],
  });

  project.synth();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Then run &lt;code&gt;projen&lt;/code&gt; to update the &lt;code&gt;package.json&lt;/code&gt;, &lt;code&gt;.projen&lt;/code&gt;, and other files managed by Projen
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  ➜  projen
  👾 default | ts-node --project tsconfig.dev.json .projenrc.ts
  👾 Installing dependencies...
  👾 install | yarn install --check-files
  yarn install v1.22.19
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🚀 &lt;strong&gt;Write &lt;code&gt;blueprint.ts&lt;/code&gt; to build worksflow&lt;/strong&gt; &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;If you've utilized CodeCatalyst custom blueprints, you are likely familiar with blueprint.ts, which contains code for generating UI options, environment settings, source repository configurations, and workflows. When creating a custom blueprint, these elements are automatically generated. However, if your goal is to leverage the CI/CD capabilities of the CodeCatalyst workspace without requiring all components, you specifically need the workflow generation part.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In short, the &lt;code&gt;blueprint.ts&lt;/code&gt; file encompasses the following elements:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Source repository - serves as a reference point for workflow configurations
&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const repository = new SourceRepository(this, {
  title: "cdk-todo-web-app",
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Environment - Where we define the CI/CD environment, including the connection to the AWS account.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const environment = new Environment(this, {
  name: "default_environment",
  environmentType: "DEVELOPMENT",
  description: "Blueprint environment",
  awsAccount: {
    cdkRole: { name: CDK_DEFAULT_ROLE },
    id: CDK_DEFAULT_ACCOUNT,
    name: CDK_DEFAULT_ACCOUNT,
  },
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Workflow Actions&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An Action includes the following major components
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  export interface ActionProps {
    actionName: string;
    identifier: string;
    steps: string[];
    environment?: WorkflowEnvironment;
    dependancies?: string[];
    inputs?: { [key: string]: any[] };
    outputs?: { [key: string]: any };
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- A wrapper function that generates a workflow Action based on the interface
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  ```
  /**
  * Generate an action for the workflow
  * @param props ActionProps
  * @returns Action
  */
  export function GenerateAction(props: ActionProps) {
    return {
      [props.actionName]: {
        Identifier: props.identifier,
        Inputs: props.inputs ? props.inputs : { Sources: ["WorkflowSource"] },
        Outputs: props.outputs
          ? props.outputs
          : {
              AutoDiscoverReports: {
                IncludePaths: ["**/*"],
                ExcludePaths: ["*/.codecatalyst/workflows/*"],
                ReportNamePrefix: "AutoDiscovered",
                Enabled: true,
              },
            },
        Configuration: {
          Steps: props.steps.map((step) =&amp;gt; ({ Run: step })),
        },
        Environment: props.environment,
        DependsOn: (props.dependancies) ? props.dependancies : undefined,
      },
    };
  }
  ```
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- We will have following actions
  1. `FrontendBuildAndPackage`
  2. `FrontendTest`
  3. `CDKBootstrapAction`
  4. `CDKDeploy`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;WorkflowBuilder - Responsible for defining the workflow name, compute type, trigger type, and the required actions&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const workflowBuilder = new WorkflowBuilder(this, {
  Name: "main_fullstack_workflow",
  Compute: {
    Type: ComputeType.EC2,
    Fleet: ComputeFleet.LINUX_X86_64_LARGE,
  },
  Triggers: [
    {
      Branches: ["main"],
      Type: TriggerType.PUSH,
    },
  ],
  Actions: {
    ...frontendBuildAndPackage,
    ...frontendTest,
    ...cdkBootstrapAction,
    ...cdkDeploy,
  },
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Workflow - Collects all WorkflowBuilder instances and incorporates them into the source code repository&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;new Workflow(this, repository, workflowBuilder.getDefinition());
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  🚀 &lt;strong&gt;Generate workflow yaml file&lt;/strong&gt; &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Run &lt;code&gt;yarn blueprint:synth&lt;/code&gt; (This script is from &lt;code&gt;package.json&lt;/code&gt;)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  ➜  cdk-todo-web-app git:(main) ✗ yarn blueprint:synth
  yarn run v1.22.19
  $ blueprint drive-synth --blueprint ./ --outdir ./synth --default-options ./src/defaults.json --additional-options ./src/wizard-configurations $*
  [1706372494181] INFO (5048 on Daos-MBP): Running in quick mode. Run this command with --cache to emulate the wizard
  [1706372494192] INFO (5048 on Daos-MBP): ==========================================
  [1706372494192] INFO (5048 on Daos-MBP): [00.synth.defaults.json]
  [1706372494192] INFO (5048 on Daos-MBP): npx blueprint synth --options merge[./src/defaults.json,./src/defaults.json] --blueprint ./ --outdir synth/00.synth.defaults.json/proposed-bundle
  [1706372494192] INFO (5048 on Daos-MBP): ==========================================
  ===== Starting synthesis =====
  options:  {}
  outputDir:  synth/00.synth.defaults.json/proposed-bundle
  Instantiations location not specified
  running synthesis into /codecatalyst/cdk-todo-web-app/synth/00.synth.defaults.json/proposed-bundle/src/cdk-todo-web-app
  ===== Ending synthesis =====
  ✨  Done in 2.10s.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;We have the generated files in &lt;code&gt;synth/00.synth.defaults.json/proposed-bundle&lt;/code&gt; and we have our workflow YAML file is located at &lt;code&gt;synth/00.synth.defaults.json/proposed-bundle/src/cdk-todo-web-app/.codecatalyst/workflows/main_fullstack_workflow.yaml&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  ➜  cdk-todo-web-app git:(main) ✗ tree synth/00.synth.defaults.json/proposed-bundle/src/cdk-todo-web-app/.codecatalyst
  synth/00.synth.defaults.json/proposed-bundle/src/cdk-todo-web-app/.codecatalyst
  └── workflows
      └── main_fullstack_workflow.yaml

  2 directories, 1 file
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Copy the YAML file
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  ➜  cdk-todo-web-app git:(main) ✗ cp synth/00.synth.defaults.json/proposed-bundle/src/cdk-todo-web-app/.codecatalyst/workflows/main_fullstack_workflow.yaml .codecatalyst/workflows/main_fullstack_workflow.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Now we can push the code to the repository and check the workflow run&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LB6lSlDZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://github.com/vumdao/codecatalyst-cdk-todo-web-app/blob/master/docs/images/workflows-run.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LB6lSlDZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://github.com/vumdao/codecatalyst-cdk-todo-web-app/blob/master/docs/images/workflows-run.png%3Fraw%3Dtrue" width="800" height="377"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 &lt;strong&gt;Conclusion&lt;/strong&gt; &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Congratulations! You have successfully generated CodeCatalyst workflows as code using &lt;a href="https://github.com/aws/codecatalyst-blueprints"&gt;codecatalyst-blueprints&lt;/a&gt; without enabling the CodeCatalyst Enterprise tier.&lt;/li&gt;
&lt;li&gt;You can create an Action to automatically generate and update the workflow YAML file by pushing a new commit to the main branch, reflecting changes from the &lt;code&gt;blueprint.ts&lt;/code&gt; file.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  &lt;a href="https://dev.to/vumdao"&gt;🌠 Blog&lt;/a&gt;
  &lt;span&gt; · &lt;/span&gt;
  &lt;a href="https://github.com/vumdao/cdk-todo-web-app"&gt;Github&lt;/a&gt;
  &lt;span&gt; · &lt;/span&gt;
  &lt;a href="https://stackoverflow.com/users/11430272/vumdao"&gt;stackoverflow&lt;/a&gt;
  &lt;span&gt; · &lt;/span&gt;
  &lt;a href="https://www.linkedin.com/in/vu-dao-9280ab43/"&gt;Linkedin&lt;/a&gt;
  &lt;span&gt; · &lt;/span&gt;
  &lt;a href="https://www.linkedin.com/groups/12488649/"&gt;Group&lt;/a&gt;
  &lt;span&gt; · &lt;/span&gt;
  &lt;a href="https://www.facebook.com/CloudOpz-104917804863956"&gt;Page&lt;/a&gt;
  &lt;span&gt; · &lt;/span&gt;
  &lt;a href="https://twitter.com/VuDao81124667"&gt;Twitter 🌠&lt;/a&gt;
&lt;/h3&gt;

</description>
      <category>simflexcloud</category>
      <category>cdk</category>
      <category>codecatalyst</category>
      <category>cicd</category>
    </item>
    <item>
      <title>Bootstrapping AWS CDK Automation With Amazon CodeCatalyst</title>
      <dc:creator>🚀 Vu Dao 🚀 </dc:creator>
      <pubDate>Wed, 24 Jan 2024 17:14:49 +0000</pubDate>
      <link>https://forem.com/aws-builders/bootstrapping-aws-cdk-automation-with-amazon-codecatalyst-4pa8</link>
      <guid>https://forem.com/aws-builders/bootstrapping-aws-cdk-automation-with-amazon-codecatalyst-4pa8</guid>
      <description>&lt;h2&gt;
  
  
  Abstract
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A step-by-step guide on establishing an AWS CDK setup alongside Amazon CodeCatalyst from the ground up, enabling the creation of a comprehensive CI/CD pipeline for your infrastructure.&lt;/li&gt;
&lt;li&gt;AWS CDK is fantastic for overseeing your entire infrastructure as code, but when multiple developers are involved in modifying the infrastructure, the situation can become chaotic without a proper mechanism like a CI/CD pipeline. Absence of such a system makes coordinating and communicating changes to the infrastructure a challenging task, and this challenge amplifies as more individuals participate in the modification process.&lt;/li&gt;
&lt;li&gt;This tutorial will guide you through setting up a CI/CD pipeline using Amazon CodeCatalyst and AWS CDK for building To-Do web application&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fvumdao%2Fcodecatalyst-cdk-todo-web-app%2Fblob%2Fmaster%2Fdocs%2Fimages%2Fdiagram.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fvumdao%2Fcodecatalyst-cdk-todo-web-app%2Fblob%2Fmaster%2Fdocs%2Fimages%2Fdiagram.png%3Fraw%3Dtrue"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Table Of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Setting up a CodeCatalyst Project, Repo, and Environment&lt;/li&gt;
&lt;li&gt;Design workflows&lt;/li&gt;
&lt;li&gt;Source code and CDK stacks&lt;/li&gt;
&lt;li&gt;Push source code to repo&lt;/li&gt;
&lt;li&gt;Workflows Runs&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🚀 &lt;strong&gt;Setting up a CodeCatalyst Project, Repo, and Environment&lt;/strong&gt; &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Login to CodeCatalyst and go to your Space (Create one if you don't have)&lt;/li&gt;
&lt;li&gt;Create a project from scratch&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fvumdao%2Fcodecatalyst-cdk-todo-web-app%2Fblob%2Fmaster%2Fdocs%2Fimages%2Fcreate-project.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fvumdao%2Fcodecatalyst-cdk-todo-web-app%2Fblob%2Fmaster%2Fdocs%2Fimages%2Fcreate-project.png%3Fraw%3Dtrue"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create repository to store code and workflows of the project&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fvumdao%2Fcodecatalyst-cdk-todo-web-app%2Fblob%2Fmaster%2Fdocs%2Fimages%2Fcreate-repo.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fvumdao%2Fcodecatalyst-cdk-todo-web-app%2Fblob%2Fmaster%2Fdocs%2Fimages%2Fcreate-repo.png%3Fraw%3Dtrue"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fvumdao%2Fcodecatalyst-cdk-todo-web-app%2Fblob%2Fmaster%2Fdocs%2Fimages%2Fcreate-repo-details.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fvumdao%2Fcodecatalyst-cdk-todo-web-app%2Fblob%2Fmaster%2Fdocs%2Fimages%2Fcreate-repo-details.png%3Fraw%3Dtrue"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create CICD &lt;code&gt;Environments&lt;/code&gt; which associates to AWS account for deploying our infrastructure.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fvumdao%2Fcodecatalyst-cdk-todo-web-app%2Fblob%2Fmaster%2Fdocs%2Fimages%2Fcreate-cicd-env.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fvumdao%2Fcodecatalyst-cdk-todo-web-app%2Fblob%2Fmaster%2Fdocs%2Fimages%2Fcreate-cicd-env.png%3Fraw%3Dtrue"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create IAM role for codecatalyst to consume during running workflows. It should be already created while you create the Space or you can customize the others&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fvumdao%2Fcodecatalyst-cdk-todo-web-app%2Fblob%2Fmaster%2Fdocs%2Fimages%2Fiam-role.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fvumdao%2Fcodecatalyst-cdk-todo-web-app%2Fblob%2Fmaster%2Fdocs%2Fimages%2Fiam-role.png%3Fraw%3Dtrue"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 &lt;strong&gt;Design workflows&lt;/strong&gt; &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Workflows directory
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  .codecatalyst
  └── workflows
      └── main_fullstack_workflow.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Workflows is triggered by &lt;code&gt;PUSH&lt;/code&gt; of branch &lt;code&gt;main&lt;/code&gt; and includes following &lt;code&gt;Actions&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  Triggers:
    - Branches:
        - main
      Type: PUSH
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;FrontendBuildAndPackage&lt;/code&gt; build react app, target &lt;code&gt;build&lt;/code&gt; which is shared to cross-actions by &lt;code&gt;Artifacts&lt;/code&gt; of &lt;code&gt;Outputs&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FrontendBuildAndPackage:
  Identifier: aws/build@v1
  Inputs:
    Sources:
      - WorkflowSource
  Outputs:
    Artifacts:
      - Name: frontend
        Files:
          - "**/*"
  Configuration:
    Steps:
      - Run: cd static-assets/frontend
      - Run: npm install
      - Run: echo "REACT_APP_SERVICE_URL=/api/todos" &amp;gt; ".env"
      - Run: npm run build
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;FrontendTest&lt;/code&gt; Test frontend code&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FrontendTest:
    Identifier: aws/managed-test@v1
    Inputs:
      Sources:
        - WorkflowSource
    Outputs:
      AutoDiscoverReports:
        IncludePaths:
          - frontend/**/*.xml
        ExcludePaths:
          - frontend/node_modules/**/*
        ReportNamePrefix: AutoDiscovered
        Enabled: true
        SuccessCriteria:
          PassRate: 100
    Configuration:
      Steps:
        - Run: cd static-assets/frontend
        - Run: npm install
        - Run: npm test -- --coverage --watchAll=false;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;CDKBootstrapAction&lt;/code&gt; Run &lt;code&gt;cdk bootstrap&lt;/code&gt; for the region of the account with latest CDK version. This action depends on &lt;code&gt;FrontendTest&lt;/code&gt; and &lt;code&gt;FrontendBuildAndPackage&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CDKBootstrapAction:
  Identifier: aws/cdk-bootstrap@v1
  Configuration:
    Region: us-east-1
    CdkCliVersion: latest
  Environment:
    Name: default_environment
    Connections:
      - Name: "123456789012"
        Role: CodeCatalystWorkflowDevelopmentRole-simflexcloud
  DependsOn:
    - FrontendTest
    - FrontendBuildAndPackage
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;CDKDeploy&lt;/code&gt; Download build target of &lt;code&gt;FrontendBuildAndPackage&lt;/code&gt; and trigger &lt;code&gt;cdk deploy&lt;/code&gt;, this action depends on &lt;code&gt;CDKBootstrapAction&lt;/code&gt;. Here I don't use the defined action &lt;code&gt;aws/cdk-deploy@v1&lt;/code&gt; of CodeCatalyst because I'd like to use &lt;code&gt;projen&lt;/code&gt; and &lt;code&gt;pnmp&lt;/code&gt; in CDK and handle copying frontend target build&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CDKDeploy:
  Identifier: aws/build@v1
  Inputs:
    Artifacts:
      - frontend
  Outputs:
    AutoDiscoverReports:
      IncludePaths:
        - "**/*"
      ExcludePaths:
        - "*/.codecatalyst/workflows/*"
      ReportNamePrefix: AutoDiscovered
      Enabled: true
  Configuration:
    Steps:
      - Run: cp -r static-assets/frontend/build static-assets/cdkStack/src/lib/frontend/
      - Run: cd static-assets/cdkStack
      - Run: npm install -g pnpm
      - Run: pnpm i --no-frozen-lockfile
      - Run: export CDK_DEPLOY_ACCOUNT=123456789012
      - Run: export CDK_DEPLOY_REGION=us-east-1
      - Run: pnpm dlx projen deploy --all --require-approval never
  Environment:
    Name: default_environment
    Connections:
      - Name: "123456789012"
        Role: CodeCatalystWorkflowDevelopmentRole-simflexcloud
  DependsOn:
    - FrontendTest
    - FrontendBuildAndPackage
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Use EC2 compute type for CodeCatalyst workflows
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  Compute:
    Type: EC2
    Fleet: Linux.x86-64.Large
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🚀 &lt;strong&gt;Source code and CDK stacks&lt;/strong&gt; &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Structure

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;cdkStack&lt;/code&gt; Define CDK stacks and use &lt;code&gt;projen&lt;/code&gt; for configuration management as well as &lt;code&gt;pnpm&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;frontend&lt;/code&gt; Frontend react app
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  static-assets
  ├── cdkStack
  │   │   ├── LICENSE
  │   │   ├── README.md
  │   │   ├── cdk.json
  │   │   ├── package.json
  │   │   ├── src
  │   │   │   ├── bin
  │   │   │   │   └── main.ts
  │   │   │   ├── lib
  │   │   │   │   ├── backend
  │   │   │   │   │   ├── lambda
  │   │   │   │   │   │   ├── CorsAPIGatewayProxyResult.ts
  │   │   │   │   │   │   ├── Todo.ts
  │   │   │   │   │   │   ├── addTodo.ts
  │   │   │   │   │   │   ├── deleteTodo.ts
  │   │   │   │   │   │   ├── getTodo.ts
  │   │   │   │   │   │   ├── getTodos.ts
  │   │   │   │   │   │   └── updateTodo.ts
  │   │   │   │   │   └── todo-api-stack.ts
  │   │   │   │   └── frontend
  │   │   │   │       ├── build
  │   │   │   │       ├── constants.ts
  │   │   │   │       └── frontend-stack.ts
  │   │   │   └── main.ts
  │   │   ├── test
  │   │   │   └── todo-api.test.ts
  │   │   ├── tsconfig.dev.json
  │   │   └── tsconfig.json
  │   └── frontend
  │       ├── README.md
  │       ├── babel.config.js
  │       ├── jest.config.js
  │       ├── package.json
  │       ├── public
  │       │   ├── index.html
  │       │   ├── manifest.json
  │       │   └── robots.txt
  │       ├── src
  │       │   ├── App.css
  │       │   ├── App.test.tsx
  │       │   ├── App.tsx
  │       │   ├── index.css
  │       │   ├── index.tsx
  │       │   ├── react-app-env.d.ts
  │       │   ├── reportWebVitals.ts
  │       │   ├── setupTests.ts
  │       │   ├── to-do.api.ts
  │       │   └── to-do.types.ts
  │       └── tsconfig.json
  ├── tsconfig.dev.json
  ├── tsconfig.json
  └── yarn.lock
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🚀 &lt;strong&gt;Push source code to repo&lt;/strong&gt; &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Init the repo and add repo URL which is created from the above as &lt;code&gt;origin&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fvumdao%2Fcodecatalyst-cdk-todo-web-app%2Fblob%2Fmaster%2Fdocs%2Fimages%2Fclone-repo.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fvumdao%2Fcodecatalyst-cdk-todo-web-app%2Fblob%2Fmaster%2Fdocs%2Fimages%2Fclone-repo.png%3Fraw%3Dtrue"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  ➜  git init
  Initialized empty Git repository in /Users/vudao/workspace/codecatalyst/cdk-todo-web-app/.git/
  ➜  git remote add origin https://vumdao@git.us-west-2.codecatalyst.aws/v1/simflexcloud/cdk-todo-web-app/cdk-todo-web-app
  ➜  git branch --set-upstream-to=origin/main main
  branch 'main' set up to track 'origin/main' by rebasing.
  ➜  git pull
  ➜  git add .
  ➜  git commit -m "Init commit"
  ➜  git push origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🚀 &lt;strong&gt;Workflows Runs&lt;/strong&gt; &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;When the commit is pushed to the &lt;code&gt;main&lt;/code&gt; branch, CodeCatalyst CI/CD triggers the workflows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fvumdao%2Fcodecatalyst-cdk-todo-web-app%2Fblob%2Fmaster%2Fdocs%2Fimages%2Fworkflows-run.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fvumdao%2Fcodecatalyst-cdk-todo-web-app%2Fblob%2Fmaster%2Fdocs%2Fimages%2Fworkflows-run.png%3Fraw%3Dtrue"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fvumdao%2Fcodecatalyst-cdk-todo-web-app%2Fblob%2Fmaster%2Fdocs%2Fimages%2Fcdkdeploy.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fvumdao%2Fcodecatalyst-cdk-todo-web-app%2Fblob%2Fmaster%2Fdocs%2Fimages%2Fcdkdeploy.png%3Fraw%3Dtrue"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;CDKDeploy&lt;/code&gt; triggers cloudformation to create AWS resources&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fvumdao%2Fcodecatalyst-cdk-todo-web-app%2Fblob%2Fmaster%2Fdocs%2Fimages%2Fcloudformation.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fvumdao%2Fcodecatalyst-cdk-todo-web-app%2Fblob%2Fmaster%2Fdocs%2Fimages%2Fcloudformation.png%3Fraw%3Dtrue"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After the workflows done, we now have the To-Do Web app UI&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fvumdao%2Fcodecatalyst-cdk-todo-web-app%2Fblob%2Fmaster%2Fdocs%2Fimages%2Fwebapp-ui.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fvumdao%2Fcodecatalyst-cdk-todo-web-app%2Fblob%2Fmaster%2Fdocs%2Fimages%2Fwebapp-ui.png%3Fraw%3Dtrue"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 &lt;strong&gt;Conclusion&lt;/strong&gt; &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Congratulations! You've successfully bootstrapped and initialized AWS CDK with CodeCatalyst, and you can now deploy infrastructure changes or update frontend/backend using a pull request workflow.&lt;/p&gt;




&lt;h3&gt;
  &lt;a href="https://dev.to/vumdao"&gt;🌠 Blog&lt;/a&gt;
  &lt;span&gt; · &lt;/span&gt;
  &lt;a href="https://github.com/vumdao/codecatalyst-cdk-todo-web-app" rel="noopener noreferrer"&gt;Github&lt;/a&gt;
  &lt;span&gt; · &lt;/span&gt;
  &lt;a href="https://stackoverflow.com/users/11430272/vumdao" rel="noopener noreferrer"&gt;stackoverflow&lt;/a&gt;
  &lt;span&gt; · &lt;/span&gt;
  &lt;a href="https://www.linkedin.com/in/vu-dao-9280ab43/" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt;
  &lt;span&gt; · &lt;/span&gt;
  &lt;a href="https://www.linkedin.com/groups/12488649/" rel="noopener noreferrer"&gt;Group&lt;/a&gt;
  &lt;span&gt; · &lt;/span&gt;
  &lt;a href="https://www.facebook.com/CloudOpz-104917804863956" rel="noopener noreferrer"&gt;Page&lt;/a&gt;
  &lt;span&gt; · &lt;/span&gt;
  &lt;a href="https://twitter.com/VuDao81124667" rel="noopener noreferrer"&gt;Twitter 🌠&lt;/a&gt;
&lt;/h3&gt;

</description>
      <category>simflexcloud</category>
      <category>cdk</category>
      <category>codecatalyst</category>
      <category>cicd</category>
    </item>
    <item>
      <title>Multi-Tenancy In EKS Cluster Using Vcluster</title>
      <dc:creator>🚀 Vu Dao 🚀 </dc:creator>
      <pubDate>Sun, 08 Oct 2023 17:18:34 +0000</pubDate>
      <link>https://forem.com/aws-builders/multi-tenancy-in-eks-cluster-using-vcluster-2pni</link>
      <guid>https://forem.com/aws-builders/multi-tenancy-in-eks-cluster-using-vcluster-2pni</guid>
      <description>&lt;h2&gt;
  
  
  Abstract
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Why should we consider using Vcluster? Our requirement is to establish multiple environments for developers to facilitate development, testing, as well as regression and performance tests.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The crucial aspect is ensuring that these environments closely mimic the structure of our staging and production environments, which are based on Kubernetes. Instead of relying on Kubernetes namespaces to create these environments, We opt to offer developers a solution that provides them with an environment that closely resembles a real Kubernetes cluster. This is where Vcluster comes into play.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Watch Demo: &lt;a href="https://www.youtube.com/watch?v=vWNkGyLajJE" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=vWNkGyLajJE&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Source code: &lt;a href="https://github.com/vumdao/multi-tenancy-using-vcluster-in-eks/tree/master" rel="noopener noreferrer"&gt;https://github.com/vumdao/multi-tenancy-using-vcluster-in-eks/tree/master&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Table Of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Abstract&lt;/li&gt;
&lt;li&gt;Table Of Contents&lt;/li&gt;
&lt;li&gt;🚀 &lt;strong&gt;vcluster overview&lt;/strong&gt; &lt;/li&gt;
&lt;li&gt;🚀 &lt;strong&gt;Solution overview&lt;/strong&gt; &lt;/li&gt;
&lt;li&gt;🚀 &lt;strong&gt;Bootstrap EKS cluster using CDK EKS Blueprints&lt;/strong&gt; &lt;/li&gt;
&lt;li&gt;🚀 &lt;strong&gt;Create vcluster&lt;/strong&gt; &lt;/li&gt;
&lt;li&gt;🚀 &lt;strong&gt;Expose vcluster using Network Laoad Balancer&lt;/strong&gt; &lt;/li&gt;
&lt;li&gt;🚀 &lt;strong&gt;Cleanup&lt;/strong&gt; &lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🚀 &lt;strong&gt;vcluster overview&lt;/strong&gt; &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.vcluster.com" rel="noopener noreferrer"&gt;https://www.vcluster.com&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fmulti-tenancy-using-vcluster-in-eks%2Fmaster%2Fimages%2Fvcluster-architecture.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fmulti-tenancy-using-vcluster-in-eks%2Fmaster%2Fimages%2Fvcluster-architecture.png" width="800" height="297"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 &lt;strong&gt;Solution overview&lt;/strong&gt; &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fmulti-tenancy-using-vcluster-in-eks%2Fmaster%2Fimages%2Farchitect.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fmulti-tenancy-using-vcluster-in-eks%2Fmaster%2Fimages%2Farchitect.png" width="800" height="773"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 &lt;strong&gt;Bootstrap EKS cluster using CDK EKS Blueprints&lt;/strong&gt; &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The bootstrap provisions EKS cluster with required AddOns using &lt;a href="https://github.com/aws-quickstart/cdk-eks-blueprints/tree/main" rel="noopener noreferrer"&gt;CDK EKS blueprints&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    new VpcCniAddOn(),
    new MetricsServerAddOn(),
    new KarpenterAddOn(),
    new AwsLoadBalancerControllerAddOn(),
    new EbsCsiDriverAddOn(),
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Cluster provider

&lt;ul&gt;
&lt;li&gt;Fargate to deploy Karpenter&lt;/li&gt;
&lt;li&gt;Karpenter simplifies Kubernetes infrastructure with the right nodes at the right time.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  🚀 &lt;strong&gt;Create vcluster&lt;/strong&gt; &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Create two vclusters with namepsace &lt;code&gt;app1&lt;/code&gt; and &lt;code&gt;app2&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  $ ./demo/create-vcl.sh app1
  $ ./demo/create-vcl.sh app2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  🚀 &lt;strong&gt;Expose vcluster using Network Laoad Balancer&lt;/strong&gt; &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Create NLB service
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  ✗ k apply -f demo/app1/service.yaml
  service/app1-lb created

  ✗ k apply -f demo/app2/service.yaml
  service/app2-lb created

  ✗ k get svc -n app1 app1-lb
  NAME      TYPE           CLUSTER-IP       EXTERNAL-IP                                                                    PORT(S)         AGE
  app1-lb   LoadBalancer   172.20.150.105   k8s-app1-app1lb-bb32c11098-3381306256798df4.elb.ap-southeast-1.amazonaws.com   443:32392/TCP   30h

  ✗ k get svc -n app2 app2-lb
  NAME      TYPE           CLUSTER-IP      EXTERNAL-IP                                                                    PORT(S)         AGE
  app2-lb   LoadBalancer   172.20.78.127   k8s-app2-app2lb-4690ffbcfe-bfb88a1245728e8a.elb.ap-southeast-1.amazonaws.com   443:31510/TCP   49s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Create CName record point to the NLB DNS
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  ➜  multi-tenancy-in-eks-using-vcluster git:(master) ✗ ./demo/r53-record.sh create app2
  ➜  multi-tenancy-in-eks-using-vcluster git:(master) ✗ ping app2-eks.simflexcloud.com
  PING k8s-app2-app2lb-4690ffbcfe-bfb88a1245728e8a.elb.ap-southeast-1.amazonaws.com (13.250.162.120): 56 data bytes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Now we can connect to the vcluster app1 and app2 using their expose endpoint&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://app1-eks.simflexcloud.com" rel="noopener noreferrer"&gt;https://app1-eks.simflexcloud.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://app2-eks.simflexcloud.com" rel="noopener noreferrer"&gt;https://app2-eks.simflexcloud.com&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;✗ vcluster connect app2 -n app2 --server=https://app2-eks.simflexcloud.com --update-current=false
done √ Virtual cluster kube config written to: ./kubeconfig.yaml
- Use `kubectl --kubeconfig ./kubeconfig.yaml get namespaces` to access the vcluster
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  🚀 Deploy applications on vcluster
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Deploy &lt;code&gt;echo&lt;/code&gt; and &lt;code&gt;guestbook&lt;/code&gt; project
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  ✗ ka2 apply -f demo/app2/vcluster
  ingress.networking.k8s.io/echo created
  deployment.apps/echo created
  service/echo created
  ingress.networking.k8s.io/guestbook created
  service/redis-leader created
  deployment.apps/redis-leader created
  service/redis-follower created
  deployment.apps/redis-follower created
  service/frontend created
  deployment.apps/frontend created
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Get ALB DNS and point to the Web app endpoint&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://app1.simflexcloud.com" rel="noopener noreferrer"&gt;https://app1.simflexcloud.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://app2.simflexcloud.com" rel="noopener noreferrer"&gt;https://app2.simflexcloud.com&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;✗ ka2 get ingress
NAME        CLASS   HOSTS   ADDRESS                                                          PORTS   AGE
echo        alb     *       k8s-app2-dbb948e3be-939359744.ap-southeast-1.elb.amazonaws.com   80      10s
guestbook   alb     *       k8s-app2-dbb948e3be-939359744.ap-southeast-1.elb.amazonaws.com   80      10s
✗ ./demo/r53-record.sh create app2 k8s-app2-dbb948e3be-939359744.ap-southeast-1.elb.amazonaws.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  🚀 &lt;strong&gt;Cleanup&lt;/strong&gt; &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Delete vcluster
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  ✗ vcluster delete dev -n dev
  info   Delete vcluster dev...
  done √ Successfully deleted virtual cluster dev in namespace dev
  done √ Successfully deleted virtual cluster pvc data-dev-0 in namespace dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Destroy all AWS resources within this project&lt;/li&gt;
&lt;/ul&gt;




&lt;div class="ltag__user ltag__user__id__512906"&gt;
    &lt;a href="/vumdao" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&gt;
        &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F512906%2F83cde530-e04d-4510-90e4-d73bd4d1e7bd.png" alt="vumdao image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/vumdao"&gt;🚀 Vu Dao 🚀 &lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/vumdao"&gt;🚀 AWSome Devops | AWS Community Builder | AWS SA || ☁️ CloudOpz ☁️&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;




&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/vumdao" rel="noopener noreferrer"&gt;
        vumdao
      &lt;/a&gt; / &lt;a href="https://github.com/vumdao/vumdao" rel="noopener noreferrer"&gt;
        vumdao
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


</description>
      <category>simflexcloud</category>
      <category>eks</category>
      <category>vcluster</category>
      <category>aws</category>
    </item>
    <item>
      <title>Single-Sign-On By Vouch Proxy And AWS Cognito</title>
      <dc:creator>🚀 Vu Dao 🚀 </dc:creator>
      <pubDate>Wed, 31 May 2023 15:55:04 +0000</pubDate>
      <link>https://forem.com/aws-builders/single-sign-on-by-vouch-proxy-and-aws-cognito-427g</link>
      <guid>https://forem.com/aws-builders/single-sign-on-by-vouch-proxy-and-aws-cognito-427g</guid>
      <description>&lt;h2&gt;
  
  
  Abstract
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;For Kubernetes cluster, we have many observability and monitoring tools which are built-in with separated dashboard/console UIs with login-authentication. We don't want to create many domains as well as multiple accounts to handle them. This post introduces vouch proxy as a solution to provide single-sign on which supports many OAuth and OIDC login providers and can enforce authentication to AWS Cognito user pool.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Table Of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Vouch Proxy Overview&lt;/li&gt;
&lt;li&gt;What Exactly Vouch Proxy Does?&lt;/li&gt;
&lt;li&gt;How does vouch-proxy protect the domains?&lt;/li&gt;
&lt;li&gt;Setup AWS Cognito as authorised provider&lt;/li&gt;
&lt;li&gt;Deploy vouch-proxy and nginx&lt;/li&gt;
&lt;li&gt;Troubleshooting&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🚀 &lt;strong&gt;Vouch Proxy Overview&lt;/strong&gt; &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/vouch/vouch-proxy" rel="noopener noreferrer"&gt;Vouch Proxy&lt;/a&gt; - An SSO solution for Nginx using the &lt;a href="http://nginx.org/en/docs/http/ngx_http_auth_request_module.html" rel="noopener noreferrer"&gt;auth_request&lt;/a&gt; module. Vouch Proxy can protect all of your websites at once.&lt;/li&gt;
&lt;li&gt;Vouch Proxy supports many OAuth and OIDC login providers and can enforce authentication to... This blog introduces applying vouch-proxy with AWS Cognito userpool&lt;/li&gt;
&lt;li&gt;In this blog post, we apply this solution for Applications such as &lt;a href="https://solr.apache.org/guide/6_6/getting-started-with-solrcloud.html" rel="noopener noreferrer"&gt;Solr Cloud&lt;/a&gt;, &lt;a href="https://akhq.io" rel="noopener noreferrer"&gt;AKHQ&lt;/a&gt;, and &lt;a href="https://glowroot.org" rel="noopener noreferrer"&gt;glowroot&lt;/a&gt; in Kubernetes cluster where vouch proxy and nginx are also deployed on.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🚀 &lt;strong&gt;What Exactly Vouch Proxy Does&lt;/strong&gt; &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Diagram&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fsso-vouch-proxy%2Fmaster%2Fimages%2Fvp-diagram.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fsso-vouch-proxy%2Fmaster%2Fimages%2Fvp-diagram.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The flows&lt;/strong&gt;

&lt;ol&gt;
&lt;li&gt;User access to one of the subpaths such as &lt;code&gt;/solr&lt;/code&gt; for Solr Admin UI through &lt;a href="https://sso.simflexcloud.com/solr" rel="noopener noreferrer"&gt;https://sso.simflexcloud.com/solr&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The request is go to AWS Application load balancer and then forwarded to NGINX target group&lt;/li&gt;
&lt;li&gt;Nginx authorizes the request by calling/validating the request using vouch-proxy through the internal endpoint &lt;code&gt;http://vouch:9090/validate&lt;/code&gt; of Kubernetes service&lt;/li&gt;
&lt;li&gt;Vouch-proxy validates and returns 200 if the user already has the cache login token or returns &lt;code&gt;401&lt;/code&gt; if not yet performed login

&lt;ul&gt;
&lt;li&gt;With 200 code, the request is redirected to the target location here is Solr UI admin&lt;/li&gt;
&lt;li&gt;With 401 code, the request is redirected to &lt;code&gt;https://vouch.simflexcloud.com/login?url=https://$http_host$request_uri&amp;amp;vouch-failcount=$auth_resp_failcount&amp;amp;X-Vouch-Token=$auth_resp_jwt&amp;amp;error=$auth_resp_err&amp;gt;&lt;/code&gt; to login, if the login is successful, the request is redirected to the target location here is Solr UI admin&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Default redirect is the main page or marketing page or anything you would like to show as your SSO&lt;/li&gt;

&lt;/ol&gt;

&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  🚀 &lt;strong&gt;How does vouch-proxy protect the domains?&lt;/strong&gt; &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Vouch-proxy (VP) supports many OAuth and OIDC login providers to authentication&lt;/li&gt;
&lt;li&gt;Furthermore, vouch-proxy whitelists the domains, not only the access domain but also the domain of email login. The cookie domain, the domain that VP is served from and the protected app must all be the same domain. For example, if we just whitelist the app domain such as simflexcloud.com but the email is &lt;code&gt;simflex.cloud@gmail.com&lt;/code&gt; it will not authorize the user
```
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;2022-07-07T15:58:12.716Z        WARN    /auth User is not authorized: verifyUser: Email &lt;a href="mailto:simflex.cloud@gmail.com"&gt;simflex.cloud@gmail.com&lt;/a&gt; is not within a Vouch Proxy managed domain . Please try again or seek support from your administrator&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
## 🚀 **Setup AWS Cognito as authorised provider** &amp;lt;a name="Setup-AWS-Cognito-as-authorize-provider"&amp;gt;&amp;lt;/a&amp;gt;
- Pre-requisite: You already create Coginto user for login authentication.

- Cognito userpool application client

  &amp;lt;img src=https://raw.githubusercontent.com/vumdao/sso-vouch-proxy/master/images/cognito-sso.png width=1100&amp;gt;

- Setup vouch-proxy config with AWS Cognito, replace the URLs with one's setup from Cognito
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;vouch:&lt;br&gt;
    logLevel: debug&lt;br&gt;
    port: 9090&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cookie:
  secure: false

domains: # app domain and mail domain only
- simflexcloud.com
- gmail.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;oauth:&lt;br&gt;
    provider: oidc&lt;br&gt;
    client_id: AWS_COGNITO_VOUCH_CLIENT_ID&lt;br&gt;
    auth_url: &lt;a href="https://%7ByourCognitoDomain%7D.amazoncognito.com/oauth2/authorize" rel="noopener noreferrer"&gt;https://{yourCognitoDomain}.amazoncognito.com/oauth2/authorize&lt;/a&gt;&lt;br&gt;
    token_url: &lt;a href="https://%7ByourCognitoDomain%7D.amazoncognito.com/oauth2/token" rel="noopener noreferrer"&gt;https://{yourCognitoDomain}.amazoncognito.com/oauth2/token&lt;/a&gt;&lt;br&gt;
    user_info_url: &lt;a href="https://%7ByourCognitoDomain%7D.amazoncognito.com/oauth2/userInfo" rel="noopener noreferrer"&gt;https://{yourCognitoDomain}.amazoncognito.com/oauth2/userInfo&lt;/a&gt;&lt;br&gt;
    scopes:&lt;br&gt;
    - openid&lt;br&gt;
    - email&lt;br&gt;
    - profile&lt;br&gt;
    callback_url: &lt;a href="https://%7BcallbackURL%7D/auth" rel="noopener noreferrer"&gt;https://{callbackURL}/auth&lt;/a&gt;&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
## 🚀 **Deploy vouch-proxy and nginx** &amp;lt;a name="Deploy-vouch-proxy-and-nginx"&amp;gt;&amp;lt;/a&amp;gt;
- Go to [nginx](https://github.com/vumdao/sso-vouch-proxy/tree/master/nginx) to get Dockerfile, nginx config files to build the `nginx-gw` image
- Use the `quay.io/vouch/vouch-proxy` image to start vouch-proxy by mounting the config file to `/config/config.yml`

## 🚀 **Troubleshooting** &amp;lt;a name="Troubleshooting"&amp;gt;&amp;lt;/a&amp;gt;
- Getting started to align between Nginx, Vouch Proxy and your identity provider (IdP) can be tricky, vouch-proxy provides a config to enable the testing mode
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;vouch:&lt;br&gt;
    testing: true&lt;br&gt;
    logLevel: debug&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
- With testing enable, the UI will step us to each phase of redirecting

  &amp;lt;img src=https://raw.githubusercontent.com/vumdao/sso-vouch-proxy/master/images/vp-1.png width=1100&amp;gt;

  &amp;lt;img src=https://raw.githubusercontent.com/vumdao/sso-vouch-proxy/master/images/vp-2.png width=1100&amp;gt;

## 🚀 **Conclusion** &amp;lt;a name="Conclusion"&amp;gt;&amp;lt;/a&amp;gt;
- Now we have SSO domain to access all the services conveniently and it's possible to add any more subpath for other services. The session with Congito userpool token has expired time and we can update this timeout through Cognito attributes.

---

&lt;div class="ltag__user ltag__user__id__512906"&gt;
    &lt;a href="/vumdao" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&gt;
        &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F512906%2F83cde530-e04d-4510-90e4-d73bd4d1e7bd.png" alt="vumdao image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/vumdao"&gt;🚀 Vu Dao 🚀 &lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/vumdao"&gt;🚀 AWSome Devops | AWS Community Builder | AWS SA || ☁️ CloudOpz ☁️&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/vumdao" rel="noopener noreferrer"&gt;
        vumdao
      &lt;/a&gt; / &lt;a href="https://github.com/vumdao/vumdao" rel="noopener noreferrer"&gt;
        vumdao
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>simflexcloud</category>
      <category>sso</category>
      <category>vouchproxy</category>
      <category>nginx</category>
    </item>
    <item>
      <title>FastApi With AWS Serverless powered by CDK Typescript</title>
      <dc:creator>🚀 Vu Dao 🚀 </dc:creator>
      <pubDate>Sun, 21 May 2023 07:05:20 +0000</pubDate>
      <link>https://forem.com/aws-builders/fastapi-with-aws-serverless-powered-by-cdk-typescript-58a1</link>
      <guid>https://forem.com/aws-builders/fastapi-with-aws-serverless-powered-by-cdk-typescript-58a1</guid>
      <description>&lt;h2&gt;
  
  
  Abstract
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Deploy FastAPI in a Lambda function that is fronted by an HTTP API in API Gateway, you can enable API key required for the API&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Table Of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Solution overview&lt;/li&gt;
&lt;li&gt;Build FastAPI as lambda funnction handler&lt;/li&gt;
&lt;li&gt;Deploy&lt;/li&gt;
&lt;li&gt;Test API&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🚀 &lt;strong&gt;Solution overview&lt;/strong&gt; &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fsimple-serverless-fastapi%2Fmaster%2Fimages%2Farchitect.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fsimple-serverless-fastapi%2Fmaster%2Fimages%2Farchitect.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use AWS APIGW to build a simple API server with lambda integration&lt;/li&gt;
&lt;li&gt;APIGW route paths such as &lt;code&gt;/api/v1/&lt;/code&gt; and &lt;code&gt;/chat_gpt/&lt;/code&gt; require API key (with usage plan)&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The lambda function contains FastApi code to serves API requests and responses.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Let's see the stack relationships&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fsimple-serverless-fastapi%2Fmaster%2Fimages%2Fdiagram.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fsimple-serverless-fastapi%2Fmaster%2Fimages%2Fdiagram.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 &lt;strong&gt;Build FastAPI as a lambda funnction handler&lt;/strong&gt; &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Lambda handler source code&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

  ➜  simple-serverless-fastapi tree src/lambda-handler
  src/lambda-handler
  ├── api
  │   └── api_v1
  │       ├── api.py
  │       └── endpoints
  │           └── users.py
  ├── main.py
  └── requirements.txt

  4 directories, 4 files


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Direct route paths include &lt;code&gt;/&lt;/code&gt; and &lt;code&gt;chat_gpt&lt;/code&gt;
```
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;@app.get("/")&lt;br&gt;
  async def root():&lt;br&gt;
      return {"message": "FastAPI running in a Lambda function"}&lt;/p&gt;

&lt;p&gt;@app.get("/chat_gpt/")&lt;br&gt;
  async def read_chatgpt(question: str = None):&lt;br&gt;
      return {"message": f"We got question: {question}"}&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
- Restructure FastAPI Routing for developing API and optimize source code by using `APIRouter`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;src/lambda-handler/api&lt;br&gt;
  └── api_v1&lt;br&gt;
      ├── api.py&lt;br&gt;
      └── endpoints&lt;br&gt;
          └── users.py&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;from api.api_v1.api import router as api_router&lt;br&gt;
  app.include_router(api_router, prefix="/api/v1")&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
- For the lambda function handler, we use [`Mangum`](https://pypi.org/project/mangum/) python module which is an adapter for running ASGI applications in AWS Lambda to handle Function URL, API Gateway, ALB, and Lambda@Edge events.

- For building API Docs, one must set the following parameters in `FastApi()` constructor to resolve `/openapi.json` correctly
  - For API URL using APIGW stage URL, set `root_path` equal to the API stage name, eg. `root_path=/AppAPI`
  - For API custom domain
    ```


    docs_url='/docs',
    openapi_url='/openapi.json',


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  🚀 &lt;strong&gt;Deploy&lt;/strong&gt; &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;For production, building CDK pipeline for this is the best practice.&lt;/li&gt;
&lt;li&gt;For the demo, I run &lt;code&gt;cdk deploy&lt;/code&gt; manually
```
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;➜  simple-serverless-fastapi cdk deploy&lt;br&gt;
   ✅  SimpleFastApiServerless&lt;/p&gt;

&lt;p&gt;✨  Deployment time: 72.44s&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
- The API GW and method request

  &amp;lt;img src=https://raw.githubusercontent.com/vumdao/simple-serverless-fastapi/master/images/apigw.png width=1100&amp;gt;

  &amp;lt;img src=https://raw.githubusercontent.com/vumdao/simple-serverless-fastapi/master/images/chat_gpt.png width=1100&amp;gt;

- Custom domain mapped to the API

  &amp;lt;img src=https://raw.githubusercontent.com/vumdao/simple-serverless-fastapi/master/images/custom-domain.png width=1100&amp;gt;

## 🚀 **Test API** &amp;lt;a name="Test-API"&amp;gt;&amp;lt;/a&amp;gt;
- Open API Docs

  &amp;lt;img src=https://raw.githubusercontent.com/vumdao/simple-serverless-fastapi/master/images/api_docs.png width=1100&amp;gt;

- Call `/chat_gpt` with API key and query `question`

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;➜  simple-serverless-fastapi curl -X GET -H "Content-Type: application/json" -H 'x-api-key: 6sUnYj8PAw8MKu8O6FqSw1kf1clmC0Fx8ilQhVeO' &lt;a href="https://chatgpt.simflexcloud.com/chat_gpt/" rel="noopener noreferrer"&gt;https://chatgpt.simflexcloud.com/chat_gpt/&lt;/a&gt; -d 'question=how%20are%20you' -G&lt;br&gt;
  {"message":"We got question: how are you"}&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
## 🚀 **Conclusion** &amp;lt;a name="Conclusion"&amp;gt;&amp;lt;/a&amp;gt;
- We created a FastAPI application using AWS Serverless. The user must provide the API key to query request and the API key is associated with the usage plan where we can specify who can access the deployed API stages and methods, and optionally sets the target request rate to start throttling requests.

---

References:
- [Simple Serverless FastAPI with AWS Lambda](https://www.deadbear.io/simple-serverless-fastapi-with-aws-lambda/)

---

&lt;div class="ltag__user ltag__user__id__512906"&gt;
    &lt;a href="/vumdao" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&gt;
        &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F512906%2F83cde530-e04d-4510-90e4-d73bd4d1e7bd.png" alt="vumdao image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/vumdao"&gt;🚀 Vu Dao 🚀 &lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/vumdao"&gt;🚀 AWSome Devops | AWS Community Builder | AWS SA || ☁️ CloudOpz ☁️&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/vumdao" rel="noopener noreferrer"&gt;
        vumdao
      &lt;/a&gt; / &lt;a href="https://github.com/vumdao/vumdao" rel="noopener noreferrer"&gt;
        vumdao
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>simflexcloud</category>
      <category>cdk</category>
      <category>serverless</category>
      <category>fastapi</category>
    </item>
    <item>
      <title>Amazon ECS Farget with Blue-Green Deployments by CDK Typescript - Part 2</title>
      <dc:creator>🚀 Vu Dao 🚀 </dc:creator>
      <pubDate>Wed, 17 May 2023 15:25:49 +0000</pubDate>
      <link>https://forem.com/aws-builders/amazon-ecs-farget-with-blue-green-deployments-by-cdk-typescript-part-2-19f1</link>
      <guid>https://forem.com/aws-builders/amazon-ecs-farget-with-blue-green-deployments-by-cdk-typescript-part-2-19f1</guid>
      <description>&lt;h2&gt;
  
  
  Abstract
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Continue the previous post &lt;a href="https://dev.to/aws-builders/hands-on-amazon-ecs-for-blue-green-deployments-with-cdk-typescript-part-1-4ie3"&gt;Hands-on Amazon ECS for Blue-Green Deployments With CDK Typescript&lt;/a&gt; which uses EC2 to host the ECS container service and manually operate blue-green deployments. In this blog post, I use AWS Fargate as a container of ECS service and codedeploy to operate blue-green deployment automatically.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Table Of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Solution overview&lt;/li&gt;
&lt;li&gt;Source code structure&lt;/li&gt;
&lt;li&gt;Process flow&lt;/li&gt;
&lt;li&gt;Cleanup&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🚀 &lt;strong&gt;Solution overview&lt;/strong&gt; &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-fargate-blue-green-deployments%2Fmaster%2Fimages%2Farchitect.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-fargate-blue-green-deployments%2Fmaster%2Fimages%2Farchitect.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The whole AWS resources are created using CDK pipeline except the pipeline itself.&lt;/li&gt;
&lt;li&gt;The ECS cluster is placed in private subnet as well as the fargate service. We create ECS service with task definition that has desired count of 3 and use FARGATE as &lt;code&gt;requiresCompatibilities&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;The ECS service is registered to ECS deployment controller with the type &lt;code&gt;CODE_DEPLOY&lt;/code&gt; for handling blue-green deployment. It sticks the application load balancer to the replacement target group when deploying successfully.&lt;/li&gt;
&lt;li&gt;A container image is built with codepipeline and codebuild which store images to ECR.&lt;/li&gt;
&lt;li&gt;Here is the stacks relationship&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-fargate-blue-green-deployments%2Fmaster%2Fimages%2Fdiagram.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-fargate-blue-green-deployments%2Fmaster%2Fimages%2Fdiagram.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 &lt;strong&gt;Source code structure&lt;/strong&gt; &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;We have two Git repositories (codecommit) one for application project &lt;code&gt;app-project&lt;/code&gt; directory and others for CDK infrastructure &lt;code&gt;cdk-infra&lt;/code&gt; directory&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

  ➜  ecs-blue-green-deployments tree -L 1
  .
  ├── README.md
  ├── app-project
  ├── cdk-infra
  └── images

  3 directories, 1 file


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;We create the codecommit repositories through CDK&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to &lt;code&gt;cdk-infra&lt;/code&gt; and run &lt;code&gt;cdk ls&lt;/code&gt;
```
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;cdk ls&lt;br&gt;
simflexcloud-ecs-blue-green-deployments-pipeline&lt;br&gt;
simflexcloud-ecs-blue-green-deployments-pipeline/master-sin/EcsBlueGreenDeploymentsStack&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
  - Deploy `simflexcloud-ecs-blue-green-deployments-pipeline` it will create the repository of `cdk-infra`. Note: replace `CDK_DEFAULT_ACCOUNT` and `CDK_DEFAULT_REGION` in `cdk-infra/src/shared/constants.ts` with expected ones.
    ```


    cdk deploy simflexcloud-ecs-blue-green-deployments-pipeline


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Add the remote Git repository to &lt;code&gt;cdk-infra&lt;/code&gt; (Note: Replace the &lt;code&gt;priv-acc&lt;/code&gt; with yours)&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

git remote add origin ssh://priv-acc/v1/repos/ecs-blue-green-deployments-infra
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
  - Create branch `master` and push source code to the repo, it will trigger CDK pipeline to create all stacks which also include the repository and pipeline for `app-proj`

  - After the pipeline is completed successfully, go to `app-proj` directory and add Git remote repository, then create the branches `testgreen` and `testblue` and push them to codecommit
    ```


    git remote add origin ssh://priv-acc/v1/repos/simflexcloud-ecs-blue-green-deployments


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  🚀 &lt;strong&gt;Process flow&lt;/strong&gt; &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Build project&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use AWS CodeBuild to create Docker images and store them in Amazon ECR. This process is powered by codepipeline to handle CICD.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Create ECS cluster&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Create an Amazon ECS cluster using fargate.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-fargate-blue-green-deployments%2Fmaster%2Fimages%2Fecs-infra.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-fargate-blue-green-deployments%2Fmaster%2Fimages%2Fecs-infra.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. Application load balancer&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;We have two rules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Port 80: the main rule&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-fargate-blue-green-deployments%2Fmaster%2Fimages%2Falb-rule-80.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-fargate-blue-green-deployments%2Fmaster%2Fimages%2Falb-rule-80.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Port 8080: testing rule&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-fargate-blue-green-deployments%2Fmaster%2Fimages%2Falb-rule-test-8080.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-fargate-blue-green-deployments%2Fmaster%2Fimages%2Falb-rule-test-8080.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The ALB is currently stuck to the target group of green&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-fargate-blue-green-deployments%2Fmaster%2Fimages%2Falb-stick-to-green-tg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-fargate-blue-green-deployments%2Fmaster%2Fimages%2Falb-stick-to-green-tg.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;4. CodeDeploy application and deployment group&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;A CodeDeploy deployment group that orchestrates ECS blue-green deployments.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-fargate-blue-green-deployments%2Fmaster%2Fimages%2Fapp-deployment-group.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-fargate-blue-green-deployments%2Fmaster%2Fimages%2Fapp-deployment-group.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  🚀 &lt;strong&gt;Test the blue-green deployments&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Test the blue service by loading ALB DNS&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-fargate-blue-green-deployments%2Fmaster%2Fimages%2Ftest-blue.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-fargate-blue-green-deployments%2Fmaster%2Fimages%2Ftest-blue.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Now we change the color to red in &lt;code&gt;app-proj/index.html&lt;/code&gt; and push the commit to CodeCommit. It triggers the pipeline to build and then deploy a new change&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-fargate-blue-green-deployments%2Fmaster%2Fimages%2Fdeploy-blue-green.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-fargate-blue-green-deployments%2Fmaster%2Fimages%2Fdeploy-blue-green.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The deploy stage creates codedeploy deployment ID to perform the deployment process and handle the Traffic shifting progress strategy with rule &lt;code&gt;LINEAR_10PERCENT_EVERY_1MINUTES&lt;/code&gt; (CodeDeploy predefined deployment configuration that shifts 10 percent of traffic every minute until all traffic is shifted)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-fargate-blue-green-deployments%2Fmaster%2Fimages%2Fdeployment-id.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-fargate-blue-green-deployments%2Fmaster%2Fimages%2Fdeployment-id.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ECS run new tasks with new image version on the ECS service&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-fargate-blue-green-deployments%2Fmaster%2Fimages%2Fdesired-count.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-fargate-blue-green-deployments%2Fmaster%2Fimages%2Fdesired-count.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After the new tasks are in healthy state, the deployment starts rerouting production traffic to replacement task set gradually following the rule &lt;code&gt;LINEAR_10PERCENT_EVERY_1MINUTES&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-fargate-blue-green-deployments%2Fmaster%2Fimages%2F70-percentage.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-fargate-blue-green-deployments%2Fmaster%2Fimages%2F70-percentage.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-fargate-blue-green-deployments%2Fmaster%2Fimages%2F90-percentage.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-fargate-blue-green-deployments%2Fmaster%2Fimages%2F90-percentage.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use port 8080 for testing and compare with current version&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-fargate-blue-green-deployments%2Fmaster%2Fimages%2Fblue-green-percentage.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-fargate-blue-green-deployments%2Fmaster%2Fimages%2Fblue-green-percentage.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Complete the replacement and start terminating the original task set&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-fargate-blue-green-deployments%2Fmaster%2Fimages%2F100-percentage.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-fargate-blue-green-deployments%2Fmaster%2Fimages%2F100-percentage.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ECS remove the tasks with old revision&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-fargate-blue-green-deployments%2Fmaster%2Fimages%2Fterminate-old-task-version.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-fargate-blue-green-deployments%2Fmaster%2Fimages%2Fterminate-old-task-version.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The final result&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-fargate-blue-green-deployments%2Fmaster%2Fimages%2Ffinal-result.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-fargate-blue-green-deployments%2Fmaster%2Fimages%2Ffinal-result.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  🚀 &lt;strong&gt;Cleanup&lt;/strong&gt; &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;To cleanup all resources in this project, we first need to delete the ECR image as they were not created by CDK and prevent CDK to destroy the ECR repository.&lt;/li&gt;
&lt;li&gt;Go to cloudformation and delete stacks.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-fargate-blue-green-deployments%2Fmaster%2Fimages%2Fcleanup.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-fargate-blue-green-deployments%2Fmaster%2Fimages%2Fcleanup.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  🚀 &lt;strong&gt;Conclusion&lt;/strong&gt; &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Now that you know how to launch tasks into your Amazon ECS cluster using CDK pipeline with the required type EC2 or Fargate.&lt;/li&gt;
&lt;li&gt;The approach of a blue-green deployment involves utilizing two identical production environments as a means of reducing downtime. Various cutover strategies may be employed, but typically only one of the environments should be actively serving production traffic.&lt;/li&gt;
&lt;/ul&gt;



&lt;p&gt;References:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://ecsworkshop.com/blue_green_deployments/update_code_commit/" rel="noopener noreferrer"&gt;BLUE/GREEN DEPLOYMENTS ON ECS FARGATE&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;div class="ltag__user ltag__user__id__512906"&gt;
    &lt;a href="/vumdao" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&gt;
        &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F512906%2F83cde530-e04d-4510-90e4-d73bd4d1e7bd.png" alt="vumdao image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/vumdao"&gt;🚀 Vu Dao 🚀 &lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/vumdao"&gt;🚀 AWSome Devops | AWS Community Builder | AWS SA || ☁️ CloudOpz ☁️&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;




&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/vumdao" rel="noopener noreferrer"&gt;
        vumdao
      &lt;/a&gt; / &lt;a href="https://github.com/vumdao/vumdao" rel="noopener noreferrer"&gt;
        vumdao
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


</description>
      <category>simflexcloud</category>
      <category>cdk</category>
      <category>aws</category>
      <category>ecs</category>
    </item>
    <item>
      <title>Hands-on Amazon ECS for Blue-Green Deployments With CDK Typescript - Part 1</title>
      <dc:creator>🚀 Vu Dao 🚀 </dc:creator>
      <pubDate>Wed, 10 May 2023 15:38:26 +0000</pubDate>
      <link>https://forem.com/aws-builders/hands-on-amazon-ecs-for-blue-green-deployments-with-cdk-typescript-part-1-4ie3</link>
      <guid>https://forem.com/aws-builders/hands-on-amazon-ecs-for-blue-green-deployments-with-cdk-typescript-part-1-4ie3</guid>
      <description>&lt;h2&gt;
  
  
  Abstract
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;This blog post supports you in hands-on AWS ECS by building the Blue-Green Deployments With CDK Typescript. Instead of using AWS console to create all necessary resources, you will create them through CDK code and automate deployment with CDK pipeline for both project application and infrastructure as code.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Table Of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Solution overview&lt;/li&gt;
&lt;li&gt;Source code structure&lt;/li&gt;
&lt;li&gt;Process flow&lt;/li&gt;
&lt;li&gt;Cleanup&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🚀 &lt;strong&gt;Solution overview&lt;/strong&gt; &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-blue-green-deployments%2Fmaster%2Fimages%2Farchitect.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-blue-green-deployments%2Fmaster%2Fimages%2Farchitect.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The whole AWS resources are created using CDK pipleine except the pipeline itself.&lt;/li&gt;
&lt;li&gt;The ECS cluster is placed in a private subnet with EC2 instances which is managed by the autoscaling group. We create two services which are Blue and Green, there should be only one service that has a desired count &amp;gt; 0 and the other is 0 at the time so that the application load balancer always forwards the request to one of them.&lt;/li&gt;
&lt;li&gt;A container image is built with codepipeline and codebuild which store images to ECR.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🚀 &lt;strong&gt;Source code structure&lt;/strong&gt; &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;We have two Git repositories (codecommit) one for application project &lt;code&gt;app-project&lt;/code&gt; directory and others for CDK infrastructure &lt;code&gt;cdk-infra&lt;/code&gt; directory
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  ➜  ecs-blue-green-deployments tree -L 1
  .
  ├── README.md
  ├── app-project
  ├── cdk-infra
  └── images

  3 directories, 1 file
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;We create the codecommit repositories through CDK&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to &lt;code&gt;cdk-infra&lt;/code&gt; and run &lt;code&gt;cdk ls&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cdk ls
simflexcloud-ecs-blue-green-deployments-pipeline
simflexcloud-ecs-blue-green-deployments-pipeline/master-sin/EcsBlueGreenDeploymentsStack
simflexcloud-ecs-blue-green-deployments-pipeline/master-sin/simflexcloud-ecs-blue-green-deployments-build-image
&lt;/code&gt;&lt;/pre&gt;


&lt;ul&gt;
&lt;li&gt;Deploy &lt;code&gt;simflexcloud-ecs-blue-green-deployments-pipeline&lt;/code&gt; it will create the repository of &lt;code&gt;cdk-infra&lt;/code&gt;. Note: replace &lt;code&gt;CDK_DEFAULT_ACCOUNT&lt;/code&gt; and &lt;code&gt;CDK_DEFAULT_REGION&lt;/code&gt; in &lt;code&gt;cdk-infra/src/shared/constants.ts&lt;/code&gt; with expected ones.
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cdk deploy simflexcloud-ecs-blue-green-deployments-pipeline
&lt;/code&gt;&lt;/pre&gt;


&lt;ul&gt;
&lt;li&gt;Add the remote Git repository to &lt;code&gt;cdk-infra&lt;/code&gt; (Note: Replace the &lt;code&gt;priv-acc&lt;/code&gt; with yours)
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git remote add origin ssh://priv-acc/v1/repos/ecs-blue-green-deployments-infra
&lt;/code&gt;&lt;/pre&gt;


&lt;ul&gt;
&lt;li&gt;Create branch &lt;code&gt;master&lt;/code&gt; and push source code to the repo, it will trigger CDK pipeline to create all stacks which also include the repository and pipeline for &lt;code&gt;app-proj&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;After the pipeline completed successfully, go to &lt;code&gt;app-proj&lt;/code&gt; directory and add Git remote repository, then create the branches &lt;code&gt;testgreen&lt;/code&gt; and &lt;code&gt;testblue&lt;/code&gt; and push them to codecommit
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git remote add origin ssh://priv-acc/v1/repos/simflexcloud-ecs-blue-green-deployments
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  🚀 &lt;strong&gt;Process flow&lt;/strong&gt; &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Build project&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Use AWS CodeBuild to create Docker images and store them in Amazon ECR. This process is powered by codepipeline to handle CICD. We need to build two image tags which are &lt;code&gt;testgreen&lt;/code&gt; based on branch &lt;code&gt;testgreen&lt;/code&gt; and &lt;code&gt;testblue&lt;/code&gt; based on branch &lt;code&gt;testblue&lt;/code&gt;. Any commits from these branches will trigger pipelines to execute build projects based on the &lt;code&gt;buildspec.yml&lt;/code&gt; and &lt;code&gt;Dockerfile&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-blue-green-deployments%2Fmaster%2Fimages%2Fbuild-images.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-blue-green-deployments%2Fmaster%2Fimages%2Fbuild-images.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-blue-green-deployments%2Fmaster%2Fimages%2Fbuild-projects.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-blue-green-deployments%2Fmaster%2Fimages%2Fbuild-projects.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-blue-green-deployments%2Fmaster%2Fimages%2Fecr-images.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-blue-green-deployments%2Fmaster%2Fimages%2Fecr-images.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Create ECS cluster&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Create an Amazon ECS cluster using EC2 as container instance. The EC2 instance is attached an IAM role which includes &lt;code&gt;AmazonEC2ContainerServiceforEC2Role&lt;/code&gt; policy for the ECS agent to connect to ECS cluster.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-blue-green-deployments%2Fmaster%2Fimages%2Fecs-infra.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-blue-green-deployments%2Fmaster%2Fimages%2Fecs-infra.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Task definitions are required to run Docker containers in Amazon ECS. They tell the services which Docker images to use for the container instances, what kind of resources to allocate, network specifics, and other details. We create two task definitions which are Blue and Green. In the task, we define image tag, task size, container port, Task execution role, etc.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-blue-green-deployments%2Fmaster%2Fimages%2Ftask-definition.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-blue-green-deployments%2Fmaster%2Fimages%2Ftask-definition.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;With ECS, we can easily deploy and manage containerized applications at scale, while benefiting from features such as automatic scaling, load balancing, and automatic service discovery. It resembles Auto Scaling in that it keeps a specified number of instances, but unlike Auto Scaling, it doesn't adjust the number of instances in response to CloudWatch alarms or other Auto Scaling mechanisms. By utilizing a load balancer, it is possible to maintain a specified amount of resources while ensuring a singular application reference point. As such, we generate two distinct services, one for the blue application and the other for the green application. Only one service is active (has desire count greater than zero) at a time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-blue-green-deployments%2Fmaster%2Fimages%2Fservice.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-blue-green-deployments%2Fmaster%2Fimages%2Fservice.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-blue-green-deployments%2Fmaster%2Fimages%2Fservice-configuration.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-blue-green-deployments%2Fmaster%2Fimages%2Fservice-configuration.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Due to desired tasks 2, the service creates 2 containers on the EC2 instance and expose the public port for ALB target group, mapping to container port 8081.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-blue-green-deployments%2Fmaster%2Fimages%2Ftargetgroup.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-blue-green-deployments%2Fmaster%2Fimages%2Ftargetgroup.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. Test the blue green deployments&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Test the blue service by calling the &lt;code&gt;/api&lt;/code&gt; request with ALB DNS&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-blue-green-deployments%2Fmaster%2Fimages%2Ftest-blue.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-blue-green-deployments%2Fmaster%2Fimages%2Ftest-blue.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Now we switch deployment to green service by updating &lt;code&gt;desiredCount&lt;/code&gt; from &lt;code&gt;blue&lt;/code&gt; to 0 and from &lt;code&gt;green&lt;/code&gt; to 2 then deploy.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-blue-green-deployments%2Fmaster%2Fimages%2Fcdk-pipeline.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-blue-green-deployments%2Fmaster%2Fimages%2Fcdk-pipeline.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;We see targetgroup add new target port and draining the old one&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-blue-green-deployments%2Fmaster%2Fimages%2Ftargetgroup-green.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-blue-green-deployments%2Fmaster%2Fimages%2Ftargetgroup-green.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-blue-green-deployments%2Fmaster%2Fimages%2Ftest-green.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-blue-green-deployments%2Fmaster%2Fimages%2Ftest-green.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  🚀 &lt;strong&gt;Cleanup&lt;/strong&gt; &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;To cleanup all resoures in this project, we first need to delete the ECR image as they were not created by CDK and prevent CDK to destroy the ECR repository.&lt;/li&gt;
&lt;li&gt;Go to cloudformation and delete stacks.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-blue-green-deployments%2Fmaster%2Fimages%2Fcleanup.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvumdao%2Fcdk-ecs-blue-green-deployments%2Fmaster%2Fimages%2Fcleanup.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  🚀 &lt;strong&gt;Conclusion&lt;/strong&gt; &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Now that you know how to launch tasks into your Amazon ECS cluster using CDK pipeline&lt;/li&gt;
&lt;li&gt;The approach of a blue-green deployment involves utilizing two identical production environments as a means of reducing downtime. Various cutover strategies may be employed, but typically only one of the environments should be actively serving production traffic.&lt;/li&gt;
&lt;/ul&gt;



&lt;h3&gt;
  &lt;a href="https://dev.to/vumdao"&gt;🌠 Blog&lt;/a&gt;
  &lt;span&gt; · &lt;/span&gt;
  &lt;a href="https://github.com/vumdao/ecs-blue-green-deployments" rel="noopener noreferrer"&gt;Github&lt;/a&gt;
  &lt;span&gt; · &lt;/span&gt;
  &lt;a href="https://stackoverflow.com/users/11430272/vumdao" rel="noopener noreferrer"&gt;stackoverflow&lt;/a&gt;
  &lt;span&gt; · &lt;/span&gt;
  &lt;a href="https://www.linkedin.com/in/vu-dao-9280ab43/" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt;
  &lt;span&gt; · &lt;/span&gt;
  &lt;a href="https://www.linkedin.com/groups/12488649/" rel="noopener noreferrer"&gt;Group&lt;/a&gt;
  &lt;span&gt; · &lt;/span&gt;
  &lt;a href="https://www.facebook.com/CloudOpz-104917804863956" rel="noopener noreferrer"&gt;Page&lt;/a&gt;
  &lt;span&gt; · &lt;/span&gt;
  &lt;a href="https://twitter.com/VuDao81124667" rel="noopener noreferrer"&gt;Twitter 🌠&lt;/a&gt;
&lt;/h3&gt;




&lt;div class="ltag__user ltag__user__id__512906"&gt;
    &lt;a href="/vumdao" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&gt;
        &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F512906%2F83cde530-e04d-4510-90e4-d73bd4d1e7bd.png" alt="vumdao image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/vumdao"&gt;🚀 Vu Dao 🚀 &lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/vumdao"&gt;🚀 AWSome Devops | AWS Community Builder | AWS SA || ☁️ CloudOpz ☁️&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;




&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/vumdao" rel="noopener noreferrer"&gt;
        vumdao
      &lt;/a&gt; / &lt;a href="https://github.com/vumdao/vumdao" rel="noopener noreferrer"&gt;
        vumdao
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


</description>
      <category>simflexcloud</category>
      <category>cdk</category>
      <category>aws</category>
      <category>ecs</category>
    </item>
  </channel>
</rss>
