Skip to content

Instantly share code, notes, and snippets.

@Anthonyhawkins
Created November 29, 2016 01:05
Show Gist options
  • Save Anthonyhawkins/c94b17d1367164a81dc4dd3fd6374374 to your computer and use it in GitHub Desktop.
Save Anthonyhawkins/c94b17d1367164a81dc4dd3fd6374374 to your computer and use it in GitHub Desktop.
cd-with-salt-run.sls
#
# Blog as a Service Pipeline
# - Author: Anthony Hawkins
# - Purpose: Automate the testing and deployment of my personal blog
#
#
# Name of the pipeline used to lookup pipeline configuration in pillar
#
{% set pipeline_name = pillar['pipeline_name'] %}
#
# Build Space - Where the work will be done
#
{% set build_space = pillar['pipelines'][pipeline_name]['build_env']['build_dir'] %}
#
# Lookup the Repo we are building
#
{% set repo_source = pillar['pipelines'][pipeline_name]['git']['provider'] %}
{% set repo_user = pillar['pipelines'][pipeline_name]['git']['username'] %}
{% set repo_name = pillar['pipelines'][pipeline_name]['git']['repo'] %}
#
# Container Info
#
# Image base name to append tags to for builds
{% set image_base = pillar['pipelines'][pipeline_name]['container']['image'] %}
# A volumn will be created from this dir - this allows salt to import the output
# and process testing results
{% set log_dir = pillar['pipelines'][pipeline_name]['container']['log_dir'] %}
##
## PIPELINE TASKS
##
# Set Build ID
{% set build_id = "ID-" + salt.cmd.run('date +%s') %}
{% set slack_key = pillar['pipelines'][pipeline_name]['slack']['api_key'] %}
{% set slack_channel = pillar['pipelines'][pipeline_name]['slack']['channel'] %}
#
# STEP 1 - Target the Build Box and tell the minion to clone the repo
#
clone:
salt.state:
- tgt: {{pillar['pipelines'][pipeline_name]['build_env']['minion']}}
- sls:
- pipelines.{{pipeline_name}}.clone
- pillar:
build_id: {{ build_id }}
build_space: {{ build_space }}
repo_user: {{ repo_user }}
repo_name: {{ repo_name }}
repo_source: {{ repo_source }}
slack_key: {{ slack_key }}
slack_channel: {{ slack_channel }}
#
# STEP 2 - Ensure the Docker Image has been built
#
build:
salt.state:
- tgt: {{pillar['pipelines'][pipeline_name]['build_env']['minion']}}
- sls:
- pipelines.{{pipeline_name}}.build
- pillar:
build_id: {{ build_id }}
build_space: {{ build_space }}
repo_user: {{ repo_user }}
repo_name: {{ repo_name }}
image_base: {{ image_base }}
slack_key: {{ slack_key}}
slack_channel: {{ slack_channel }}
- require:
- clone
#
# STEP 3 - Run the container in test mode this will do the following within the container
# - start all processes
# - start the salt minion
# - run the salt-call --local state.apply blog.test.run command localy within the container
# - output the result to a file bound to a volumn, this is now accesible by the next STEP
#
test:
salt.state:
- tgt: {{pillar['pipelines'][pipeline_name]['build_env']['minion']}}
- sls:
- pipelines.{{pipeline_name}}.test
- pillar:
build_id: {{ build_id }}
build_space: {{ build_space }}
log_dir: {{ log_dir }}
repo_user: {{ repo_user }}
repo_name: {{ repo_name }}
image_base: {{ image_base }}
slack_key: {{ slack_key }}
slack_channel: {{ slack_channel }}
- require:
- build
#
# STEP 4 - Process the Test Results, This state loads in the yaml which was outputed by the local
# minion within the contaienr, from there it is run through conditionals to see what needs to be done next:
# - PASS: Push the Image to Dockerhub
# - FAIL: Terminate Pipeline
#
push:
salt.state:
- tgt: {{pillar['pipelines'][pipeline_name]['build_env']['minion']}}
- sls:
- pipelines.{{pipeline_name}}.push
- pillar:
build_id: {{ build_id }}
build_space: {{ build_space }}
log_dir: {{ log_dir }}
repo_user: {{ repo_user }}
repo_name: {{ repo_name }}
image_base: {{ image_base }}
slack_key: {{ slack_key}}
slack_channel: {{ slack_channel}}
- require:
- test
#
# STEP 5 - Deploy to Production
#
{% set kuber_host = pillar['pipelines'][pipeline_name]['kubernetes']['api_endpoint']['host'] %}
{% set kuber_username = pillar['pipelines'][pipeline_name]['kubernetes']['api_endpoint']['username'] %}
{% set kuber_password = pillar['pipelines'][pipeline_name]['kubernetes']['api_endpoint']['password'] %}
{% set kuber_namespace = pillar['pipelines'][pipeline_name]['kubernetes']['api_endpoint']['namespace'] %}
# where the kubernetes source files are located in relation to the root of the git repo
{% set deployment_file = pillar['pipelines'][pipeline_name]['kubernetes']['deployment']['source'] %}
{% set service_file = pillar['pipelines'][pipeline_name]['kubernetes']['service']['source'] %}
# tells the build minion where to find the kubernetes source files AFTER being cloned from step 1
{% set deploy_source = build_space + "/" + repo_user + "/" + repo_name + "/" + deployment_file %}
{% set service_source = build_space + "/" + repo_user + "/" + repo_name + "/" + service_file %}
# entities use which api versions
{% set deployment_api = pillar['pipelines'][pipeline_name]['kubernetes']['deployment']['api_version'] %}
{% set service_api = pillar['pipelines'][pipeline_name]['kubernetes']['service']['api_version'] %}
deploy:
salt.state:
- tgt: {{pillar['pipelines'][pipeline_name]['build_env']['minion']}}
- sls:
- pipelines.{{pipeline_name}}.deploy
- pillar:
build_id: {{ build_id }}
repo_user: {{ repo_user }}
repo_name: {{ repo_name }}
image_base: {{ image_base }}
slack_key: {{ slack_key}}
slack_channel: {{ slack_channel}}
kubernetes:
api_endpoint:
host: {{ kuber_host }}
username: {{ kuber_username }}
password: {{ kuber_password }}
namespace: {{ kuber_namespace }}
deployment:
api_version: {{ deployment_api }}
source: {{ deploy_source }}
service:
api_version: {{ service_api }}
source: {{ service_source }}
- require:
- push
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment