<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
    <channel>
      <title>Mahesh Rijal - Blog</title>
      <link>https://maheshrijal.com/blog/</link>
      <description>Hi! I am Mahesh, an engineer, tinkerer, reader, and troubleshooter, among other things. I live in Bangalore, but I&#39;m virtually omnipresent on the internet.</description>
      <generator>Zola</generator>
      <language>en</language>
      <atom:link href="https://maheshrijal.com/blog/rss.xml" rel="self" type="application/rss+xml"/>
      <lastBuildDate>Sat, 07 Feb 2026 00:00:00 +0000</lastBuildDate>
      <item>
          <title>Coding with Agents</title>
          <pubDate>Sat, 07 Feb 2026 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://maheshrijal.com/blog/coding-with-agents/</link>
          <guid>https://maheshrijal.com/blog/coding-with-agents/</guid>
          <description xml:base="https://maheshrijal.com/blog/coding-with-agents/">&lt;p&gt;AI agents have changed how I approach, deliver, and solve problems at a fundamental level. Over the last year, I have spent a lot of time with agentic tools and frameworks. From the early days of Copilot, to Claude Code, and now Cursor, Codex, and many others. Code, now more than ever, feels replaceable, and how I build and run applications has changed drastically in the last year.&lt;/p&gt;
&lt;h2 id=&quot;interfaces-and-tools&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#interfaces-and-tools&quot; aria-label=&quot;Anchor link for: interfaces-and-tools&quot;&gt;Interfaces and Tools&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I was not a regular user of Copilot when it launched, but I remember trying it a couple of times. I used to work on Infrastructure Ops (think Ansible, Jenkins, Linux, etc.) back then and didn&#39;t write code regularly. But Copilot came in handy when I had to write a shell script or Ansible playbook. It felt magical at the time.&lt;/p&gt;
&lt;h2 id=&quot;claude-code&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#claude-code&quot; aria-label=&quot;Anchor link for: claude-code&quot;&gt;Claude Code&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When Claude Code launched, I received a few hundred dollars in free credits to try it out. I burned through the credits in a month.&lt;/p&gt;
&lt;p&gt;This was a completely new approach to coding. The terminal is where I lived (and still do). So having a terminal tab dedicated to answering questions, running ops, writing new code was a game changer. I would delegate something boring/menial that I didn&#39;t want to spend time on to Claude. Things like checking if a new release for a Terraform provider was out, or upgrading dependencies in an application.
I remember using it to create manifests to provision a new EKS cluster by looking at what I had already done in the past in another repository. Basically, at a higher level, I was delegating tasks that I already knew how to do.&lt;/p&gt;
&lt;p&gt;It did make mistakes, which was expected.  This was my first rodeo with agentic interfaces and since it was not part of my core workflow yet, when the credits ran out, I stopped using claude and it didn&#39;t bother me the slightest.&lt;/p&gt;
&lt;p&gt;Then, when working on a client engagement through my employer, I got access to Claude Code, which meant cost was no longer a concern. I began to use it more liberally. It became more like an assistant helping with documentation, bug fixes, upgrading dependencies, and writing Terraform modules. These were tasks I knew how to do, but I wasn&#39;t completely aware of the approach I would take to solve the problem. This was something I would figure out by talking to the agent. I also became more comfortable with delegation and often had multiple terminals running Claude sessions in parallel.&lt;/p&gt;
&lt;h2 id=&quot;cursor&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#cursor&quot; aria-label=&quot;Anchor link for: cursor&quot;&gt;Cursor&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;VS Code, but with wings.&lt;/p&gt;
&lt;p&gt;When I joined &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://www.people.inc/&quot;&gt;People Inc&lt;/a&gt; I started working heavily on infrastructure and platform engineering. I also got access to &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://cursor.com/&quot;&gt;Cursor&lt;/a&gt;. I was building things in record time. I remember deploying something new to the platform every other day. Things like EKS, ArgoCD, Traefik, and Cert Manager, External DNS all of these I rolled out in record time. I liked the planning aspect, and its understanding of the codebase. I have found that the editor+agent interface is good for quickly walking through the codebase, asking focused questions on specific functions or files and trying to understand how different pieces of a large codebase fit together.&lt;/p&gt;
&lt;p&gt;One quirk around Cursor that I&#39;ve found is that it&#39;s not super easy to see or work with it while you actively run terminal commands (aws, kubectl, argo, etc.). Also, the UI does not feel suited towards for terminal-first operations.&lt;/p&gt;
&lt;p&gt;Cursor does have issues. It consumes too much memory and makes &lt;a href=&quot;https://maheshrijal.com/uses/&quot;&gt;my system&lt;/a&gt; slow when I open multiple windows. It has gotten much better in the last 2 months, and I&#39;ve had fewer problems with it now. But I still prefer a terminal-native workflow over a code editor.&lt;/p&gt;
&lt;p&gt;I now use the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://cursor.com/cli&quot;&gt;Cursor CLI&lt;/a&gt; more than I use the editor. It&#39;s faster than the GUI, but it&#39;s not as polished as the other options out there.&lt;/p&gt;
&lt;h2 id=&quot;codex&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#codex&quot; aria-label=&quot;Anchor link for: codex&quot;&gt;Codex&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For me, &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://openai.com/codex/&quot;&gt;Codex&lt;/a&gt; has really been a journey. I&#39;ve seen the harness evolve over time. In its early days, Codex was just trying to keep up with Claude Code. I like my tools fast. And Codex definitely is fast, but the models historically have not been. In my experience, OpenAI’s models are generally more capable at long-running and focused tasks, but the speed of the model has been too slow. Although that has not stopped me from using it for most of my day almost every day.&lt;/p&gt;
&lt;p&gt;Codex is the tool I have used the most and it has gotten a lot better, especially in the last couple of weeks as I am writing this blog with the new &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://openai.com/index/introducing-gpt-5-3-codex/&quot;&gt;gpt-5.3-codex&lt;/a&gt; release and other new features added to Codex CLI. The new Codex app is really good as well.&lt;/p&gt;
&lt;p&gt;Codex excels at gathering context both locally and remotely (through aws, kubectl, helm commands). It is also the best at troubleshooting. I often point it to a failing deployment, or an issue in AWS. It can map out dependencies well and its review system is also good at catching issues early. I typically ask Codex to look around and once it has context, ask it to work on a specific task.&lt;/p&gt;
&lt;p&gt;Codex is my agent harness of choice. I have become so comfortable that I typically have three or more terminal tabs open with different Codex sessions all working on different things. I do have a robust &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://agents.md/&quot;&gt;AGENTS.md&lt;/a&gt; and require it (codex) to seek approval for commands that mutate state, so I don&#39;t have to worry about it nuking something important accidentally.&lt;/p&gt;
&lt;h2 id=&quot;others&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#others&quot; aria-label=&quot;Anchor link for: others&quot;&gt;Others&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Thoughts on &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://ampcode.com/&quot;&gt;Amp&lt;/a&gt;, &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://cline.bot/&quot;&gt;Cline&lt;/a&gt;, &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://factory.ai/&quot;&gt;Droid&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Out of all of these, I like Amp the most. I like what they are doing with the advertisement model. Amp can one-shot most simple tasks, but it is the most expensive of all of these tools because it is not subsidized via a subscription. I use it from time to time and assign it specific focused tasks. Over time I have learned the kind of tasks that would fit within a $10 budget window and only use it on those tasks. If the task is more complex or time consuming, I hand it off to Codex.&lt;/p&gt;
&lt;p&gt;On Cline and Droid, I felt that Cline has the same problems Cursor does, and it is far less capable at what it can do. It is also the slowest of the bunch, at least for the things that I have tested it on. It&#39;s one of my least used tools.&lt;/p&gt;
&lt;p&gt;I used Droid CLI for two weeks. It definitely had an edge over codex &amp;amp; the cursor CLI in the past, but the other two have caught up. I don&#39;t use droid because I already pay 20$ for Claude Code. I use Cursor agent when I need to with models not supported by Codex CLI.&lt;/p&gt;
&lt;h2 id=&quot;writing-code&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#writing-code&quot; aria-label=&quot;Anchor link for: writing-code&quot;&gt;Writing Code&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Writing code was not my forte. But, that has changed. Now that I don&#39;t have to go in depth into every single line of code, I find myself using agents to write more and more code.&lt;/p&gt;
&lt;p&gt;At work, I find myself using agents to bootstrap things I need quickly. Recently, I used Codex to build a documentation site on top of &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://starlight.astro.build/&quot;&gt;Starlight&lt;/a&gt; that aggregates documentation for all of the internal tools we have. It uses &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://agentskills.io/home&quot;&gt;Agent Skills&lt;/a&gt; and &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://argoproj.github.io/workflows/&quot;&gt;Argo Workflows&lt;/a&gt; under the hood, to  generate documentation for our internal platform. I probably wouldn&#39;t have worked on this project if I had to write all of the code by hand. And this was implemented in a few hours.&lt;/p&gt;
&lt;p&gt;On the personal front, I have been building tools and automations. A Few weeks ago, built &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://f1recap.pages.dev/&quot;&gt;F1Recap&lt;/a&gt;. A website for gathering Formula 1 recaps &amp;amp; schedule, built an &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://rebill.mrjl.dev/&quot;&gt;Invoice generator&lt;/a&gt; for my dad&#39;s business, and even a CLI to place &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://github.com/maheshrijal/bislericli&quot;&gt;orders for water cans&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The pace at which I build things both at work and in personal life has increased multifold. I have been reading various &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://registerspill.thorstenball.com/p/joy-and-curiosity-71&quot;&gt;blogposts&lt;/a&gt; which tend to express the idea that code is replaceable and I think I agree. But, this is just the early days and I&#39;m excited to see what lies ahead.&lt;/p&gt;
&lt;h2 id=&quot;learning-new-skills&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#learning-new-skills&quot; aria-label=&quot;Anchor link for: learning-new-skills&quot;&gt;Learning New Skills&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Last week, I started learning about &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://www.crossplane.io/&quot;&gt;Crossplane&lt;/a&gt; and used it to automate Grafana provisioning at work. Crossplane is a completely new tool for me. My approach to learning this tool has been different from how I learned other tools in the past.&lt;/p&gt;
&lt;p&gt;In the past, I would find YouTube videos, tutorials, and maybe watch a demo on how the tool works, what its capabilities are.&lt;/p&gt;
&lt;p&gt;This time around, I asked Codex about it. It showed me examples, use cases, created a sample codebase for me to explore, and I feel this approach is going to stick. Having an agent on the terminal that can run the same commands as me feels like a game changer now.&lt;/p&gt;
&lt;p&gt;Terminal based access to AI Agents has become a fundamental part of my workflow. Something I cannot imagine working without. I&#39;m excited to see what&#39;s ahead in this space.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;I did read this interesting article by Anthropic on how using &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://www.anthropic.com/research/AI-assistance-coding-skills&quot;&gt;agents impact our skills&lt;/a&gt;. It does make me worry a little. But, I have yet to think deeply about this topic.&lt;/p&gt;
&lt;p&gt;Exciting times are ahead of us. We are witnessing a shift in the software paradigm right under our eyes. I am glad I am in some way able to take part in this, and excited to see what lies ahead.&lt;/p&gt;
&lt;p&gt;What the future holds, I don&#39;t really know. I eagerly wait for new releases, constantly get new ideas and try to build something, and always try to find &amp;amp; optimize my workflow around agents. I&#39;m constantly learning from many others who have shared similar experiences.&lt;/p&gt;
</description>
      </item>
      <item>
          <title>Using IaC to Manage DNS Records</title>
          <pubDate>Thu, 13 Jun 2024 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://maheshrijal.com/blog/using-iac-to-manage-dns-records/</link>
          <guid>https://maheshrijal.com/blog/using-iac-to-manage-dns-records/</guid>
          <description xml:base="https://maheshrijal.com/blog/using-iac-to-manage-dns-records/">&lt;p&gt;Organizations like to manage their DNS records using Infrastructure as Code (IaC) tools. This approach helps streamline approval processes, makes changes easy to track, and simplifies rollbacks in case of failure. I came across this idea&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-first-1&quot;&gt;&lt;a href=&quot;https://maheshrijal.com/blog/using-iac-to-manage-dns-records/#fn-first&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt; recently and wanted to try it out for the DNS records of my domain &lt;code&gt;maheshrijal.com&lt;/code&gt;. This blog outlines the process.&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://www.cloudflare.com/learning/dns/dns-records/dns-ns-record/&quot;&gt;NS records&lt;/a&gt; for my domain are in Cloudflare. They already have a &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs&quot;&gt;terraform provider&lt;/a&gt;. It was quite easy to get started.&lt;/p&gt;
&lt;h2 id=&quot;initialize-the-provider&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#initialize-the-provider&quot; aria-label=&quot;Anchor link for: initialize-the-provider&quot;&gt;Initialize the provider&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;First step was initializing the Cloudflare provider for Terraform and creating a &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://developers.cloudflare.com/fundamentals/api/get-started/create-token/&quot;&gt;Cloudflare API token&lt;/a&gt; with edit access to the DNS zone.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;terraform&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; providers.tf&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;terraform&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;  required_providers&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    cloudflare&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      source&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;  =&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;cloudflare/cloudflare&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      version&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;4.33.0&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;provider&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; &amp;quot;cloudflare&amp;quot;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  api_token&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; var&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span&gt;cloudflare_api_token&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, I defined the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://github.com/maheshrijal/dns/blob/main/variables.tf&quot;&gt;variables.tf&lt;/a&gt; file and created &lt;code&gt;terraform.tfvars&lt;/code&gt; file in which the actual API token will be assigned. This file will not be comitted to GitHub.&lt;/p&gt;
&lt;p&gt;I then initialized the provider with &lt;code&gt;terraform init&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;what-to-do-with-the-state-file&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#what-to-do-with-the-state-file&quot; aria-label=&quot;Anchor link for: what-to-do-with-the-state-file&quot;&gt;What to do with the state file?&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Terraform uses a &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://developer.hashicorp.com/terraform/language/state&quot;&gt;state file&lt;/a&gt; to keep track of the current state of the infrastructure. I initially thought storing the state file locally would be a good idea and relatively simple. But, if I stored the state file locally, I would not be able to edit my DNS records if I did not have the device that stored the state. This was a no-go. I looked at other options.&lt;/p&gt;
&lt;h3 id=&quot;store-the-state-file-in-cloudflare-r2&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#store-the-state-file-in-cloudflare-r2&quot; aria-label=&quot;Anchor link for: store-the-state-file-in-cloudflare-r2&quot;&gt;Store the state file in Cloudflare R2?&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://www.cloudflare.com/developer-platform/r2/&quot;&gt;R2&lt;/a&gt; is is a object storage service privded by Cloudflare. It is compatible with S3 which means it can use the terraform provider for S3 it also has a generous &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://developers.cloudflare.com/r2/pricing/&quot;&gt;free tier&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I was already using the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs&quot;&gt;Cloudflare provider&lt;/a&gt; for terraform anyway, so one would think using R2 would be straightforward right?&lt;/p&gt;
&lt;p&gt;Welp, initializing the provider for R2 is not straightforward because terraform &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://github.com/hashicorp/terraform/issues/33847&quot;&gt;does not support R2&lt;/a&gt; officially. But, given that R2 is compatible with S3, I could use the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://developer.hashicorp.com/terraform/language/settings/backends/s3&quot;&gt;S3 backend&lt;/a&gt; to configure R2.&lt;/p&gt;
&lt;p&gt;However, another issue I ran into was that the backend block(&lt;code&gt;backend.tf&lt;/code&gt;) &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://github.com/hashicorp/terraform/issues/13022&quot;&gt;does not support variables&lt;/a&gt;. This is unlikely to be ever fixed in the terraform core repository given the incentive hashicorp has with terraform cloud. But, there is still hope as a &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://github.com/opentofu/opentofu/issues/1042&quot;&gt;similar issue&lt;/a&gt; is open in the recently forked &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://opentofu.org/&quot;&gt;OpenTofu&lt;/a&gt;. There is a &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://github.com/hashicorp/terraform/issues/13022#issuecomment-294262392&quot;&gt;workaround&lt;/a&gt; to the issue using &lt;code&gt;-backend-config&lt;/code&gt; but, I was worried about &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://github.com/hashicorp/terraform/issues/13022&quot;&gt;credential leak&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;store-the-state-file-in-terraform-cloud&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#store-the-state-file-in-terraform-cloud&quot; aria-label=&quot;Anchor link for: store-the-state-file-in-terraform-cloud&quot;&gt;Store the state file in Terraform Cloud&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;I could use AWS S3, but my free tier on AWS just ended, and I didn&#39;t want to pay for bucket storage. So, I settled on using terraform cloud.  I defined the backend and logged in with &lt;code&gt;terraform login&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;terraform&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; backend.tf&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;terraform&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;  cloud&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    organization&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;xyz&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    workspaces&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      name&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;abc&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;importing-existing-dns-records&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#importing-existing-dns-records&quot; aria-label=&quot;Anchor link for: importing-existing-dns-records&quot;&gt;Importing existing DNS records&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Since I already have existing DNS records for my domain in Cloudflare, it is not ideal to start creating new records. First, I will have to import these records into my terraform state. There is a CLI utility called &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://github.com/cloudflare/cf-terraforming&quot;&gt;cf-terraforming&lt;/a&gt; that does just this.&lt;/p&gt;
&lt;p&gt;I &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://github.com/cloudflare/cf-terraforming?tab=readme-ov-file#installation&quot;&gt;installed&lt;/a&gt; the tool and exported the Cloudflare API token &amp;amp; Zone ID.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;export&lt;/span&gt;&lt;span&gt; CLOUDFLARE_API_TOKEN&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;abc&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;export&lt;/span&gt;&lt;span&gt; CLOUDFLARE_ZONE_ID&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;xyz&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, I ran the tool to generate the &lt;code&gt;main.tf&lt;/code&gt; file. This will create the terraform code for all the existing DNS records and write it to &lt;code&gt;main.tf&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;cf-terraforming&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; generate&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;-resource-type&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;cloudflare_record&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; main.tf&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, we can get to importing the current state into our state file. Without this, terraform would think these are new DNS records.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;cf-terraforming&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; import&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;-resource-type&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;cloudflare_record&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;-modern-import-block&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; import.tf&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Together, the above 2 files will generate the state file by importing existing resources rather than creating new ones.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://maheshrijal.com/blog/using-iac-to-manage-dns-records/./images/tf-dns-import.jpg&quot; alt=&quot;terraform-dns-import&quot; /&gt;&lt;/p&gt;
&lt;p&gt;In our current &lt;code&gt;main.tf&lt;/code&gt; file the &lt;code&gt;zone_id&lt;/code&gt; is hard-coded. I want to store it in a variable so that it is not pushed to Github. I converted the zone_id assignment to a variable.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;terraform&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;var&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span&gt;zone_id&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, created a variable for &lt;code&gt;zone_id&lt;/code&gt;. The &lt;code&gt;zone_id&lt;/code&gt; variable also needs a value which will be passed from &lt;code&gt;terraform.tfvars&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;terraform&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; variables.tf&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;variable&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; &amp;quot;cloudflare_api_token&amp;quot;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  description&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;The API token for Cloudflare&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  type&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;        =&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; string&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;variable&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; &amp;quot;zone_id&amp;quot;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  description&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;The zone ID for the Cloudflare domain&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  type&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;        =&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; string&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Before completing the import, I wanted to have a clear naming scheme for all the records. To achieve this, I renamed the records in &lt;code&gt;main.tf&lt;/code&gt; and changed the import destination accordingly in &lt;code&gt;import.tf&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Now, I was ready to apply the changes. Just to be safe, I &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://developers.cloudflare.com/dns/manage-dns-records/how-to/import-and-export/&quot;&gt;exported&lt;/a&gt; my DNS records from the Cloudflare dashboard incase something went wrong.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://maheshrijal.com/blog/using-iac-to-manage-dns-records/./images/tf-apply-complete.png&quot; alt=&quot;terraform-dns-apply-complete&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Yay! 🎉 I&#39;m able to see the state in terraform cloud, and no records were changed in Cloudflare. Which is a success. Now, to make it work with Github actions.&lt;/p&gt;
&lt;h2 id=&quot;integrate-with-github-actions&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#integrate-with-github-actions&quot; aria-label=&quot;Anchor link for: integrate-with-github-actions&quot;&gt;Integrate with Github actions&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Since the code is on Github, I wanted a workflow to run &lt;code&gt;terraform plan&lt;/code&gt; whenever a pull request is created and &lt;code&gt;terraform apply&lt;/code&gt; to run when change merged to &lt;code&gt;main&lt;/code&gt; branch. To do this, I used Github actions.&lt;/p&gt;
&lt;p&gt;To authenticate with Terraform workspace, we need to create a &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://app.terraform.io/app/settings/tokens&quot;&gt;secret for our terraform workspace&lt;/a&gt; called &lt;code&gt;TF_API_TOKEN&lt;/code&gt; &amp;amp; and add it to &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions&quot;&gt;github repository&lt;/a&gt; as actions secret.&lt;/p&gt;
&lt;p&gt;Until now, I was running the terraform plan &amp;amp; apply locally so, the variables defined in &lt;code&gt;terraform.tfvars&lt;/code&gt; were being passed to terraform cloud on each run. Now, the plan is to run Terrafrom straight from github so, I added the &lt;code&gt;zone_id&lt;/code&gt; and &lt;code&gt;cloudflare_api_token&lt;/code&gt; as &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://developer.hashicorp.com/terraform/cloud-docs/workspaces/variables&quot;&gt;sensitive variables&lt;/a&gt; in terraform workspace.&lt;/p&gt;
&lt;p&gt;I also created a &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://docs.github.com/en/rest/authentication/permissions-required-for-fine-grained-personal-access-tokens&quot;&gt;personal access token&lt;/a&gt; called &lt;code&gt;GH_TOKEN&lt;/code&gt; and added it to the github repo. This token has the permission to comment on a pull request. This will be required to output changes of the &lt;code&gt;terraform plan&lt;/code&gt; command.&lt;/p&gt;
&lt;p&gt;After these changes are pushed, once a pull request is created, github actions should run the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://github.com/maheshrijal/dns/blob/main/.github/workflows/terraform-plan.yml&quot;&gt;terraform plan&lt;/a&gt; workflow which runs &lt;code&gt;terrafrom plan&lt;/code&gt; in terraform cloud using the API. The output of the plan is shown as a comment. When merged into &lt;code&gt;main&lt;/code&gt;, the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://github.com/maheshrijal/dns/blob/main/.github/workflows/terraform-apply.yml&quot;&gt;terraform apply&lt;/a&gt; workflow runs, which creates the DNS records.&lt;/p&gt;
&lt;p&gt;With this approach, it is critical to make sure the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/managing-a-branch-protection-rule&quot;&gt;branch protection rules&lt;/a&gt; are strong to prevent accidental pushes into &lt;code&gt;main&lt;/code&gt; branch.&lt;/p&gt;
&lt;p&gt;With this, the project is ready. Now, whenever I need to create/change a DNS record I create a pull request on the repo and I can easily track changes or rollback in case of failure. This also helps me keep track of provider documentation that I might have referred for DNS configuration.&lt;/p&gt;
&lt;h2 id=&quot;future-scope&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#future-scope&quot; aria-label=&quot;Anchor link for: future-scope&quot;&gt;Future Scope&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Few things in this project are still not ideal. For starters, the Terraform organization and workspace name are public in the GitHub repo, which is probably a concern. Also, it would be great to have the ability to query DNS records after they are configured to verify if they are set correctly.&lt;/p&gt;
&lt;p&gt;Overall, that&#39;s where I feel like leaving this project now. I might get back to it in the future.&lt;/p&gt;
&lt;p&gt;If you&#39;re interested, the code is public on my &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://github.com/maheshrijal/dns&quot;&gt;github repository&lt;/a&gt;.&lt;/p&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-first&quot;&gt;
&lt;p&gt;I started working on this after reading through &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://alexwlchan.net/2024/documenting-my-dns/&quot;&gt;Alex&#39;s blog&lt;/a&gt;. &lt;a href=&quot;https://maheshrijal.com/blog/using-iac-to-manage-dns-records/#fr-first-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
      </item>
      <item>
          <title>Trying the Zed code editor on Windows</title>
          <pubDate>Mon, 29 Apr 2024 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://maheshrijal.com/blog/trying-the-zed-code-editor-on-windows/</link>
          <guid>https://maheshrijal.com/blog/trying-the-zed-code-editor-on-windows/</guid>
          <description xml:base="https://maheshrijal.com/blog/trying-the-zed-code-editor-on-windows/">&lt;blockquote&gt;
