Skip to content

Instantly share code, notes, and snippets.

@pjbgf
Created January 16, 2018 14:16
Show Gist options
  • Save pjbgf/95ec4c492bb6a05c86108277234df1fe to your computer and use it in GitHub Desktop.
Save pjbgf/95ec4c492bb6a05c86108277234df1fe to your computer and use it in GitHub Desktop.
Circle CI Kubernetes Container Deployment
version: 2
jobs:
build_test_publish_image:
docker:
- image: paulinhu/netcore-docker-build:beta
environment:
ACR_NAME: akspoc
DOCKER_REGISTRY_URI: akspoc.azurecr.io
DOCKER_IMAGE_NAME_WITH_REGISTRY: akspoc.azurecr.io/template/sample-app-img
steps:
- checkout
- run: dotnet restore src
- run: |
dotnet build src
dotnet test src/Sample.Template.Api.Tests/Sample.Template.Api.Tests.csproj
- setup_remote_docker
- run: |
dotnet publish src/Sample.Template.Api/Sample.Template.Api.csproj -c Release -f netcoreapp2.0
cp src/Sample.Template.Api/Dockerfile src/Sample.Template.Api/bin/Release/netcoreapp2.0/publish/
docker build --rm --no-cache -t $DOCKER_IMAGE_NAME_WITH_REGISTRY:$(git log -1 --pretty=%h) src/Sample.Template.Api/bin/Release/netcoreapp2.0/publish/
az login --service-principal -u $SERVICE_PRINCIPAL --password $SERVICE_PRINCIPAL_PASS --tenant $SERVICE_TENANT
az account set --subscription $SUBSCRIPTION_NAME_OR_ID
docker login $DOCKER_REGISTRY_URI -u $ACR_NAME --password $(az acr credential show --name $ACR_NAME --out json --query "passwords[?name == 'password'].value | [0]" | sed 's/"//g')
# A bit of a hack to define image version.
docker push $DOCKER_IMAGE_NAME_WITH_REGISTRY:$(git log -1 --pretty=%h)
deploy_onto_ci_cluster:
docker:
- image: azuresdk/azure-cli-python
environment:
NON_PROD_RESOURCE_GROUP: aks-poc2-euw-rg
NON_PROD_CLUSTER_NAME: aks-poc2-euw
NON_PROD_NAMESPACE: nonprod-ci-dept
steps:
- checkout
- run: az login --service-principal -u $SERVICE_PRINCIPAL --password $SERVICE_PRINCIPAL_PASS --tenant $SERVICE_TENANT
- run: az account set --subscription $SUBSCRIPTION_NAME_OR_ID
- run: az aks get-credentials --resource-group $NON_PROD_RESOURCE_GROUP --name $NON_PROD_CLUSTER_NAME
- run: az aks install-cli
- run: |
ns_found=$(kubectl get namespace $NON_PROD_NAMESPACE --ignore-not-found=true -o=name | sed 's/namespaces\///g')
if echo $ns_found | grep $NON_PROD_NAMESPACE; then echo 'Namespace already exists.'; else kubectl create namespace $NON_PROD_NAMESPACE; fi
# A bit of a hack to define image version.
- run: cat src/camel.yaml | sed $'s/:latest/:'$(git log -1 --pretty=%h)'/g' | kubectl apply --namespace=$NON_PROD_NAMESPACE -f -
# Ensure deployment was successful
- run: kubectl rollout status deploy/sample-api-deploy --namespace=$NON_PROD_NAMESPACE
# Checks external end-point. TODO:
# 1. Wait for service to acquire public IP - if first deploy and yml contains service
# 2. Check the right version through HEADERS
- run: |
wget -Sq http://$(kubectl get service sample-api-svc --namespace=$NON_PROD_NAMESPACE -o jsonpath='{.status.loadBalancer.ingress[*].ip}:{.spec.ports[*].targetPort}')/healthcheck 2>&1 | grep 'HTTP/1.1 200 OK'
deploy_onto_prod_cluster:
docker:
- image: azuresdk/azure-cli-python
environment:
PROD_RESOURCE_GROUP: aks-poc2-euw-rg
PROD_CLUSTER_NAME: aks-poc2-euw
PROD_NAMESPACE: prod-ci-dept
steps:
- checkout
# LOGIN ONTO AZURE WITH EXISTING SERVICE PRINCIPAL
- run: az login --service-principal -u $SERVICE_PRINCIPAL --password $SERVICE_PRINCIPAL_PASS --tenant $SERVICE_TENANT
- run: az account set --subscription $SUBSCRIPTION_NAME_OR_ID
- run: az aks get-credentials --resource-group $PROD_RESOURCE_GROUP --name $PROD_CLUSTER_NAME
- run: az aks install-cli
- run: |
ns_found=$(kubectl get namespace $PROD_NAMESPACE --ignore-not-found=true -o=name | sed 's/namespaces\///g')
if echo $ns_found | grep $PROD_NAMESPACE; then echo 'Namespace already exists.'; else kubectl create namespace $PROD_NAMESPACE; fi
# A bit of a hack to define image version.
- run: cat src/camel.yaml | sed $'s/:latest/:'$(git log -1 --pretty=%h)'/g' | kubectl apply --namespace=$PROD_NAMESPACE -f -
# Ensure deployment was successful
- run: kubectl rollout status deploy/sample-api-deploy --namespace=$PROD_NAMESPACE
# Checks external end-point. TODO:
# 1. Wait for service to acquire public IP - if first deploy and yml contains service
# 2. Check the right version through HEADERS
- run: |
wget -Sq http://$(kubectl get service sample-api-svc --namespace=$PROD_NAMESPACE -o jsonpath='{.status.loadBalancer.ingress[*].ip}:{.spec.ports[*].targetPort}')/healthcheck 2>&1 | grep 'HTTP/1.1 200 OK'
quick_security_scan:
docker:
- image: paulinhu/netcore-docker-build:beta
steps:
- checkout
- run: |
# dotnet restore src
# snyk auth $SNYK_API_KEY
# snyk test --file=src/Sample.Template.Api/obj/project.assets.json --debug
# Actual projects would also use the command below
# snyk monitor --file=src/Sample.Template.Api/obj/project.assets.json
long_running_security_scan:
docker:
- image: paulinhu/netcore-docker-build:beta
steps:
- checkout
- run: |
echo DO SOMETHING VERY SLOW
sleep 60
workflows:
version: 2
continuous_delivery:
jobs:
- build_test_publish_image
#- quick_security_scan
- deploy_onto_ci_cluster:
requires:
- build_test_publish_image
- deploy_onto_prod_cluster:
requires:
- deploy_onto_ci_cluster
nightly:
triggers:
- schedule:
cron: "0 0 * * *"
filters:
branches:
only:
- master
jobs:
- long_running_security_scan
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment