<?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: Semih ERDOGAN</title>
    <description>The latest articles on DEV Community by Semih ERDOGAN (@semiherdogan).</description>
    <link>https://dev.to/semiherdogan</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3918052%2Fd806d51a-71a1-49fd-ab25-f6f49f46936e.jpeg</url>
      <title>DEV Community: Semih ERDOGAN</title>
      <link>https://dev.to/semiherdogan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/semiherdogan"/>
    <language>en</language>
    <item>
      <title>Cloudflare Tunnel, Traefik, and a Cleaner Self-Hosted Setup</title>
      <dc:creator>Semih ERDOGAN</dc:creator>
      <pubDate>Thu, 07 May 2026 13:26:01 +0000</pubDate>
      <link>https://dev.to/semiherdogan/cloudflare-tunnel-traefik-and-a-cleaner-self-hosted-setup-546l</link>
      <guid>https://dev.to/semiherdogan/cloudflare-tunnel-traefik-and-a-cleaner-self-hosted-setup-546l</guid>
      <description>&lt;p&gt;Today I set up a small stack on my own server using Docker, Cloudflare Tunnel, and Traefik.&lt;/p&gt;

&lt;p&gt;The goal was simple: I wanted a cleaner way to expose and manage multiple projects without treating every new deployment like a one-off configuration job.&lt;/p&gt;

&lt;p&gt;The useful part was not just that it worked. It made the server feel like a reusable system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I wanted this
&lt;/h2&gt;

&lt;p&gt;I like keeping small projects available online, but once there is more than one service involved, setup work starts repeating itself very quickly.&lt;/p&gt;

&lt;p&gt;You need routing, domain handling, HTTPS, container management, and some way to stop the server from becoming a pile of unrelated manual decisions.&lt;/p&gt;

&lt;p&gt;I wanted something that felt structured enough to grow, but still lightweight enough for personal projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  The stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Docker runs the services&lt;/li&gt;
&lt;li&gt;Traefik handles reverse proxying and routing&lt;/li&gt;
&lt;li&gt;Cloudflare Tunnel connects the server to the outside world without the usual direct exposure model&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Docker gives each project a predictable runtime shape. Traefik gives those projects a consistent entry point. Cloudflare Tunnel removes a lot of the usual friction around exposing services safely.&lt;/p&gt;

&lt;p&gt;What makes the stack work is that the responsibilities are separated in a sensible way. Containers are responsible for running applications. Traefik is responsible for routing and service discovery. The tunnel is responsible for controlled external access. Once those boundaries are clear, the setup becomes easier to extend without each layer leaking too much into the others.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why not just keep it simpler?
&lt;/h2&gt;

&lt;p&gt;That is a fair question, because for one app, a simpler setup is often good enough. A straightforward reverse proxy config is not a problem when there is only one destination behind it.&lt;/p&gt;

&lt;p&gt;The problem starts when the server stops being "the place where one app runs" and becomes "the place where different projects may come and go over time."&lt;/p&gt;

&lt;p&gt;That is the point where I stop caring only about whether something works and start caring more about whether the structure will still feel reasonable after the fourth or fifth service.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where this starts to make sense
&lt;/h2&gt;

&lt;p&gt;With a single app, almost any setup can feel acceptable. A manual proxy config does not look too bad when there is only one target. But once there are multiple services, different hostnames, and the possibility of adding more over time, the difference becomes obvious.&lt;/p&gt;

&lt;p&gt;That is the point where Traefik stops feeling optional. It becomes the layer that gives the server a stable structure. Services become easier to reason about, routing stops feeling ad hoc, and adding another project starts to look like a repeatable step instead of a fresh configuration job.&lt;/p&gt;

&lt;p&gt;The most useful part was reduction in repeated decisions.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;services run in containers&lt;/li&gt;
&lt;li&gt;routing is handled in one consistent way&lt;/li&gt;
&lt;li&gt;external access follows the same pattern&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Adding another project no longer looks like "what do I need to invent for this one?" It looks more like "how does this fit into the structure that already exists?"&lt;/p&gt;

&lt;p&gt;That is a much better place to be, especially for side projects and internal tools.&lt;/p&gt;

&lt;h2&gt;
  
  
  What adding a new project looks like
&lt;/h2&gt;

&lt;p&gt;At a high level, adding a new project comes down to two things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;add a hostname rule in the Cloudflare Tunnel dashboard&lt;/li&gt;
&lt;li&gt;add Traefik labels to the project's &lt;code&gt;docker-compose.yaml&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;On the Cloudflare side, the rule is straightforward: point something like &lt;code&gt;test.semiherdogan.net&lt;/code&gt; to the Traefik entry point behind the tunnel.&lt;/p&gt;

&lt;p&gt;On the container side, the project can stay very small:&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;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;
    &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;traefik.enable=true&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;traefik.http.routers.test.rule=Host(`test.semiherdogan.net`)&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;traefik.http.routers.test.entrypoints=web&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;traefik.http.services.test.loadbalancer.server.port=80&lt;/span&gt;
    &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;proxy&lt;/span&gt;

&lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;proxy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;external&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The required shape is easy to understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;join the shared proxy network&lt;/li&gt;
&lt;li&gt;declare the hostname in Traefik&lt;/li&gt;
&lt;li&gt;let the tunnel rule send traffic to that entry point&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That repeatability matters more than the individual labels themselves. Once the naming and network pattern are stable, the cost of adding another service drops a lot because the shape of the problem is already known.&lt;/p&gt;

&lt;p&gt;Cloudflare Tunnel also changes the order of concerns in a useful way. Instead of thinking first about direct exposure, port handling, and the outer edge of the server, I can focus more on internal service organization and routing.&lt;/p&gt;

&lt;p&gt;That does not remove the need to think carefully, but it does remove some of the repetitive edge-work that usually makes self-hosting feel more fragile than it needs to be.&lt;/p&gt;

&lt;p&gt;It also gives me an easy path for the cases where a domain, subdomain, or internal endpoint should not be openly reachable. In those cases, Cloudflare Zero Trust fits naturally into the same setup and makes it straightforward to put a protected layer in front of something without rethinking the whole deployment model.&lt;/p&gt;

&lt;p&gt;It is easier to extend, easier to keep mentally organized, and much nicer to work with than a collection of separate, hand-made deployment paths.&lt;/p&gt;

&lt;p&gt;The interesting part is not the individual tools. It is that together they create a setup where future projects feel cheaper to add.&lt;/p&gt;

&lt;p&gt;And that is exactly the kind of infrastructure decision I tend to like: not flashy, but immediately useful once the number of projects starts growing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where I would be careful
&lt;/h2&gt;

&lt;p&gt;The main risk in setups like this is not usually the first deployment. It is slow operational drift.&lt;/p&gt;

&lt;p&gt;If hostnames, labels, networks, and entry points are not kept consistent, the "clean structure" benefit disappears surprisingly fast. The same is true if observability is left behind. Once multiple services share the same routing layer, it becomes more important to know what is failing, where requests are going, and which layer is actually responsible when something breaks.&lt;/p&gt;

&lt;p&gt;That is also why I like this stack more as a pattern than as a one-time setup. The value is not just that the first app is online. The value is that the second, third, and fourth app can follow the same rules without the server turning back into improvisation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where this is probably too much
&lt;/h2&gt;

&lt;p&gt;If you only have one small app and do not expect that to change, this may be more structure than you actually need. In that case, a simpler setup might be the better engineering decision.&lt;/p&gt;

&lt;p&gt;What makes this stack appealing is not that it is universally better. It is that it starts paying off when you want a server to host multiple projects without every new service feeling like a fresh round of setup decisions.&lt;/p&gt;

</description>
      <category>cloudflare</category>
      <category>docker</category>
      <category>selfhosted</category>
      <category>devops</category>
    </item>
    <item>
      <title>Devbox: The First Nix-Based Tool That Felt Practical</title>
      <dc:creator>Semih ERDOGAN</dc:creator>
      <pubDate>Thu, 07 May 2026 13:25:51 +0000</pubDate>
      <link>https://dev.to/semiherdogan/devbox-the-first-nix-based-tool-that-felt-practical-4mbb</link>
      <guid>https://dev.to/semiherdogan/devbox-the-first-nix-based-tool-that-felt-practical-4mbb</guid>
      <description>&lt;p&gt;Recently I started using &lt;a href="https://github.com/jetify-com/devbox" rel="noopener noreferrer"&gt;Devbox&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It is one of those tools that made immediate sense to me because it sits exactly in the gap I have been feeling for a long time.&lt;/p&gt;

&lt;p&gt;Before that, my default workflow for trying a new idea was usually one of two things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;install whatever I needed directly on my machine with Homebrew&lt;/li&gt;
&lt;li&gt;put the whole thing into Docker, even when the project was small&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both approaches work, but neither one felt right all the time.&lt;/p&gt;

&lt;p&gt;Installing tools directly on my laptop is easy in the short term, but it slowly turns the machine into a place where random project decisions accumulate. A tool I needed once ends up sitting around forever. Version differences start to matter. The system becomes less intentional over time.&lt;/p&gt;

&lt;p&gt;Docker solves a different problem, and sometimes it is exactly the right answer. But for very small experiments, side projects, or quick idea testing, it can also feel heavier than what I actually need. Sometimes I do not want a containerized runtime model. I just want a clean development shell with the right tools available.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I never fully committed to Nix
&lt;/h2&gt;

&lt;p&gt;I have wanted something like this for a long time, which is why Nix has always been interesting to me in theory.&lt;/p&gt;

&lt;p&gt;The promise is very attractive: reproducible environments, clean dependency boundaries, and less pollution on the host machine.&lt;/p&gt;

&lt;p&gt;The part that always stopped me was not the idea. It was the feeling that the configuration itself asked for more commitment than I wanted to give, especially for small projects. Every time I looked at a Nix-based setup directly, it felt like I needed to buy into a whole way of thinking before I could get the practical benefit I was actually after.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Devbox clicked
&lt;/h2&gt;

&lt;p&gt;Devbox was the first tool in this space that felt like it reduced the activation energy enough for me to actually use it.&lt;/p&gt;

&lt;p&gt;The part I liked immediately is that it gives me the Nix-backed isolation I wanted, but through a much more approachable shape. Instead of feeling like I need to adopt the Nix language first, I can describe a project environment in a small JSON file and move on.&lt;/p&gt;

&lt;p&gt;Instead of thinking, "do I want to invest in learning this whole toolchain right now?", the question becomes much simpler: "do I want this project to have a clean shell with pinned tools?"&lt;/p&gt;

&lt;p&gt;That is a much easier yes.&lt;/p&gt;

&lt;p&gt;Jetify's own docs describe Devbox as a way to create isolated, reproducible development shells without needing Docker or the Nix language, and that matches the part that mattered most to me in practice. Sources: &lt;a href="https://www.jetify.com/devbox/docs" rel="noopener noreferrer"&gt;What is Devbox?&lt;/a&gt;, &lt;a href="https://github.com/jetify-com/devbox" rel="noopener noreferrer"&gt;Devbox GitHub repository&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it looks like in practice
&lt;/h2&gt;

&lt;p&gt;When I want to try a small project, I do not have to decide between making my laptop messier or creating more container setup than the project deserves. I can define the tools, enter the shell, and keep going.&lt;/p&gt;

&lt;p&gt;The flow is simple enough that it is easy to remember:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;devbox init
devbox search hugo
devbox add hugo@0.159.0

devbox shell &lt;span class="c"&gt;# activate environment&lt;/span&gt;
hugo server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the config stays small:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"packages"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"hugo@0.159.0"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"shell"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"dev"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"hugo server"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"hugo --gc --minify"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is what made it click for me. It gives me the boundary I wanted without forcing a heavier setup than the project deserves.&lt;/p&gt;

&lt;p&gt;It also makes cleanup feel more realistic. When the project is over, I do not need to remember which packages I threw onto my machine just to get through one afternoon of testing. The dependency boundary stays with the project.&lt;/p&gt;

&lt;p&gt;That is the part I appreciate most. It feels lighter than Docker for this category of work, but still much more intentional than installing everything globally.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why it feels worth keeping
&lt;/h2&gt;

&lt;p&gt;Some tools are impressive but never become habit.&lt;/p&gt;

&lt;p&gt;Devbox feels more promising to me because it fits into the kind of development work I actually do: small experiments, side projects, trying tools quickly, switching contexts often, and not wanting my machine to reflect every temporary decision I make.&lt;/p&gt;

&lt;p&gt;I still think Docker and plain host installs both have their place. This is not really about replacing everything with one tool.&lt;/p&gt;

&lt;p&gt;It is more that Devbox finally gave me a practical middle layer I had been missing for a long time.&lt;/p&gt;

&lt;p&gt;That is why it clicked.&lt;/p&gt;

</description>
      <category>devbox</category>
      <category>nix</category>
      <category>tooling</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Simplifying EC2 Connections with AWS SSH</title>
      <dc:creator>Semih ERDOGAN</dc:creator>
      <pubDate>Thu, 07 May 2026 13:25:39 +0000</pubDate>
      <link>https://dev.to/semiherdogan/simplifying-ec2-connections-with-aws-ssh-370o</link>
      <guid>https://dev.to/semiherdogan/simplifying-ec2-connections-with-aws-ssh-370o</guid>
      <description>&lt;p&gt;As a developer working with AWS, I often found myself jumping between multiple EC2 instances. Connecting to them securely and efficiently was repetitive, and it usually meant bouncing between the AWS CLI and the Session Manager Plugin.&lt;/p&gt;

&lt;p&gt;Those tools are powerful, but I wanted something simpler and faster for day-to-day use. That is why I built AWS SSH, a CLI tool with a small TUI that streamlines the process of connecting to EC2 instances.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I built AWS SSH
&lt;/h2&gt;

&lt;p&gt;The AWS CLI and Session Manager Plugin already solve the core problem, but the workflow can still feel clumsy if you switch between instances often.&lt;/p&gt;

&lt;p&gt;The main friction points for me were:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Manually searching for instance IDs and typing long commands.&lt;/li&gt;
&lt;li&gt;Having no intuitive interface for picking the target instance.&lt;/li&gt;
&lt;li&gt;Needing extra steps whenever I wanted to switch regions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I wanted a tool that reduced that overhead and made the flow interactive instead of procedural.&lt;/p&gt;

&lt;h2&gt;
  
  
  How AWS SSH works
&lt;/h2&gt;

&lt;p&gt;AWS SSH is a wrapper around the AWS CLI and Session Manager Plugin. It uses those existing tools and puts a more ergonomic interface on top.&lt;/p&gt;

&lt;p&gt;The basic flow looks like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It fetches the EC2 instances available in your AWS account.&lt;/li&gt;
&lt;li&gt;It shows them in a TUI so you can search and select the one you want.&lt;/li&gt;
&lt;li&gt;Once selected, it starts the connection through AWS Session Manager.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It also supports region configuration. If you define regions in your AWS credentials file, the tool can search them automatically. If not, it asks you to pick a region at runtime.&lt;/p&gt;

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

&lt;p&gt;Before using AWS SSH, make sure these are installed and available in your &lt;code&gt;PATH&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html" rel="noopener noreferrer"&gt;AWS CLI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html" rel="noopener noreferrer"&gt;Session Manager plugin&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can verify both with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws &lt;span class="nt"&gt;--version&lt;/span&gt;
session-manager-plugin &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;Download the latest release from the &lt;a href="https://github.com/semiherdogan/aws-ssh/releases" rel="noopener noreferrer"&gt;GitHub releases page&lt;/a&gt;, make it executable, and move it into your &lt;code&gt;PATH&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="nb"&gt;chmod&lt;/span&gt; +x aws-ssh
&lt;span class="nb"&gt;mv &lt;/span&gt;aws-ssh /usr/local/bin/aws-ssh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On macOS, the first run may require allowing the binary from &lt;strong&gt;System Settings &amp;gt; Privacy &amp;amp; Security&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;

&lt;p&gt;Run the tool like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws-ssh &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;--profile&lt;/span&gt;|-p] &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;--region&lt;/span&gt;|-r] searchparam1 searchparam2 ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That opens the interface, lets you filter the instance list, and then connects to the selected EC2 instance through AWS Session Manager.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A simple TUI for selecting EC2 instances.&lt;/li&gt;
&lt;li&gt;Search support for narrowing down instances quickly.&lt;/li&gt;
&lt;li&gt;Region configuration through your AWS credentials file.&lt;/li&gt;
&lt;li&gt;Optional profile selection with &lt;code&gt;--profile&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Configuring regions
&lt;/h2&gt;

&lt;p&gt;If you want the tool to search specific regions automatically, add a &lt;code&gt;regions&lt;/code&gt; key to the relevant section in your &lt;code&gt;.aws/credentials&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[default]&lt;/span&gt;
&lt;span class="py"&gt;aws_access_key_id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;YOUR_ACCESS_KEY&lt;/span&gt;
&lt;span class="py"&gt;aws_secret_access_key&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;YOUR_SECRET_KEY&lt;/span&gt;
&lt;span class="py"&gt;regions&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;us-east-1,us-west-2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With that in place, AWS SSH will search those regions without asking each time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Required AWS permissions
&lt;/h2&gt;

&lt;p&gt;To run the tool, you need at least these IAM permissions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ec2:DescribeInstances&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ssm:StartSession&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;An example policy looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Statement"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"ec2:DescribeInstances"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"ssm:StartSession"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want tighter access control, you can scope &lt;code&gt;Resource&lt;/code&gt; down to specific instances or tags.&lt;/p&gt;

&lt;p&gt;Also make sure SSM is enabled on the target EC2 instance, with the required IAM role attached and the SSM agent installed and running. AWS documents that setup here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-prerequisites.html" rel="noopener noreferrer"&gt;Session Manager prerequisites&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why this tool is useful
&lt;/h2&gt;

&lt;p&gt;AWS SSH is meant to remove friction from a workflow that developers repeat constantly. If you manage one instance it is convenient. If you manage many, it becomes much more valuable.&lt;/p&gt;

&lt;p&gt;Project links:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/semiherdogan/aws-ssh" rel="noopener noreferrer"&gt;AWS SSH repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html" rel="noopener noreferrer"&gt;AWS CLI installation guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html" rel="noopener noreferrer"&gt;Session Manager plugin installation guide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>aws</category>
      <category>ec2</category>
      <category>cli</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