&lt;p&gt;This page has been updated to highlight my experience using Zed on Linux.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;intro&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#intro&quot; aria-label=&quot;Anchor link for: intro&quot;&gt;Intro&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://github.blog/2022-06-08-sunsetting-atom/&quot;&gt;Atom&lt;/a&gt; was my favourite code editor until it was sunset. I then switched to using VSCode which is good, but I found its performance subpar on my old laptop.&lt;/p&gt;
&lt;p&gt;A few months ago, I heard of a new text editor called &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://zed.dev/&quot;&gt;Zed&lt;/a&gt;. Interestingly, the creators of Zed have worked on Atom as well. Sadly, Zed was not yet available on Windows at release. Well, it still isn&#39;t but now it can be compiled from &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://github.com/zed-industries/zed&quot;&gt;source&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;compiling-from-source-for-windows&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#compiling-from-source-for-windows&quot; aria-label=&quot;Anchor link for: compiling-from-source-for-windows&quot;&gt;Compiling from source for Windows&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://github.com/zed-industries/zed/blob/main/docs/src/development/windows.md&quot;&gt;The instructions&lt;/a&gt; listed in the repo were fairly straightforward. But it did take me around 25 minutes to build it all. I don&#39;t have experience building rust apps from scratch, so I&#39;m not sure if this is an ideal time or just a result of aging hardware on my laptop.&lt;/p&gt;
&lt;h2 id=&quot;look-and-feel&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#look-and-feel&quot; aria-label=&quot;Anchor link for: look-and-feel&quot;&gt;Look and Feel&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://maheshrijal.com/blog/trying-the-zed-code-editor-on-windows/./images/zed-first-look.png&quot; alt=&quot;A screenshot of zed code editor on windows&quot; title=&quot;Zed running on windows&quot; /&gt;&lt;/p&gt;
&lt;p&gt;On first glance, I felt it was similar to atom. The UI isn&#39;t something completely new and follows a similar layout to almost all the text editors out there today, which is to be expected because developers are not just going to learn their way around a new layout for a new text editor.&lt;/p&gt;
&lt;h2 id=&quot;performance&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#performance&quot; aria-label=&quot;Anchor link for: performance&quot;&gt;Performance&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Zed was fast. Extremely fast. Files and large directories opened in a snap. I did see the performance benchmark comparison listed on their website, but I was still surprised at the quickness with which it operated. Now I get why Rust can be huge for software.&lt;/p&gt;
&lt;p&gt;Here is a quick comparison of app launch times.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://maheshrijal.com/blog/trying-the-zed-code-editor-on-windows/./images/app-launch-time.png&quot; alt=&quot;Zed editor app launch time&quot; /&gt;&lt;/p&gt;
&lt;h2 id=&quot;features&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#features&quot; aria-label=&quot;Anchor link for: features&quot;&gt;Features&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Given that it is in active development, the overall editor is quite bare bones which I like. I don&#39;t think a code editor needs a lot of features. The theme selection is pretty decent, and it supports keymaps for all the popular editors out there. It also has support built in for &lt;code&gt;vim&lt;/code&gt; mode. It has a bunch of &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://zed.dev/features&quot;&gt;other features&lt;/a&gt; that are not yet available on Windows.&lt;/p&gt;
&lt;h2 id=&quot;on-linux&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#on-linux&quot; aria-label=&quot;Anchor link for: on-linux&quot;&gt;On Linux&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;At the time of writing this blog, I was on windows. But, now I have migrated to Linux and Zed recently released native support for linux. My experience on Linux has been really good. It&#39;s simple, fast and easy to use. Although, I have used Zed more like text editor rather than a code editor it has been a good expereince using Zed on Linux. I feel it is less bloated compared to VSCode but, that could be because it&#39;s still a new kid on the block.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#conclusion&quot; aria-label=&quot;Anchor link for: conclusion&quot;&gt;Conclusion&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Zed looks quite promising, but it is still in its infancy. While the code is open source, Zed requires contributors to &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://zed.dev/cla&quot;&gt;sign a CLA&lt;/a&gt; and they also have &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://techcrunch.com/2023/03/15/zed-code-editor-raises-10m/&quot;&gt;raised private funding&lt;/a&gt;. As an end-user, this makes me concerned about the long term revenue prospects for the code editor. This is probably because I have seen plenty of venture-backed projects shut down, get acquired, or both. Only time will tell if Zed can live on.&lt;/p&gt;
</description>
      </item>
      <item>
          <title>Quick and easy directory navigation using CDPATH</title>
          <pubDate>Sat, 14 Oct 2023 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://maheshrijal.com/blog/quick-and-easy-directory-navigation-using-cdpath/</link>
          <guid>https://maheshrijal.com/blog/quick-and-easy-directory-navigation-using-cdpath/</guid>
          <description xml:base="https://maheshrijal.com/blog/quick-and-easy-directory-navigation-using-cdpath/">&lt;p&gt;Traversing through multiple directories in Linux often takes time and can be inefficient when multiple sub directories are involved.
To easily move to directories in Linux, we can use the CDPATH variable.&lt;/p&gt;
&lt;p&gt;I store all my code in the &lt;code&gt;/home/mahesh/code&lt;/code&gt; directory. But, every time I want to go into one of the sub directories inside &lt;code&gt;/home/mahesh/code&lt;/code&gt;, I have to &lt;code&gt;cd&lt;/code&gt; into Code and then switch to the sub directory I am interested in.&lt;/p&gt;
&lt;p&gt;However, if I set the CDPATH variable to &lt;code&gt;/home/mahesh/code&lt;/code&gt; I can directly jump to any of the sub directories under Code without having to traverse the full path. This can be a lifesaver when the directories are nested deep inside.&lt;/p&gt;
&lt;p&gt;Syntax for CDPATH: &lt;code&gt;export CDPATH=/home/mahesh/code/&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Let&#39;s see how this works practically. Initially, if I attempted to change into the &lt;code&gt;dotfiles&lt;/code&gt; directory without CDPATH, I&#39;d encounter an error due to the incomplete path.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellsession&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;mahesh@workstation:~&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt; cd dotfiles&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;bash: cd: dotfiles: No such file or directory&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However, once the CDPATH variable is exported, I&#39;m able to &lt;code&gt;cd&lt;/code&gt; into &lt;code&gt;dotfiles&lt;/code&gt; directory directly without having to type the complete path.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellsession&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;mahesh@workstation:~&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; export&lt;/span&gt;&lt;span&gt; CDPATH&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span&gt;/&lt;/span&gt;&lt;span&gt;home&lt;/span&gt;&lt;span&gt;/&lt;/span&gt;&lt;span&gt;mahesh&lt;/span&gt;&lt;span&gt;/&lt;/span&gt;&lt;span&gt;code&lt;/span&gt;&lt;span&gt;/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;mahesh@workstation:~&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt; cd dotfiles&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;/home/mahesh/code/dotfiles&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Additionally, all directories under &lt;code&gt;/home/mahesh/code/&lt;/code&gt; will also show up as suggestions in bash.&lt;/p&gt;
&lt;p&gt;The CDPATH variable can also contain multiple colon &lt;code&gt;:&lt;/code&gt; separated directories just like the PATH variable.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellsession&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; export&lt;/span&gt;&lt;span&gt; CDPATH&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span&gt;/&lt;/span&gt;&lt;span&gt;home&lt;/span&gt;&lt;span&gt;/&lt;/span&gt;&lt;span&gt;mahesh&lt;/span&gt;&lt;span&gt;/&lt;/span&gt;&lt;span&gt;code&lt;/span&gt;&lt;span&gt;:/&lt;/span&gt;&lt;span&gt;home&lt;/span&gt;&lt;span&gt;/&lt;/span&gt;&lt;span&gt;mahesh&lt;/span&gt;&lt;span&gt;/&lt;/span&gt;&lt;span&gt;Documents&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Something to keep in mind is that, the order in which you define the directories with CDPATH determines where you end up. So there could be issues if subfolders across exported CDPATH&#39;s have the same name.&lt;/p&gt;
&lt;p&gt;While CDPATH is easy effective but it does run into issues. While changing directories, it can jump into unexpected directories and it writes text to the standard output, which is bad for shell scripts.&lt;/p&gt;
&lt;p&gt;I have my CDPATH exported in &lt;code&gt;~/.bashrc&lt;/code&gt; so that the the change is applied only in interactive shells.&lt;/p&gt;
</description>
      </item>
    </channel>
</rss>
