<?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>DEV Community: Coang Ha</title>
    <description>The latest articles on DEV Community by Coang Ha (@coangha21).</description>
    <link>https://dev.to/coangha21</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%2F1126940%2F394e468c-03c0-428f-8b1b-e81807547357.jpg</url>
      <title>DEV Community: Coang Ha</title>
      <link>https://dev.to/coangha21</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/coangha21"/>
    <language>en</language>
    <item>
      <title>🚀Hailow - Bootstrap Your Engineering Workspace with AI Agents</title>
      <dc:creator>Coang Ha</dc:creator>
      <pubDate>Sat, 28 Mar 2026 15:55:09 +0000</pubDate>
      <link>https://dev.to/coangha21/hailow-bootstrap-your-engineering-workspace-with-ai-agents-28f7</link>
      <guid>https://dev.to/coangha21/hailow-bootstrap-your-engineering-workspace-with-ai-agents-28f7</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Stop setting up projects manually. Let AI agents do it for you.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Hey everyone 👋&lt;/p&gt;

&lt;p&gt;I'm Harvey --- a DevOps engineer who spends &lt;em&gt;way too much time&lt;/em&gt; setting&lt;br&gt;
up the same environments over and over again.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Recreating configs&lt;/li&gt;
&lt;li&gt;  Rewriting boilerplate&lt;/li&gt;
&lt;li&gt;  Reinstalling tools&lt;/li&gt;
&lt;li&gt;  Rebuilding workflows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So I built something to fix that.&lt;/p&gt;

&lt;p&gt;👉 Meet &lt;strong&gt;Hailow&lt;/strong&gt;: an AI agent--driven CLI that bootstraps your&lt;br&gt;
engineering workspace in seconds.&lt;/p&gt;

&lt;p&gt;🔗 GitHub: &lt;a href="https://github.com/Harvey-N-Lab/hailow" rel="noopener noreferrer"&gt;https://github.com/Harvey-N-Lab/hailow&lt;/a&gt;&lt;/p&gt;


&lt;h1&gt;
  
  
  🤯 The Problem
&lt;/h1&gt;

&lt;p&gt;Every time you start a new project:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  You recreate your environment from scratch\&lt;/li&gt;
&lt;li&gt;  You configure tools manually\&lt;/li&gt;
&lt;li&gt;  You copy configs from old repos\&lt;/li&gt;
&lt;li&gt;  You lose time before writing actual code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And even worse...&lt;/p&gt;

&lt;p&gt;👉 Your workflow isn't consistent across projects\&lt;br&gt;
👉 Your setup isn't reusable\&lt;br&gt;
👉 Your knowledge isn't structured&lt;/p&gt;


&lt;h1&gt;
  
  
  ⚡ The Idea
&lt;/h1&gt;

&lt;p&gt;What if your setup was:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  reusable\&lt;/li&gt;
&lt;li&gt;  composable\&lt;/li&gt;
&lt;li&gt;  automated\&lt;/li&gt;
&lt;li&gt;  powered by AI agents&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's what &lt;strong&gt;Hailow&lt;/strong&gt; does.&lt;/p&gt;


&lt;h1&gt;
  
  
  🧠 What is Hailow?
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Hailow is a CLI that installs domain-specific AI agent workflows into&lt;br&gt;
your workspace.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Each domain includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  🤖 agents (researcher → planner → architect → implementer →
reviewer)\&lt;/li&gt;
&lt;li&gt;  📏 rules (best practices &amp;amp; standards)\&lt;/li&gt;
&lt;li&gt;  🧰 skills (via &lt;code&gt;npx skills&lt;/code&gt;)\&lt;/li&gt;
&lt;li&gt;  ⚙️ commands (workflow automation)\&lt;/li&gt;
&lt;li&gt;  🧠 contexts (project-specific knowledge)&lt;/li&gt;
&lt;/ul&gt;


&lt;h1&gt;
  
  
  ⚡ Install
&lt;/h1&gt;

