everything-as-code: devops und continuous delivery aus sicht des entwicklers. @conlifecycle

60

Upload: mario-leander-reimer

Post on 22-Jan-2018

37 views

Category:

Software


0 download

TRANSCRIPT

Page 1: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle
Page 2: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle

#whoami

Mario-Leander ReimerCheftechnologe, QAware GmbH

- Senior Developer && Architect- 20+ Jahre Erfahrung- #CloudNativeNerd- Open Source Enthusiast

[email protected]://github.com/lreimerhttp://speakerdeck.com/lreimer

// ContinuousLifecycle 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }

Page 3: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle
Page 4: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle

// ContinuousLifecycle 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }

Page 5: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle

// ContinuousLifecycle 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }

Page 6: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle

// ContinuousLifecycle 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }

Page 7: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle
Page 8: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle

// ContinuousLifecycle 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }

Page 9: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle

Software Industrialization ist eine Schlüsselanforderung für erfolgreiches DevOps und

Continuous Delivery.

// ContinuousLifecycle 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }

Page 10: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle

Ein Software-Fließband produziert und liefert die fertige Software an.

// ContinuousLifecycle 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }

Page 11: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle

Software Industrialisierung bedeutet ...

• Hoher Automatisiersgrad von arbeitsintensiven und wiederkehrenden Arbeitsschritten

• Bessere Software-Qualität durch eine abgestimmte Tool-Chain

• Mehr Produktivität und Zufriedenheit der Teams

• Kosten-Effizienz und Wettbewerbsfähigkeit

// ContinuousLifecycle 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }

Page 12: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle

Die IDE ist unsere Werkbank.

Page 13: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle

val softwareIndustrialization = everythingAsCode()

open fun everythingAsCode() =

everythingIsMadeFromCode()

&& everythingIsMadeByCode()

private fun everythingIsMadeFromCode() = true

private fun everythingIsMadeByCode() = true

// ContinuousLifecycle 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }

Page 14: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle

Auf die Domäne kommt es an!Eine beste Programmiersprache gibt es nicht.

// ContinuousLifecycle 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }

Page 15: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle

Die Queste nach dem idealen Polyglot Project Archetype

• Welche Sprachen werden in unseren Projekten in welchen Domänen verwendet?

• Welche Tools verwenden wir für Setup, Build, Code, Test, CI, Infrastructure, Documentation?

• Was davon hat sich bewährt und was eher nicht?

• Gibt es bereits Best Practices oder Anti-Patterns?

+ Wishful Greenfield Thinking!

// ContinuousLifecycle 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }

Page 16: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle

Eine vielsprachige Reise beginnt ...

Page 17: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle
Page 18: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle

Lightweight Developer Provisioning mit Gradle

• [ SEU ] -> Software Entwicklungs Umgebung

• Nutzung von Gradle als Build-Tool für das Setup und die Aktualisierung unserer Entwicklungsumgebungen

• Software-Pakete werden als Dependencies definiert

• Gradle Tasks und Groovy Code statt Shell-Scripting

• Versionskontrolle der SEU Definition und Skripte

• Open Source. http://seu-as-code.io

// ContinuousLifecycle 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }

Page 19: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle

plugins { id 'de.qaware.seu.as.code.base' version '2.4.0' }

import static de.qaware.seu.as.code.plugins.base.Platform.isMac

seuAsCode { seuHome = { if (isMac()) '/Volumes/Everything-as-code' else 'Y:' } projectName = 'Everything-as-code'}

dependencies { // list of software dependencies ... software 'org.groovy-lang:groovy:2.4.7' software 'org.scala-lang:scala:2.11.8' software 'org.jruby:jruby:9.1.4.0'}

// ContinuousLifecycle 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }

Page 20: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle
Page 21: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle

# language: enFunctionality: Authentication and Authorization

Scenario Outline: Check proper login behaviour Given the username "<USERNAME>" And the password "<PASSWORD>" When the user logs into the system Then the login result is "<RESULT>"

Examples: Login data | USERNAME | PASSWORD | RESULT | | mario-leander.reimer | invalidpwd | failure | | unknown | somepwd | failure | | mario-leander.reimer | correctpwd | success |

// ContinuousLifecycle 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }

Page 22: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle

// ContinuousLifecycle 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }

Page 23: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle
Page 24: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle

Maven ist gut. Gradle ist 100x schneller.

• Sehr flexibel und vielseitig einsetzbar.

• Einfache Unterstützung für polyglotte Projekte.

• Build Skripte sind maximal kurz und prägnant.

• Deutlich reduzierte Build-Zeiten durch inkrementelle Builds und Caching

• Zahlreiche neue Features: Composite Builds, Kotlin-basierte Build-Skripte, Performance Verbesserungen, ...

• Regelmäßige Releases. Stabil und ausgereift.

// ContinuousLifecycle 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }

Page 25: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle

apply plugin: 'application'

apply plugin: 'war'

apply plugin: 'kotlin'

apply plugin: 'groovy'

repositories { jcenter() }

dependencies {

providedCompile 'fish.payara.extras:payara-micro:4.1.1.164'

// and many more ...

}

task everythingAsCode() << {

println 'Everything-as-code using Gradle @ ContinuousLifecycle 2017.'

}

// ContinuousLifecycle 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }

Page 26: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle
Page 27: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle

Java ist nach wie vor unsereprimäre Implementierungssprache!

Und das ist gut so!

// ContinuousLifecycle 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }

Page 28: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle

Aber:Kotlin als Alternative zu Java ist einen Blick wert!

// ContinuousLifecycle 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }

Page 29: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle

Warum Kotlin? Und nicht Scala, Clojure, ...

• Für Java Entwickler sehr schnell zu erlernen.

• Sehr ausgewogene Universalsprache.

• Null Safety + Synatctic Sugar + jede Menge andere nützliche Features.

• JDK6 kompatibel. Kleine Library-Größe.

• Sehr guter IDE und Tool Support.

// ContinuousLifecycle 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }

Page 30: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle

@JsonIgnoreProperties(ignoreUnknown = true)data class Book(val title: String, val isbn: String, val author: String)

@ApplicationScopedopen class Bookshelf { private val books = listOf(Book("The Hitchhiker's Guide to the Galaxy", "0345391802")) open fun byIsbn(isbn: String): Book? = books.find { it.isbn == isbn }}

@Path("books")@Produces(MediaType.APPLICATION_JSON)open class BookResource @Inject constructor(private val bookshelf: Bookshelf) { @GET @Path("/{isbn}") open fun byIsbn(@PathParam("isbn") isbn: String): Response { val book = bookshelf.byIsbn(isbn) return if (book != null) Response.ok(book).build() else Response.status(Status.NOT_FOUND).build() }}

@ApplicationPath("api")class BookstoreAPI : Application() { override fun getClasses() = hashSetOf(JacksonFeature::class.java, BookResource::class.java)}

// ContinuousLifecycle 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }

Page 31: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle
Page 32: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle

Willkommen in der JavaScript Wunderwelt.

• Ein Universum für sich!

• Klarer Trend: Single Page Webapplikationen.

• HTML5 + CSS3 + ?

• ? = TypeScript oder

• ? = ECMAScript2015 + Babel

• Rückgrat des Builds: node + npm + webpack

// ContinuousLifecycle 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }

Page 33: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle
Page 34: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle

Grovy + Spock eignen sich für Unit, Integration, Acceptance und UI-Testsclass BookshelfSpec extends Specification { @Subject def bookshelf = new Bookshelf()

@Unroll def "Find book #title by ISBN #isbn"() { when: 'we search a book by ISBN' def book = bookshelf.byIsbn(isbn)

then: 'the title and author are correct' book?.title == title book?.author == author

where: isbn || title | author "0345391802" || "The Hitchhiker's Guide to the Galaxy" | "Douglas Adams" "0345391829" || "Life, the Universe and Everything" | "Douglas Adams" }}

// ContinuousLifecycle 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }

Page 35: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle

Scala und Gatling für lesbare und performante Last-Testsclass BooksPerformanceTest extends Simulation { val conf = http.baseURL("http://localhost:18080").acceptHeader("application/json")

val feeder = csv("books.csv").random

val scn = scenario("Book Search") .exec(http("Get all books").get("/api/books")) .during(30 seconds) { feed(feeder) .exec(http("Get book by title ${Title}").get("/api/books?title=${Title}")) .pause(1 second) .exec(http("Get book with ISBN ${ISBN}").get("/api/books/${ISBN}")) }

setUp(scn.inject(atOnceUsers(10), rampUsers(50) over (30 seconds))) .assertions(global.responseTime.max.lessThan(5000)) .protocols(conf)}

// ContinuousLifecycle 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }

Page 36: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle
Page 37: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle

Definition einer Build-Pipeline per Jenkinsfile und Groovy#!/usr/bin/env groovy

node {

stage 'Checkout SCM'

checkout scm

stage 'Build/Analyse/Test'

sh './gradlew clean build'

archiveUnitTestResults()

archiveDistributions()

stage 'Dockerize'

sh './gradlew buildDockerImage'

stage 'Generate Documentation'

sh './gradlew asciidoctor'

}

// ContinuousLifecycle 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }

Page 38: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle

// ContinuousLifecycle 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }

Page 39: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle
Page 40: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle

Architektur-Definition und Prüfung mit QAvalidator für wartbaren Code.architecture(name: "Mail Example", prefix: "tview", reflexMLversion: "1.0") {

excludes "java.lang.*"

api "JavaMail" : "javax.mail.*"

component "Mail" {

api "IMail" : "de.qaware.mail.*"

impl ["de.qaware.mail.impl.*", "de.qaware.mail.impl2.*"]

uses "JavaMail"

component "MailSender" {

api ["de.qaware.mail.sender.*", "javax.mail.*"]

impl "de.qaware.mail.impl.javamail.JavaMailSender"

uses "JavaMail"

}

}

}

// ContinuousLifecycle 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }

Page 41: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle
Page 42: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle

Docker, Docker, Docker, ...

FROM qaware-oss-docker-registry.bintray.io/base/alpine-k8s-openjdk8:8u121MAINTAINER M.-Leander Reimer <[email protected]>

RUN mkdir -p /appADD build/distributions/everything-as-code-1.2.3.tar /app

WORKDIR /app/everything-as-code-1.2.3RUN chmod 755 bin/everything-as-code

EXPOSE 18080

CMD ./bin/everything-as-code

// ContinuousLifecycle 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }

Page 43: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle

Cluster Orchestration mit K8s et.al.

---apiVersion: extensions/v1beta1kind: Deploymentmetadata: name: everything-as-codespec: replicas: 2 template: metadata: labels: tier: backend spec: containers: - name: everything-as-code image: "qaware-oss-docker-registry.bintray.io/lreimer/everything-as-code:1.2.3" ports: - containerPort: 18080 env: - name: PORT value: 18080

// ContinuousLifecycle 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }

Page 44: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle

Einfache Provisionierung mit Ansible.

---

# file: jenkinsci.yml

- hosts: jenkinsci

remote_user: root

tasks:

- debug: msg="Creating a Jenkins pipeline job on {{ inventory_hostname }}"

- jenkins_job:

name: Everything-as-code Pipeline

config: "{{ lookup('file', 'templates/pipeline-job.xml') }}"

url: "http://{{ inventory_hostname }}"

user: admin

password: admin

// ContinuousLifecycle 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }

Page 45: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle

Vagrant und Ruby zum Setup lokaler VMs.

require 'yaml'

$setup = <<SCRIPT

sudo apt-add-repository ppa:ansible/ansible

sudo apt-get update

sudo apt-get install -y ansible sshpass

SCRIPT

Vagrant.configure("2") do |config|

config.vm.box = "ubuntu/trusty32"

settings = YAML.load_file 'src/vagrant/vagrant.yml'

config.vm.provider "virtualbox" do |vb|

vb.name = settings['vm']['name']

vb.gui = false

vb.memory = "512"

end

config.vm.provision "shell", inline: $setup

end

// ContinuousLifecycle 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }

Page 46: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle
Page 47: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle

Ja, wir brauchen Dokumentation!

• Und nein. Der Quellcode ist nicht genug!

• Technische Dokumente mit Word sind ! " #

• Dokumentation sollte neben dem Quellcode liegen: change code, change docs.

• Schnell und einfach zu schreiben.

• Unterstützung für Code, Bilder, Diagramme

// ContinuousLifecycle 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }

Page 48: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle

// Beispiel Architektur-Dokumentation mit arc42 (https://arc42.github.io)

:imagesdir: ./images

= image:qaware-logo.png[QAware GmbH,2016] Everything-as-code:toc-title: Table of Contents:toc:

[[section-introduction-and-goals]]== Introduction and Goals

The introduction to the architecture documentation should list the driving forcesthat software architects must consider in their decisions.

=== Requirements Overview

=== Quality Goals

=== Stakeholders

<<<<include::02_architecture_constraints.adoc[]

// further includes for the remaining sections

// ContinuousLifecycle 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }

Page 49: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle

Mit AsciidoctorJ und Gradle zum fertigen Dokument.

plugins { id "org.asciidoctor.convert" version "1.5.3" }

asciidoctorj { version = '1.5.4.1' }

asciidoctor {

sourceDir 'src/docs/architecture'

resources {

from('src/docs/architecture') {

include 'images/**/*.png'

include 'images/**/*.jpg'

}

}

backends ['html5', 'pdf']

options doctype: 'article'

attributes 'source-highlighter': 'coderay'

}

// ContinuousLifecycle 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }

Page 50: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle

Architectur-Dokumentation mit Structurizr

def workspace = new Workspace("Everything-as-code", "The system context of Everything-as-code.")def model = workspace.model

// create a model and the software system we want to describedef bookApp = model.addSoftwareSystem("Book Application", "The best source to get info on books.")

// create the various types of people (roles) that use the software systemdef anonymousUser = model.addPerson("Anonymous User", "Anybody on the web.")anonymousUser.uses(bookApp, "Searches for books and views details.")

def browser = bookApp.addContainer("Web Browser", "Allows users to view information about books", "Edge, Chrome, Firefox")anonymousUser.uses(browser, "Views information from and makes requests to")

def webApp = bookApp.addContainer("Web Application", "Hosts the browser-based web application and services", "Payara Fish")browser.uses(webApp, "uses [JSON/HTTPS]")

// ContinuousLifecycle 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }

Page 51: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle

// ContinuousLifecycle 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }

Page 52: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle
Page 53: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle

These slides were written in Markdown.

---## [fit] These slides were written in Markdown.

- This is for real programmers! :smiley:- Several open source projects available- Use HTML and JavaScript alternatively.

---

// ContinuousLifecycle 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }

Page 54: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle
Page 55: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle

Use the right tool for the job!

Page 56: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle
Page 57: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle

Alles mit Augenmaß!Der richtige Technologie-Stack hängt vom Team,

dem Projekt-Kontext und unseren Kunden ab.

// ContinuousLifecycle 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }

Page 58: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle

Fork me on GitHub.https://github.com/lreimer/everything-as-code

// ContinuousLifecycle 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }

Page 59: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle

// ContinuousLifecycle 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }

Page 60: Everything-as-code: DevOps und Continuous Delivery aus Sicht des Entwicklers. @ConLifecycle