Advertisement
Guest User

Untitled

a guest
Feb 14th, 2018
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 16.79 KB | None | 0 0
  1. # This file is a template, and might need editing before it works on your project.
  2. # Auto DevOps
  3. # This CI/CD configuration provides a standard pipeline for
  4. # * building a Docker image (using a buildpack if necessary),
  5. # * storing the image in the container registry,
  6. # * running tests from a buildpack,
  7. # * running code quality analysis,
  8. # * creating a review app for each topic branch,
  9. # * and continuous deployment to production
  10. #
  11. # In order to deploy, you must have a Kubernetes cluster configured either
  12. # via a project integration, or via group/project variables.
  13. # AUTO_DEVOPS_DOMAIN must also be set as a variable at the group or project
  14. # level, or manually added below.
  15. #
  16. # If you want to deploy to staging first, or enable canary deploys,
  17. # uncomment the relevant jobs in the pipeline below.
  18. #
  19. # If Auto DevOps fails to detect the proper buildpack, or if you want to
  20. # specify a custom buildpack, set a project variable `BUILDPACK_URL` to the
  21. # repository URL of the buildpack.
  22. # e.g. BUILDPACK_URL=https://github.com/heroku/heroku-buildpack-ruby.git#v142
  23. # If you need multiple buildpacks, add a file to your project called
  24. # `.buildpacks` that contains the URLs, one on each line, in order.
  25. # Note: Auto CI does not work with multiple buildpacks yet
  26.  
  27. image: alpine:latest
  28.  
  29. variables:
  30. # AUTO_DEVOPS_DOMAIN is the application deployment domain and should be set as a variable at the group or project level.
  31. # AUTO_DEVOPS_DOMAIN: domain.example.com
  32.  
  33. POSTGRES_USER: user
  34. POSTGRES_PASSWORD: testing-password
  35. POSTGRES_ENABLED: "true"
  36. POSTGRES_DB: $CI_ENVIRONMENT_SLUG
  37.  
  38. KUBERNETES_VERSION: 1.8.6
  39. HELM_VERSION: 2.6.1
  40. CODECLIMATE_VERSION: 0.69.0
  41.  
  42. stages:
  43. - build
  44. - test
  45. - review
  46. - dast
  47. - staging
  48. - canary
  49. - production
  50. - performance
  51. - cleanup
  52.  
  53. build:
  54. stage: build
  55. image: docker:git
  56. services:
  57. - docker:dind
  58. variables:
  59. DOCKER_DRIVER: overlay2
  60. script:
  61. - setup_docker
  62. - build
  63. only:
  64. - branches
  65.  
  66. test:
  67. services:
  68. - postgres:latest
  69. variables:
  70. POSTGRES_DB: test
  71. stage: test
  72. image: gliderlabs/herokuish:latest
  73. script:
  74. - setup_test_db
  75. - cp -R . /tmp/app
  76. - /bin/herokuish buildpack test
  77. only:
  78. - branches
  79.  
  80. codequality:
  81. image: docker:latest
  82. variables:
  83. DOCKER_DRIVER: overlay2
  84. allow_failure: true
  85. services:
  86. - docker:dind
  87. script:
  88. - setup_docker
  89. - codeclimate
  90. artifacts:
  91. paths: [codeclimate.json]
  92.  
  93. performance:
  94. stage: performance
  95. image: docker:latest
  96. variables:
  97. DOCKER_DRIVER: overlay2
  98. allow_failure: true
  99. services:
  100. - docker:dind
  101. script:
  102. - setup_docker
  103. - performance
  104. artifacts:
  105. paths:
  106. - performance.json
  107. - sitespeed-results/
  108. only:
  109. refs:
  110. - branches
  111. kubernetes: active
  112.  
  113. sast:
  114. image: docker:latest
  115. variables:
  116. DOCKER_DRIVER: overlay2
  117. allow_failure: true
  118. services:
  119. - docker:dind
  120. script:
  121. - setup_docker
  122. - sast
  123. artifacts:
  124. paths: [gl-sast-report.json]
  125.  
  126. sast:container:
  127. image: docker:latest
  128. variables:
  129. DOCKER_DRIVER: overlay2
  130. allow_failure: true
  131. services:
  132. - docker:dind
  133. script:
  134. - setup_docker
  135. - sast_container
  136. artifacts:
  137. paths: [gl-sast-container-report.json]
  138.  
  139. dast:
  140. stage: dast
  141. allow_failure: true
  142. image: owasp/zap2docker-stable
  143. variables:
  144. POSTGRES_DB: "false"
  145. script:
  146. - dast
  147. artifacts:
  148. paths: [gl-dast-report.json]
  149. only:
  150. refs:
  151. - branches
  152. kubernetes: active
  153. except:
  154. - master
  155.  
  156. review:
  157. stage: review
  158. script:
  159. - check_kube_domain
  160. - install_dependencies
  161. - download_chart
  162. - ensure_namespace
  163. - install_tiller
  164. - create_secret
  165. - deploy
  166. - persist_environment_url
  167. environment:
  168. name: review/$CI_COMMIT_REF_NAME
  169. url: http://$CI_PROJECT_PATH_SLUG-$CI_ENVIRONMENT_SLUG.$AUTO_DEVOPS_DOMAIN
  170. on_stop: stop_review
  171. artifacts:
  172. paths: [environment_url.txt]
  173. only:
  174. refs:
  175. - branches
  176. kubernetes: active
  177. except:
  178. - master
  179.  
  180. stop_review:
  181. stage: cleanup
  182. variables:
  183. GIT_STRATEGY: none
  184. script:
  185. - install_dependencies
  186. - delete
  187. environment:
  188. name: review/$CI_COMMIT_REF_NAME
  189. action: stop
  190. when: manual
  191. allow_failure: true
  192. only:
  193. refs:
  194. - branches
  195. kubernetes: active
  196. except:
  197. - master
  198.  
  199. # Keys that start with a dot (.) will not be processed by GitLab CI.
  200. # Staging and canary jobs are disabled by default, to enable them
  201. # remove the dot (.) before the job name.
  202. # https://docs.gitlab.com/ee/ci/yaml/README.html#hidden-keys
  203.  
  204. # Staging deploys are disabled by default since
  205. # continuous deployment to production is enabled by default
  206. # If you prefer to automatically deploy to staging and
  207. # only manually promote to production, enable this job by removing the dot (.),
  208. # and uncomment the `when: manual` line in the `production` job.
  209.  
  210. .staging:
  211. stage: staging
  212. script:
  213. - check_kube_domain
  214. - install_dependencies
  215. - download_chart
  216. - ensure_namespace
  217. - install_tiller
  218. - create_secret
  219. - deploy
  220. environment:
  221. name: staging
  222. url: http://$CI_PROJECT_PATH_SLUG-staging.$AUTO_DEVOPS_DOMAIN
  223. only:
  224. refs:
  225. - master
  226. kubernetes: active
  227.  
  228. # Canaries are disabled by default, but if you want them,
  229. # and know what the downsides are, enable this job by removing the dot (.),
  230. # and uncomment the `when: manual` line in the `production` job.
  231.  
  232. .canary:
  233. stage: canary
  234. script:
  235. - check_kube_domain
  236. - install_dependencies
  237. - download_chart
  238. - ensure_namespace
  239. - install_tiller
  240. - create_secret
  241. - deploy canary
  242. environment:
  243. name: production
  244. url: http://$CI_PROJECT_PATH_SLUG.$AUTO_DEVOPS_DOMAIN
  245. when: manual
  246. only:
  247. refs:
  248. - master
  249. kubernetes: active
  250.  
  251. # This job continuously deploys to production on every push to `master`.
  252. # To make this a manual process, either because you're enabling `staging`
  253. # or `canary` deploys, or you simply want more control over when you deploy
  254. # to production, uncomment the `when: manual` line in the `production` job.
  255.  
  256. production:
  257. stage: production
  258. script:
  259. - check_kube_domain
  260. - install_dependencies
  261. - download_chart
  262. - ensure_namespace
  263. - install_tiller
  264. - create_secret
  265. - deploy
  266. - delete canary
  267. - persist_environment_url
  268. environment:
  269. name: production
  270. url: http://$CI_PROJECT_PATH_SLUG.$AUTO_DEVOPS_DOMAIN
  271. artifacts:
  272. paths: [environment_url.txt]
  273. # when: manual
  274. only:
  275. refs:
  276. - master
  277. kubernetes: active
  278.  
  279. # ---------------------------------------------------------------------------
  280.  
  281. .auto_devops: &auto_devops |
  282. # Auto DevOps variables and functions
  283. [[ "$TRACE" ]] && set -x
  284. auto_database_url=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${CI_ENVIRONMENT_SLUG}-postgres:5432/${POSTGRES_DB}
  285. export DATABASE_URL=${DATABASE_URL-$auto_database_url}
  286. export CI_APPLICATION_REPOSITORY=$CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG
  287. export CI_APPLICATION_TAG=$CI_COMMIT_SHA
  288. export CI_CONTAINER_NAME=ci_job_build_${CI_JOB_ID}
  289. export TILLER_NAMESPACE=$KUBE_NAMESPACE
  290.  
  291. function sast_container() {
  292. if [[ -n "$CI_REGISTRY_USER" ]]; then
  293. echo "Logging to GitLab Container Registry with CI credentials..."
  294. docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY"
  295. echo ""
  296. fi
  297.  
  298. docker run -d --name db arminc/clair-db:latest
  299. docker run -p 6060:6060 --link db:postgres -d --name clair arminc/clair-local-scan:v2.0.1
  300. apk add -U wget ca-certificates
  301. docker pull ${CI_APPLICATION_REPOSITORY}:${CI_APPLICATION_TAG}
  302. wget https://github.com/arminc/clair-scanner/releases/download/v8/clair-scanner_linux_amd64
  303. mv clair-scanner_linux_amd64 clair-scanner
  304. chmod +x clair-scanner
  305. touch clair-whitelist.yml
  306. ./clair-scanner -c http://docker:6060 --ip $(hostname -i) -r gl-sast-container-report.json -l clair.log -w clair-whitelist.yml ${CI_APPLICATION_REPOSITORY}:${CI_APPLICATION_TAG} || true
  307. }
  308.  
  309. function codeclimate() {
  310. cc_opts="--env CODECLIMATE_CODE="$PWD" \
  311. --volume "$PWD":/code \
  312. --volume /var/run/docker.sock:/var/run/docker.sock \
  313. --volume /tmp/cc:/tmp/cc"
  314.  
  315. docker run ${cc_opts} "codeclimate/codeclimate:${CODECLIMATE_VERSION}" init
  316. docker run ${cc_opts} "codeclimate/codeclimate:${CODECLIMATE_VERSION}" analyze -f json > codeclimate.json
  317. }
  318.  
  319. function sast() {
  320. case "$CI_SERVER_VERSION" in
  321. *-ee)
  322. # Extract "MAJOR.MINOR" from CI_SERVER_VERSION and generate "MAJOR-MINOR-stable"
  323. SAST_VERSION=$(echo "$CI_SERVER_VERSION" | sed 's/^\([0-9]*\)\.\([0-9]*\).*/\1-\2-stable/')
  324.  
  325. docker run --volume "$PWD:/code" \
  326. --volume /var/run/docker.sock:/var/run/docker.sock \
  327. "registry.gitlab.com/gitlab-org/security-products/sast:$SAST_VERSION" /app/bin/run /code
  328. ;;
  329. *)
  330. echo "GitLab EE is required"
  331. ;;
  332. esac
  333. }
  334.  
  335. function deploy() {
  336. track="${1-stable}"
  337. name="$CI_ENVIRONMENT_SLUG"
  338.  
  339. if [[ "$track" != "stable" ]]; then
  340. name="$name-$track"
  341. fi
  342.  
  343. replicas="1"
  344. service_enabled="false"
  345. postgres_enabled="$POSTGRES_ENABLED"
  346. # canary uses stable db
  347. [[ "$track" == "canary" ]] && postgres_enabled="false"
  348.  
  349. env_track=$( echo $track | tr -s '[:lower:]' '[:upper:]' )
  350. env_slug=$( echo ${CI_ENVIRONMENT_SLUG//-/_} | tr -s '[:lower:]' '[:upper:]' )
  351.  
  352. if [[ "$track" == "stable" ]]; then
  353. # for stable track get number of replicas from `PRODUCTION_REPLICAS`
  354. eval new_replicas=\$${env_slug}_REPLICAS
  355. service_enabled="true"
  356. else
  357. # for all tracks get number of replicas from `CANARY_PRODUCTION_REPLICAS`
  358. eval new_replicas=\$${env_track}_${env_slug}_REPLICAS
  359. fi
  360. if [[ -n "$new_replicas" ]]; then
  361. replicas="$new_replicas"
  362. fi
  363.  
  364. if [[ "$CI_PROJECT_VISIBILITY" != "public" ]]; then
  365. secret_name='gitlab-registry'
  366. else
  367. secret_name=''
  368. fi
  369.  
  370. helm upgrade --install \
  371. --wait \
  372. --set service.enabled="$service_enabled" \
  373. --set releaseOverride="$CI_ENVIRONMENT_SLUG" \
  374. --set image.repository="$CI_APPLICATION_REPOSITORY" \
  375. --set image.tag="$CI_APPLICATION_TAG" \
  376. --set image.pullPolicy=IfNotPresent \
  377. --set image.secrets[0].name="$secret_name" \
  378. --set application.track="$track" \
  379. --set application.database_url="$DATABASE_URL" \
  380. --set service.url="$CI_ENVIRONMENT_URL" \
  381. --set replicaCount="$replicas" \
  382. --set postgresql.enabled="$postgres_enabled" \
  383. --set postgresql.nameOverride="postgres" \
  384. --set postgresql.postgresUser="$POSTGRES_USER" \
  385. --set postgresql.postgresPassword="$POSTGRES_PASSWORD" \
  386. --set postgresql.postgresDatabase="$POSTGRES_DB" \
  387. --namespace="$KUBE_NAMESPACE" \
  388. --version="$CI_PIPELINE_ID-$CI_JOB_ID" \
  389. "$name" \
  390. chart/
  391. }
  392.  
  393. function install_dependencies() {
  394. apk add -U openssl curl tar gzip bash ca-certificates git
  395. wget -q -O /etc/apk/keys/sgerrand.rsa.pub https://raw.githubusercontent.com/sgerrand/alpine-pkg-glibc/master/sgerrand.rsa.pub
  396. wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.23-r3/glibc-2.23-r3.apk
  397. apk add glibc-2.23-r3.apk
  398. rm glibc-2.23-r3.apk
  399.  
  400. curl "https://kubernetes-helm.storage.googleapis.com/helm-v${HELM_VERSION}-linux-amd64.tar.gz" | tar zx
  401. mv linux-amd64/helm /usr/bin/
  402. helm version --client
  403.  
  404. curl -L -o /usr/bin/kubectl "https://storage.googleapis.com/kubernetes-release/release/v${KUBERNETES_VERSION}/bin/linux/amd64/kubectl"
  405. chmod +x /usr/bin/kubectl
  406. kubectl version --client
  407. }
  408.  
  409. function setup_docker() {
  410. if ! docker info &>/dev/null; then
  411. if [ -z "$DOCKER_HOST" -a "$KUBERNETES_PORT" ]; then
  412. export DOCKER_HOST='tcp://localhost:2375'
  413. fi
  414. fi
  415. }
  416.  
  417. function setup_test_db() {
  418. if [ -z ${KUBERNETES_PORT+x} ]; then
  419. DB_HOST=postgres
  420. else
  421. DB_HOST=localhost
  422. fi
  423. export DATABASE_URL="postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${DB_HOST}:5432/${POSTGRES_DB}"
  424. }
  425.  
  426. function download_chart() {
  427. if [[ ! -d chart ]]; then
  428. auto_chart=${AUTO_DEVOPS_CHART:-gitlab/auto-deploy-app}
  429. auto_chart_name=$(basename $auto_chart)
  430. auto_chart_name=${auto_chart_name%.tgz}
  431. else
  432. auto_chart="chart"
  433. auto_chart_name="chart"
  434. fi
  435.  
  436. helm init --client-only
  437. helm repo add gitlab https://charts.gitlab.io
  438. if [[ ! -d "$auto_chart" ]]; then
  439. helm fetch ${auto_chart} --untar
  440. fi
  441. if [ "$auto_chart_name" != "chart" ]; then
  442. mv ${auto_chart_name} chart
  443. fi
  444.  
  445. helm dependency update chart/
  446. helm dependency build chart/
  447. }
  448.  
  449. function ensure_namespace() {
  450. kubectl describe namespace "$KUBE_NAMESPACE" || kubectl create namespace "$KUBE_NAMESPACE"
  451. }
  452.  
  453. function check_kube_domain() {
  454. if [ -z ${AUTO_DEVOPS_DOMAIN+x} ]; then
  455. echo "In order to deploy or use Review Apps, AUTO_DEVOPS_DOMAIN variable must be set"
  456. echo "You can do it in Auto DevOps project settings or defining a secret variable at group or project level"
  457. echo "You can also manually add it in .gitlab-ci.yml"
  458. false
  459. else
  460. true
  461. fi
  462. }
  463.  
  464. function build() {
  465.  
  466. if [[ -n "$CI_REGISTRY_USER" ]]; then
  467. echo "Logging to GitLab Container Registry with CI credentials..."
  468. docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY"
  469. echo ""
  470. fi
  471.  
  472. if [[ -f Dockerfile ]]; then
  473. echo "Building Dockerfile-based application..."
  474. docker build -t "$CI_APPLICATION_REPOSITORY:$CI_APPLICATION_TAG" .
  475. else
  476. echo "Building Heroku-based application using gliderlabs/herokuish docker image..."
  477. docker run -i --name="$CI_CONTAINER_NAME" -v "$(pwd):/tmp/app:ro" gliderlabs/herokuish /bin/herokuish buildpack build
  478. docker commit "$CI_CONTAINER_NAME" "$CI_APPLICATION_REPOSITORY:$CI_APPLICATION_TAG"
  479. docker rm "$CI_CONTAINER_NAME" >/dev/null
  480. echo ""
  481.  
  482. echo "Configuring $CI_APPLICATION_REPOSITORY:$CI_APPLICATION_TAG docker image..."
  483. docker create --expose 5000 --env PORT=5000 --name="$CI_CONTAINER_NAME" "$CI_APPLICATION_REPOSITORY:$CI_APPLICATION_TAG" /bin/herokuish procfile start web
  484. docker commit "$CI_CONTAINER_NAME" "$CI_APPLICATION_REPOSITORY:$CI_APPLICATION_TAG"
  485. docker rm "$CI_CONTAINER_NAME" >/dev/null
  486. echo ""
  487. fi
  488.  
  489. echo "Pushing to GitLab Container Registry..."
  490. docker push "$CI_APPLICATION_REPOSITORY:$CI_APPLICATION_TAG"
  491. echo ""
  492. }
  493.  
  494. function install_tiller() {
  495. echo "Checking Tiller..."
  496. helm init --upgrade
  497. kubectl rollout status -n "$TILLER_NAMESPACE" -w "deployment/tiller-deploy"
  498. if ! helm version --debug; then
  499. echo "Failed to init Tiller."
  500. return 1
  501. fi
  502. echo ""
  503. }
  504.  
  505. function create_secret() {
  506. echo "Create secret..."
  507. if [[ "$CI_PROJECT_VISIBILITY" == "public" ]]; then
  508. return
  509. fi
  510.  
  511. kubectl create secret -n "$KUBE_NAMESPACE" \
  512. docker-registry gitlab-registry \
  513. --docker-server="$CI_REGISTRY" \
  514. --docker-username="$CI_REGISTRY_USER" \
  515. --docker-password="$CI_REGISTRY_PASSWORD" \
  516. --docker-email="$GITLAB_USER_EMAIL" \
  517. -o yaml --dry-run | kubectl replace -n "$KUBE_NAMESPACE" --force -f -
  518. }
  519.  
  520. function dast() {
  521. export CI_ENVIRONMENT_URL=$(cat environment_url.txt)
  522.  
  523. mkdir /zap/wrk/
  524. /zap/zap-baseline.py -J gl-dast-report.json -t "$CI_ENVIRONMENT_URL" || true
  525. cp /zap/wrk/gl-dast-report.json .
  526. }
  527.  
  528. function performance() {
  529. export CI_ENVIRONMENT_URL=$(cat environment_url.txt)
  530.  
  531. mkdir gitlab-exporter
  532. wget -O gitlab-exporter/index.js https://gitlab.com/gitlab-org/gl-performance/raw/10-5/index.js
  533.  
  534. mkdir sitespeed-results
  535.  
  536. if [ -f .gitlab-urls.txt ]
  537. then
  538. sed -i -e 's@^@'"$CI_ENVIRONMENT_URL"'@' .gitlab-urls.txt
  539. docker run --shm-size=1g --rm -v "$(pwd)":/sitespeed.io sitespeedio/sitespeed.io:6.3.1 --plugins.add ./gitlab-exporter --outputFolder sitespeed-results .gitlab-urls.txt
  540. else
  541. docker run --shm-size=1g --rm -v "$(pwd)":/sitespeed.io sitespeedio/sitespeed.io:6.3.1 --plugins.add ./gitlab-exporter --outputFolder sitespeed-results "$CI_ENVIRONMENT_URL"
  542. fi
  543.  
  544. mv sitespeed-results/data/performance.json performance.json
  545. }
  546.  
  547. function persist_environment_url() {
  548. echo $CI_ENVIRONMENT_URL > environment_url.txt
  549. }
  550.  
  551. function delete() {
  552. track="${1-stable}"
  553. name="$CI_ENVIRONMENT_SLUG"
  554.  
  555. if [[ "$track" != "stable" ]]; then
  556. name="$name-$track"
  557. fi
  558.  
  559. if [[ -n "$(helm ls -q "^$name$")" ]]; then
  560. helm delete "$name"
  561. fi
  562. }
  563.  
  564. before_script:
  565. - *auto_devops
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement