Workflow for managing bash rc's in cloud environments

I previously haven't edited bashrc on my cloud servers. The servers change too often the effort seems not worth it. I also don't want to upload my local bashrc to each cloud server because there is a lot of stuff in my local bashrc that only makes sense for my local machine. But I have certain aliases etc that I would like to have on all my cloud servers. There's a few ways I could think to manage this:

  1. Write one bashrc for cloud servers and then always replace the default bashrc with this one. Downside: If I start a server with a different operating system that has a different bashrc I will override it's contents when I upload?
  2. I create a separate file with my alias' etc and upload it onto my servers and then add a line to the end of the existing bashrc which sources this additional file. Downsides: bit more effort.
  3. Just copy-paste every time I start a new server. Downsides: lotsa effort.

Anyone have a nice solution or recommendation? Thanks.


Solution 1:

This is my setup (high initial overhead, low ongoing effort)

  1. create a git repo to store your config files, and write a small install script to install them.

    For example, you might clone your repo into ~/src/my_config and the install script will overwrite (or symlink) ~/.bashrc to ~/src/my_config/.bashrc

    This makes working on new environments quite simple: you just need to

    git clone $repo_url
    ./my_config/install.sh
    

    That's not strictly true: on the remote machine you'll also need to ssh-keygen and add the new public key to your account at your git host.

  2. create a ~/.bash.d directory. Add this to your .bashrc

    for file in ~/.bash.d/*.bash; do
        if [[ -r "$file" ]]; then
            . "$file"
        fi
    done
    

    This lets you put stuff like defining your prompt into a separate file: ~/.bash.d/prompt.bash. I like this to keep my .bashrc small since I use tons of functions in my interactive shell.

  3. For each environment, create a ~/.bash.d/$(hostname) directory. Add this to your .bashrc

    for file in ~/.bash.d/$(hostname)/*.bash; do
        if [[ -r "$file" ]]; then
            . "$file"
        fi
    done
    

    All the stuff that's strictly local to a particular machine can be kept segregated.

    Symlinks work fine here: If all your AWS servers use the same setup then you can create ~/.bash.d/AWS and symlink all the specific hostnames to it.

This system has worked very well for me. I add something new, push the changes to git, and on the remote systems to git pull to pick up the new code.