Skip to content

Instantly share code, notes, and snippets.

@pedroelsner
Created January 9, 2019 20:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pedroelsner/efe2b7dfcc0f407c099a7ba0bd474fcf to your computer and use it in GitHub Desktop.
Save pedroelsner/efe2b7dfcc0f407c099a7ba0bd474fcf to your computer and use it in GitHub Desktop.
Pipeline Jenkins Simple: Node + Sonar + Consul + Vault + K8S + AWS ECR + SLACK NOTIFY
node {
try {
def PROJECT = "project-name"
def REPO_GIT = "project.git"
def BRANCH_NAME = "ti"
def IMAGE_VERSION = "$BUILD_NUMBER"
def ENV_DOMAIN = "k8s-ti-company"
def ECR_URL = "12345664.dkr.ecr.sa-east-1.amazonaws.com/$PROJECT"
def DEPLOY_NAME = "$PROJECT-deploy"
def DEPLOY_FILE = "$PROJECT-deploy.yaml"
def SERVICE_NAME = "$PROJECT-service"
def SERVICE_FILE = "$PROJECT-service.yaml"
def SONARQUBE_BIN = "/opt/sonar-scanner/bin"
def SONARQUBE_SERVER = "http://sonar.company.com"
def SONARQUBE_PKEY = "$PROJECT"
def SONARQUBE_DASHBOARD = "$SONARQUBE_SERVER/dashboard?id=$SONARQUBE_PKEY"
def CONSUL_HOST = "http://consul-dev.company.com:8500"
def CONSUL_DL = "https://releases.hashicorp.com/consul/1.1.0/consul_1.1.0_linux_amd64.zip"
def VAULT_HOST = "http://vault-dev.company.com:8200"
def VAULT_TOKEN = "e58a9b13-747b-c29e-92f4-b983c222cd71"
def K8S_NAMESPACE = "$PROJECT"
def KUBECTL = "kubectl --kubeconfig ~jenkins/kube/.kube/config "
def APP_URL = "http://project.k8s-ti-company.com.br/health"
message = "PIPELINE STARTED IN BRANCH $BRANCH_NAME - Build $BUILD_NUMBER"
notifyBuild(message)
stage("cloning_$PROJECT") {
checkout([$class: 'GitSCM',
userRemoteConfigs: [[url: "$REPO_GIT"]],
branches: [[name: "$BRANCH_NAME"]],
credentialsId: 'f2504523-0111-41a4-a9be-f7d2b40163af',
clean: false,
extensions: [[$class: 'SubmoduleOption',
disableSubmodules: false,
parentCredentials: false,
recursiveSubmodules: true,
reference: '',
trackingSubmodules: false]],
doGenerateSubmoduleConfigurations: false,
submoduleCfg: []
])
}
/*stage('unit_tests') {
dir(env.WORKSPACE) {
sh """
npm test
"""
}
}*/
stage('submit_to_SonarQube'){
sh("$SONARQUBE_BIN/sonar-scanner -Dsonar.host.url=$SONARQUBE_SERVER \
-Dsonar.projectKey=$SONARQUBE_PKEY \
-Dsonar.sources=$WORKSPACE/src \
-Dsonar.login=81f000c88504e2407f789dbb5a10512d3c39fadd \
-Dsonar.java.binaries=$WORKSPACE/target; sleep 3")
def SONAR_STATUS = sh(script: "curl -qsG $SONARQUBE_SERVER:9000/api/qualitygates/project_status?projectKey=$SONARQUBE_PKEY | jq -r .projectStatus.status", returnStdout: true).trim()
if ( SONAR_STATUS == "ERROR") {
message = "THE CODE WAS NOT APPROVED BY SONARQUBE, GO CHECK -> $SONARQUBE_DASHBOARD"
notifyBuild(message, "SONARQUBE")
}
}
/* stage('container_up') {
dir(env.WORKSPACE) {
sh(script: "docker-compose up --build -d")
}
}
stage('validate') {
dir(env.WORKSPACE) {
sh """
export JAVA_HOME='/usr/java/jdk1.8.0_112/'
export PATH=/usr/local/bin:/usr/bin:/bin:/opt/maven/bin
mvn -P nexus verify
"""
}
}
stage('container_stop') {
dir(env.WORKSPACE) {
sh """
for services in `docker-compose config --services`; do
docker-compose stop -t1 \$services
done
"""
}
} */
/* stage('setting_up_support_application'){
dir("$WORKSPACE/data"){
echo 'Setting up consul data'
echo 'Setting up vault data'
}
} */
stage('push_container_to_ECR') {
def LOGIN_CMD = sh(script: "aws ecr get-login --profile ti --no-include-email --region sa-east-1", returnStdout: true)
//def LOGIN_CMD = sh(script: "aws ecr get-login --profile ti --region sa-east-1", returnStdout: true)
dir(env.WORKSPACE) {
sh """
${LOGIN_CMD}
docker build -t $ECR_URL:$IMAGE_VERSION -f docker/Dockerfile .
docker push $ECR_URL:$IMAGE_VERSION
"""
}
}
stage('change_image_name') {
dir(env.WORKSPACE) {
sh """
egrep -lRZ '__TAG__' . | xargs -0 -l sed -i -e 's/__TAG__/'$IMAGE_VERSION'/g'
"""
}
}
stage('check_vault_structures') {
dir(env.WORKSPACE) {
def SECRET_STATUS_FILE = "$WORKSPACE/secret.txt"
sh(script: "curl -i -q -s -o $SECRET_STATUS_FILE -H 'X-Vault-Token: $VAULT_TOKEN' -L $VAULT_HOST/v1/secret/contentful-wrapper")
def SECRET = sh(script: "head -n 1 $SECRET_STATUS_FILE | cut -d ' ' -f 2", returnStdout: true).trim()
if (SECRET.equals('200')) {
notifyBuild("VAULT STRUCTURE EXISTS", "INFO")
sh(script: "rm $SECRET_STATUS_FILE")
} else {
sh """
cd data/vault
curl \
-H "X-Vault-Token: $VAULT_TOKEN" \
-H "Content-Type: application/json" \
-X POST -d @secret.json \
-L $VAULT_HOST/v1/secret/contentful-wrapper
rm $SECRET_STATUS_FILE
"""
notifyBuild("VAULT STRUCTURE CREATED", "INFO")
}
}
}
stage('import_consul_keys') {
dir(env.WORKSPACE) {
sh """
export CONSUL_HTTP_ADDR='$CONSUL_HOST'
cd data/consul
wget $CONSUL_DL
echo $CONSUL_DL | awk -F "/" '{print \$6}' | xargs unzip -o
./consul kv import @data.json
"""
}
}
stage('k8s_create_structures') {
dir(env.WORKSPACE) {
sh """
cd kubernetes
$KUBECTL apply -f namespace.yaml
$KUBECTL apply -f configmaps.yaml
$KUBECTL apply -f secrets.yaml
"""
}
}
stage('k8s_create_deploy') {
dir(env.WORKSPACE) {
sh """
cd kubernetes
sed -i s/__TAG__/$IMAGE_VERSION/ $DEPLOY_FILE
$KUBECTL apply -f $DEPLOY_FILE
"""
}
}
stage('k8s_create_service') {
dir(env.WORKSPACE) {
sh """
cd kubernetes
sed -i s/__SERVICE_ENV__/$ENV_DOMAIN/ $SERVICE_FILE
$KUBECTL apply -f $SERVICE_FILE
"""
notifyBuild("APP URL (TI): $APP_URL", "INFO")
}
}
stage('response_check') {
sleep(90)
def APP_STATUS_FILE = sh(script: "curl --write-out %{http_code} --silent --output /dev/null ${APP_URL}|grep -v '%' > $WORKSPACE/health.txt")
def HEALTH = sh(script: "cat $WORKSPACE/health.txt", returnStdout: true).trim()
if (HEALTH.equals('200')) {
notifyBuild("APP UP AND RUNNING", "INFO")
sh(script: "rm $WORKSPACE/health.txt")
} else if (HEALTH.equals('401')) {
notifyBuild("UNAUTHORIRED VERIFY IF IS NEEDED A TOKEN", "INFO")
sh(script: "rm $WORKSPACE/health.txt")
} else {
notifyBuild("K8S POD COULD BEEN RUNNING BUT CHECK HTTP CODE RECEIVED FROM APP", "FAILED")
sh(script: "rm $WORKSPACE/health.txt")
}
}
} catch (error) {
currentBuild.result = "FAILED"
throw error
} finally {
/* dir(env.WORKSPACE) {
sh(script: "docker-compose down")
} */
notifyBuild("", currentBuild.result)
}
}
def notifyBuild(String message, String buildStatus = 'STARTED') {
def SLACK_URL = "https://hooks.slack.com/services/T0523AAYF0/ASDQWE322W/"
def SLACK_TOKEN = "faqweqe3223211111K9"
def SLACK_CHANNEL = "#project"
buildStatus = buildStatus ?: 'SUCCESSFUL'
def subject = "${buildStatus}: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]'"
def summary = "${subject} (${env.JOB_URL})"
if (buildStatus == 'STARTED') {
colorCode = '#FFFF00' // Yellow
} else if (buildStatus == 'SUCCESSFUL' || buildStatus == 'SUCCESS') {
colorCode = '#00FF00' // Green
} else if (buildStatus == 'INFO') {
colorCode = '#0080FF' // Blue
} else {
colorCode = '#FF0000' // Red
}
slackSend (color:"${colorCode}",
baseUrl: SLACK_URL,
token: SLACK_TOKEN,
channel: SLACK_CHANNEL,
message: "${summary} ${message}")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment