<?xml version="1.0" encoding="utf-8" standalone="yes"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><script src="https://www.rss.style/js/atom-style.js" xmlns="http://www.w3.org/1999/xhtml"/><title>Tower of Kubes</title><link rel="self" type="application/atom+xml" hreflang="en" href="https://www.towerofkubes.com/tags/devops/feed.xml"/><link rel="alternate" type="text/html" hreflang="en" href="https://www.towerofkubes.com/tags/devops/"/><link rel="alternate" type="application/rss+xml" hreflang="en" href="https://www.towerofkubes.com/tags/devops/index.xml"/><id>/</id><updated>2025-10-12T00:00:00Z</updated><author><name>Ro'i Bandel</name></author><generator>Hugo 0.157.0</generator><entry><title>Cloud Development Kit (CDK)</title><link rel="alternate" type="text/html" hreflang="en" href="https://www.towerofkubes.com/articles/cdk/"/><id>https://www.towerofkubes.com/articles/cdk/</id><updated>2025-10-12T00:00:00Z</updated><summary type="html">Overview of AWS CDK, cdk8s, and CDKTF: constructs model, synth commands, language support, IaC comparisons, and personal lessons learned.</summary><content type="html"><![CDATA[<p>I’ve been learning about CDK at work, using it for Infrastructure as Code (IaC).</p>

<h2 class="relative group">What is CDK?
    <div id="what-is-cdk" class="anchor"></div>
    
</h2>
<p>These “Cloud Development Kits” are used for defining and provisioning cloud infrastructure resources using familiar programming languages including TypeScript, Python, Java and Go. In AWS, CDK is offered in addition to <a href="https://docs.aws.amazon.com/sdkref/latest/guide/overview.html"  target="_blank" rel="noreferrer">AWS SDK for various languages</a>.</p>
<ul>
<li>
<p><strong>What they share:</strong> all three use the <em>constructs</em> programming model (object-oriented code → declarative infra).</p>
</li>
<li>
<p><strong>What they target:</strong></p>
</li>
</ul>
<ol>
<li>AWS CDK → CloudFormation templates (JSON/YAML) + asset packaging.</li>
<li>cdk8s → Kubernetes manifests (YAML).</li>
<li>CDKTF → Terraform configuration (Terraform JSON), then Terraform does the planning/applying/state.</li>
</ol>

<h2 class="relative group">CDK Family
    <div id="cdk-family" class="anchor"></div>
    
</h2>
<ol>
<li><strong>AWS CDK:</strong> <a href="https://docs.aws.amazon.com/cdk/"  target="_blank" rel="noreferrer">AWS Cloud Development Kit Documentation</a></li>
<li><strong>cdk8s:</strong> <a href="https://cdk8s.io/"  target="_blank" rel="noreferrer">cdk8s (Website)</a></li>
<li><strong>CDKTF:</strong> <a href="https://developer.hashicorp.com/terraform/cdktf"  target="_blank" rel="noreferrer">CDK for Terraform | Terraform | HashiCorp Developer</a></li>
</ol>
<p>As far as history goes, it seems AWS CDK was first, then cdk8s, and finally CDKTF. I remember the hype about CDKTF a few years ago.</p>

<h2 class="relative group"><code>cdk synth</code>
    <div id="cdk-synth" class="anchor"></div>
    
</h2>
<p>The different CDK tools each have their own CLI, however some commands are similar and related. For example <code>cdk synth</code>.</p>

<h3 class="relative group">“synthesize”
    <div id="synthesize" class="anchor"></div>
    
</h3>
<p>Turn constructs-based <strong>code → declarative output</strong> for the downstream engine.</p>
<table>
  <thead>
      <tr>
          <th>Tool</th>
          <th>Command</th>
          <th>Produces</th>
          <th>Next step</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>AWS CDK</td>
          <td><a href="https://docs.aws.amazon.com/cdk/v2/guide/ref-cli-cmd-synth.html"  target="_blank" rel="noreferrer"><code>cdk synth</code></a> (alias: <code>cdk synthesize</code>)</td>
          <td>CloudFormation template(s)</td>
          <td><code>cdk deploy</code></td>
      </tr>
      <tr>
          <td>cdk8s</td>
          <td><a href="https://cdk8s.io/docs/latest/cli/synth/"  target="_blank" rel="noreferrer"><code>cdk8s synth</code></a></td>
          <td>Kubernetes Manifests</td>
          <td><code>kubectl apply -f dist/</code></td>
      </tr>
      <tr>
          <td>CDKTF</td>
          <td><a href="https://developer.hashicorp.com/terraform/cdktf/cli-reference/commands#synth"  target="_blank" rel="noreferrer"><code>cdktf synth</code></a></td>
          <td>Terraform JSON</td>
          <td><code>cdktf plan</code> / <code>cdktf deploy</code></td>
      </tr>
  </tbody>
</table>

<h2 class="relative group">Quick CLI
    <div id="quick-cli" class="anchor"></div>
    
</h2>
<table>
  <thead>
      <tr>
          <th>Stage</th>
          <th>AWS CDK</th>
          <th>cdk8s</th>
          <th>CDKTF</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>Init</strong></td>
          <td><code>cdk init app --language ts</code></td>
          <td><code>cdk8s init typescript-app</code></td>
          <td><code>cdktf init --template=typescript</code></td>
      </tr>
      <tr>
          <td><strong>Bootstrap / State</strong></td>
          <td><code>cdk bootstrap</code></td>
          <td><em>(none)</em></td>
          <td>Configure TF backend (state)</td>
      </tr>
      <tr>
          <td><strong>Synthesize</strong></td>
          <td><code>cdk synth</code></td>
          <td><code>cdk8s synth</code></td>
          <td><code>cdktf synth</code></td>
      </tr>
      <tr>
          <td><strong>Preview</strong></td>
          <td><code>cdk diff</code></td>
          <td><code>kubectl diff -f dist/</code></td>
          <td><code>cdktf plan</code></td>
      </tr>
      <tr>
          <td><strong>Deploy</strong></td>
          <td><code>cdk deploy</code></td>
          <td><code>kubectl apply -f dist/</code></td>
          <td><code>cdktf deploy</code></td>
      </tr>
      <tr>
          <td><strong>Destroy</strong></td>
          <td><code>cdk destroy</code></td>
          <td><code>kubectl delete -f dist/</code></td>
          <td><code>cdktf destroy</code></td>
      </tr>
  </tbody>
</table>

<h2 class="relative group">Construct Hub
    <div id="construct-hub" class="anchor"></div>
    
</h2>
<blockquote><p>Construct Hub helps developers find open-source construct libraries for use with AWS CDK, CDK8s, CDKTF and other construct-based tools.</p>
</blockquote>
<h2 class="relative group">Supported Programming Languages
    <div id="supported-programming-languages" class="anchor"></div>
    
</h2>
<ul>
<li><a href="https://docs.aws.amazon.com/cdk/v2/guide/home.html"  target="_blank" rel="noreferrer">The AWS CDK supports TypeScript, JavaScript, Python, Java, C#/.Net, and Go.</a></li>
<li>CDKTF <a href="https://developer.hashicorp.com/terraform/cdktf"  target="_blank" rel="noreferrer">supports TypeScript, Python, Java, C#, and Go.</a></li>
<li><a href="https://cdk8s.io/"  target="_blank" rel="noreferrer">cdk8s lets you define applications using Typescript, JavaScript, Python, Java, and Go.</a></li>
</ul>
<table>
  <thead>
      <tr>
          <th>Language</th>
          <th style="text-align: center">AWS CDK</th>
          <th style="text-align: center">CDKTF</th>
          <th style="text-align: center">cdk8s</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>TypeScript</td>
          <td style="text-align: center">✓</td>
          <td style="text-align: center">✓</td>
          <td style="text-align: center">✓</td>
      </tr>
      <tr>
          <td>JavaScript</td>
          <td style="text-align: center">✓</td>
          <td style="text-align: center"></td>
          <td style="text-align: center">✓</td>
      </tr>
      <tr>
          <td>Python</td>
          <td style="text-align: center">✓</td>
          <td style="text-align: center">✓</td>
          <td style="text-align: center">✓</td>
      </tr>
      <tr>
          <td>Java</td>
          <td style="text-align: center">✓</td>
          <td style="text-align: center">✓</td>
          <td style="text-align: center">✓</td>
      </tr>
      <tr>
          <td>C#</td>
          <td style="text-align: center">✓</td>
          <td style="text-align: center">✓</td>
          <td style="text-align: center"></td>
      </tr>
      <tr>
          <td>Go</td>
          <td style="text-align: center">✓</td>
          <td style="text-align: center">✓</td>
          <td style="text-align: center">✓</td>
      </tr>
  </tbody>
</table>

<h3 class="relative group">Most Used Programming Languages
    <div id="most-used-programming-languages" class="anchor"></div>
    
</h3>
<ul>
<li>Reddit Poll for AWS CDK shows “JavaScript or TypeScript” as the most used: <a href="https://www.reddit.com/r/aws/comments/1agzhl5/poll_which_programming_language_do_you_use_for/"  target="_blank" rel="noreferrer">Poll: Which programming language do you use for AWS CDK? : r/aws</a></li>
<li>Reddit Poll for CDKTF shows “Python” as the most used: <a href="https://www.reddit.com/r/Terraform/comments/1agzbew/poll_which_programming_language_do_you_use_for/"  target="_blank" rel="noreferrer">Poll: Which programming language do you use for CDKTF? : r/Terraform</a></li>
</ul>

<h2 class="relative group">Comparison to HCL
    <div id="comparison-to-hcl" class="anchor"></div>
    
</h2>
<p>The most used IaC language remains <a href="https://github.com/hashicorp/hcl"  target="_blank" rel="noreferrer">HCL</a>, using Terraform or OpenTofu.</p>
<blockquote><p>HCL syntax is designed to be easily read and written by humans, and allows <em>declarative</em> logic to permit its use in more complex applications.</p>
</blockquote><ul>
<li><a href="https://github.com/hashicorp/hcl?tab=readme-ov-file#why"  target="_blank" rel="noreferrer">GitHub - hashicorp/hcl: HCL is the HashiCorp configuration language.</a></li>
</ul>
<p>HCL is <em>declarative</em>, compared to traditional programming languages which are <em>imperative</em>. HCL is a good fit for provisioning IaC, however some find it limiting. While solutions like Terragrunt address some of Terraform’s limitations, some wished for the flexibility of a full programming language. This was what led to the birth of HCL.</p>
<p>CDKTF still uses Terraform providers under the hood, and <a href="/articles/cdk/#cdk-synth" >synthesizes</a> to valid Teraform JSON.</p>

<h2 class="relative group">My Usage At Work
    <div id="my-usage-at-work" class="anchor"></div>
    
</h2>
<p>At my client, I wanted to use OpenTofu for IaC. However, I was told that AWS CloudFormation is what’s already used internally at the client.</p>
<p>For my current use-case, my IaC mainly consists of an EC2 instance configured for use as a <a href="/articles/bitbucket-vs-the-competition/" >Bitbucket</a> Runner. I decided to use AWS CDK for this use case, as it works with AWS CloudFormation but is more flexible than the JSON syntax that CFN uses.</p>
<p>Converting my working OpenTofu HCL code to AWS CDK TypeScript code was <em>frustrating</em> and made me curse AWS multiple times. However, I eventually got it working and functionally equivalent to what I already had working with OpenTofu.</p>

<h2 class="relative group">My Opinion
    <div id="my-opinion" class="anchor"></div>
    
</h2>

<h3 class="relative group">Declarative vs Imperative IaC
    <div id="declarative-vs-imperative-iac" class="anchor"></div>
    
</h3>
<p>I personally don’t find much value in using a “real” programming language for IaC. I believe Terraform owes a lot of success to the simple, imperative nature of <a href="/articles/cdk/#comparison-to-hcl" >HCL</a>, and in some ways succeeded <em>because</em> of its limitations and not despite them.</p>
<p>My experiences with Pulumi and AWS CDK show me that if not being careful, the IaC could turn into spaghetti code. Of course, the potential for spaghetti code exists for HCL as well, especially when attempting to overcome some of its limitations. However, I believe for many of the common use-cases of IaC, the imperative design fits better and should be used unless there is a specific need for a “real” programming language.</p>

<h3 class="relative group">AWS CDK
    <div id="aws-cdk" class="anchor"></div>
    
</h3>
<p>Assuming I get the choice, I wouldn’t willingly use AWS CDK again. I have tried many IaC tools. Terraform, Ansible, OpenTofu, Terragrunt and Pulumi. Out of all ones I tried, AWS CDK was <em>by far</em> the most confusing.</p>

<h3 class="relative group">CDKTF
    <div id="cdktf" class="anchor"></div>
    
</h3>
<p>I was initially interested in CDKTF, but it seems it has gained very little traction compared to Terraform or OpenTofu:</p>
<ul>
<li><a href="https://www.reddit.com/r/Terraform/comments/18115po/why_cdktf_has_such_little_adoption/"  target="_blank" rel="noreferrer">Why CDKTF has such little adoption? : r/Terraform</a></li>
<li><a href="https://www.reddit.com/r/Terraform/comments/1gugfxe/is_cdktf_becoming_abandonware/"  target="_blank" rel="noreferrer">Is CDKTF becoming abandonware? : r/Terraform</a></li>
<li><a href="https://www.reddit.com/r/Terraform/comments/1o8k9jv/cdktf_net_vs_normal_terraform/"  target="_blank" rel="noreferrer">CDKTF .Net vs Normal Terraform? : r/Terraform</a></li>
</ul>
<p>I was also concerned that CDKTF might not work well with OpenTofu. It seems it does currently work even if it’s not officially supported, but might break in the future: <a href="https://github.com/opentofu/opentofu/issues/601"  target="_blank" rel="noreferrer">Port cdktf to OpenTofu · Issue #601 · opentofu/opentofu · GitHub</a></p>
<p>I believe that CDKTF is now an afterthought for HashiCorp, compared to Terraform. Development for CDKTF is not completely abandoned, but based on recent activity development seems slow and mainly focuses on fixes and dependency updates, rather than major new features.</p>

<h3 class="relative group">cdk8s
    <div id="cdk8s" class="anchor"></div>
    
</h3>
<p>I haven’t found a compelling reason to use this either. I’m not sure where exactly it fits into the Kubernetes manifest landscape between KYAML, Helm Charts, Kustomizations, <a href="https://www.devoteam.com/expert-view/infrastructure-as-code-with-configuration-languages/"  target="_blank" rel="noreferrer">CUE/HCL</a> and GitOps solutions (mainly Argo CD and Flux CD).</p>

    <div class="admonition info">
      <div class="admonition-header"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM216 336l24 0 0-64-24 0c-13.3 0-24-10.7-24-24s10.7-24 24-24l48 0c13.3 0 24 10.7 24 24l0 88 8 0c13.3 0 24 10.7 24 24s-10.7 24-24 24l-80 0c-13.3 0-24-10.7-24-24s10.7-24 24-24zm40-208a32 32 0 1 1 0 64 32 32 0 1 1 0-64z"/></svg>
        <span>Info</span>
      </div>
      <div class="admonition-content">
        <p><strong>UPDATE:</strong> CDKTF has been archived: <a href="https://github.com/hashicorp/terraform-cdk"  target="_blank" rel="noreferrer">GitHub - hashicorp/terraform-cdk: Define infrastructure resources using programming constructs and provision them using HashiCorp Terraform</a></p>
      </div>
    </div>
<h2 class="relative group">Pulumi IaC
    <div id="pulumi-iac" class="anchor"></div>
    
</h2>
<p>Not technically CDK but is similar in many ways. Supports TypeScript, JavaScript, Python, Go, C#, Java and YAML. Last year, <a href="https://www.pulumi.com/blog/any-terraform-provider/"  target="_blank" rel="noreferrer">Pulumi introduced support for any Terraform Provider</a>, With that, I believe Pulumi can serve as a solid replacement for CDKTF (not a drop-in replacement, but can be functionally equivalent). Unlike HashiCorp, which seems to treat CDKTF as an afterthought, Pulumi (the company) is primarily focused on Pulumi IaC. <a href="https://github.com/pulumi/pulumi"  target="_blank" rel="noreferrer">pulumi/pulumi</a> is open-source under the <a href="https://github.com/pulumi/pulumi#Apache-2.0-1-ov-file"  target="_blank" rel="noreferrer">Apache-2.0 license</a>, though Pulumi as a company also offers paid solutions (such as <a href="https://www.pulumi.com/product/pulumi-cloud/"  target="_blank" rel="noreferrer">Pulumi Cloud</a>).</p>
<p><strong>If I had to choose between CDKTF and Pulumi, I would lean towards Pulumi.</strong></p>
<hr>
<p><em>Photo by <a href="https://unsplash.com/@abebarrera?utm_source=hugo&utm_medium=referral"  target="_blank" rel="noreferrer">Abraham Barrera</a> on <a href="https://unsplash.com/photos/aerial-view-on-concrete-road-8Nn49K7Snow?utm_source=hugo&utm_medium=referral"  target="_blank" rel="noreferrer">Unsplash</a>.</em></p>
]]></content><author><name>Ro'i Bandel</name></author><category term="infra-as-code" label="Infra-as-Code" scheme="https://www.towerofkubes.com/tags/infra-as-code/"/><category term="devops" label="Devops" scheme="https://www.towerofkubes.com/tags/devops/"/><published>2025-10-12T00:00:00Z</published></entry></feed>