Recently I started using yabai + skhd for window management in OS X.

I have set up Caps Lock as a Hyper key using Karabiner elements and dedicated it for yabai + skhd.

Hyper key simply produces the effect of Shift + Alt + Command + Control. Basically, if I press Caps Lock + <something> it will be converted to Shift + Alt + Command + Control + <something>.

I wanted to set up some hotkeys to open applications that I frquently use like Terminal and Browser. I am a Firefox user so I wanted to open Firefox whenever I…


I have been using Alacritty + Tmux as my default terminal for 2 years now and am very happy with it.

Vim is one of my go to editors. I use Neovim, a Vim fork with additional features. For any development activities I find it inconvenient to use Vim inside terminal as I will be using the terminal for various other things as well. I prefer a GUI. For Neovim there are a lot of GUIs available as mentioned in their wiki page. I have used VimR, Oni, gnvim and neovide. Among them I chose VimR as I find it…


GoLang’s net/http package provides client and server implementation for HTTP. For applications where there is less logic involved with the request and response objects, we could directly use net/http instead of any web frameworks as the abstractions provided by a framework is unnecessary in such cases. One example I could think of is prometheus-exporters. Usually, it will have a /metrics endpoint that returns metrics for a component as plain text.

The server provided by net/http does not log request/response by default. A feedback containing URI, method, status code, duration, etc. would be really helpful. I was using logrus for logging…


At work, while writing an Airlfow DAG I needed to convert {{ execution_date }} macro from UTC to IST inside Jinja template. Initially I thought {{ execution_date }} gives a datatime object, so converting it inside Jinja template would be tricky as the it requires a tzinfo object.

For example,

from datetime import datetime
from dateutil.tz import gettz

utc = gettz("UTC")
utc_now = datetime.now(utc)
print(f"UTC: {utc_now}")
# UTC: 2020-06-17 16:04:04.952171+00:00

ist = gettz("Asia/Kolkata")
ist_now = utc_now.astimezone(ist)
print(f"IST: {ist_now}")
# IST: 2020-06-17 21:34:04.952171+05:30

Luckily, {{ execution_date }} is not a datetime object. Airflow uses Pendulum for datetime and it is an…


  1. With ssh we often deal with lengthy domain names and plain IP addresses. To ssh easily we usually create short aliases by adding entries to /etc/hosts. This can be done using ~/.sshconfig itself:
Host my-server-1
Hostname 192.168.1.10

Host my-server-2
Hostname my-lenghthy-domain-name.example.com

Now,

To access 192.168.1.10:

ssh user@my-server-1

To access my-lenghthy-domain-name.example.com:

ssh user@my-server-2

2. In SSH via Jump Server in One Step I shared about ssh-ing via jump servers in one step using the -J option. This too can be configured in ~/.sshconfig.

To access 192.168.1.10 that is accessible only through 192.168.1.2 we would do:

ssh -J user@192.168.1.2 user@192.168.1.10

With the…


Its common to use bastion/bounce/jump machine to access machines in a separate security zone.

I have been doing it in two steps so far:

  1. ssh into bastion-machine with agent authentication forwarding
ssh -A <user>@<bastion-machine>

2. then from bastion-machine ssh to the secure-machine:

ssh <user>@<secure-machine>

Recently, I learned that this can be done in a single step:

ssh -J <user>@<bastion-machine> <user>@<secure-machine>

Additionally, its also possible to do port-forwarding through the secure-machine in a single step. For example to forward requests to 5433 port of your local machine to 5432 of Postgres instance that is accessible only from the secure-machine:

ssh -J <user>@<bastion-machine> -L 5433:<postgres-machine>:5432 <user>@<secure-machine>

Originally published at https://arunvelsriram.dev.


When using multiple AWS accounts it very likely that you will have hard-coded AWS account IDs all over your Terraform codebase. Hard-coding is annoying and prone to errors. For example, you could use the production AWS account ID instead of pre-production one by mistake. So its always better to have these account numbers defined somewhere and consumed by name.

The immediate solution to this is to extract them as variables. However, if your codebase is complex and involves tons of modules and terraform files then you will have to copy these variable definitions all over the modules and terraform files.


Recently I used Kotlin DSL for writing Gradle scripts in a spring boot project. As Gradle’s Kotlin DSL is quite new, the documentation and community support was less compared to the Groovy DSL. So I found it hard to configure JaCoCo for test coverage. In this blog I will share how I added test coverage in my project:

Before getting in to the implementation let me put down the requirements:

  1. A test task to run all unit tests
  2. A testCoverage task that run all unit tests, generate coverage report and run verification
  3. A way to ignore classes and files from…


docker-time-sync-agent is a tool to overcome the time drift issue in Docker for Mac’s VM that runs the Docker Engine. This issue mostly occurs when Mac wakes up after a long sleep. Docker daemon fails to update the VM’s time after the computer wakes up from sleep. The result is that VM’s clock will be set to a past time. This in turn will make Docker containers use that time.

So what is the problem if the containers use a wrong time ? Well, some services (like S3, Okta) will block requests originating from a source whose time is wrong…

Arunvel Sriram

Open Source | DevOps | Infrastructure | Backend | Ployglot Programmer

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store