&lt;p&gt;Download the latest binary:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-sSL&lt;/span&gt; https://raw.githubusercontent.com/Harvey-N-Lab/hailow/master/scripts/install.sh | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify installation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;hailow &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  🚀 Usage
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Install a domain
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;hailow &lt;span class="nb"&gt;install &lt;/span&gt;python-backend-engineer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Install multiple domains
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;hailow &lt;span class="nb"&gt;install &lt;/span&gt;devops-engineer js-ts-software-engineer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Install all domains
&lt;/h3&gt;



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

&lt;/div&gt;






&lt;h1&gt;
  
  
  🤖 Choose agent platform
&lt;/h1&gt;

&lt;p&gt;Hailow supports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Roo Code\&lt;/li&gt;
&lt;li&gt;  Claude Code
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;hailow &lt;span class="nb"&gt;install &lt;/span&gt;python-backend-engineer &lt;span class="nt"&gt;--platform&lt;/span&gt; roo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;hailow &lt;span class="nb"&gt;install &lt;/span&gt;devops-engineer &lt;span class="nt"&gt;--platform&lt;/span&gt; claude
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  🧰 Install skills (optional)
&lt;/h1&gt;

&lt;p&gt;Example for Python backend:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx skills &lt;span class="nb"&gt;install &lt;/span&gt;python-backend
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  📁 What gets installed
&lt;/h1&gt;

&lt;p&gt;After running Hailow, your workspace will include:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.claude/ or .roo/
  agents/
  rules/
  skills/
  commands/
  contexts/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Each domain provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  structured AI agent workflow\&lt;/li&gt;
&lt;li&gt;  reusable configs\&lt;/li&gt;
&lt;li&gt;  domain-specific best practices&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  ⚡ Example workflow
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;hailow &lt;span class="nb"&gt;install &lt;/span&gt;devops-engineer python-backend-engineer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 Your workspace is instantly ready with DevOps + backend workflows.&lt;/p&gt;




&lt;h1&gt;
  
  
  💥 That's it
&lt;/h1&gt;

&lt;p&gt;From zero → structured AI workflow in one command.&lt;/p&gt;

&lt;p&gt;Give it a try and let me know what you think 🚀&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Setup Account Factory for Terraform and enable default VPCs deletion (with bug fix on source code)</title>
      <dc:creator>Coang Ha</dc:creator>
      <pubDate>Mon, 02 Oct 2023 14:37:13 +0000</pubDate>
      <link>https://dev.to/coangha21/setup-account-factory-for-terraform-and-enable-default-vpcs-deletion-with-bug-fix-on-source-code-3eai</link>
      <guid>https://dev.to/coangha21/setup-account-factory-for-terraform-and-enable-default-vpcs-deletion-with-bug-fix-on-source-code-3eai</guid>
      <description>&lt;p&gt;In today's article, we will learn step by step how to deploy Account Factory for Terraform (AFT), alongside with that, we will enable Cloud Trail and default VPCs deletion feature to remove default VPC in all regions on every newly created account. After that we will have a little bug fix on &lt;code&gt;aws-ia&lt;/code&gt; code since we are leveraging it.&lt;/p&gt;

&lt;p&gt;I have raise the issue in here, you can check it out.&lt;br&gt;
&lt;a href="https://github.com/aws-ia/terraform-aws-control_tower_account_factory/issues/393" rel="noopener noreferrer"&gt;https://github.com/aws-ia/terraform-aws-control_tower_account_factory/issues/393&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Prerequisite
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;An AWS Control Tower that already setup. If you haven't setup one, check it out &lt;a href="https://catalog.workshops.aws/control-tower/en-US/prerequisites" rel="noopener noreferrer"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;A Github account. &lt;/li&gt;
&lt;li&gt;Terraform installed. If you haven't installed follow my guide on &lt;a href="https://dev.to/coangha21/eks-hand-on-series-introduction-and-setup-environment-b9h"&gt;this post&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The following is what we will do in this article:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Setup OU and Account for AFT&lt;/li&gt;
&lt;li&gt;Setup repositories&lt;/li&gt;
&lt;li&gt;Deploy AFT to Control Tower&lt;/li&gt;
&lt;li&gt;Enable Cloud Trail and default VPCs deletion feature with 
bugfix&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's get into details!&lt;/p&gt;
&lt;h2&gt;
  
  
  Setup OU and Account.
&lt;/h2&gt;

&lt;p&gt;First, let's setup a separate OU and account for AFT as AWS recommended. Go to Control Tower console and in Organization tab, create a new OU and select &lt;code&gt;Root&lt;/code&gt; as parent OU.&lt;br&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%2Fbkkqgyvts2556zjmkod5.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%2Fbkkqgyvts2556zjmkod5.png" alt="Create new OU" width="800" height="228"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, choose Account Factory tab and provision a new account. Select account's OU as the OU you just created and skip &lt;code&gt;Account Factory customization&lt;/code&gt; for now. &lt;br&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%2F9zv0a55ujitwy33xvejq.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%2F9zv0a55ujitwy33xvejq.png" alt="Provision new account" width="800" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Wait couple of minutes and you should have a new account in your organization.&lt;/p&gt;
&lt;h2&gt;
  
  
  Setup repositories
&lt;/h2&gt;

&lt;p&gt;Next, go to Github and create following 4 repositories:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;aft-account-request&lt;/code&gt; for handling account request&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;aft-global-customizations&lt;/code&gt; for customizing all AFT managed accounts&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;aft-account-customizations&lt;/code&gt; for specific customization on AFT managed accounts&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;aft-account-provisioning-customizations&lt;/code&gt; for customizing account provision.
&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%2F75yem194jeqm970fcxxq.png" alt="Repositories" width="800" height="362"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After that, please use the code that I already prepare to the repositories:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/vippr1237/aft-account-request" rel="noopener noreferrer"&gt;aft-account-request&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/vippr1237/aft-global-customizations" rel="noopener noreferrer"&gt;aft-global-customization&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/vippr1237/aft-account-customizations" rel="noopener noreferrer"&gt;aft-account-customizations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/vippr1237/aft-account-provisioning-customizations" rel="noopener noreferrer"&gt;aft-account-provisioning-customizations&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Finally, clone &lt;code&gt;aws-ia&lt;/code&gt; &lt;a href="https://github.com/aws-ia/terraform-aws-control_tower_account_factory" rel="noopener noreferrer"&gt;AFT repository&lt;/a&gt; to your Github to create custom version for our own. I will show you later.&lt;/p&gt;
&lt;h2&gt;
  
  
  Deploy AFT to Control Tower
&lt;/h2&gt;

&lt;p&gt;Now, the main step, we will deploy AFT to our Control Tower. Before you start, you need to prepare:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An account or role with Administrator policy on Control Tower management account (account that you deploy AWS Control Tower) and create access key for it.&lt;/li&gt;
&lt;li&gt;A terraform environment with the access key above.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you have never done 2 things above, no worry, check out my &lt;a href="https://dev.to/coangha21/eks-hand-on-series-introduction-and-setup-environment-b9h"&gt;post&lt;/a&gt;, it will guide you &lt;br&gt;
step by step how to do it.&lt;/p&gt;

&lt;p&gt;After it all setup, create &lt;code&gt;main.tf&lt;/code&gt; file and call to &lt;code&gt;aws-ia&lt;/code&gt; module that you just clone in previous step. You can use the following code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module "aft" {
  source = "github.com/&amp;lt;Your-Github-Org&amp;gt;/terraform-aws-control_tower_account_factory"
  # Required Vars
  ct_management_account_id    = "&amp;lt;your-ct-management-account-id"
  log_archive_account_id      = "&amp;lt;your-ct-logging-account-id&amp;gt;"
  audit_account_id            = "&amp;lt;your-ct-audit-account-id&amp;gt;"
  aft_management_account_id   = "&amp;lt;aft-management-account-id&amp;gt;"
  ct_home_region              = "&amp;lt;your-region&amp;gt;"
  # VCS Vars
  vcs_provider                                  = "github"
  account_request_repo_name                     = "&amp;lt;your-github-org&amp;gt;/aft-account-request"
  global_customizations_repo_name               = "&amp;lt;your-github-org&amp;gt;/aft-global-customizations"
  account_customizations_repo_name              = "&amp;lt;your-github-org&amp;gt;/aft-account-customization"
  account_provisioning_customizations_repo_name = "&amp;lt;your-github-org&amp;gt;/aft-account-provisioning-customization"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Insert correct information and run &lt;code&gt;terraform apply&lt;/code&gt; to deploy the infrastructure, it will provision for us resources like Codebuild, CodePipeline, Step Function, Lambda, S3,... You can see overview architecture with picture below.&lt;br&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%2Fsk20wns9o8cup5rcq6a3.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%2Fsk20wns9o8cup5rcq6a3.png" alt="AFT Architecture" width="800" height="329"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before moving to next step, you will need to update Codestar connection. AFT will automatically trigger by committing code to &lt;code&gt;aft-account-request&lt;/code&gt; repo, in order for AFT to track the code change, it will use &lt;a href="https://docs.aws.amazon.com/codestar/" rel="noopener noreferrer"&gt;AWS Codestar&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Access AFT Management account&lt;/strong&gt;, then go to &lt;code&gt;CodeCommit&lt;/code&gt;&lt;br&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%2F6t67pbe14h541mgggpho.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%2F6t67pbe14h541mgggpho.png" alt="Access CodeCommit" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the left, choose Settings &amp;gt; Connections, you will see a pending connection. Click on the connection and choose &lt;code&gt;Update pending connection&lt;/code&gt;.&lt;br&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%2Faxhb6nk53uwqwb00g5b0.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%2Faxhb6nk53uwqwb00g5b0.png" alt="Codestar conneciton" width="800" height="256"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, I already enabled the connection, the steps is quite easy, so you can take it on yourself, just a few click and you will get it done.&lt;/p&gt;

&lt;p&gt;Finally, go to &lt;code&gt;Codepipeline&lt;/code&gt; and re-run the &lt;code&gt;ct-aft-account-provisioning-customizations&lt;/code&gt; pipeline, it will create a step function for account provisioning customization, we need to do this so our account provisioning step funciton won't failed.&lt;br&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%2Fobahztxqkdebfg6wjud4.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%2Fobahztxqkdebfg6wjud4.png" alt="Re-run pipeline" width="800" height="291"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can ignore the first pipeline, I created it for testing.&lt;/p&gt;
&lt;h2&gt;
  
  
  Enable Cloud Trail and default VPCs deletion feature with
&lt;/h2&gt;

&lt;p&gt;bugfix&lt;br&gt;
Enable Cloud Trail and default VPCs deletion feature by adding this 2 lines to the code block.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Run &lt;code&gt;terraform apply&lt;/code&gt; to apply the infrastructure.&lt;br&gt;
Now, let's create an account by AFT to see if everything is working as expected.&lt;br&gt;
Edit &lt;code&gt;terraform/main.tf&lt;/code&gt; file in &lt;code&gt;aft-account-request&lt;/code&gt; repo, you should use the example code I provided on previous section.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module "sandbox_account_01" {
  source = "./modules/aft-account-request"

  control_tower_parameters = {
    AccountEmail = "&amp;lt;email-for-new-account&amp;gt;"
    AccountName  = "sandbox-account-01"
    # Syntax for top-level OU
    ManagedOrganizationalUnit = "Sandbox""
    SSOUserEmail     = "&amp;lt;email-for-sso&amp;gt;"
    SSOUserFirstName = "&amp;lt;sso first name&amp;gt;"
    SSOUserLastName  = "&amp;lt;sso last name&amp;gt;"
  }

  account_tags = {
    "ABC:Owner"       = "john.doe@amazon.com"
    "ABC:Division"    = "ENT"
    "ABC:Environment" = "Dev"
    "ABC:CostCenter"  = "123456"
    "ABC:Vended"      = "true"
    "ABC:DivCode"     = "102"
    "ABC:BUCode"      = "ABC003"
    "ABC:Project"     = "123456"
  }

  change_management_parameters = {
    change_requested_by = "John Doe"
    change_reason       = "testing the account vending process"
  }

  custom_fields = {
    custom1 = "a"
    custom2 = "b"
  }

  # account_customizations_name = "sandbox-customizations"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Commit code to the main branch and observe the pipeline. You should see the pipeline is running and new account is being provisioned.&lt;br&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%2Fdebmnrwu37txsblollze.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%2Fdebmnrwu37txsblollze.png" alt="Account request pipeline" width="800" height="525"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After the pipeline have run successfully, it will add an record to &lt;code&gt;DynamoDB&lt;/code&gt; table and trigger a list of functions to provisioned new account. You can check &lt;code&gt;CloudWatch Logs&lt;/code&gt; to see how it run.&lt;br&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%2Fu9yq7imuq9ybfxmccgz5.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%2Fu9yq7imuq9ybfxmccgz5.png" alt="Cloudwatch Logs" width="800" height="474"&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%2Fghfnt5e6f2ufvde700jb.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%2Fghfnt5e6f2ufvde700jb.png" alt="Request processor logs" width="800" height="499"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After couple of minutes, you should see your account had been provisioned, let check it if everything is good.&lt;br&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%2F59o80oxxbtp0jahwe27l.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%2F59o80oxxbtp0jahwe27l.png" alt="Cloud Trail enabled" width="800" height="261"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cloud Trail have been enabled, that's good news. Next, let's see if default VPCs have been delete in all regions.&lt;br&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%2F229kli14kck9pn4l0eqv.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%2F229kli14kck9pn4l0eqv.png" alt="Default VPCs" width="600" height="994"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Seem like it's not working, as mentioned above there is a bug in the function so we need to edit it a little bit. Go to file &lt;code&gt;src/aft_lambda/aft_feature_options/aft_delete_default_vpc.py&lt;/code&gt; and in the part where we will iterate through regions to delete default VPCs, change the session like below:&lt;br&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%2F59ahvqxdg4els1zxj3fq.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%2F59ahvqxdg4els1zxj3fq.png" alt="Fixing session bug" width="800" height="189"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also check this &lt;a href="https://github.com/vippr1237/terraform-aws-control_tower_account_factory/commit/ac0d90ec231c48750cb8e09bed5917e21404b90e" rel="noopener noreferrer"&gt;link&lt;/a&gt; for clearer view.&lt;br&gt;
Now create another new account, you will see the default VPCs have been deleted.&lt;br&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%2Fyf1lsz5hgxzlsuuzdz6z.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%2Fyf1lsz5hgxzlsuuzdz6z.png" alt="Default VPCs deleted in all regions" width="590" height="996"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ignore the region which have 1 VPC, I created it for testing.&lt;/p&gt;

&lt;p&gt;Congrats! Now you have officially deployed your Account Factory for Terraform.&lt;/p&gt;

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

&lt;p&gt;This article just only guide you steps to deploy your first Account Factory for Terraform, you should read the &lt;a href="https://docs.aws.amazon.com/controltower/latest/userguide/aft-overview.html" rel="noopener noreferrer"&gt;document&lt;/a&gt; to learn more about the tool. It's a very interesting tool, I recommend you to have a deep dive look into it and the value it bring to us.&lt;/p&gt;

&lt;p&gt;You can checkout the code in here:&lt;br&gt;
&lt;a href="https://github.com/vippr1237/aft-deployment" rel="noopener noreferrer"&gt;AFT Deployment Repo&lt;/a&gt;.&lt;br&gt;
&lt;a href="https://github.com/vippr1237/terraform-aws-control_tower_account_factory" rel="noopener noreferrer"&gt;Custom AFT module Repo&lt;/a&gt;.&lt;br&gt;
Also, check out my &lt;a href="https://github.com/vippr1237?tab=repositories" rel="noopener noreferrer"&gt;Github&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;See you in next post! Happy Hacking!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>[EKS Hand-on Series] Introduction and setup environment</title>
      <dc:creator>Coang Ha</dc:creator>
      <pubDate>Wed, 20 Sep 2023 04:26:42 +0000</pubDate>
      <link>https://dev.to/coangha21/eks-hand-on-series-introduction-and-setup-environment-b9h</link>
      <guid>https://dev.to/coangha21/eks-hand-on-series-introduction-and-setup-environment-b9h</guid>
      <description>&lt;p&gt;With the power of Amazon Elastic Kubernetes Service (Amazon EKS), we are now able to run Kubernetes in the AWS cloud and on-premises data centers. In this series of blogs, let find out what EKS offer to us and how to implement best practices to it.&lt;/p&gt;

&lt;h2&gt;
  
  
  About me
&lt;/h2&gt;

&lt;p&gt;I'm currently a DevOps Engineer at MegazoneCloud, I have over 2.5 year of experiences in DevOps. I have experience in AWS, GCP, Terraform, Kubernetes,... You can check out my Linkedin profile in &lt;a href="https://www.linkedin.com/in/coangha13/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;br&gt;
I'm not experience in blogging :'&amp;gt; so your feedback is really appreciated. Please feel free you share your thought regard the blogs, I will try to improve the content. Thank you.&lt;/p&gt;
&lt;h2&gt;
  
  
  About this series
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What is this series about?&lt;/strong&gt;&lt;br&gt;
This series will help you getting started with Kubernetes and EKS with mainly hand-ons, from beginner-friendly to intermediate and some advanced, the series will also contain lots of hand-on with popular tools like terraform, kubectl,... so stay tuned :3. To me, the best learning method is to practice first and theory later, so I will be mainly focus on doing the exercises, labs and I will explain some theory on the way (in plain-text of course :3).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This series is for who?&lt;/strong&gt;&lt;br&gt;
This series is mainly designed for students, developers who new to K8s, EKS, but anyone who interested can take this as well.&lt;/p&gt;

&lt;p&gt;Hope you will learn something from this. Neither to say, let start the series :3.&lt;/p&gt;
&lt;h2&gt;
  
  
  Prerequisite
&lt;/h2&gt;

&lt;p&gt;What you will need to follow this series:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An AWS account&lt;/li&gt;
&lt;li&gt;Accessibility to machine terminal&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The following step is what we will do in this article:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1&lt;/strong&gt;: Create IAM user and access key.&lt;br&gt;
&lt;strong&gt;Step 2&lt;/strong&gt;: Install and configure tools.&lt;br&gt;
&lt;strong&gt;Step 3&lt;/strong&gt;: Setup terraform environment.&lt;/p&gt;

&lt;p&gt;Without further ado, let's get our hand dirty! :D&lt;/p&gt;
&lt;h2&gt;
  
  
  Create IAM user and access key
&lt;/h2&gt;

&lt;p&gt;When we first create our AWS Account, we will have a root user from email and password we registered to AWS. AWS recommend not to use this root user for managing and deploying resources on AWS, instead we should create an IAM user to handle this.&lt;/p&gt;

&lt;p&gt;First, go to &lt;code&gt;IAM&lt;/code&gt; and create a new user.&lt;br&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%2Fdgoz5z8jt5w7ttn0gief.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%2Fdgoz5z8jt5w7ttn0gief.png" alt="AWS Console" width="800" height="405"&gt;&lt;/a&gt;&lt;br&gt;
Fill out the user information, make sure to leave a tick on option &lt;code&gt;Provide user access to the AWS Management Console&lt;/code&gt; and untick the option &lt;code&gt;Users must create a new password at next sign-in&lt;/code&gt; like the picture below to save ourself some time.&lt;br&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%2Feg3hcyl0e90wk9pihfu0.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%2Feg3hcyl0e90wk9pihfu0.png" alt="Create IAM user" width="800" height="414"&gt;&lt;/a&gt;&lt;br&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%2F9krsmiucw4h1dp0uq05b.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%2F9krsmiucw4h1dp0uq05b.png" alt="Create IAM user" width="800" height="187"&gt;&lt;/a&gt;&lt;br&gt;
After hit next, in the permission section, provide the user with policy &lt;code&gt;AdministratorAccess&lt;/code&gt;.&lt;br&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%2F0b5f9emevvijkrrobevo.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%2F0b5f9emevvijkrrobevo.png" alt="Provide privileges" width="800" height="393"&gt;&lt;/a&gt;&lt;br&gt;
AWS recommend to provide least privilege for our user but for purpose of this series we will make this simple by providing full permission for our user. For production environment, please follow AWS best practices in &lt;a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After that hit next, and next and wala, you have created your IAM user, remember to save the csv file for later use.&lt;br&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%2F0i7wv1w7lhii5lqhe5s6.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%2F0i7wv1w7lhii5lqhe5s6.png" alt="User successfully created" width="800" height="353"&gt;&lt;/a&gt;&lt;br&gt;
Next, let create an access key for this user so we can use it for command line interface later.&lt;br&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%2Folu4a6r2lzdsdsrf0ydb.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%2Folu4a6r2lzdsdsrf0ydb.png" alt="Create access key" width="800" height="394"&gt;&lt;/a&gt;&lt;br&gt;
Select &lt;code&gt;Command line interface (CLI)&lt;/code&gt; and hit &lt;code&gt;Next&lt;/code&gt;, &lt;code&gt;Create Access Key&lt;/code&gt; and the key is your. Remember to download CSV file for later use.&lt;br&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%2Foifc8m5bn69935b24j00.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%2Foifc8m5bn69935b24j00.png" alt="Access key created" width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Install and configure tools
&lt;/h2&gt;
&lt;h3&gt;
  
  
  AWS CLI
&lt;/h3&gt;

&lt;p&gt;For AWS CLI, please follow this &lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html" rel="noopener noreferrer"&gt;link&lt;/a&gt; to install. If you are a Mac user like I do, you can use the following command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl "https://awscli.amazonaws.com/AWSCLIV2.pkg" -o "AWSCLIV2.pkg"
sudo installer -pkg ./AWSCLIV2.pkg -target /
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let verify the installation by following command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~ aws --version
aws-cli/2.11.11 Python/3.11.2 Darwin/22.4.0 exe/x86_64 prompt/off
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you get output similar to above, it's mean you have successfully install AWS CLI.&lt;br&gt;
Alright, let's get used to AWS CLI a little bit. Let's create an CLI profile to store your access key so you can connect to AWS resources via CLI. Run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws configure --profile eks-hand-on-series
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then input the access key and secret from the csv file you saved above.&lt;br&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%2F9dibb3urwuboeo2jfxwt.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%2F9dibb3urwuboeo2jfxwt.png" alt="Create CLI profile" width="800" height="114"&gt;&lt;/a&gt;&lt;br&gt;
To select the profile, export the following environment variable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export AWS_PROFILE=eks-hand-on-series
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's verify if AWS CLI is authenticated&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~ aws sts get-caller-identity --no-cli-pager
{
    "UserId": "&amp;lt;your-user-id&amp;gt;",
    "Account": "&amp;lt;your-user-account-number",
    "Arn": "&amp;lt;your-user-account&amp;gt;"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the output include your user, it's mean AWS CLI is authenticated. Great work!&lt;/p&gt;

&lt;h3&gt;
  
  
  Terraform
&lt;/h3&gt;

&lt;p&gt;For the terraform installation, please follow this &lt;a href="https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli" rel="noopener noreferrer"&gt;link&lt;/a&gt;. For Mac, you can the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;brew tap hashicorp/tap
brew install hashicorp/tap/terraform
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you don't have &lt;code&gt;brew&lt;/code&gt; yet, install it from &lt;a href="https://brew.sh/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;br&gt;
Let's verify if terraform is installed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~ terraform --version
Terraform v1.4.5
on darwin_arm64

Your version of Terraform is out of date! The latest version
is 1.5.7. You can update by downloading from https://www.terraform.io/downloads.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Good job! Let move on to setup terraform environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup terraform environment
&lt;/h2&gt;

&lt;p&gt;First, setup your directory like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;├── README.md
├── backend
│   └──  main.tf
├── data.tf
├── main.tf
├── outputs.tf
├── provider.tf
├── variables.tf
└── version.tf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next let's setup initialize terraform directory and create remote backend for terraform state file, open up your favorite IDE and edit &lt;code&gt;backend/main.tf&lt;/code&gt; file with following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Bucket used to store our state file
resource "aws_s3_bucket" "state_file" {
  bucket = "terraform-lock-state-&amp;lt;random-number&amp;gt;"
}

# Enabling bucket versioning to keep backup copies of the state file
resource "aws_s3_bucket_versioning" "state_file" {
  bucket = aws_s3_bucket.state_file.id

  versioning_configuration {
    status = "Enabled"
  }
}

# Table used to store the lock to prevent parallel runs causing issues
resource "aws_dynamodb_table" "state_file_lock" {
  name           = "terraform-lock-state-&amp;lt;random-number&amp;gt;"
  read_capacity  = 5
  write_capacity = 5
  hash_key       = "LockID"

  attribute {
    name = "LockID"
    type = "S"
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;provider.tf&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;provider "aws" {
  region = "ap-southeast-1"
  default_tags {
    tags = {
      environment = "Dev"
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;version.tf&lt;/code&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;terraform {
  required_version = " ~&amp;gt; 1.4.5"

  backend "s3" {
     bucket         = "eks-hand-on-series-&amp;lt;random-number&amp;gt;"
     key            = "tf-aws-bootstrap/terraform.tfstate"
     region         = "ap-southeast-1"
     dynamodb_table = "terraform-lock-state-&amp;lt;random-number&amp;gt;"
  }

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~&amp;gt; 5.0.0"
    }

    kubernetes = {
      source  = "hashicorp/kubernetes"
      version = "~&amp;gt; 2.20.0"
    }
    helm = {
      source  = "hashicorp/helm"
      version = "~&amp;gt; 2.9.0"
    }
    kubectl = {
      source  = "gavinbunney/kubectl"
      version = "&amp;gt;= 1.14"
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note: Please remember to change  to a random number so the bucket won't be duplicate and run terraform.&lt;/strong&gt;&lt;br&gt;
Now, let's run &lt;code&gt;terraform init&lt;/code&gt; to install the provider and initialize local backend, make sure you are &lt;strong&gt;in correct directory (backend)&lt;/strong&gt;. The result should look like this.&lt;br&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%2Fdpb3d51vv8r5dt8vu86k.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%2Fdpb3d51vv8r5dt8vu86k.png" alt="Terraform init" width="693" height="387"&gt;&lt;/a&gt;&lt;br&gt;
Next, run &lt;code&gt;terraform apply --auto-approve&lt;/code&gt; to create remote backend. You should get the result below.&lt;br&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%2F2q6zk0vzvfwou0gfsyfj.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%2F2q6zk0vzvfwou0gfsyfj.png" alt="Terraform apply" width="800" height="168"&gt;&lt;/a&gt;&lt;br&gt;
Go back to main directory and run &lt;code&gt;terraform init&lt;/code&gt;.&lt;br&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%2F1q4ntlprqlbu8c973x4g.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%2F1q4ntlprqlbu8c973x4g.png" alt="Using S3 bucket as remote state" width="748" height="604"&gt;&lt;/a&gt;&lt;br&gt;
Now your state file will be store in S3 bucket. Don't worry about the cost. S3 and DynamoDB won't charge you until 5GB of storage being used, so you can keep this until you have finished the series or you can terminate it whenever you like with &lt;code&gt;terraform destroy&lt;/code&gt; (remember to be in correct directory)&lt;/p&gt;

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

&lt;p&gt;Congrats! We have successfully setup terraform environment... Finally, we can focus on the main task :). In the next post, I will show you how to create your first cluster with encrypted feature enabled using terraform. It will be really exciting so stay tune :3&lt;/p&gt;

&lt;p&gt;The source code is upload &lt;a href="https://github.com/vippr1237/EKS_series" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;br&gt;
I will update it usually so be patient.&lt;/p&gt;

&lt;p&gt;Thank you and happy hacking!&lt;/p&gt;

</description>
      <category>cloud</category>
      <category>aws</category>
      <category>eks</category>
      <category>kubernetes</category>
    </item>
  </channel>
</rss>
