Git Product home page Git Product logo

cloudenv's Introduction

cloudenv

  • Build Status

The Cloud Environment ⛅

This is a suite of modern cloud tooling that wraps seamlessly over your existing shell. It provides:

  • Infrastructure-as-code (IaC) tools.
  • Authentication tools for Okta and AWS.
  • A large collection of Kubernetes and container tools.

Tested on Mac and Linux with both Podman and Docker.

How To Use

If you are using Docker on Linux, first add your user to the 'docker' group so you can run docker commands directly. Podman users do not need to do this.

Install the cloudenv command:

sudo curl https://raw.githubusercontent.com/snw35/cloudenv/master/cloudenv -o /usr/local/bin/cloudenv && sudo chmod +x /usr/local/bin/cloudenv;

Run the cloudenv command as your own user (not as root). It will pull the latest version of the container image (around 2GB), start the container, and drop you into the shell:

⛅user@cloudenv-user:~$

Everything should work as you expect. The bash shell contains common utilities (git, curl, ssh, etc) and all of the installed tools (listed below) with working bash-completion for those that support it. If your session has an ssh-agent running with cached credentials, then these will continue to work and be available for git/ssh etc.

There may be updates to the 'cloudenv' script itself which won't be automatically applied, so re-run the install command above if you experience any issues launching the tool.

Included Software

The following software is installed and checked for updates weekly:

If something you want is missing, please open an issue or submit a PR, both are welcome!

Multi-User and Multi-Session Support

One instance of cloudenv will be run per user, named 'cloudenv-username', and multiple sessions can be run in each instance. The environment inside each instance is separate, e.g separate environment variables. In summary:

  • A user can run multiple sessions of cloudenv.
  • Multiple users can run separate instances of cloudenv.

WARNING: If multiple users run cloudenv on the same machine, because the home directory is bind-mounted into the container, anyone in the docker group will be able to exec into any cloudenv container and access all of that user's files. This tool is meant to be run on e.g trusted jumpbox hosts, or on single-user workstations. Keep this in mind when deploying it elsewhere.

Terraform and Terragrunt Versions

If you require other versions of terraform or terragrunt, then they can be installed inside the container by e.g fetching the binaries with wget:

Changing The Shell

By default, a custom bash shell is run inside the container. You can change this to a plain fish or a bash session that will use your host machine's shell configuration. To do this, edit the cloudenv script and change the "user_shell" variable to zsh, fish or bash.

Remove The Container

The container is left running in the background after you run the command for the first time. It won't re-start itself after a reboot, but will be in the stopped state. If you'd like to clean it up, then you can run the following: docker/podman rm -f cloudenv-*

Why?

If you deal with infrastructure as code, or simply work with AWS and GCP from the command line, then you will have quickly realised:

  • There are too many tools.
  • Most of them aren't in your package manager.
  • Updating them is annoying.
  • Installing them on a new machine can take hours.
  • Installing them on a colleague's machine can take hours++.
  • If you don't use the same versions as all of your colleagues, $BAD_THINGS can happen.

Ironically (or elegantly), cloud-tooling solves its own problem in the form of Docker images that can be used to package all of these tools up, isolate them from your host machine, and make installing and running them simple.

How It Works

This is fundamentally a Docker container running an interactive shell, though it does some extra things to make the experience seamless and pleasant.

It works in the following way:

  1. The cloudenv script pulls latest version of the container and starts it.
  2. It bind-mounts your home directory into the container, passes your user and group from the host machine in with environment variables, and ensures all permissions match up.
  3. If the host has an ssh-agent running, it bind-mounts the auth socket into the container. If not, it runs a separate ssh-agent as your user. This lets ssh commands access stored credentials as though they were running on the host.
  4. It starts a bash session inside the container as your user with a custom shell configuration (/etc/bashrc).
  5. The container runs in the background and can be connected to with multiple sessions.

Further information on some of these aspects is below.

Bind-Mounting The Home Directory

Your home directory is bind-mounted into the container. This allows access to your files as well as all of your dot-files and dot-directories, such as ~/.ssh, which contain all of the configuration for those utilities.

This allows the environment inside the container to behave as closely as possible to the environment on the host, and means that all of the included tools have access to the keys/credentials that they may require.

UserID and GroupID Mapping

Bind-mounting your home directory into a container normally creates issues with permissions, as your user on the host will not exist inside it. This is overcome by passing the IDs and names of the host's user and group into the container with environment variables, which the entrypoint script then uses to ensure that everything inside the container matches the host machine.

Timezones

The timezone inside an Alpine container defaults to UTC. Normally this is fine, but when your home directory is bind-mounted into the image in read-write mode, the timestamps on files will be incorrect if anything inside the container modifies them.

