Created
October 23, 2020 21:46
-
-
Save MrEcco/c9010144764e7ce62995bcaf7c30ec32 to your computer and use it in GitHub Desktop.
Little tricks for binding terraform state to current branch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# ~/.bashrc: executed by bash(1) for non-login shells. | |
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc) | |
# for examples | |
# If not running interactively, don't do anything | |
case $- in | |
*i*) ;; | |
*) return;; | |
esac | |
# don't put duplicate lines or lines starting with space in the history. | |
# See bash(1) for more options | |
HISTCONTROL=ignoreboth | |
# append to the history file, don't overwrite it | |
shopt -s histappend | |
# for setting history length see HISTSIZE and HISTFILESIZE in bash(1) | |
HISTSIZE=1000 | |
HISTFILESIZE=2000 | |
# check the window size after each command and, if necessary, | |
# update the values of LINES and COLUMNS. | |
shopt -s checkwinsize | |
# If set, the pattern "**" used in a pathname expansion context will | |
# match all files and zero or more directories and subdirectories. | |
#shopt -s globstar | |
# make less more friendly for non-text input files, see lesspipe(1) | |
[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)" | |
# set variable identifying the chroot you work in (used in the prompt below) | |
if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then | |
debian_chroot=$(cat /etc/debian_chroot) | |
fi | |
# set a fancy prompt (non-color, unless we know we "want" color) | |
case "$TERM" in | |
xterm-color|*-256color) color_prompt=yes;; | |
esac | |
# uncomment for a colored prompt, if the terminal has the capability; turned | |
# off by default to not distract the user: the focus in a terminal window | |
# should be on the output of commands, not on the prompt | |
force_color_prompt=yes | |
if [ -n "$force_color_prompt" ]; then | |
if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then | |
# We have color support; assume it's compliant with Ecma-48 | |
# (ISO/IEC-6429). (Lack of such support is extremely rare, and such | |
# a case would tend to support setf rather than setaf.) | |
color_prompt=yes | |
else | |
color_prompt= | |
fi | |
fi | |
if [ "$color_prompt" = yes ]; then | |
PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ ' | |
else | |
PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ ' | |
fi | |
unset color_prompt force_color_prompt | |
# If this is an xterm set the title to user@host:dir | |
case "$TERM" in | |
xterm*|rxvt*) | |
PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1" | |
;; | |
*) | |
;; | |
esac | |
# enable color support of ls and also add handy aliases | |
if [ -x /usr/bin/dircolors ]; then | |
test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)" | |
alias ls='ls --color=auto' | |
#alias dir='dir --color=auto' | |
#alias vdir='vdir --color=auto' | |
alias grep='grep --color=auto' | |
alias fgrep='fgrep --color=auto' | |
alias egrep='egrep --color=auto' | |
fi | |
# colored GCC warnings and errors | |
#export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01' | |
# some more ls aliases | |
alias ll='ls -alF' | |
alias la='ls -A' | |
alias l='ls -CF' | |
# Add an "alert" alias for long running commands. Use like so: | |
# sleep 10; alert | |
alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"' | |
# Alias definitions. | |
# You may want to put all your additions into a separate file like | |
# ~/.bash_aliases, instead of adding them here directly. | |
# See /usr/share/doc/bash-doc/examples in the bash-doc package. | |
if [ -f ~/.bash_aliases ]; then | |
. ~/.bash_aliases | |
fi | |
# enable programmable completion features (you don't need to enable | |
# this, if it's already enabled in /etc/bash.bashrc and /etc/profile | |
# sources /etc/bash.bashrc). | |
if ! shopt -oq posix; then | |
if [ -f /usr/share/bash-completion/bash_completion ]; then | |
. /usr/share/bash-completion/bash_completion | |
elif [ -f /etc/bash_completion ]; then | |
. /etc/bash_completion | |
fi | |
fi | |
eval "$(env-helper)" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
version: '3.6' | |
services: | |
workbench: | |
container_name: awsome-project | |
image: awsome-project-iac:local | |
entrypoint: bash -c "eval $$(env-helper); kubectl proxy --address='0.0.0.0' --port=8001 --accept-hosts='.*'" | |
ports: | |
- "8001:8001" | |
stdin_open: true | |
volumes: | |
- ./data:/data | |
- ./.aws-gi:/root/.aws:ro | |
- ./.ssh:/root/.ssh:ro | |
- ./.gpg:/root/.gpg:ro | |
- ./.kube:/root/.kube | |
- ~/.terraform/.terraformrc:/root/.terraformrc:ro | |
- ./.git/HEAD:/githead:ro | |
stop_grace_period: 1s | |
# proxy: | |
# container_name: awsome-project-proxy | |
# image: awsome-project-iac:local | |
# entrypoint: bash -c "eval $$(env-helper); kubectl port-forward --address='0.0.0.0' -n smth svc/smth 8080:8080" | |
# ports: | |
# - "8080:8080" | |
# stdin_open: true | |
# volumes: | |
# - ./data:/data:ro | |
# - ./.aws-gi:/root/.aws:ro | |
# - ./.kube:/root/.kube:ro | |
# - ./.git/HEAD:/githead:ro | |
# stop_grace_period: 1s |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
FROM ubuntu:bionic | |
# kube{ctl,adm,let} latest: see https://storage.googleapis.com/kubernetes-release/release/stable.txt | |
ARG AWSCLI_VERSION=1.18.161 | |
ARG HELM_VERSION=2.16.12 | |
ARG KUBECTL_VERSION=1.15.3 | |
ARG TERRAFORM_VERSION=0.13.4 | |
ARG PACKER_VERSION=1.6.4 | |
ARG KUBELESS_VERSION=1.0.7 | |
ARG VAULT_VERSION=1.5.4 | |
RUN apt-get update && \ | |
apt-get install --no-install-recommends -y \ | |
software-properties-common && \ | |
add-apt-repository ppa:ansible/ansible -y && \ | |
apt-get install --no-install-recommends -y ansible make \ | |
curl dnsutils git jq net-tools ssh telnet zip unzip \ | |
vim nano wget python3-pip groff bash-completion less && \ | |
git clone https://github.com/dysosmus/ansible-completion ansible-completion && \ | |
mv ansible-completion/ansible-*.bash /etc/bash_completion.d/ && \ | |
apt-get clean && \ | |
apt-get autoclean && \ | |
apt-get autoremove && \ | |
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* | |
# Terraform | |
RUN wget -O terraform.zip https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_amd64.zip && \ | |
unzip terraform.zip && \ | |
mv terraform /usr/local/bin/terraform && \ | |
chmod +x /usr/local/bin/terraform && \ | |
rm terraform.zip && \ | |
echo "complete -C /usr/local/bin/terraform terraform" > /etc/bash_completion.d/terraform.bash && \ | |
mv /usr/local/bin/terraform /usr/local/bin/terraform-origin | |
# Packer | |
RUN wget -O packer.zip https://releases.hashicorp.com/packer/${PACKER_VERSION}/packer_${PACKER_VERSION}_linux_amd64.zip && \ | |
unzip packer.zip && \ | |
mv packer /usr/local/bin/packer && \ | |
chmod +x /usr/local/bin/packer && \ | |
rm packer.zip && \ | |
echo "complete -C /usr/local/bin/packer packer" > /etc/bash_completion.d/packer.bash | |
# Helm | |
RUN wget -O helm.tar.gz https://storage.googleapis.com/kubernetes-helm/helm-v${HELM_VERSION}-linux-amd64.tar.gz && \ | |
tar xfz helm.tar.gz && \ | |
mv linux-amd64/helm /usr/local/bin/helm && \ | |
chmod +x /usr/local/bin/helm && \ | |
rm -Rf linux-amd64 && \ | |
rm helm.tar.gz && \ | |
helm completion bash >> /etc/bash_completion.d/helm.bash | |
# Kubectl | |
RUN wget https://storage.googleapis.com/kubernetes-release/release/v${KUBECTL_VERSION}/bin/linux/amd64/kubectl -O /usr/local/bin/kubectl && \ | |
chmod +x /usr/local/bin/kubectl && \ | |
kubectl completion bash \ | |
>> /etc/bash_completion.d/kubectl.bash && \ | |
curl -sL https://raw.githubusercontent.com/kvaps/kubectl-node-shell/156053f8bd3ac7a70d59564ac486d522f252e9c7/kubectl-node_shell \ | |
-o /usr/local/bin/kubectl-node_shell && \ | |
chmod +x /usr/local/bin/kubectl-node_shell | |
# Kubeless | |
RUN wget https://github.com/kubeless/kubeless/releases/download/v${KUBELESS_VERSION}/kubeless_linux-amd64.zip -O kubeless.zip && \ | |
TMPDIRNAME=$(openssl rand -hex 20) && \ | |
mkdir ${TMPDIRNAME} && \ | |
cd ${TMPDIRNAME} && \ | |
unzip ../kubeless.zip && \ | |
rm ../kubeless.zip && \ | |
mv $(find . -type f | egrep "/kubeless$" | head -1) /usr/local/bin/kubeless && \ | |
chmod +x /usr/local/bin/kubeless && \ | |
cd .. && \ | |
rm -r ${TMPDIRNAME} && \ | |
kubeless completion bash > /etc/bash_completion.d/kubeless.bash | |
# Pip3 | |
RUN pip3 --no-cache --no-cache-dir install \ | |
setuptools \ | |
wheel && \ | |
pip3 --no-cache --no-cache-dir install \ | |
configparser \ | |
yq && \ | |
pip3 --no-cache --no-cache-dir install \ | |
awscli==${AWSCLI_VERSION} && \ | |
echo "complete -C $(which aws_completer) aws" > /etc/bash_completion.d/awscli.bash | |
# Vault | |
RUN curl -o vault.zip https://releases.hashicorp.com/vault/${VAULT_VERSION}/vault_${VAULT_VERSION}_linux_amd64.zip && \ | |
unzip vault.zip && \ | |
rm vault.zip && \ | |
mv vault /bin/vault && \ | |
echo "complete -C /bin/vault vault" > /etc/bash_completion.d/hashicorp_vault.bash | |
COPY ./docker /docker | |
# Others | |
RUN mkdir -p /root/.kube && \ | |
touch /root/.kube/config && \ | |
cp /etc/skel/.profile /root/.profile && \ | |
cp /docker/.bashrc /root/.bashrc && \ | |
chmod +x /docker/bin/* && \ | |
cp /docker/bin/* /usr/local/bin/ | |
WORKDIR /data |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python3 -u | |
import sys, os | |
import configparser | |
# Helpers | |
__warn_color_in = '\033[1;97;41m' | |
__warn_color_wipe = '\033[0;39;49m' | |
def fixpath(filename): | |
filename = filename.strip(' ') | |
if filename.find('~') == 0: | |
filename = '{}{}'.format( | |
os.environ.get('HOME', '/'), | |
filename[1:], | |
) | |
return filename | |
# Instructions builers. Unsafe for envname, but must receive legal | |
# environment fullname ("production" or "development" at this time). | |
# Aliases and must be resolved by envrouter (see below). | |
def common(envname, envshort): | |
return [ | |
'export ENV={}'.format(envname), | |
'export ENVSHORT={}'.format(envshort), | |
] | |
def aws(envname, envshort): | |
__const_awsconfig_file = fixpath('~/.aws/config') | |
__const_awscreds_file = fixpath('~/.aws/credentials') | |
__const_aws_default_profile = 'default' | |
configmap = {} | |
profile = '' | |
# Config | |
config = configparser.ConfigParser() | |
config.read(__const_awsconfig_file) | |
if __const_aws_default_profile in config.sections(): | |
profile = __const_aws_default_profile | |
else: | |
profile = config.sections()[0] # first available | |
configmap.update(config[profile]) | |
del config | |
# Credentials | |
config = configparser.ConfigParser() | |
config.read(__const_awscreds_file) | |
configmap.update(config[profile]) | |
del config | |
if envname == 'development': | |
configmap['region'] = 'eu-west-1' | |
else: | |
configmap['region'] = 'us-east-1' | |
return [ | |
'export AWS_ACCESS_KEY_ID={}'.format(configmap['aws_access_key_id']), | |
'export AWS_SECRET_ACCESS_KEY={}'.format(configmap['aws_secret_access_key']), | |
'export AWS_DEFAULT_REGION={}'.format(configmap['region']), | |
'export AWS_PROFILE={}'.format(profile), | |
] | |
def terraform(envname, envshort): | |
configmap = { | |
'env': envname, | |
'envfile': 'envs/{}.tf'.format(envname), | |
} | |
return ['export TF_VAR_{}={}'.format(k,v) for (k,v) in configmap.items()] | |
def kubernetes(envname, envshort): | |
exports = [ | |
'export KUBECONFIG={}'.format(fixpath('~/.kube/' + envname)), | |
] | |
return exports | |
def getbranchname(): | |
__git_head_filepath = '/githead' # IMPORTANT HERE | |
ret = '' | |
with open(__git_head_filepath, 'r') as fd: | |
for line in fd.readlines(): | |
line = line.strip(" \n") | |
if line[:5] == 'ref: ': | |
refparts = line[5:].split('/') | |
if len(refparts) >= 3: | |
if '/'.join(refparts[0:2]) == 'refs/heads': | |
ret = '/'.join(refparts[2:]) | |
return ret | |
def envrouter(): | |
__branch_production = ['master'] | |
__branch_development = ['develop'] | |
try: | |
branchname = getbranchname() | |
except Exception as e: | |
print(__warn_color_in + str(e) + __warn_color_wipe, file=sys.stderr, flush=True) | |
return 'unspecified' | |
if branchname in __branch_production: | |
return 'production', 'prod' | |
elif branchname in __branch_development: | |
return 'development', 'dev' | |
else: | |
return 'unspecified', 'unspecified' | |
builders = [ | |
aws, | |
terraform, | |
kubernetes, | |
common, | |
] | |
if __name__ == "__main__": | |
envname, envshort = envrouter() | |
if envname == 'unspecified': # This I see if something goes wronk - when shell into container | |
print(__warn_color_in + '############################################################' + __warn_color_wipe, file=sys.stderr, flush=True) | |
print(__warn_color_in + '### Cannot detect environment. Fallback to "unspecified" ###' + __warn_color_wipe, file=sys.stderr, flush=True) | |
print(__warn_color_in + '### environment. It can broke any appliements or bring ###' + __warn_color_wipe, file=sys.stderr, flush=True) | |
print(__warn_color_in + '### you to disruption! ###' + __warn_color_wipe, file=sys.stderr, flush=True) | |
print(__warn_color_in + '############################################################' + __warn_color_wipe, file=sys.stderr, flush=True) | |
sys.exit(128) | |
instructions = [] | |
for builder in builders: | |
instructions = instructions + builder(envname, envshort) | |
print( | |
"\n".join(instructions), | |
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python3 -u | |
import sys, os, subprocess | |
import pathlib | |
__origin_command = '/usr/local/bin/terraform-origin' | |
__color_in = '\033[1;95m' | |
__color_wipe = '\033[0;39;49m' | |
__dispatch_file = 'globals.tf' | |
if __name__ == "__main__": | |
# Replace symlink | |
lets_replace = True | |
must_be = 'envs/{}.tf'.format(os.environ.get('ENV', 'unspecified')) | |
if os.path.exists(__dispatch_file): | |
if pathlib.Path(__dispatch_file).is_symlink(): | |
points_to = str(pathlib.Path(__dispatch_file).resolve()) | |
if points_to.find(os.getcwd()) == 0: | |
points_to = str(points_to[len(os.getcwd()):]).lstrip('/') | |
if points_to == must_be: | |
lets_replace = False | |
if lets_replace: | |
print("{}Replaced env dispatcher symlink: {} -> {}{}".format(__color_in, __dispatch_file, must_be, __color_wipe), file=sys.stderr, flush=True) | |
if os.path.exists(__dispatch_file) or pathlib.Path(__dispatch_file).is_symlink(): | |
os.remove(__dispatch_file) | |
os.symlink(must_be, __dispatch_file) | |
os.execve(__origin_command, sys.argv, os.environ) |
Author
MrEcco
commented
Oct 23, 2020
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment