<?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: piyushsachdeva</title>
    <description>The latest articles on DEV Community by piyushsachdeva (@piyushsachdeva).</description>
    <link>https://dev.to/piyushsachdeva</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F662113%2F9caedf74-70f5-4068-8c0c-255bf1463ac9.jpeg</url>
      <title>DEV Community: piyushsachdeva</title>
      <link>https://dev.to/piyushsachdeva</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/piyushsachdeva"/>
    <language>en</language>
    <item>
      <title>Build an AI Observability Pipeline on EKS Using Elasticsearch</title>
      <dc:creator>piyushsachdeva</dc:creator>
      <pubDate>Sun, 14 Jun 2026 14:30:05 +0000</pubDate>
      <link>https://dev.to/aws-builders/build-an-ai-observability-pipeline-on-eks-using-elasticsearch-1cpl</link>
      <guid>https://dev.to/aws-builders/build-an-ai-observability-pipeline-on-eks-using-elasticsearch-1cpl</guid>
      <description>&lt;p&gt;It's 2am and your pager is going off. You're on call, you were asleep, and now there's a pod stuck in &lt;code&gt;CrashLoopBackOff&lt;/code&gt;. You know the drill: tail the logs, &lt;code&gt;kubectl describe&lt;/code&gt;, scroll Git history, ask in Slack whether anyone shipped anything in the last hour. &lt;/p&gt;

&lt;p&gt;Forty minutes later you've found it, and you've woken up your tech lead to confirm.&lt;/p&gt;

&lt;p&gt;This walkthrough is about not doing that anymore.&lt;/p&gt;

&lt;p&gt;We'll build an AI observability pipeline on Amazon EKS with Elastic Cloud and OpenTelemetry, end to end. The whole thing rests on one move: join two streams of data, your crash logs and your deployment history, and let a language model reason across the join. &lt;/p&gt;

&lt;p&gt;Then you ask a plain question, "Why is paymentservice crashing?", and instead of another dashboard to squint at, you get the root cause:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;paymentservice went OOMKilled three minutes after commit a1b2c3 by xyz, which dropped the memory limit from 128Mi to 24Mi.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The commit SHA, the author, what changed, what to revert. Two indices and one agent is all it takes. Over the next sections you'll wire OpenTelemetry, Elasticsearch, and ArgoCD into your EKS cluster until that 2am question answers itself.&lt;/p&gt;




&lt;h2&gt;
  
  
  Table of contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Architecture&lt;/li&gt;
&lt;li&gt;Prerequisites&lt;/li&gt;
&lt;li&gt;Step 1: Provision Elasticsearch from AWS Marketplace&lt;/li&gt;
&lt;li&gt;Step 2: Configure OpenTelemetry to ship Kubernetes logs&lt;/li&gt;
&lt;li&gt;Step 3: Index Git commit metadata via GitHub Actions&lt;/li&gt;
&lt;li&gt;Step 4: Set up Argo CD for GitOps deployment&lt;/li&gt;
&lt;li&gt;Step 5: Build the AI diagnostic agent in Elastic&lt;/li&gt;
&lt;li&gt;Step 6: Simulate and diagnose a crash&lt;/li&gt;
&lt;li&gt;Why this works&lt;/li&gt;
&lt;li&gt;FAQs&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6fyg2vjosmj9tqz71etw.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%2F6fyg2vjosmj9tqz71etw.png" alt="Architecture diagram of AI observability setup on EKS using Elasticsearch" width="800" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Two data flows meet inside Elasticsearch.&lt;/p&gt;

&lt;p&gt;On the infrastructure side, you push code, Argo CD syncs it to EKS, a pod crashes, and OpenTelemetry ships the crash event to the &lt;code&gt;logs-*&lt;/code&gt; index.&lt;/p&gt;

&lt;p&gt;On the metadata side, the same push fires a GitHub Action that POSTs the commit details (SHA, author, diff URL, and message) to the &lt;code&gt;github-deployments&lt;/code&gt;index.&lt;/p&gt;

&lt;p&gt;The Elastic AI agent owns both queries. Ask it a question, and it runs one &lt;code&gt;ES|QL&lt;/code&gt; query against the logs to find the failure and a second against the deployments to find the most recent push and stitches the two into a plain-English answer.&lt;/p&gt;

&lt;p&gt;A few things to keep in mind before you start.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Push your Kubernetes manifests to GitHub before you create the Argo CD app. Argo CD syncs whatever is in the repo on first sync, so an empty repo sends you down a long debugging detour.&lt;/li&gt;
&lt;li&gt;Setup Elastic Cloud before you install OpenTelemetry. The OTel chart wants the endpoint and API key at install time.&lt;/li&gt;
&lt;li&gt;Create the &lt;code&gt;github-deployments&lt;/code&gt;index before you push to a repo that already has the workflow file, because the first push tries to write straight away.&lt;/li&gt;
&lt;li&gt;Both indices need real data before you switch on the agent. It cannot reason over nothing.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;You'll need these tools installed locally:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AWS CLI (&lt;code&gt;aws&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Kubernetes CLI (&lt;code&gt;kubectl&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;eksctl&lt;/code&gt; (for EKS cluster management)&lt;/li&gt;
&lt;li&gt;Helm&lt;/li&gt;
&lt;li&gt;Argo CD CLI&lt;/li&gt;
&lt;li&gt;GitHub CLI (&lt;code&gt;gh&lt;/code&gt;) and Git&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Connect &lt;code&gt;kubectl&lt;/code&gt; to your EKS cluster:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws eks update-kubeconfig &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; &amp;lt;CLUSTER_NAME&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify nodes are healthy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get nodes
&lt;span class="c"&gt;# Expect: 3 nodes, Status: Ready&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One sizing note that will save you a Slack message later: use &lt;code&gt;m5.xlarge&lt;/code&gt; instances, not &lt;code&gt;t3.medium&lt;/code&gt;. You're running microservices, OTel DaemonSets, and Argo CD on the same cluster. Two vCPUs per node won't cut it. Three &lt;code&gt;m5.xlarge&lt;/code&gt;nodes is the sweet spot.&lt;/p&gt;

&lt;p&gt;If you don't have an EKS cluster yet, spin one up quickly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;eksctl create cluster &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; demo-cluster &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--nodegroup-name&lt;/span&gt; standard-workers &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--node-type&lt;/span&gt; m5.xlarge &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--nodes&lt;/span&gt; 3 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--nodes-min&lt;/span&gt; 3 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--nodes-max&lt;/span&gt; 5 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--managed&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 1: Provision Elasticsearch from AWS Marketplace
&lt;/h2&gt;

&lt;p&gt;You could self-host Elasticsearch; however, the Elastic Cloud takes care of managing the service for you, which is another way to get peace of mind. The Marketplace deployment lands on the same AWS invoice and handles upgrades for you. (A free trial is enough for the demo.)&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Open the &lt;a href="https://console.aws.amazon.com" rel="noopener noreferrer"&gt;AWS Console&lt;/a&gt; and navigate to &lt;strong&gt;AWS Marketplace&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Search for &lt;strong&gt;Elastic Cloud (Elasticsearch Service)&lt;/strong&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%2F92miy1pifi6urwucuk2h.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%2F92miy1pifi6urwucuk2h.png" alt="Elastic Cloud (Elasticsearch Service) on AWS Marketplace" width="799" height="562"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Subscribe, then click &lt;strong&gt;Set up your account&lt;/strong&gt;. That kicks you over to the Elastic Cloud console.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The setup wizard will ask a few basic questions, along with &lt;strong&gt;"Which use case are you looking to try first?"&lt;/strong&gt;. Choose &lt;strong&gt;Elastic for Observability&lt;/strong&gt;. This template pre-enables the bits you need: log aggregation, APM, and AIOps. The plain Elasticsearch template means turning those on later by hand.&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%2Ft1d03q2kbumbyn1gbxep.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%2Ft1d03q2kbumbyn1gbxep.png" alt="Elastic for observability" width="799" height="406"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The next question it will ask is &lt;strong&gt;"Which Deployment option would you like to try?"&lt;/strong&gt; Click &lt;strong&gt;Create Cloud Serverless&lt;/strong&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%2Fh1rjiyds6zn3y0wqohc0.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%2Fh1rjiyds6zn3y0wqohc0.png" alt="Elastic Cloud Serverless Deployment" width="799" height="406"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Then it will ask for the configuration options; select &lt;strong&gt;"Observability complete."&lt;/strong&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%2F8h27fyytiabt9eb276hn.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%2F8h27fyytiabt9eb276hn.png" alt="Observability complete" width="799" height="406"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Lastly, it will ask the preferred region for cloud data storage, you can keep the default as &lt;strong&gt;cloud provider&lt;/strong&gt;: &lt;strong&gt;Amazon Web Services&lt;/strong&gt; and region to &lt;strong&gt;us-east-1&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Provisioning takes about five minutes. When the credentials screen appears, copy the &lt;code&gt;elastic&lt;/code&gt; user password.&lt;/p&gt;

&lt;h3&gt;
  
  
  Get your endpoints
&lt;/h3&gt;

&lt;p&gt;From the Elastic Cloud console, open your deployment and grab these two:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Elasticsearch → Copy endpoint&lt;/strong&gt; — used with GitHub Actions secret &lt;code&gt;ES_ENDPOINT&lt;/code&gt; and &lt;code&gt;curl&lt;/code&gt; commands.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integrations → Manage → APM → copy OTLP endpoint&lt;/strong&gt; — used as the OTel kube-stack secret &lt;code&gt;elastic_otlp_endpoint&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step 1b: Generate a Kibana API key
&lt;/h3&gt;

&lt;p&gt;You'll need one API key in two places (the OTel install and your GitHub repo secrets), so generate it now.&lt;/p&gt;

&lt;p&gt;Navigate to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://&amp;lt;YOUR-KIBANA-URL&amp;gt;/app/management/security/api_keys
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or via the menu: &lt;strong&gt;dashboard -&amp;gt; settings -&amp;gt; Access -&amp;gt; Api Keys&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpg73vlkhhhst84rdi0sk.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%2Fpg73vlkhhhst84rdi0sk.png" alt="Create Kibana API keys" width="800" height="397"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click &lt;strong&gt;Create API key&lt;/strong&gt;, name it something obvious like &lt;code&gt;github-deploy-key&lt;/code&gt;, and click &lt;strong&gt;Create&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg0hlytvky0gzynw2k594.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%2Fg0hlytvky0gzynw2k594.png" alt="Kibana API key creation screen" width="700" height="387"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copy the key. Same rule as the password: shown once. You'll reuse it as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;elastic_api_key&lt;/code&gt; in the OTel secret (Step 2)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ES_API_KEY&lt;/code&gt; in your GitHub repo secrets (Step 3)
Verify the key works:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-w&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;HTTP:%{http_code}"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-X&lt;/span&gt; GET &lt;span class="s2"&gt;"&amp;lt;YOUR-ES-ENDPOINT&amp;gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: ApiKey &amp;lt;YOUR-API-KEY&amp;gt;"&lt;/span&gt;
&lt;span class="c"&gt;# Expect: HTTP:200&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you don't get a 200, fix that now. A bad key here causes OTel to silently drop logs later, and you'll spend an hour wondering why Discover is empty.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 2: Configure OpenTelemetry to ship Kubernetes logs
&lt;/h2&gt;

&lt;p&gt;OpenTelemetry is the bridge between your cluster and Elasticsearch. Once it's installed as a DaemonSet, every pod log in the cluster ships automatically. You don't have to instrument individual services for this tutorial.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In Elastic, open your deployment and click &lt;strong&gt;Add Observability Data&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Choose &lt;strong&gt;Kubernetes&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Under &lt;strong&gt;Monitor your Kubernetes cluster using&lt;/strong&gt;, pick &lt;strong&gt;OpenTelemetry: Full Observability&lt;/strong&gt;.
Elastic pre-fills the Helm commands with your endpoint and credentials.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Add the Helm repo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;helm repo add open-telemetry &lt;span class="se"&gt;\&lt;/span&gt;
  https://open-telemetry.github.io/opentelemetry-helm-charts &lt;span class="nt"&gt;--force-update&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create the namespace, secret, and chart:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl create namespace opentelemetry-operator-system

kubectl create secret generic elastic-secret-otel &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--namespace&lt;/span&gt; opentelemetry-operator-system &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--from-literal&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;elastic_otlp_endpoint&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'&amp;lt;YOUR-OTLP-INGEST-ENDPOINT&amp;gt;'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--from-literal&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;elastic_api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'&amp;lt;YOUR-API-KEY&amp;gt;'&lt;/span&gt;

helm upgrade &lt;span class="nt"&gt;--install&lt;/span&gt; opentelemetry-kube-stack &lt;span class="se"&gt;\&lt;/span&gt;
  open-telemetry/opentelemetry-kube-stack &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--namespace&lt;/span&gt; opentelemetry-operator-system &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--values&lt;/span&gt; &lt;span class="s1"&gt;'https://raw.githubusercontent.com/elastic/elastic-agent/refs/tags/v9.3.3/deploy/helm/edot-collector/kube-stack/managed_otlp/values.yaml'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--version&lt;/span&gt; &lt;span class="s1"&gt;'0.12.4'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If Helm complains about a conflict, run &lt;code&gt;helm uninstall opentelemetry-kube-stack -n opentelemetry-operator-system&lt;/code&gt; and reinstall. This happens to everyone the first time.&lt;/p&gt;

&lt;p&gt;Verify all pods came up:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get all &lt;span class="nt"&gt;-n&lt;/span&gt; opentelemetry-operator-system
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqtlb7nw98mztfvmwmzb1.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%2Fqtlb7nw98mztfvmwmzb1.png" alt="All pods running in the opentelemetry-operator-system namespace" width="700" height="140"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2b: Verify logs are flowing in Kibana
&lt;/h3&gt;

&lt;p&gt;Before you wire up anything else, confirm OTel is actually shipping logs. Open Kibana and go to &lt;strong&gt;Discover&lt;/strong&gt;. The Kibana URL is on the Elastic Cloud deployment overview page, listed next to the Elasticsearch endpoint.&lt;/p&gt;

&lt;p&gt;In Discover, pick the &lt;strong&gt;All logs&lt;/strong&gt; data view, set the time range to &lt;strong&gt;Last 15 minutes&lt;/strong&gt;, and look for documents arriving from your EKS pods. You should see system components, OTel collectors, and any applications running on the cluster.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F03sas466tl4fm4o10dmc.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%2F03sas466tl4fm4o10dmc.png" alt="Kibana Discover showing logs flowing from cluster pods" width="700" height="365"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you see documents, you're good. If not, double-check the API key and the OTLP endpoint in the secret.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;EKS-specific note:&lt;/strong&gt; If you're using a private EKS cluster (no public endpoint), make sure the OTel collector pods can reach the Elastic endpoint. You may need to add a NAT Gateway or VPC endpoint for outbound HTTPS traffic on port 443.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Step 3: Index Git commit metadata via GitHub Actions
&lt;/h2&gt;

&lt;p&gt;The agent answers "Who deployed this?" by querying a second index, and that index needs data in it. A GitHub Action handles that automatically on every push. Nothing runs inside your cluster for this part; Actions runs in GitHub's cloud and POSTs straight to Elasticsearch.&lt;/p&gt;

&lt;h3&gt;
  
  
  3a. Create the index
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; PUT &lt;span class="s2"&gt;"&amp;lt;YOUR-ES-ENDPOINT&amp;gt;/github-deployments"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: ApiKey &amp;lt;YOUR-API-KEY&amp;gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "mappings": {
      "properties": {
        "timestamp":   { "type": "date" },
        "commit_sha":  { "type": "keyword" },
        "author":      { "type": "keyword" },
        "service":     { "type": "keyword" },
        "image_tag":   { "type": "keyword" },
        "change":      { "type": "text" },
        "diff_url":    { "type": "keyword" }
      }
    }
  }'&lt;/span&gt;
&lt;span class="c"&gt;# Expect: {"acknowledged":true}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3b. Add GitHub repository secrets
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh secret &lt;span class="nb"&gt;set &lt;/span&gt;ES_ENDPOINT &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--repo&lt;/span&gt; &amp;lt;YOUR-GITHUB-USERNAME&amp;gt;/&amp;lt;YOUR-REPO&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--body&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;YOUR-ES-ENDPOINT&amp;gt;"&lt;/span&gt;

gh secret &lt;span class="nb"&gt;set &lt;/span&gt;ES_API_KEY &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--repo&lt;/span&gt; &amp;lt;YOUR-GITHUB-USERNAME&amp;gt;/&amp;lt;YOUR-REPO&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--body&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;YOUR-API-KEY&amp;gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3c: The workflow file
&lt;/h3&gt;

&lt;p&gt;Create &lt;code&gt;.github/workflows/index-deploy.yml&lt;/code&gt;. On every push to &lt;code&gt;main&lt;/code&gt;, it figures out which service changed (by diffing &lt;code&gt;release/kubernetes-manifests.yaml&lt;/code&gt;) and POSTs one document to the &lt;code&gt;github-deployments&lt;/code&gt; index.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Index deployment to Elasticsearch&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;main&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;index&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;fetch-depth&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Detect changed service&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;changed&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;CHANGED=$(git diff HEAD~1 HEAD -- release/kubernetes-manifests.yaml \&lt;/span&gt;
            &lt;span class="s"&gt;| grep '^+' \&lt;/span&gt;
            &lt;span class="s"&gt;| grep -oP 'name:\s+\K[a-z][a-z0-9-]+service' \&lt;/span&gt;
            &lt;span class="s"&gt;| head -1)&lt;/span&gt;
          &lt;span class="s"&gt;if [ -z "$CHANGED" ]; then&lt;/span&gt;
            &lt;span class="s"&gt;CHANGED=$(git diff HEAD~1 HEAD -- release/kubernetes-manifests.yaml \&lt;/span&gt;
              &lt;span class="s"&gt;| grep -oE 'paymentservice|cartservice|frontend|recommendationservice|adservice|checkoutservice|productcatalogservice|currencyservice|shippingservice|emailservice|redis-cart|loadgenerator' \&lt;/span&gt;
              &lt;span class="s"&gt;| head -1)&lt;/span&gt;
          &lt;span class="s"&gt;fi&lt;/span&gt;
          &lt;span class="s"&gt;echo "service=${CHANGED:-unknown}" &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Push deploy event to Elasticsearch&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;curl -X POST "${{ secrets.ES_ENDPOINT }}/github-deployments/_doc" \&lt;/span&gt;
            &lt;span class="s"&gt;-H "Authorization: ApiKey ${{ secrets.ES_API_KEY }}" \&lt;/span&gt;
            &lt;span class="s"&gt;-H "Content-Type: application/json" \&lt;/span&gt;
            &lt;span class="s"&gt;-d "{&lt;/span&gt;
              &lt;span class="s"&gt;\"timestamp\":  \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",&lt;/span&gt;
              &lt;span class="s"&gt;\"commit_sha\": \"${{ github.sha }}\",&lt;/span&gt;
              &lt;span class="s"&gt;\"author\":     \"${{ github.actor }}\",&lt;/span&gt;
              &lt;span class="s"&gt;\"service\":    \"${{ steps.changed.outputs.service }}\",&lt;/span&gt;
              &lt;span class="s"&gt;\"image_tag\":  \"${{ github.sha }}\",&lt;/span&gt;
              &lt;span class="s"&gt;\"change\":     \"${{ github.event.head_commit.message }}\",&lt;/span&gt;
              &lt;span class="s"&gt;\"diff_url\":   \"${{ github.event.compare }}\"&lt;/span&gt;
            &lt;span class="s"&gt;}"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3d: Verify it works
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git commit &lt;span class="nt"&gt;--allow-empty&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"test: verify ES indexing"&lt;/span&gt;
git push origin main

gh run list &lt;span class="nt"&gt;--limit&lt;/span&gt; 3
&lt;span class="c"&gt;# Expect: "Index deployment to Elasticsearch" → completed success&lt;/span&gt;

curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;YOUR-ES-ENDPOINT&amp;gt;/github-deployments/_count"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: ApiKey &amp;lt;YOUR-API-KEY&amp;gt;"&lt;/span&gt;
&lt;span class="c"&gt;# Expect: {"count":1,...}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 4: Set up Argo CD for GitOps deployment
&lt;/h2&gt;

&lt;p&gt;Argo CD watches your repo and syncs changes to EKS on a schedule. The whole point of the demo is to push code and have it deploy on its own, and Argo CD is what makes that real.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install Argo CD&lt;/span&gt;
kubectl create namespace argocd
kubectl apply &lt;span class="nt"&gt;-n&lt;/span&gt; argocd &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-f&lt;/span&gt; https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
kubectl rollout status deployment/argocd-server &lt;span class="nt"&gt;-n&lt;/span&gt; argocd &lt;span class="nt"&gt;--timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;180s

&lt;span class="c"&gt;# Expose publicly via LoadBalancer (creates an AWS ELB)&lt;/span&gt;
kubectl patch svc argocd-server &lt;span class="nt"&gt;-n&lt;/span&gt; argocd &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s1"&gt;'{"spec":{"type":"LoadBalancer"}}'&lt;/span&gt;
kubectl get svc argocd-server &lt;span class="nt"&gt;-n&lt;/span&gt; argocd
&lt;span class="c"&gt;# Note the EXTERNAL-IP (AWS ELB hostname)&lt;/span&gt;

&lt;span class="c"&gt;# Get admin password&lt;/span&gt;
kubectl get secret argocd-initial-admin-secret &lt;span class="nt"&gt;-n&lt;/span&gt; argocd &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nv"&gt;jsonpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'{.data.password}'&lt;/span&gt; | &lt;span class="nb"&gt;base64&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;

&lt;span class="c"&gt;# Log in&lt;/span&gt;
argocd login &amp;lt;EXTERNAL-IP&amp;gt; &lt;span class="nt"&gt;--username&lt;/span&gt; admin &lt;span class="nt"&gt;--password&lt;/span&gt; &amp;lt;PASSWORD&amp;gt; &lt;span class="nt"&gt;--insecure&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; On EKS, the &lt;code&gt;EXTERNAL-IP&lt;/code&gt; for the LoadBalancer will be an AWS ELB DNS hostname (e.g., &lt;code&gt;xxxxxx.us-east-1.elb.amazonaws.com&lt;/code&gt;), not a plain IP. Use that hostname wherever &lt;code&gt;&amp;lt;EXTERNAL-IP&amp;gt;&lt;/code&gt; appears.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Feel free to use &lt;a href="https://github.com/GoogleCloudPlatform/microservices-demo" rel="noopener noreferrer"&gt;this sample repo&lt;/a&gt; as your application.&lt;/p&gt;

&lt;p&gt;Create the Argo CD application pointing at your repo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; - &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: online-boutique
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/&amp;lt;YOUR-USERNAME&amp;gt;/microservices-demo
    targetRevision: main
    path: release
  destination:
    server: https://kubernetes.default.svc
    namespace: online-boutique
  syncPolicy:
    automated:
      prune: true
    syncOptions:
      - CreateNamespace=true
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Trigger the first sync. The default Argo CD poll interval is three minutes, which is fine in production and brutal in a demo. Drop it to thirty seconds so you can actually watch things happen.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;argocd app &lt;span class="nb"&gt;sync &lt;/span&gt;online-boutique &lt;span class="nt"&gt;--force&lt;/span&gt; &lt;span class="nt"&gt;--prune&lt;/span&gt;

kubectl patch configmap argocd-cm &lt;span class="nt"&gt;-n&lt;/span&gt; argocd &lt;span class="nt"&gt;--type&lt;/span&gt; merge &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s1"&gt;'{"data": {"timeout.reconciliation": "30s"}}'&lt;/span&gt;
kubectl rollout restart deployment/argocd-repo-server &lt;span class="nt"&gt;-n&lt;/span&gt; argocd

&lt;span class="c"&gt;# Verify all 12 pods are running&lt;/span&gt;
kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; online-boutique
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 5: Build the AI diagnostic agent in Kibana
&lt;/h2&gt;

&lt;p&gt;Both indices are live. Now build the agent that queries them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5a: LLM setup
&lt;/h3&gt;

&lt;p&gt;The agent needs a language model behind it. Use &lt;strong&gt;Elastic Inference Service (EIS)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;EIS ships with Elastic for Observability deployments and Marketplace trials, so the model dropdown is already populated when you create an agent. You'll see Claude for reasoning, JINA embeddings for vectorization, and the JINA reranker for retrieval ordering, all billed through the same Elastic invoice. Pick Claude (or whichever reasoning model you prefer) for the agent itself.&lt;/p&gt;

&lt;p&gt;You'll want the JINA models later, if you extend this pattern to semantic search over logs or RAG over runbooks. For the diagnostic agent here, the reasoning model is all you need.&lt;/p&gt;

&lt;p&gt;If EIS isn't available on your deployment, fall back to an external connector:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Kibana → ☰ → Stack Management → Connectors → Create connector → OpenAI&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Paste an API key from &lt;code&gt;platform.openai.com&lt;/code&gt;, set the model to &lt;code&gt;gpt-4o&lt;/code&gt;, click &lt;strong&gt;Save &amp;amp; test&lt;/strong&gt;, then pick the connector in Agent Builder.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Anthropic, Google Vertex, and AWS Bedrock connectors follow the same shape. Pick whichever you already have billing set up for.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5b: Create the ES|QL tools
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Kibana → ☰ → Search → Tools → Create tool.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tool 1: &lt;code&gt;get_crash_logs&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Type: Elasticsearch query&lt;/li&gt;
&lt;li&gt;Index: &lt;code&gt;logs-*&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM logs-*
| WHERE resource.attributes.k8s.namespace.name == "online-boutique"
| WHERE body.text LIKE "*OOMKill*" OR body.text LIKE "*memory*"
| SORT @timestamp DESC
| LIMIT 20
| KEEP @timestamp, resource.attributes.k8s.deployment.name, resource.attributes.k8s.pod.name, body.text
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqi60kvtx62eahn50qqw4.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%2Fqi60kvtx62eahn50qqw4.png" alt="Elastic Agent Builder create tool wizard" width="700" height="409"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tool 2: &lt;code&gt;get_deploy_history&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Type: Elasticsearch query&lt;/li&gt;
&lt;li&gt;Index: &lt;code&gt;github-deployments&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM github-deployments
| SORT timestamp DESC
| LIMIT 5
| KEEP timestamp, author, commit_sha, service, change, diff_url
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 5c: Create the agent
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Kibana → ☰ → Search → Agent Builder → Create agent.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Name:&lt;/strong&gt; &lt;code&gt;blame-the-deploy&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Model:&lt;/strong&gt; Claude, or your configured connector&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Paste these instructions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You are an SRE assistant. When asked why a service is crashing:
1. Use get_crash_logs to find OOMKill or memory events in logs-*
2. Use get_deploy_history to find the most recent GitHub deployment to that service
3. If the deploy happened shortly before the crash, that is the likely cause
4. Report: crash time, commit SHA, author, what changed, and how to fix it
Always cite the commit SHA and author name in your answer.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Under &lt;strong&gt;Tools&lt;/strong&gt;, add &lt;code&gt;get_crash_logs&lt;/code&gt; and &lt;code&gt;get_deploy_history&lt;/code&gt; and click save.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 6: Simulate and diagnose a crash
&lt;/h2&gt;

&lt;p&gt;The whole reason you built this is to ask the agent a hard question. So break something on purpose.&lt;/p&gt;

&lt;h3&gt;
  
  
  Introduce the bad commit
&lt;/h3&gt;

&lt;p&gt;Open &lt;code&gt;release/kubernetes-manifests.yaml&lt;/code&gt;. Find the &lt;code&gt;paymentservice&lt;/code&gt; deployment (around line 631) and squeeze the memory limits below what the service actually needs at startup:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;requests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;24Mi"&lt;/span&gt;   &lt;span class="c1"&gt;# was 64Mi&lt;/span&gt;
  &lt;span class="na"&gt;limits&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;24Mi"&lt;/span&gt;   &lt;span class="c1"&gt;# was 128Mi&lt;/span&gt;
&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;git add release/kubernetes-manifests.yaml
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"perf: tune paymentservice memory limits for cost optimisation"&lt;/span&gt;
git push origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That commit message is the kind of thing a tired engineer actually writes at 4pm on a Friday. Argo CD picks it up within thirty seconds and applies the manifest. Because 24Mi isn't enough, the pod dies on startup.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; online-boutique &lt;span class="nt"&gt;-w&lt;/span&gt;
&lt;span class="c"&gt;# paymentservice: Running → OOMKilled → CrashLoopBackOff&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Confirm which pod is unhappy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl describe pod &lt;span class="nt"&gt;-n&lt;/span&gt; online-boutique &amp;lt;pod-name&amp;gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-A5&lt;/span&gt; &lt;span class="s1"&gt;'Last State\|OOM'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Ask the agent
&lt;/h3&gt;

&lt;p&gt;Open the Elastic Agent chat:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Why is paymentservice crashing? Check the logs and recent deployments.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&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%2F5h88sz9qnb4ewi47gnyo.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%2F5h88sz9qnb4ewi47gnyo.png" alt="Elastic Agent chat interface" width="700" height="244"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The agent runs &lt;code&gt;get_crash_logs&lt;/code&gt;, sees the OOMKill, runs &lt;code&gt;get_deploy_history&lt;/code&gt;, finds the commit that lowered the memory limit, and reports back with the SHA, the author, the commit message, the diff URL, and a fix suggestion.&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%2F0rsu207jk1yu8c83cww3.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%2F0rsu207jk1yu8c83cww3.png" alt="Elastic Agent response showing root cause analysis" width="700" height="431"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Fix it
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git revert HEAD &lt;span class="nt"&gt;--no-edit&lt;/span&gt;
git push origin main
&lt;span class="c"&gt;# Pod recovers in about 30 seconds&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ask the agent again:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Is paymentservice healthy now?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It checks the logs, finds no recent OOMKills, and confirms the service is stable.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why this works
&lt;/h2&gt;

&lt;p&gt;It comes down to the join. Kubernetes logs tell you what crashed and when. The &lt;code&gt;github-deployments&lt;/code&gt; index tells you what was deployed and by whom. Either index alone leaves you guessing. Stitch them together behind an agent and you skip the part of the incident where you're bouncing between CloudWatch, GitHub, Slack, and &lt;code&gt;kubectl&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The pattern extends. Want to diagnose CPU throttling? Add a tool that searches &lt;code&gt;logs-*&lt;/code&gt; for &lt;code&gt;CPUThrottlingHigh&lt;/code&gt; events. Want to catch failed health checks? Same idea with a different ES|QL clause. The tools are just saved queries, and the agent picks up a new diagnostic capability the next time you chat with it.&lt;/p&gt;

&lt;p&gt;One caveat before you put this in front of the rest of your team. The agent is good at &lt;strong&gt;correlation&lt;/strong&gt;, not causation. If two services deploy in the same five-minute window and one crashes, the agent will cheerfully blame the wrong commit. Treat the output as a strong lead, not a verdict.&lt;/p&gt;




&lt;h2&gt;
  
  
  Quick reference
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Commands you will reuse
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; online-boutique        &lt;span class="c"&gt;# check all pods&lt;/span&gt;
kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; online-boutique &lt;span class="nt"&gt;-w&lt;/span&gt;     &lt;span class="c"&gt;# watch live&lt;/span&gt;
kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; opentelemetry-operator-system  &lt;span class="c"&gt;# check OTel&lt;/span&gt;
argocd app get online-boutique             &lt;span class="c"&gt;# Argo CD sync status&lt;/span&gt;
argocd app &lt;span class="nb"&gt;sync &lt;/span&gt;online-boutique &lt;span class="nt"&gt;--force&lt;/span&gt;    &lt;span class="c"&gt;# force sync&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ES|QL: find OOMKill events
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM logs-*
| WHERE resource.attributes.k8s.namespace.name == "online-boutique"
| WHERE body.text LIKE "*OOMKill*"
| SORT @timestamp DESC
| LIMIT 20
| KEEP @timestamp, resource.attributes.k8s.deployment.name, body.text
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ES|QL: find recent deploys
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM github-deployments
| SORT timestamp DESC
| LIMIT 10
| KEEP timestamp, author, commit_sha, service, change
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  FAQs
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What is an AI observability pipeline?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;An AI observability pipeline is a system that ships infrastructure telemetry and deployment metadata into the same data store, then puts an LLM in front of it so you can ask plain-English questions about failures. The model runs structured queries against your indices instead of asking you to remember which dashboard goes with which symptom.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I run this without AWS?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes. The architecture is portable. Swap EKS for GKE, AKS, or any conformant Kubernetes cluster. Elasticsearch has hosted offerings on GCP and Azure Marketplace, and OpenTelemetry doesn't care which cloud it runs on. The only AWS-specific steps are the Marketplace billing flow and the &lt;code&gt;aws eks update-kubeconfig&lt;/code&gt; command, and both have direct equivalents on the other clouds.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why use Elasticsearch for this use case?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Elasticsearch lets you keep your logs, metrics, deployment events, and vector embeddings in one place. The Kibana AI agent is built in. You define a tool, point it at an index, and chat with it. No LangChain wrapper, no FastAPI orchestrator, no model gateway to keep alive. And ES|QL is one query language across logs, metrics, and structured JSON metadata, which is the only reason the join in this tutorial (&lt;code&gt;logs-*&lt;/code&gt; against &lt;code&gt;github-deployments&lt;/code&gt;) is five lines instead of a Python service.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How much does this cost to run?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A small Elastic Cloud deployment on &lt;code&gt;us-east-1&lt;/code&gt; runs about $95 per month at the time of writing. EKS costs depend on node count; three &lt;code&gt;m5.xlarge&lt;/code&gt; nodes are roughly $210 per month before Savings Plans or Reserved Instance discounts. The EKS control plane itself is $0.10/hour (~$73/month). If you're running this as a learning exercise, tear the cluster down between sessions with &lt;code&gt;eksctl delete cluster --name demo-cluster --region us-east-1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My GitHub action fires, but no document lands in Elasticsearch. What now?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Check three things in this order. First, do the repo secrets resolve? Add &lt;code&gt;echo "endpoint length: ${#ES_ENDPOINT}"&lt;/code&gt; to the workflow to verify. Second, does the API key have write permission on &lt;code&gt;github-deployments&lt;/code&gt;? Test with &lt;code&gt;curl -X POST&lt;/code&gt; from your laptop using the same key. Third, is your &lt;code&gt;ES_ENDPOINT&lt;/code&gt; value missing the &lt;code&gt;https://&lt;/code&gt; prefix? That one bites everyone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can the Kibana AI agent fix the bug or just identify it?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For this tutorial, it identifies. It doesn't open a pull request or call &lt;code&gt;kubectl rollout undo&lt;/code&gt; on your behalf. You can extend it to do that with a custom tool that wraps the GitHub API or &lt;code&gt;kubectl&lt;/code&gt;, but I'd rather you read the diagnosis first and decide. Autonomous remediation in production is a separate conversation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does this replace my on-call runbooks?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No. It collapses the first ten minutes of an incident, the part where you're hunting for the right tab. The runbook still tells you what to do once you know what broke. Think of the agent as the on-call's first responder, not the surgeon.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What IAM permissions does my EKS cluster need?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The OTel DaemonSet only needs outbound HTTPS to the Elastic endpoint; no AWS-specific IAM permissions are required. If your EKS nodes use an instance profile, make sure the security group allows outbound 443. Argo CD similarly needs no special AWS permissions, since it operates against the Kubernetes API only.&lt;/p&gt;




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

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.elastic.co/partners/aws-marketplace-offer-application?utm_source=youtube&amp;amp;utm_medium=paid-video&amp;amp;utm_campaign=aws-influencer-piyush-bedrock-pm" rel="noopener noreferrer"&gt;Elastic Cloud on AWS Marketplace&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Similar project on &lt;a href="https://youtu.be/kublq2Y9dNs" rel="noopener noreferrer"&gt;GKE&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://open-telemetry.github.io/opentelemetry-helm-charts" rel="noopener noreferrer"&gt;OpenTelemetry Helm Charts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://argo-cd.readthedocs.io/en/stable/" rel="noopener noreferrer"&gt;Argo CD Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://eksctl.io/" rel="noopener noreferrer"&gt;eksctl — EKS cluster management&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/esql.html" rel="noopener noreferrer"&gt;Elastic ES|QL Reference&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.elastic.co/guide/en/kibana/current/search-ai-assistant.html" rel="noopener noreferrer"&gt;Elastic Agent Builder&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Deploy Your Own 24/7 AI Agent on AWS EC2 with Docker &amp; Tailscale (The Secure Way)</title>
      <dc:creator>piyushsachdeva</dc:creator>
      <pubDate>Wed, 11 Feb 2026 04:39:29 +0000</pubDate>
      <link>https://dev.to/aws-builders/deploy-your-own-247-ai-agent-on-aws-ec2-with-docker-tailscale-the-secure-way-53aa</link>
      <guid>https://dev.to/aws-builders/deploy-your-own-247-ai-agent-on-aws-ec2-with-docker-tailscale-the-secure-way-53aa</guid>
      <description>&lt;p&gt;No, you don't need a Mac Mini or fancy hardware setup to run your own AI agent 24/7. All you need is a cloud virtual machine or VPS (Virtual Private Server).&lt;/p&gt;

&lt;p&gt;I know what you're thinking: &lt;em&gt;"What about security?"&lt;/em&gt; And you should be thinking about it. That's exactly why I'm going to walk you through the step-by-step process to &lt;strong&gt;securely&lt;/strong&gt; set up an AI agent running as a Docker container.&lt;/p&gt;

&lt;p&gt;Imagine having your own private AI assistant running 24/7 on a cloud server you control-accessible from anywhere, yet completely shielded from the public internet. That's exactly what we're building today.&lt;/p&gt;

&lt;p&gt;In this guide, we'll deploy &lt;strong&gt;OpenClaw&lt;/strong&gt; (also known as Moltbot/Clawdbot) on an AWS EC2 instance using Docker containers. But we're not just going to spin up a container and call it a day. We'll harden our server, lock down SSH access, and use Tailscale to create a secure private network that only you can access.&lt;/p&gt;

&lt;h2&gt;
  
  
  What You'll Have by the End
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A hardened Ubuntu server with non-standard SSH configuration&lt;/li&gt;
&lt;li&gt;Docker running OpenClaw in an isolated container&lt;/li&gt;
&lt;li&gt;Secure private access via Tailscale (no public ports exposed)&lt;/li&gt;
&lt;li&gt;A fully functional AI assistant accessible from your browser
Let's get started.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;If you prefer video tutorial, you can watch the below end-to-end video (else, keep reading the blog)&lt;/p&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/Qx97iDCCccM"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

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

&lt;p&gt;Before we dive in, make sure you have the following ready:&lt;/p&gt;

&lt;h3&gt;
  
  
  Cloud Infrastructure
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AWS Account&lt;/strong&gt; with EC2 access&lt;/li&gt;
&lt;li&gt;A fresh &lt;strong&gt;Ubuntu 24.04 LTS&lt;/strong&gt; instance (Recommended specs: 2 vCPU, 4GB RAM, 15GB storage)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Key Pair&lt;/strong&gt;: Your &lt;code&gt;.pem&lt;/code&gt; file from AWS (e.g., &lt;code&gt;moltbot.pem&lt;/code&gt;) saved on your local computer&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Current Access&lt;/strong&gt;: Ability to SSH into the instance as the default &lt;code&gt;ubuntu&lt;/code&gt; user&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  API Keys
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Anthropic API Key&lt;/strong&gt; (for Claude Sonnet/Opus - recommended for best performance)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OpenAI API Key&lt;/strong&gt; (Optional, as a backup)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Networking
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tailscale Account&lt;/strong&gt;: Free tier is sufficient (this is how we'll securely access our bot)&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Pro Tip&lt;/strong&gt;: If you're new to AWS, providers like Hetzner, DigitalOcean, or Vultr also work perfectly with this guide.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Phase 1: VM Hardening (Do This FIRST)
&lt;/h2&gt;

&lt;p&gt;Before we install anything fun, we need to secure our server. Think of this as locking the doors and windows before you move your valuables inside.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Create a New User
&lt;/h3&gt;

&lt;p&gt;First, SSH into your server as the default &lt;code&gt;ubuntu&lt;/code&gt; user:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"moltbot.pem"&lt;/span&gt; ubuntu@&amp;lt;YOUR-EC2-PUBLIC-IP&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once connected, let's update the system and create a dedicated user for OpenClaw:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Update system&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;apt upgrade &lt;span class="nt"&gt;-y&lt;/span&gt;

&lt;span class="c"&gt;# Create a new user (replace 'openclaw' if you want a different name)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;adduser openclaw
&lt;span class="c"&gt;# (Enter a strong password when prompted)&lt;/span&gt;

&lt;span class="c"&gt;# Grant sudo rights&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;usermod &lt;span class="nt"&gt;-aG&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;openclaw
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Why a new user?&lt;/strong&gt; Running applications as a dedicated user follows the principle of least privilege. If something goes wrong, the blast radius is contained.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Step 2: Set Up SSH Keys for the New User
&lt;/h3&gt;

&lt;p&gt;Here's where many tutorials fail you. The AWS key (&lt;code&gt;.pem&lt;/code&gt; file) only works for the &lt;code&gt;ubuntu&lt;/code&gt; user by default. We need to copy the authorized keys to our new user, or we'll be locked out.&lt;/p&gt;

&lt;p&gt;Run these commands while still logged in as &lt;code&gt;ubuntu&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Create the SSH directory for the new user&lt;/span&gt;
&lt;span class="nb"&gt;sudo mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /home/openclaw/.ssh

&lt;span class="c"&gt;# 2. Copy the authorized keys from 'ubuntu' to 'openclaw'&lt;/span&gt;
&lt;span class="nb"&gt;sudo cp&lt;/span&gt; /home/ubuntu/.ssh/authorized_keys /home/openclaw/.ssh/

&lt;span class="c"&gt;# 3. Fix permissions (CRITICAL: If this is wrong, login will fail)&lt;/span&gt;
&lt;span class="nb"&gt;sudo chown&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; openclaw:openclaw /home/openclaw/.ssh
&lt;span class="nb"&gt;sudo chmod &lt;/span&gt;700 /home/openclaw/.ssh
&lt;span class="nb"&gt;sudo chmod &lt;/span&gt;600 /home/openclaw/.ssh/authorized_keys
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The Permission Trinity&lt;/strong&gt;: Directory at &lt;code&gt;700&lt;/code&gt;, keys file at &lt;code&gt;600&lt;/code&gt;, owned by the user. Get any of these wrong, and SSH will silently reject your login.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Step 3: Configure AWS Security Group (External Firewall)
&lt;/h3&gt;

&lt;p&gt;Time to switch to your web browser. We need to tell AWS to allow traffic on our new SSH port.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;strong&gt;EC2 Dashboard → Security Groups&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Select your instance's security group → &lt;strong&gt;Edit inbound rules&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Add Rule&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Type: &lt;code&gt;Custom TCP&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Port: &lt;code&gt;2222&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Source: &lt;code&gt;0.0.0.0/0&lt;/code&gt; (or "My IP" for extra security)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DO NOT&lt;/strong&gt; delete the rule for Port 22 yet - this is your safety net&lt;/li&gt;
&lt;li&gt;Save rules&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step 4: Configure UFW (Internal Firewall)
&lt;/h3&gt;

&lt;p&gt;Back in your terminal, let's set up the host-level firewall:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Set default policies&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw default deny incoming
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw default allow outgoing

&lt;span class="c"&gt;# Allow the CURRENT port (Safety Net)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw allow 22/tcp

&lt;span class="c"&gt;# Allow the FUTURE port&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw allow 2222/tcp

&lt;span class="c"&gt;# Enable the firewall&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw &lt;span class="nb"&gt;enable&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When prompted, type &lt;code&gt;y&lt;/code&gt; to confirm. You now have two layers of firewall protection.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: The Golden Test
&lt;/h3&gt;

&lt;p&gt;This is the moment of truth. Before we disable password authentication or change ports, we need to prove that our new user can log in with the SSH key.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Keep your current terminal window open&lt;/strong&gt; (this is your lifeline).&lt;/p&gt;

&lt;p&gt;Open a &lt;strong&gt;NEW&lt;/strong&gt; terminal window on your local computer and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"moltbot.pem"&lt;/span&gt; openclaw@&amp;lt;YOUR-IP-ADDRESS&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Success&lt;/strong&gt;: You log in without being prompted for a password&lt;/td&gt;
&lt;td&gt;Proceed to Step 6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Failure&lt;/strong&gt;: "Permission denied"&lt;/td&gt;
&lt;td&gt;Go back and re-check Step 2. &lt;strong&gt;Do not proceed.&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Step 6: Lock Down SSH Configuration
&lt;/h3&gt;

&lt;p&gt;Now that we've verified key-based login works, it's time to harden SSH. This is where Ubuntu 24.04 throws a curveball that catches many admins off guard.&lt;/p&gt;

&lt;p&gt;Edit the SSH config file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;vi /etc/ssh/sshd_config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make the following changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Port 2222
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save and close the file (&lt;code&gt;:wq&lt;/code&gt; in vi).&lt;/p&gt;

&lt;h4&gt;
  
  
  Disable Systemd Socket Activation (CRITICAL)
&lt;/h4&gt;

&lt;p&gt;Here's the gotcha: Ubuntu 24.04 uses "socket activation" which holds Port 22 open regardless of what you put in &lt;code&gt;sshd_config&lt;/code&gt;. You &lt;strong&gt;must&lt;/strong&gt; disable this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Stop the socket listener&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl stop ssh.socket
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl disable ssh.socket

&lt;span class="c"&gt;# Restart the SSH service to apply your new config&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart ssh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Verify the Port Change:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;ss &lt;span class="nt"&gt;-tulpn&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;ssh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Output&lt;/th&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;0.0.0.0:2222&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Success!&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;0.0.0.0:22&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Something went wrong. Do NOT disconnect.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Step 7: Final Verification &amp;amp; Cleanup
&lt;/h3&gt;

&lt;p&gt;Open a &lt;strong&gt;NEW&lt;/strong&gt; terminal window and test the new port:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh &lt;span class="nt"&gt;-p&lt;/span&gt; 2222 &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"moltbot.pem"&lt;/span&gt; openclaw@&amp;lt;YOUR-IP-ADDRESS&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Only if that works&lt;/strong&gt;, go back to your server terminal and lock down Port 22:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw delete allow 22/tcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then go to &lt;strong&gt;AWS Security Groups&lt;/strong&gt; and delete the inbound rule for Port 22.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Important&lt;/strong&gt;: From this point forward, you can no longer use "EC2 Instance Connect" (the browser console). You must always use the SSH command above.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Phase 2: Environment Setup
&lt;/h2&gt;

&lt;p&gt;With our server hardened, it's time to install the software stack. We'll set up Docker to run OpenClaw in isolation and Tailscale to create our private access tunnel.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Install Docker &amp;amp; Docker Compose
&lt;/h3&gt;

&lt;p&gt;Docker ensures OpenClaw's dependencies don't interfere with your host OS. Here's the official installation method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install Docker dependencies&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;apt-transport-https ca-certificates curl software-properties-common &lt;span class="nt"&gt;-y&lt;/span&gt;

&lt;span class="c"&gt;# Add Docker GPG key &amp;amp; Repository&lt;/span&gt;
curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://download.docker.com/linux/ubuntu/gpg | &lt;span class="nb"&gt;sudo &lt;/span&gt;gpg &lt;span class="nt"&gt;--dearmor&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /usr/share/keyrings/docker-archive-keyring.gpg

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"deb [arch=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;dpkg &lt;span class="nt"&gt;--print-architecture&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt; signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;lsb_release &lt;span class="nt"&gt;-cs&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt; stable"&lt;/span&gt; | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; /etc/apt/sources.list.d/docker.list &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /dev/null

&lt;span class="c"&gt;# Install Docker&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;docker-ce docker-ce-cli containerd.io docker-compose-plugin &lt;span class="nt"&gt;-y&lt;/span&gt;

&lt;span class="c"&gt;# Allow 'openclaw' user to run Docker without sudo&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;usermod &lt;span class="nt"&gt;-aG&lt;/span&gt; docker &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;USER&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now log out and log back in for the group change to take effect:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Then reconnect via SSH:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh &lt;span class="nt"&gt;-p&lt;/span&gt; 2222 &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"moltbot.pem"&lt;/span&gt; openclaw@&amp;lt;YOUR-IP-ADDRESS&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify Docker works without sudo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run hello-world
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Install Tailscale (The Secure Access Layer)
&lt;/h3&gt;

&lt;p&gt;Here's where the magic happens. Instead of exposing OpenClaw's web port (18789) to the public internet, we'll use Tailscale to create a private mesh network. Only devices on your Tailnet can access the bot.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;On your EC2 server:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://tailscale.com/install.sh | sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After installation, authenticate with your Tailscale account:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;tailscale up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Follow the link provided to authorize your server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;On your local machine:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Install Tailscale from &lt;a href="https://tailscale.com/download" rel="noopener noreferrer"&gt;tailscale.com/download&lt;/a&gt; and sign in with the same account.&lt;/p&gt;

&lt;p&gt;Once both devices are on your Tailnet, they can communicate securely without any public ports.&lt;/p&gt;




&lt;h2&gt;
  
  
  Phase 3: OpenClaw Installation
&lt;/h2&gt;

&lt;p&gt;The infrastructure is ready. Let's deploy the bot.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Clone the Repository
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/openclaw/openclaw.git
&lt;span class="nb"&gt;cd &lt;/span&gt;openclaw
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Clean Up Old Configurations
&lt;/h3&gt;

&lt;p&gt;If you've experimented with OpenClaw before, nuke any old config folders to prevent conflicts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; ~/.openclaw
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Pre-Create the Configuration Folder
&lt;/h3&gt;

&lt;p&gt;This step prevents the dreaded "Permission Denied" errors. We create the folder manually and set permissions so both you AND Docker can write to it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create the folder structure&lt;/span&gt;
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /home/openclaw/.openclaw/workspace

&lt;span class="c"&gt;# Give full read/write access (fixes the "Permission Denied" error)&lt;/span&gt;
&lt;span class="nb"&gt;sudo chmod&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; 777 /home/openclaw/.openclaw
&lt;span class="nb"&gt;sudo chown&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; openclaw:openclaw ~/openclaw
&lt;span class="nb"&gt;sudo chmod&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; 775 ~/openclaw
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Run the Setup Script
&lt;/h3&gt;

&lt;p&gt;Now we're ready for the main event:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~/openclaw
./docker-setup.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A series of prompts will appear. Select &lt;strong&gt;EXACTLY&lt;/strong&gt; these options to avoid crashes:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Prompt&lt;/th&gt;
&lt;th&gt;Selection&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Onboarding mode&lt;/td&gt;
&lt;td&gt;Manual&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Setup&lt;/td&gt;
&lt;td&gt;Local gateway (this machine)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Workspace directory&lt;/td&gt;
&lt;td&gt;(Press Enter to accept default)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Model/auth Provider&lt;/td&gt;
&lt;td&gt;Anthropic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Anthropic API Key&lt;/td&gt;
&lt;td&gt;(Enter your key)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gateway port&lt;/td&gt;
&lt;td&gt;18789&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gateway bind&lt;/td&gt;
&lt;td&gt;Tailnet&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gateway auth&lt;/td&gt;
&lt;td&gt;Token&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tailscale exposure&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Off&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gateway Token&lt;/td&gt;
&lt;td&gt;(Create a secure token)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Configure chat channel&lt;/td&gt;
&lt;td&gt;(Whatsapp/Telegram - your choice)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Configure Skills&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hooks&lt;/td&gt;
&lt;td&gt;Skip for Now&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Critical Warning&lt;/strong&gt;: Do NOT select "Serve" for Tailscale exposure. This bypasses complex proxy logic that causes crashes. Select "Off" - Tailscale already handles secure access.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Wait for completion. The container will start, but &lt;strong&gt;DO NOT LOGIN YET&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. The "Insecure Auth" Injection
&lt;/h3&gt;

&lt;p&gt;Here's a quirk with OpenClaw: At this stage, the bot is running but will block your browser because you're connecting over HTTP (not HTTPS). Since Tailscale already encrypts our traffic end-to-end, we can safely enable HTTP authentication.&lt;/p&gt;

&lt;p&gt;First, install &lt;code&gt;jq&lt;/code&gt; inside the container:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; root openclaw-gateway bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"apt update &amp;amp;&amp;amp; apt install -y jq"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then inject the setting:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-T&lt;/span&gt; openclaw-gateway bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'
jq ".gateway.controlUi.allowInsecureAuth = true" \
/home/node/.openclaw/openclaw.json &amp;gt; /home/node/.openclaw/tmp.json &amp;amp;&amp;amp; \
mv /home/node/.openclaw/tmp.json /home/node/.openclaw/openclaw.json'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Restart the bot to apply changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose restart
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Why is this safe?&lt;/strong&gt; We're not exposing any ports to the public internet. Traffic flows exclusively through your encrypted Tailscale tunnel. The "insecure" part only refers to HTTP vs HTTPS - and Tailscale already provides encryption.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Phase 4: Login &amp;amp; Verify
&lt;/h2&gt;

&lt;p&gt;The moment of truth. Your bot is running, security is configured, and Tailscale is connecting your devices. Let's access the interface.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Check Container Status
&lt;/h3&gt;

&lt;p&gt;Make sure the containers are healthy and staying up:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose ps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Watch it for a few seconds. If the status stays "Up" for more than 10 seconds, you're good.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Get Your Tailscale IP
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;tailscale ip &lt;span class="nt"&gt;-4&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This returns something like &lt;code&gt;100.x.x.x&lt;/code&gt; - your private Tailscale IP address.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Access the Web Interface
&lt;/h3&gt;

&lt;p&gt;On your local machine (which must also be connected to Tailscale), open your browser and navigate to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://&amp;lt;YOUR_TAILSCALE_IP&amp;gt;:18789
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example: &lt;code&gt;http://100.64.0.1:18789&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Enter the &lt;strong&gt;Gateway Token&lt;/strong&gt; you created during setup and click Connect.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Congratulations!&lt;/strong&gt; You now have a private AI assistant running on your own infrastructure, accessible only through your secure Tailscale network.&lt;/p&gt;




&lt;h2&gt;
  
  
  Phase 5: Best Practices &amp;amp; Maintenance
&lt;/h2&gt;

&lt;p&gt;Your bot is running, but a few housekeeping practices will keep it healthy and your wallet safe.&lt;/p&gt;

&lt;h3&gt;
  
  
  Set API Spend Limits
&lt;/h3&gt;

&lt;p&gt;Agentic AI can sometimes get stuck in loops and burn through API credits rapidly. Protect yourself:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to your &lt;a href="https://console.anthropic.com" rel="noopener noreferrer"&gt;Anthropic Console&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Navigate to &lt;strong&gt;Settings → Limits&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Set a hard monthly budget (e.g., $20)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Do the same for OpenAI if you configured it as a backup.&lt;/p&gt;

&lt;h3&gt;
  
  
  Enable Sandbox Mode
&lt;/h3&gt;

&lt;p&gt;In the OpenClaw configuration, ensure &lt;strong&gt;Sandbox Mode&lt;/strong&gt; is enabled if available. This restricts the bot's ability to execute unrestricted shell commands on the host system.&lt;/p&gt;

&lt;h3&gt;
  
  
  Back Up Your Bot's Memory
&lt;/h3&gt;

&lt;p&gt;OpenClaw stores its "long-term memory" in Markdown files. If you lose this directory, the bot forgets everything it knows about you.&lt;/p&gt;

&lt;p&gt;Create regular backups:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Simple backup command&lt;/span&gt;
&lt;span class="nb"&gt;tar&lt;/span&gt; &lt;span class="nt"&gt;-czvf&lt;/span&gt; memory_backup_&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; +%F&lt;span class="si"&gt;)&lt;/span&gt;.tar.gz ./openclaw/memory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Consider automating this with a cron job for daily backups.&lt;/p&gt;

&lt;h3&gt;
  
  
  Monitor Logs
&lt;/h3&gt;

&lt;p&gt;When things go sideways (and they sometimes do), logs are your best friend:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose logs &lt;span class="nt"&gt;-f&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;-f&lt;/code&gt; flag follows the log output in real-time. Press &lt;code&gt;Ctrl+C&lt;/code&gt; to exit.&lt;/p&gt;




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

&lt;p&gt;You've successfully deployed OpenClaw on a hardened EC2 instance with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Non-standard SSH port (2222) with key-only authentication&lt;/li&gt;
&lt;li&gt;Dual-layer firewall protection (AWS Security Groups + UFW)&lt;/li&gt;
&lt;li&gt;Docker containerization for clean isolation&lt;/li&gt;
&lt;li&gt;Tailscale private networking for secure, zero-trust access&lt;/li&gt;
&lt;li&gt;No public ports exposed for the application itself&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your AI assistant is now running on infrastructure you control, accessible only to devices on your private Tailnet. No VPN configurations, no exposed ports, no attack surface for the public internet to probe.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Happy building!&lt;/strong&gt;&lt;/p&gt;




</description>
      <category>openclaw</category>
      <category>ai</category>
      <category>tailscale</category>
      <category>aws</category>
    </item>
    <item>
      <title>DevOps and Cloud Engineering Roadmap 2025 🚀</title>
      <dc:creator>piyushsachdeva</dc:creator>
      <pubDate>Fri, 20 Dec 2024 15:46:03 +0000</pubDate>
      <link>https://dev.to/aws-builders/devops-and-cloud-engineering-roadmap-2025-24o</link>
      <guid>https://dev.to/aws-builders/devops-and-cloud-engineering-roadmap-2025-24o</guid>
      <description>&lt;h1&gt;
  
  
  🚀 DevOps and Cloud Engineering Roadmap 2025
&lt;/h1&gt;

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

&lt;ul&gt;
&lt;li&gt;About&lt;/li&gt;
&lt;li&gt;Learning Path&lt;/li&gt;
&lt;li&gt;Projects&lt;/li&gt;
&lt;li&gt;Resources&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🎯 About
&lt;/h2&gt;

&lt;p&gt;This repository contains a structured learning path for beginners entering the DevOps and Cloud Engineering field. The curriculum is designed for students, recent graduates, and career switchers, with an estimated completion time of 6-12 months of dedicated learning.&lt;/p&gt;

&lt;h2&gt;
  
  
  📚 Learning Path
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F30aw03u6n2b7xb7ltz3w.gif" 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%2F30aw03u6n2b7xb7ltz3w.gif" alt="roadmap" width="1173" height="904"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 1: Foundation (2-3 months)
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Linux and Shell Scripting
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Topics:&lt;/span&gt;
├── Linux Administration
|   ├── Linux Installation
│   ├── Command Line Basics
│   ├── File System Management
│   ├── Process Management
│   ├── User Administration
│   └── Package Management
└── Bash Scripting
    ├── Variables and Data Types
    ├── Control Structures
    ├── Functions
    └── Automation Scripts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Programming Foundation
&lt;/h4&gt;

&lt;p&gt;Choose one:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Python&lt;/strong&gt; (Recommended for beginners)

&lt;ul&gt;
&lt;li&gt;Basic syntax and data structures&lt;/li&gt;
&lt;li&gt;Object Oriented Programming&lt;/li&gt;
&lt;li&gt;File handling and automation&lt;/li&gt;
&lt;li&gt;API integration&lt;/li&gt;
&lt;li&gt;Libraries: requests, pandas, numpy&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Golang&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Systems programming&lt;/li&gt;
&lt;li&gt;Concurrent programming&lt;/li&gt;
&lt;li&gt;Cloud-native development&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h4&gt;
  
  
  Version Control
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Git &amp;amp; GitHub&lt;/span&gt;
├── Git Setup
├── Basic Commands
├── Branching Strategies
├── Git Flow
├── Pull Requests
├── Code Reviews
└── Collaborative Development
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Phase 2: Core IT Skills (1 month)
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Network Fundamentals
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;OSI Model - In-depth&lt;/li&gt;
&lt;li&gt;TCP/IP Protocol Suite&lt;/li&gt;
&lt;li&gt;Internet Protocols ( HTTP, HTTPS, SSH, SMTP, ICMP, etc)&lt;/li&gt;
&lt;li&gt;How to analyze network packets using tools such as Wireshark&lt;/li&gt;
&lt;li&gt;DDOS attack and how to mitigate that&lt;/li&gt;
&lt;li&gt;CIDR and Subnetting &lt;a href="https://youtu.be/G1azmL5-eQI" rel="noopener noreferrer"&gt;Video Link&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;DNS and DHCP &lt;a href="https://youtu.be/fDOoB4k4YSs" rel="noopener noreferrer"&gt;Video Link&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Vertical V/s Horizontal Scaling&lt;/li&gt;
&lt;li&gt;SSL/TLS, symmetric vs asymmetric encryption and how it works : &lt;a href="https://youtu.be/njT5ECuwCTo" rel="noopener noreferrer"&gt;Video Link&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Reverse Proxy V/s Forward Proxy V/s load balancer&lt;/li&gt;
&lt;li&gt;Troubleshooting application slowness, latency, unavailability etc&lt;/li&gt;
&lt;li&gt;RAID&lt;/li&gt;
&lt;li&gt;NAS vs SAN storage&lt;/li&gt;
&lt;li&gt;SQL vs NoSQL&lt;/li&gt;
&lt;li&gt;DB Sharding, Caching etc&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Phase 3: Cloud Computing (2-3 months)
&lt;/h3&gt;

&lt;p&gt;Choose your cloud provider:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which Cloud Provider to choose? Confused? Watch the video below and you should be good
&lt;a href="https://youtu.be/K1U137j23p8" rel="noopener noreferrer"&gt;Video link&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Cloud provider&lt;/th&gt;
&lt;th&gt;Certification type&lt;/th&gt;
&lt;th&gt;Certification&lt;/th&gt;
&lt;th&gt;Tutorials&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;AWS&lt;/td&gt;
&lt;td&gt;Foundation&lt;br&gt;Associate&lt;/td&gt;
&lt;td&gt;• AWS Certified Cloud Practitioner&lt;br&gt;• AWS Solutions Architect Associate&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Azure&lt;/td&gt;
&lt;td&gt;Foundation&lt;br&gt;Associate&lt;/td&gt;
&lt;td&gt;• AZ-900 Azure Fundamentals&lt;br&gt;• AZ-104 Azure Administrator&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.youtube.com/playlist?list=PLl4APkPHzsUUOCWcjaXcH-WBVxCccZ4uO" rel="noopener noreferrer"&gt;Playlist&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GCP&lt;/td&gt;
&lt;td&gt;Foundation&lt;br&gt;Associate&lt;/td&gt;
&lt;td&gt;• Google Cloud Digital Leader&lt;br&gt;• Associate Cloud Engineer&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.youtube.com/playlist?list=PLl4APkPHzsUXvkDFARdrH2LMESVqeuH8W" rel="noopener noreferrer"&gt;Playlist&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: Got more questions about the Cloud/DevOps Certifications? Watch the video below:&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://youtu.be/vATIASghb18" rel="noopener noreferrer"&gt;Video Link&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 4: DevOps Tools (3-4 months)
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. Containerization (Docker)
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Docker Fundamentals&lt;/span&gt;
├── Container Basics
├── Dockerfile Creation, Multi-Stage Builds
├── Image Management
├── Docker Compose
├── Container Networking
├── Docker Best Practices
└── Volume Management
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Checkout the free YouTube playlist 👉 &lt;a href="https://www.youtube.com/playlist?list=PLl4APkPHzsUUOkOv3i62UidrLmSB8DcGC" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Container Orchestration (Kubernetes)
&lt;/h4&gt;

&lt;p&gt;Checkout the free YouTube playlist 👉 &lt;a href="https://www.youtube.com/playlist?list=PLl4APkPHzsUUOkOv3i62UidrLmSB8DcGC" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  3. CI/CD Pipeline
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Jenkins ( Checkout the free Youtube video &lt;a href="https://youtu.be/To-KzPB_EnE" rel="noopener noreferrer"&gt;here&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Modern CI/CD Tools(at least one from below)

&lt;ul&gt;
&lt;li&gt;GitHub Actions&lt;/li&gt;
&lt;li&gt;Azure DevOps (Checkout the free Youtube Playlist &lt;a href="https://www.youtube.com/playlist?list=PLl4APkPHzsUXseJO1a03CtfRDzr2hivbD" rel="noopener noreferrer"&gt;here&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;GitLab CI/CD (Checkout the free Youtube video &lt;a href="https://youtu.be/uYaMRn2meJQ" rel="noopener noreferrer"&gt;here&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h4&gt;
  
  
  4. Infrastructure as Code
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Terraform&lt;/span&gt;
├── HCL Syntax
├── Resource Management
├── State Management
├── Modules
└── Cloud Provider Integration
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Checkout the free Terraform playlist &lt;a href="https://www.youtube.com/playlist?list=PLl4APkPHzsUUHlbhuq9V02n9AMLPySoEQ" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  5. Monitoring &amp;amp; Logging
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Prometheus &amp;amp; Grafana&lt;/li&gt;
&lt;li&gt;ELK Stack&lt;/li&gt;
&lt;li&gt;Fluentd&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Phase 5: 🛠️ Projects
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Check out the &lt;a href="https://github.com/piyushsachdeva/10weeksofcloudops" rel="noopener noreferrer"&gt;Repo here&lt;/a&gt; for #10weeksofcloudops projects&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  📚 Learning Resources
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Official Documentation
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.docker.com/" rel="noopener noreferrer"&gt;Docker Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kubernetes.io/docs/" rel="noopener noreferrer"&gt;Kubernetes Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.terraform.io/docs/" rel="noopener noreferrer"&gt;Terraform Docs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  YouTube Channels
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/@TechTutorialswithPiyush" rel="noopener noreferrer"&gt;Tech Tutorials With Piyush&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Practice Platforms
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.katacoda.com/" rel="noopener noreferrer"&gt;Katacoda&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://labs.play-with-docker.com/" rel="noopener noreferrer"&gt;Play with Docker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://labs.play-with-k8s.com/" rel="noopener noreferrer"&gt;Play with Kubernetes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Made with ❤️ by [Piyush Sachdeva]&lt;br&gt;
Last updated: December 2024&lt;/p&gt;

</description>
      <category>devops</category>
      <category>roadmap</category>
      <category>aws</category>
      <category>azure</category>
    </item>
    <item>
      <title>Top 3 Cloud and DevOps Projects To Supercharge Your Resume</title>
      <dc:creator>piyushsachdeva</dc:creator>
      <pubDate>Wed, 08 May 2024 05:24:54 +0000</pubDate>
      <link>https://dev.to/aws-builders/top-5-cloud-and-devops-projects-to-supercharge-your-resume-62f</link>
      <guid>https://dev.to/aws-builders/top-5-cloud-and-devops-projects-to-supercharge-your-resume-62f</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In this blog, we'll be discussing three amazing DevOps and Cloud projects that you should have in your resume, and when I say have in your resume, it doesn't mean you add in your resume. It means that you should Implement those projects by yourself, get the learning out of it, create some useful artifacts like blogs or GitHub repositories, and then you should add them to your resume so that the recruiters/hiring managers will know that these projects you have implemented by yourself.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you prefer watching a 10-minute video with all the details, you can check the below link; else, you can continue with the blog:&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/GCH33XeL_9I"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  What can you expect from this blog?
&lt;/h2&gt;

&lt;p&gt;In addition to sharing project ideas and steps, I will provide a complete end-to-end solution through blog posts, GitHub repositories, and YouTube videos. Anyone interested in implementing the solution can learn how to do so using these resources as guidance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Project 1: Static website hosting and CICD
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Difficulty Level:&lt;/strong&gt; Beginner&lt;br&gt;
&lt;strong&gt;Focus Area:&lt;/strong&gt; Cloud Storage, CDN and CICD&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Host a static website on the cloud of your choice, either AWS, Azure, or GCP, and Implement cicd on that.&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Technologies Covered 📚 ( Use either of the below options)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AWS&lt;/strong&gt;: Amazon S3, CloudFront, and Route 53&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Azure&lt;/strong&gt;: Azure Storage, Azure CDN, and DNS Management&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Google Cloud&lt;/strong&gt;: Cloud Storage, Load Balancing, and Content Delivery Networks (CDN)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Get Started 🚀
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Review the project requirements. ✔️&lt;/li&gt;
&lt;li&gt;Dive into AWS, Azure, or GCP documentation to familiarize yourself with the services mentioned. 📖&lt;/li&gt;
&lt;li&gt;Start building your architecture diagram. 🏗️&lt;/li&gt;
&lt;li&gt;Document your progress and implementation steps in a blog or GitHub Readme. 📝&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Challenges Faced&lt;/strong&gt;: Discuss any challenges you encountered and how you overcame them. 🤔&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Key Takeaways&lt;/strong&gt;: Share what you learned from this project. 🧐&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resources&lt;/strong&gt;: List any helpful resources or references you used. 📚&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Reference resources: ✅
&lt;/h3&gt;

&lt;p&gt;💡 If you are an absolute beginner to the cloud and CICD, get yourself. Familiarize with the concepts, you can refer to the below documentation and study material:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For AWS&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://docs.aws.amazon.com/AmazonS3/latest/userguide/HostingWebsiteOnS3Setup.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/AmazonS3/latest/userguide/HostingWebsiteOnS3Setup.html&lt;/a&gt;&lt;br&gt;
&lt;a href="https://docs.aws.amazon.com/AmazonS3/latest/userguide/website-hosting-cloudfront-walkthrough.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/AmazonS3/latest/userguide/website-hosting-cloudfront-walkthrough.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For Azure&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://learn.microsoft.com/en-us/azure/storage/blobs/storage-blob-static-website-how-to?tabs=azure-portal" rel="noopener noreferrer"&gt;https://learn.microsoft.com/en-us/azure/storage/blobs/storage-blob-static-website-how-to?tabs=azure-portal&lt;/a&gt;&lt;br&gt;
&lt;a href="https://learn.microsoft.com/en-us/azure/storage/blobs/storage-custom-domain-name?tabs=azure-portal" rel="noopener noreferrer"&gt;https://learn.microsoft.com/en-us/azure/storage/blobs/storage-custom-domain-name?tabs=azure-portal&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For GCP&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://cloud.google.com/storage/docs/hosting-static-website" rel="noopener noreferrer"&gt;https://cloud.google.com/storage/docs/hosting-static-website&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.cloudskillsboost.google/focuses/1251?parent=catalog" rel="noopener noreferrer"&gt;https://www.cloudskillsboost.google/focuses/1251?parent=catalog&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  If you are a visual learner, feel free to check out the video solution
&lt;/h2&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/UVvc_RtOoWg"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture Diagram for AWS by Ankit
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fpiyushsachdeva%2F10weeksofcloudops%2Fassets%2F40286378%2F1c645259-3075-4b4a-9d63-eb5bf9065f65" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fpiyushsachdeva%2F10weeksofcloudops%2Fassets%2F40286378%2F1c645259-3075-4b4a-9d63-eb5bf9065f65" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Blog containing step-by-step instructions for AWS
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://ankitjodhani.hashnode.dev/host-your-static-website-on-amazon-s3-services-cicd-pipeline-with-the-domain-name-and-ssl-certificate-10weeksofcloudops" rel="noopener noreferrer"&gt;Blog by Ankit&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture Diagram for Azure by Nishant
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fpiyushsachdeva%2F10weeksofcloudops%2Fassets%2F40286378%2F7b646161-7a81-4113-bbfe-2fe547f463dd" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fpiyushsachdeva%2F10weeksofcloudops%2Fassets%2F40286378%2F7b646161-7a81-4113-bbfe-2fe547f463dd" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Blog By Nishant containing the step-by-step instructions for Azure
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://nishantsingh.hashnode.dev/10weeksofcloudops-firstweek" rel="noopener noreferrer"&gt;Blog by Nishant&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Project #2: 3-tier architecture
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Difficulty Level:&lt;/strong&gt; Intermediate&lt;br&gt;
&lt;strong&gt;Focus Area&lt;/strong&gt;: Cloud Infrastructure, Networking, 3-tier application&lt;/p&gt;

&lt;p&gt;For this project, your objective is to design a 3-tier architecture in a cloud platform, such as AWS, Azure, or GCP, with a focus on the following key considerations:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;High Availability&lt;/strong&gt;: Ensure your architecture is highly available, capable of withstanding failures, and can provide uninterrupted service.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Scalability&lt;/strong&gt;: Design your architecture to be highly scalable, allowing for easy and efficient resource scaling as your application's demands increase.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Fault Tolerance&lt;/strong&gt;: Implement fault-tolerant mechanisms to minimize downtime and service interruptions during failures.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Custom VPC/VNET&lt;/strong&gt;: Consider using a custom Virtual Private Cloud (VPC) for AWS or GCP, a Virtual Network (VNET) for Azure, or a similar network customization instead of relying on the default configurations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Security&lt;/strong&gt;: Prioritize security by adhering to best practices for Identity and Access Management (IAM) and implementing robust security measures.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;Your design should consider these considerations, resulting in a well-structured, efficient, and secure 3-tier architecture.&lt;br&gt;
You can use your chosen cloud platform to implement this architecture effectively.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  Reference resources: ✅
&lt;/h3&gt;

&lt;p&gt;💡 To ensure you're ready to take on this challenge, it's essential to have a solid understanding of networking concepts. Check out the following resources for guidance:&lt;/p&gt;

&lt;p&gt;👉 AWS: &lt;a href="https://youtu.be/yUhzvVrwkV8?si=CZs9EllFW8Lp3G17" rel="noopener noreferrer"&gt;Click Here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👉 Azure: &lt;a href="https://youtu.be/fzaWF9OzkRs" rel="noopener noreferrer"&gt;Click Here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👉 GCP: &lt;a href="https://youtu.be/XLaFU1t9pM8" rel="noopener noreferrer"&gt;Click Here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🚀IP address calculation/CIDR and Subnet Masks: &lt;a href="https://youtu.be/G1azmL5-eQI" rel="noopener noreferrer"&gt;Click here&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  If you are a video person, feel free to check out the below video for end to end solution:👇
&lt;/h3&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/amiIcyt-J2A"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  Architecture Diagram for AWS
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Faws-samples%2Faws-three-tier-web-architecture-workshop%2Fblob%2Fmain%2Fapplication-code%2Fweb-tier%2Fsrc%2Fassets%2F3TierArch.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Faws-samples%2Faws-three-tier-web-architecture-workshop%2Fblob%2Fmain%2Fapplication-code%2Fweb-tier%2Fsrc%2Fassets%2F3TierArch.png%3Fraw%3Dtrue" alt="Architecture"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/aws-samples/aws-three-tier-web-architecture-workshop/blob/main/application-code/web-tier/src/assets/3TierArch.png" rel="noopener noreferrer"&gt;Image Source&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture Diagram for Azure
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fthakurnishu%2F10_Weeks_Of_CloudOps%2Fblob%2Fweek2%2Fapplication-code%2Fweb-tier%2Fsrc%2Fassets%2F3TierArch.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fthakurnishu%2F10_Weeks_Of_CloudOps%2Fblob%2Fweek2%2Fapplication-code%2Fweb-tier%2Fsrc%2Fassets%2F3TierArch.png%3Fraw%3Dtrue" alt="Architecture"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/thakurnishu/10_Weeks_Of_CloudOps/tree/week2" rel="noopener noreferrer"&gt;Image Source&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Detailed workshop for AWS with step-by-step instructions:
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://catalog.us-east-1.prod.workshops.aws/workshops/85cd2bb2-7f79-4e96-bdee-8078e469752a/en-US" rel="noopener noreferrer"&gt;Workshop link&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Detailed blog for Azure for step-by-step instructions
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://nishantsingh.hashnode.dev/10weeksofcloudops-secondweek" rel="noopener noreferrer"&gt;Blog by Nishant Singh&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Project 3: Implement a 2-tier architecture in AWS, Azure, or GCP using Terraform 🚀
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Difficulty Level:&lt;/strong&gt; Intermediate&lt;br&gt;
&lt;strong&gt;Focus Area:&lt;/strong&gt; Iac using Terraform, Custom modules, Infrastructure.&lt;/p&gt;

&lt;p&gt;This project aims to leverage the best practices of infrastructure as code (IaC) to create a reusable and shareable infrastructure setup. Our focus is on promoting modularity, flexibility, and maintainability.&lt;/p&gt;
&lt;h2&gt;
  
  
  Key Guidelines
&lt;/h2&gt;
&lt;h3&gt;
  
  
  1. Leverage Custom Modules
&lt;/h3&gt;

&lt;p&gt;Build custom modules to break your infrastructure code into reusable and shareable components. This approach organizes your code and allows other team members to incorporate and adapt the components easily for their specific needs.&lt;/p&gt;
&lt;h3&gt;
  
  
  2. Use Variables and Data Sources
&lt;/h3&gt;

&lt;p&gt;Please implement variables and data sources in your IaC code to enhance flexibility and maintainability. Variables make it easier to adapt and modify configuration settings, while data sources allow you to retrieve information from external sources to inform your infrastructure.&lt;/p&gt;
&lt;h3&gt;
  
  
  3. Remote State File
&lt;/h3&gt;

&lt;p&gt;You can store your state file remotely. This practice enhances collaboration, security, and version control of your IaC code. Consider using your infrastructure's remote state storage service, such as Terraform Cloud or AWS S3.&lt;/p&gt;
&lt;h3&gt;
  
  
  4. Security First
&lt;/h3&gt;

&lt;p&gt;Keep security in mind throughout your IaC development. Ensure your infrastructure is configured with appropriate security measures and adhere to best practices for secure and compliant deployments.&lt;/p&gt;
&lt;h2&gt;
  
  
  If you are a visual learner, feel free to check out the video solution
&lt;/h2&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/s8q5B6DLH7s"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Repository containing the code for AWS Terraform 👉&lt;a href="https://github.com/piyushsachdeva/10WeeksOfCloudOps_Task3/blob/main/README.md" rel="noopener noreferrer"&gt;Click here&lt;/a&gt;👈
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Architecture Diagram for AWS by Mahesh Upreti
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fmahupreti%2FKeeping-it-DRY-with-reusable-Terraform-modules-in-the-AWS-cloud%2Fblob%2Fmain%2F2tier-web-application-architecture.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fmahupreti%2FKeeping-it-DRY-with-reusable-Terraform-modules-in-the-AWS-cloud%2Fblob%2Fmain%2F2tier-web-application-architecture.png%3Fraw%3Dtrue" alt="Diagram by Mahesh"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Blog containing step-by-step instructions for AWS
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://mupreti.hashnode.dev/keeping-it-dry-with-reusable-terraform-modules-in-the-aws-cloud" rel="noopener noreferrer"&gt;Blog by Mahesh Upreti&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture Diagram for Azure by Joel
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FJoelayo%2FWeek-3_Azure_CloudOps%2Fblob%2Fmain%2Farchitecture.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FJoelayo%2FWeek-3_Azure_CloudOps%2Fblob%2Fmain%2Farchitecture.png%3Fraw%3Dtrue" alt="Diagram by Joel"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Blog containing the step-by-step instructions for Azure
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/Joelayo/Week-3_Azure_CloudOps" rel="noopener noreferrer"&gt;Blog by Joel&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>devops</category>
      <category>cloud</category>
      <category>kubernetes</category>
    </item>
    <item>
      <title>AWS Networking - AWS VPC, Subnets, Security Groups, NAT Gateway &amp; IP Addresses</title>
      <dc:creator>piyushsachdeva</dc:creator>
      <pubDate>Wed, 22 Feb 2023 21:21:59 +0000</pubDate>
      <link>https://dev.to/aws-builders/aws-networking-aws-vpc-subnets-security-groups-nat-gateway-ip-addresses-4p8c</link>
      <guid>https://dev.to/aws-builders/aws-networking-aws-vpc-subnets-security-groups-nat-gateway-ip-addresses-4p8c</guid>
      <description>&lt;p&gt;AWS Networking can be a complicated topic, but it's an essential part of building and managing resources on the AWS Cloud. In this comprehensive guide, we'll take a deep dive into the key components of AWS Networking and explore everything you need to know to get started.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;let the game begins...&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Virtual Private Clouds (VPCs)&lt;/strong&gt;&lt;br&gt;
At the heart of AWS Networking is the Virtual Private Cloud (VPC). A VPC is a virtual network that enables you to launch AWS resources into a virtual network that you define.It provides you with complete control over your virtual networking environment, including the selection of IP address ranges, subnets, and configuration of route tables and network gateways.&lt;/p&gt;

&lt;p&gt;Let's look at each of these component in detail.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Resources that you create in AWS resides pysically in one or more &lt;strong&gt;Data Centres&lt;/strong&gt; usually 100 miles apart from each other.&lt;/li&gt;
&lt;li&gt;Collection of multiple data centres are referred to as an &lt;strong&gt;Availability Zone&lt;/strong&gt; such as ca-central-1a , ca-central1b.&lt;/li&gt;
&lt;li&gt;Collection of multiple Availability zones in a geographical location is referred to as an *&lt;em&gt;AWS Region&lt;/em&gt; such as ca-central-1.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Below diagram shows an AWS Region(ca-central-1) that consists of two Availability Zones (ca-central-1a and ca-central-1b) that are part of VPC A with the CIDR range(10.0.0.0/16)&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%2F23gm5fo3e5hs33n7tfn9.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%2F23gm5fo3e5hs33n7tfn9.png" alt=" " width="800" height="454"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Subnets&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A subnetwork or subnet is a logical subdivision of an IP network.&lt;br&gt;
It further divides a VPC into multiple small networks so that they can be managed seperately.&lt;br&gt;
The practice of dividing a network into two or more networks is called subnetting.&lt;/p&gt;

&lt;p&gt;For example, a VPC having &lt;strong&gt;10.0.0.0/16 = 65,536&lt;/strong&gt; IPs can be broken down into 4 subnets:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;10.0.1.0/24 = 256 IPs&lt;/li&gt;
&lt;li&gt;10.0.2.0/24 = 256 IPs&lt;/li&gt;
&lt;li&gt;10.0.3.0/24 = 256 IPs&lt;/li&gt;
&lt;li&gt;10.0.4.0/24 = 256 IPs&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;5 IPs per CIDR are reserved by AWS and rest of them will be available for further use.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Types of Subnets:&lt;/strong&gt;&lt;br&gt;
There are two types of subnets: Private and Public.&lt;br&gt;
&lt;strong&gt;Public Subnets&lt;/strong&gt;: If you want your instance in a public subnet to communicate with the internet then you use public subnet. Generally, web facing instances are placed in Public subnets.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Private Subnet:&lt;/strong&gt; If a subnet doesn't have a route to the internet gateway, the subnet is known as a private subnet.&lt;br&gt;
Generally, your DB servers are places in private subnets.&lt;/p&gt;

&lt;p&gt;In the below diagram, we have added 1 Public and 1 Private subnet in each of the Availability zones. &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%2Fok8lmpwpv3cequmknwlx.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%2Fok8lmpwpv3cequmknwlx.png" alt=" " width="800" height="492"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Internet Gateway&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Internet Gateway allows communication between your VPC and the internet. Only one IGW can be attached to one VPC and vice-versa.&lt;/p&gt;

&lt;p&gt;In the below diagram, we have attached Internet Gateway to the VPC.&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%2F58xftnx2yei5ffpcp0qj.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%2F58xftnx2yei5ffpcp0qj.png" alt=" " width="800" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Internet gateway&lt;/strong&gt; itself doesn’t provide access to the internet&lt;br&gt;
&lt;strong&gt;Route table&lt;/strong&gt; must be associated with the subnets and routes should be defined.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A route table contains a set of rules, called &lt;strong&gt;routes&lt;/strong&gt;, that are used to determine where network traffic from your subnet or gateway is directed.&lt;/p&gt;

&lt;p&gt;Public Subnet should have a route to the internet gateway while , Private subnet should have a route to the local network. As shown in the below diagram:&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%2Fepm5ukaid2qsxhkjuvs0.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%2Fepm5ukaid2qsxhkjuvs0.png" alt=" " width="800" height="344"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After attaching the route tables with the subnets, our diagram will look something like below&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%2Fcieki3gknfpp34k9ke50.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%2Fcieki3gknfpp34k9ke50.png" alt=" " width="800" height="499"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, lets talk about another important feature of VPC: &lt;br&gt;
&lt;strong&gt;Security Groups&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A security group acts as a virtual firewall for your EC2 instances to control incoming and outgoing traffic.&lt;/li&gt;
&lt;li&gt;Inbound rules control the incoming traffic to your instance, and outbound rules control the outgoing traffic from your instance.&lt;/li&gt;
&lt;li&gt;In the rules, you define, what type of traffic is allowed/denied from which source. e.g allow http traffic from 0.0.0.0 to the EC2.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once you attach these security groups with your EC2 instances, the diagram will look something like below:&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%2F200w7qz0d4p9oh51yv2f.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%2F200w7qz0d4p9oh51yv2f.png" alt=" " width="800" height="501"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NACL(Network Access Control List)&lt;/strong&gt; :&lt;br&gt;
Like Security groups acts as a firewall on EC2/host level, NACL or Network Access control list acts as an additional layer of firewall on subnet level.&lt;/p&gt;

&lt;p&gt;Default NACL allows all inbound and outbound traffic to your subnets.You can create a custom network ACL and associate it with a subnet.&lt;br&gt;
A network ACL contains rules and a priority assigned to each rule, rules are evaluated based&lt;br&gt;
on their priority, lower the number, higher the priority.&lt;/p&gt;

&lt;p&gt;Below is a sample NACL Rule:&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%2Frfa4ticwhrpm9n0xp3x5.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%2Frfa4ticwhrpm9n0xp3x5.png" alt=" " width="800" height="295"&gt;&lt;/a&gt;&lt;br&gt;
After adding the NACL rules to your subnets, our diagram will look something like below:&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%2F29ord1e6c8cridu0euy3.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%2F29ord1e6c8cridu0euy3.png" alt=" " width="800" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, there are a lot of usecases where your instances in private subnet needs access to the internet. For instance, Database instance needs regular updates/patching to be done by downloading updates from the internet. This can be done securely using &lt;strong&gt;NAT Gateway&lt;/strong&gt; which allows instances in the private subnet to connect to the internet via a secure route.&lt;/p&gt;

&lt;p&gt;Nat Gateways should be launched in Public Subnets (One per AZ). Something like below:&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%2F6yaqkc3h4ngf81cwirzw.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%2F6yaqkc3h4ngf81cwirzw.png" alt=" " width="800" height="491"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br&gt;
AWS Networking can be a complicated topic, but by following best practices and using the tools provided by AWS, you can build a secure and efficient network for your resources.&lt;/p&gt;

&lt;p&gt;Want to see all the networking components with detailed explanation? Check out the below tutorial for the same:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/yUhzvVrwkV8"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;References 📚:&lt;br&gt;
&lt;a href="https://docs.aws.amazon.com/vpc/latest/userguide/amazon-vpc-limits.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/vpc/latest/userguide/amazon-vpc-limits.html&lt;/a&gt;&lt;br&gt;
&lt;a href="https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Subnets.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Subnets.html&lt;/a&gt;&lt;br&gt;
&lt;a href="https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-security-groups.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-security-groups.html&lt;/a&gt;&lt;br&gt;
&lt;a href="https://docs.aws.amazon.com/vpc/latest/userguide/vpc-network-acls.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/vpc/latest/userguide/vpc-network-acls.html&lt;/a&gt;&lt;br&gt;
&lt;a href="https://aws.amazon.com/about-aws/global-infrastructure/" rel="noopener noreferrer"&gt;https://aws.amazon.com/about-aws/global-infrastructure/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://docs.aws.amazon.com/vpc/latest/userguide/default-vpc.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/vpc/latest/userguide/default-vpc.html&lt;/a&gt;&lt;br&gt;
&lt;a href="https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-instance-addressing.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-instance-addressing.html&lt;/a&gt;&lt;/p&gt;

</description>
      <category>refactor</category>
      <category>softwareengineering</category>
      <category>cleancode</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Boost Your Productivity with ChatGPT - A Tutorial for DevOps/Cloud</title>
      <dc:creator>piyushsachdeva</dc:creator>
      <pubDate>Fri, 17 Feb 2023 03:03:09 +0000</pubDate>
      <link>https://dev.to/aws-builders/boost-your-productivity-with-chatgpt-a-tutorial-for-devopscloud-1aad</link>
      <guid>https://dev.to/aws-builders/boost-your-productivity-with-chatgpt-a-tutorial-for-devopscloud-1aad</guid>
      <description>&lt;p&gt;If you’re an IT professional or a student, you must have come across the term *&lt;em&gt;ChatGPT *&lt;/em&gt; at least once in the past few months. ChatGPT is an AI-based tool that allows users to have conversations and answer queries similar to that of a human being. The goal is to make it easier for people to communicate with computers and access information effortlessly. With its rising popularity, ChatGPT has become a vital tool in the field of DevOps and Cloud computing. In this tutorial, we will discuss how ChatGPT can help boost your productivity exponentially.&lt;/p&gt;

&lt;p&gt;To get started, sign up for the free version of ChatGPT. The user-friendly interface is similar to that of a phone’s messaging application.&lt;/p&gt;

&lt;p&gt;Simply visit the URL : &lt;a href="https://chat.openai.com/"&gt;https://chat.openai.com/&lt;/a&gt; aand signup using your email account. Once logged in, it will look something like below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbzr1vzxv70bf3mxqgmne.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbzr1vzxv70bf3mxqgmne.png" alt="Image description" width="800" height="727"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;you can ask ChatGPT to generate prompts, and it will provide you with a list of results. For example, if you’re a beginner in DevOps, you can ask ChatGPT to provide you with sample web applications that you could use in your CI/CD project.&lt;/p&gt;

&lt;p&gt;As soon as you hit enter, it will generate the results similar to below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftj995sc5pkwhd1rz1oi6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftj995sc5pkwhd1rz1oi6.png" alt="Image description" width="800" height="463"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you’re a beginner and looking for more ideas, you can ask ChatGPT to generate more ideas by entering the prompt as below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqwpb49r2tw9epqdc7et1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqwpb49r2tw9epqdc7et1.png" alt="Image description" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you think that this is not ideal for a beginner in programming, you can enter another prompt to generate ideas for a beginner in coding as below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4k94dboyp24yds3no9a5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4k94dboyp24yds3no9a5.png" alt="Image description" width="800" height="482"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that we have a lot of beginner friendly project ideas, let's pick one from the list and start working on that.For Instance, I have chosen : A simple calculator app.&lt;/p&gt;

&lt;p&gt;You can prompt chatGPT to generate the code in any specific programming language or let it choose the language for you. Code generate by ChatGPT is not always 100% accurate but you can quickly fix that if you know code debugging a little bit. Below are the results:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fya3i2khattewfx51et7d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fya3i2khattewfx51et7d.png" alt="Image description" width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you have the code, you can prompt ChatGPT to dockerize the web application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4ml0z42bxgx8y603efuv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4ml0z42bxgx8y603efuv.png" alt="Image description" width="800" height="698"&gt;&lt;/a&gt;&lt;br&gt;
It would have generated the dockerfile along with the steps to build the image and deploy the container.&lt;/p&gt;

&lt;p&gt;Now you can take the usecase one step further and prompt ChatGPT to create a Jenkins CI CD pipeline using the above details.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu242zre37lmy7bcw3jmo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu242zre37lmy7bcw3jmo.png" alt="Image description" width="800" height="665"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The same way, it has generate the pipeline code along with all the prerequisites steps and details of each line of the code. Pretty Neat Eh!&lt;/p&gt;

&lt;p&gt;You can perform a lot more tasks such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Generating documentation&lt;/li&gt;
&lt;li&gt;Adding comments in your code using prompt&lt;/li&gt;
&lt;li&gt;convert code from one language to another&lt;/li&gt;
&lt;li&gt;generate readme file for your application code&lt;/li&gt;
&lt;li&gt;troubleshooting the issue by pasting errors as a prompt
and the usecases are numerous.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're interested in improving your productivity using ChatGPT, be sure to check out the full tutorial for DevOps/Cloud on YouTube! 🎥👨‍💻&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/X6FMEZhbQ1o"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>ai</category>
      <category>devops</category>
      <category>cloud</category>
    </item>
    <item>
      <title>Introducing the AWS Transfer Family Service</title>
      <dc:creator>piyushsachdeva</dc:creator>
      <pubDate>Sun, 08 Jan 2023 04:26:12 +0000</pubDate>
      <link>https://dev.to/aws-builders/introducing-the-aws-transfer-family-service-4p8</link>
      <guid>https://dev.to/aws-builders/introducing-the-aws-transfer-family-service-4p8</guid>
      <description>&lt;p&gt;&lt;strong&gt;Are you tired of slow, insecure data transfer processes? 💤 The AWS Transfer Family is here to help!&lt;/strong&gt; 🚀&lt;/p&gt;

&lt;p&gt;&lt;u&gt;What is the AWS Transfer Family&lt;/u&gt;, you ask? It's a group of services that enables you to quickly and securely move data to and from the cloud. 🌩️ The family includes AWS Transfer for SFTP, AWS Transfer for FTP, and AWS Transfer for FTPS.&lt;/p&gt;

&lt;p&gt;But what makes the AWS Transfer Family so great? 🤔 For starters, it's &lt;strong&gt;super easy to use&lt;/strong&gt;. Setting up and managing your data transfer process is a breeze, thanks to the &lt;strong&gt;user-friendly interface&lt;/strong&gt; and &lt;strong&gt;integration with other AWS services&lt;/strong&gt; such as Amazon S3 and Amazon EC2. 💻 This saves you time and resources, so you can focus on running your business.&lt;/p&gt;

&lt;p&gt;But that's not all! The AWS Transfer Family is also extremely &lt;strong&gt;secure&lt;/strong&gt;. 🔒 All data transfer activities are encrypted, ensuring that your sensitive information is always protected. Plus, you have the option to enable &lt;strong&gt;multifactor authentication&lt;/strong&gt; for an extra layer of security. 🛡️&lt;/p&gt;

&lt;p&gt;But how does it all work? 🤔 It's actually quite simple. First, you choose the service that best fits your needs - SFTP, FTP, or FTPS. Next, you set up your server and configure your data transfer process, including the location of your Amazon S3 bucket. Finally, you can test your data transfer by uploading and downloading files to and from your S3 bucket. 📤📥&lt;/p&gt;

&lt;p&gt;Checkout this cool animated video to see how it works!&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/or7WC2SuECM"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Want to see the AWS Transfer Family in action? 💪 Check out our demo of how to set up an SFTP server and test the data transfer process:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/ln3Dcm6g9Tw"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;And that's it! You've successfully set up an SFTP server using AWS Transfer Family and tested the data transfer process. 🎉 As you can see, it's a quick and easy way to move data to and from the cloud. 🌩️ So why not give the AWS Transfer Family a try today? 🚀&lt;/p&gt;

&lt;p&gt;🙏Thank you for following along with the tutorial so far. If you found this blog to be helpful, please be sure to follow me and consider subscribing to my YouTube channel. Good luck 👍 on your cloud journey!&lt;/p&gt;

</description>
      <category>ai</category>
      <category>chatgpt</category>
      <category>discuss</category>
    </item>
    <item>
      <title>How To Install Multiple Gitlab Runners On a Single AWS EC2 machine</title>
      <dc:creator>piyushsachdeva</dc:creator>
      <pubDate>Mon, 05 Dec 2022 17:19:52 +0000</pubDate>
      <link>https://dev.to/aws-builders/how-to-install-multiple-gitlab-runners-on-a-single-aws-ec2-machine-api</link>
      <guid>https://dev.to/aws-builders/how-to-install-multiple-gitlab-runners-on-a-single-aws-ec2-machine-api</guid>
      <description>&lt;p&gt;&lt;strong&gt;In this quick tutorial, I am going to show you how you can install multiple Gitlab Runners on a single AWS EC2 machine.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Provision a EC2 server&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Login to you AWS console--&amp;gt; EC2 --&amp;gt; Hit launch instances&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxkgtfu9ilr5wykev14pr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxkgtfu9ilr5wykev14pr.png" alt="Launch Instance"&gt;&lt;/a&gt;&lt;br&gt;
Give it a name such as Gitlab-Runner and select a suitable Linux Image. In this demo, I have selected an Ubuntu image&lt;/p&gt;

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

&lt;p&gt;Then scroll down and select the key-pair that you would want to use for this instance or you can create a new key-pair. Once the key-pair is selected, you can create a new security group with the wizard and open access to port 22(SSH) from your local machine or a CIDR range and for your application server so that gitlab runner can ssh into your application server for code deployment. You can optionally use an existing security group as well.&lt;/p&gt;

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

&lt;p&gt;Scroll down to the advance details section and keep everything as default except the user data section. Add the below user data script and hit Launch instance.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

#!/bin/bash
sudo apt-get update -y
curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh" | sudo bash

sudo apt-get install gitlab-runner -y

#install docker 
curl -fsSL https://get.docker.com -o get-docker.sh 
sudo bash get-docker.sh

cd /var/run/ 
sudo chmod 777 docker.pid docker.sock



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

&lt;/div&gt;
&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwutddjsollyh97g8bqhf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwutddjsollyh97g8bqhf.png" alt="User data script"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 2
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Register the Runner&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once server is running, login to the server using EC2 instance connect or ssh client such as Putty and enter the command&lt;/p&gt;

&lt;p&gt;&lt;code&gt;gitlab-runner register&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;then enter your gitlab running when prompted&lt;/p&gt;

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

&lt;p&gt;Go to your Gitlab UI --&amp;gt; Settings --&amp;gt; CICD and Expand the section in front of Runners&lt;/p&gt;

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

&lt;p&gt;Copy the registration token from here and paste the same in the terminal prompt&lt;/p&gt;

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

&lt;p&gt;Enter the details as below to register the runner&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Start the Runner&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start the runner using the below command:
&lt;code&gt;sudo gitlab-runner start&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;once it is started, hit refresh on the Gitlab page and you would see the runner as active&lt;/p&gt;

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

&lt;p&gt;Give yourself a pat on the back! you were able to perform the task successfully!&lt;/p&gt;
&lt;h2&gt;
  
  
  Step4
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Register second runner(Optional)&lt;/strong&gt;&lt;br&gt;
Now , if you would like to register multiple runners on the same ec2 server, using can do so by following the same method. Give a different name and tag to the runner as follows&lt;/p&gt;

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

&lt;p&gt;Now, refresh the page to see the new runner as well&lt;/p&gt;

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

&lt;p&gt;You can use the runners based on the tags or the names.&lt;/p&gt;

&lt;p&gt;That's all folks. If you have enjoyed the blog and learned something new today. Feel free to hit the like button and follow me for more such content.&lt;/p&gt;

&lt;p&gt;I have also published a full end to end tutorial for Gitlab CI CD Pipeline, feel free to check that out using the below link&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/uYaMRn2meJQ"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>gitlab</category>
      <category>cicd</category>
      <category>aws</category>
      <category>ec2</category>
    </item>
    <item>
      <title>How To Mount AWS S3 Bucket On Amazon EC2 Linux Using S3FS</title>
      <dc:creator>piyushsachdeva</dc:creator>
      <pubDate>Wed, 31 Aug 2022 17:16:21 +0000</pubDate>
      <link>https://dev.to/aws-builders/how-to-mount-aws-s3-bucket-on-amazon-ec2-using-s3fs-1h8h</link>
      <guid>https://dev.to/aws-builders/how-to-mount-aws-s3-bucket-on-amazon-ec2-using-s3fs-1h8h</guid>
      <description>&lt;p&gt;&lt;strong&gt;In this blog, we will learn how to use S3 as a filesystem on EC2 Linux machine.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let's start!&lt;/p&gt;

&lt;p&gt;1) Create an EC2 Linux (I have used Ubuntu in this demo) instance&lt;/p&gt;

&lt;p&gt;Keep everything as default and add the below user data script to install awscli and s3fs utlity from advance section of wizard&lt;/p&gt;

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

sudo apt-get update -y
sudo apt-get install awscli -y
sudo apt-get install s3fs -y


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

&lt;/div&gt;

&lt;p&gt;2) Create an IAM user for s3fs&lt;/p&gt;

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

&lt;p&gt;3) Give the user a unique name and enable programmatic access&lt;/p&gt;

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

&lt;p&gt;Set permission --&amp;gt; create a new policy&lt;/p&gt;

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

&lt;p&gt;Select the service as S3 and include below access levels&lt;/p&gt;

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

&lt;p&gt;Give the policy a unique name and click Create policy&lt;/p&gt;

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

&lt;p&gt;Once the policy is created, go back to the IAM tab and hit refresh so that newly created policy is included in the list&lt;br&gt;
, filter by policy name and hit the enable checkbox to add the policy to our IAM user.&lt;/p&gt;

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

&lt;p&gt;Hit create user&lt;/p&gt;

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

&lt;p&gt;Once the user is created, download the credentials. We are going to use it later.&lt;/p&gt;

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

&lt;p&gt;4) Login to your Ec2 Instance&lt;/p&gt;

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

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

&lt;p&gt;Go to your home directory and run below commands to create a new directory and to generate some sample files&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

mkdir /home/ubuntu/bucket; cd $HOME/bucket ;touch test1.txt test2.txt test3.txt



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

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

&lt;p&gt;Next step is to create an S3 bucket.&lt;br&gt;
5) Go to S3 service and create a new bucket&lt;/p&gt;

&lt;p&gt;give it a unique name and leave reast of the settings as default. &lt;br&gt;
Block public access to this bucket should be enabled by default&lt;/p&gt;

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

&lt;p&gt;Hit create bucket.&lt;/p&gt;

&lt;p&gt;6) Once the bucket is created, go to the ssh session and configure our AWS credentails for authentication using the IAM account that we have created.&lt;/p&gt;

&lt;p&gt;Use the command&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

aws configure



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

&lt;/div&gt;
&lt;p&gt;and provide the credential details that we have downloaded before&lt;/p&gt;

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

&lt;p&gt;7) Now run the below command to sync local directory with the S3 bucket&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

aws s3 sync path_on_filesystem s3://bucketname



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

&lt;/div&gt;
&lt;p&gt;For example,&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

aws s3 sync /home/ubuntu/bucket s3://test-s3fs-101



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

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

&lt;p&gt;8) create the credential file for s3fs&lt;/p&gt;

&lt;p&gt;s3fs supports the standard AWS credentials file stored in ${HOME}/.aws/credentials. Alternatively, s3fs supports a custom passwd file.&lt;br&gt;
The default location for the s3fs password file can be created:&lt;br&gt;
using a .passwd-s3fs file in the users home directory (i.e. ${HOME}/.passwd-s3fs)&lt;/p&gt;

&lt;p&gt;file should have the below content:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

$AWS_ACCESS_KEY_ID:$AWS_SECRET_KEY_ID



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

&lt;/div&gt;
&lt;p&gt;You can run the below command as well:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

echo "AKIAQSCIQUH6XXYQMGDA:T5qM7rZmSaU3p/Y0xmuZyWv1/KUnT0Oc58sdCJ3t" &amp;gt; ${HOME}/.passwd-s3fs;
chmod 600 ${HOME}/.passwd-s3fs



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

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

&lt;p&gt;9) Now you can run the command to mount S3 bucket as a filesystem&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

sudo s3fs bucketname path  -o passwd_file=$HOME/.passwd-s3fs,nonempty,rw,allow_other,mp_umask=002,uid=$UID,gid=$UID -o url=http://s3.aws-region.amazonaws.com
,endpoint=aws-region1,use_path_request_style


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

&lt;/div&gt;
&lt;p&gt;for example:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

sudo s3fs s3fs-test-101 /home/ubuntu/bucket  -o passwd_file=$HOME/.passwd-s3fs,nonempty,rw,allow_other,mp_umask=002,uid=1000,gid=1000 -o url=http://s3.ca-central-1.amazonaws.com
,endpoint=ca-central-1,use_path_request_style


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

&lt;/div&gt;
&lt;p&gt;10) Once it is mounted successfully, you can verify by running the command &lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

mount|grep s3fs


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

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

&lt;p&gt;11) Add the entry in fstab using the below command so that the changes become persistent after the server reboot as well:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

bucketname directoryonfs fuse.s3fs _netdev,allow_other 0 0


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

&lt;/div&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

s3fs-test-101 /home/ubuntu/bucket fuse.s3fs _netdev,allow_other 0 0


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

&lt;/div&gt;
&lt;p&gt;12) Now the moment of truth, go to your S3 bucket and hit refresh, you should see the files that were present in your file system&lt;/p&gt;

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

&lt;p&gt;13) Let's now verify whether it's getting synced properly after a object delete/addition&lt;/p&gt;

&lt;p&gt;Go to your S3 bucket, and upload a new file&lt;/p&gt;

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

&lt;p&gt;Go to your ssh session and do ls in the same directory&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Eureka! The file that you just uploaded in your S3 bucket appears in your FileSystem.&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Same way you can test the delete file operation. And it works both ways i.e if you perform any file operation on your filesystem, it will sync to your S3 bucket as well.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Feel free to checkout the below hands-on demo of what we have learned so far:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/Qd85rhuFvqs"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;References:&lt;br&gt;
&lt;a href="https://github.com/s3fs-fuse/s3fs-fuse" rel="noopener noreferrer"&gt;https://github.com/s3fs-fuse/s3fs-fuse&lt;/a&gt;&lt;br&gt;
&lt;a href="https://aws.amazon.com/" rel="noopener noreferrer"&gt;https://aws.amazon.com/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://docs.aws.amazon.com/cli/latest/reference/s3/sync.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/cli/latest/reference/s3/sync.html&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Limitations
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Generally S3 cannot offer the same performance or semantics as a local file system. More specifically:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;random writes or appends to files require rewriting the entire object, optimized with multi-part upload copy&lt;/li&gt;
&lt;li&gt;metadata operations such as listing directories have poor performance due to network latency&lt;/li&gt;
&lt;li&gt;non-AWS providers may have eventual consistency so reads can temporarily yield stale data (AWS offers read-after-write consistency since Dec 2020)&lt;/li&gt;
&lt;li&gt;no atomic renames of files or directories&lt;/li&gt;
&lt;li&gt;no coordination between multiple clients mounting the same bucket&lt;/li&gt;
&lt;li&gt;no hard links
inotify detects only local modifications, not external ones by other clients or tools&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>s3</category>
      <category>aws</category>
      <category>amazonec2</category>
      <category>ec2</category>
    </item>
  </channel>
</rss>