An environment variable (TZ) is used to set the timezone when the container starts up. The value is set in the cloudenv script and can be changed to match your requirements. Detecting the user's timezone cross-platform is one of those "this shouldn't be this hard" problems that is unfortunately best left out of scope.

Image Tagging and Updates

Travis CI automatically runs once per week and builds a new image if any updates are found to either the included software or the container base image.

The cloudenv container stays as minimal as possible while packaging a lot of tools, some of which are large (Hashicorp ones specifically), and providing a lot of functionality. It is possible to provision, manage, and develop production-grade cloud infrastructure with just the contents of this container.

cloudenv images are tagged with the ISO-8601 date they were first built (Example: 2018-08-14). The versions of all bundled software packages inside an image are the latest that were available on that date. You can edit the cloudenv script to pin the image to a particular date if you'd like.

The latest tag always points to the most recent image. Where backwards compatibility is an issue (such as with terraform), both the old and new versions will be included.

The 'cloudenv' script pulls the latest tag each time it is run. It does not stop or remove running containers however, so you will only use an updated version when you stop/remove the current container. This will happen after a reboot for example.

Contributing

To build the container locally,

docker build -t snw35/cloudenv:latest .

To test the locally built image,

./cloudenv

To run with DEBUG mode on,

export CLOUDENV_DBG=true && ./cloudenv

Once your changes are tested, open a pull request with your changes.

cloudenv's People

Contributors

shyam-habarakada avatar shyam-habarakada-smar avatar snw35 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

cloudenv's Issues

Vulnerabilities in the docker container

Hi,
I just ran a snyk test against that latest version of the container, and it reported a couple vulns. I'm fairly certain the musl vulnerability is a false-positive, but might want to update the jq package to address.

Thanks.

-Dave

dviebrock@FVFX62JZHV2D gitlab-eks-cluster % snyk container test snw35/cloudenv:latest
Testing snw35/cloudenv:latest...
✗ Medium severity vulnerability found in musl/musl-utils
Description: Out-of-bounds Write
Info: https://snyk.io/vuln/SNYK-ALPINE313-MUSL-1067865
Introduced through: musl/[email protected], libc-dev/[email protected], meta-common-packages@meta
From: musl/[email protected]
From: libc-dev/[email protected] > musl/[email protected]
From: meta-common-packages@meta > musl/[email protected]
Fixed in: 1.2.2_pre2-r0
✗ High severity vulnerability found in jq/jq
Description: Out-of-Bounds
Info: https://snyk.io/vuln/SNYK-ALPINE313-JQ-1067448
Introduced through: jq/[email protected]
From: jq/[email protected]
Image layer: '/bin/sh -c apk --update --no-cache upgrade -a && apk --update --no-cache add bash bash-completion bind-tools ca-certificates coreutils curl diffutils fish fzf fzf-bash-completion git gnupg groff iputils jq keychain libusb ncurses net-tools nmap openssh-client openssl perl py3-pip python3 shadow su-exec tmux tzdata && pip install --upgrade pip && pip install --no-cache-dir cookiecutter datadog okta-awscli wheel && curl -o /usr/local/bin/ecs-cli https://s3.amazonaws.com/amazon-ecs-cli/ecs-cli-linux-amd64-latest && chmod +x /usr/local/bin/ecs-cli && sed -i 's/^CREATE_MAIL_SPOOL=yes/CREATE_MAIL_SPOOL=no/' /etc/default/useradd && mkdir -p /etc/bash_completion.d && ln -s /usr/bin/python3 /usr/bin/python'
Fixed in: 1.6_rc1-r0
Organization: dave.viebrock
Package manager: apk
Project name: docker-image|snw35/cloudenv
Docker image: snw35/cloudenv:latest
Platform: linux/amd64
Licenses: enabled
Tested 141 dependencies for known issues, found 2 issues.

Replicate home directory path

Due to hardcoded paths in some configs, the container should use the same path to a user's home, such as /Users/user or /home/user.

Error when running on OSX

I installed this on a Mac and on first run, got this error (in docker container logs)

No matching internal group found, creating one...
groupadd: GID '20' already exists

It looks like the check to see if the group exists, in https://github.com/snw35/cloudenv/blob/master/docker-entrypoint.sh#L70 is not working as intended.

Looking into the image we have,

bash-5.1# cat /etc/group | grep 20
dialout:x:20:root
nofiles:x:200:
smmsp:x:209:smmsp

There is a group called dialout that has the id 20 assigned. That appears to be clashing with my current HOST_GROUP_ID which is also 20. The code in docker-entrypoint.sh to detect this scenario is not working as far as I can tell, because it is falling into the flow as if there was no conflict.

I was able to work around this issue by hacking the cloudenv script (locally) to pass in an empty value into the HOST_GROUP_ID and that worked. However, I am not sure what the right fix is because it is unclear what the original use-case may have been for the "use existing group if it matches" scenario. @snw35 any advice?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.