Skip to content
4.1.1. Mars: Infra Management

4.1.1. Mars: Infra Management

A cloud provisioning and configuration management tool that leverages terraform and ansible.

Setup

Build the container

make

Make sure ssh-agent has your key private key

ssh-add -l

If ssh-add doesn't print anything, it doesn't have you key. Run ssh-add without arguments or point it to the appropriate key file in special cases.

Usage

Place a .mars-version file at the root of the repository to ensure that the behavior of mars is the same for all team members.

echo $MARS_VERSION > $(git rev-parse --show-toplevel)/.mars-version

Ensure all terraform projects have a .terraform-version file specifying which terraform version to use (technically optional). See tfenv for more details.

echo 0.11.3 > .terraform-version

MacOS users need a method of forwarding the host's ssh-agent to the docker container is necessary (see long discussions spawning from this thread). It seems like uber-common/docker-ssh-forward is the defacto best option as the avsm/docker-ssh-forward project recommended from the linked thread seems to be unmaintained now (years later).

To ease working with the docker image install a symlink pointing to the shell script in this project to make running the container less painful.

MacOS users should symlink the macOS specific script mars_macos.sh which will make use of pinata-ssh-mount to forward the host ssh agent (see note above).

ln -s $(pwd)/mars_macos.sh ~/bin/mars
mars -h

Technical details

If $SSH_AUTH_SOCK is mountable on docker containers (on Linux -- not macOS), general usage has the following form.

LOCAL_CACHE="$HOME/.mars/tfenv/versions"
END_USER=$(id -u $USER):$(id -g $USER)
DOCKER_WORKDIR=/terraform

PROJECT_PATH=$(pwd)
docker run --rm -it \
    -u $END_USER \
    -v "$LOCAL_CACHE:/opt/tfenv/versions" \
    -v "$PROJECT_PATH:/terraform" \
    -v "$HOME/.aws/:/opt/home/.aws" \
    -v "$SSH_AUTH_SOCK:$SSH_AUTH_SOCK" \
    -e "SSH_AUTH_SOCK=$SSH_AUTH_SOCK" \
    luthersystems/mars COMMAND [FLAGS] ARGS

The user (-u) is set so that state files in the project's .terraform directory will be owned by the correct user (not root). AWS credentials must be mounted into /opt/home, which is containers value for environment variable HOME. Finally, in order for ssh to work the ssh-agent's socket must be mounted into the container from the host and variable SSH_AUTH_SOCK has to be set, telling the container where to find the unix socket.

Mounting to path /opt/tfenv/versions is not a requirement but will prevent containers run with --rm from continuously needing to download versions of terraform not included in the default installation. The mount, or alternatively running with --rm, will bypass this issue. For now, --rm and mounting the cache in the docker command fits our workflow better so we typically do that.

Terraform

If you need to run a raw terraform command using the terraform binary installed in the container you may run mars terraform but without care python will intercept options/flags intended for terraform. Often you will have to use the special argument -- to tell python not to try and parse the flags meant for terraform.

mars dev terraform -- providers --help

Packer

Running packer currently expects a specific directory structure.

/IMAGE/packer.json
/...

A packer.json file is expected to be nested under a directory with the name of the output AMI. This structure allows multiple pcaker AMIs to be built using common ansible roles. Run packer commands by specifying the image and then the desired command.

mars IMAGE packer-validate
mars IMAGE packer-build

ALB

A utility is provided to locate DNS names for load balancers created by kubernetes ingress objects (via the alb-ingress-controller) using tags.

Create a file that defines environment variables PROJECT_NAME and AWS_REGION. For example,

cat > mars.env
PROJECT_NAME=xyz
AWS_REGION=eu-west-2
^D

Then invoke the utility specify an optional component and org.

mars ENV alb-dns --component COMPONENT --org ORG

The utility will print the DNS name for all matching ALBs. Any number of ALBs may be found if the provided parameters aren't specific enough or if no ALB has tags matching the input values.

We use cookies to give you the best experience of using this website. By continuing to use this site, you accept our use of cookies. Please read our Cookie Policy for more information.