Everything-as-code. Ein polyglottes Abenteuer. #jax2017

51
Everything-as-code. Ein polyglottes Abenteuer. // JAX 2017 // Everything-as-code -> { created with and by @LeanderReimer @qaware } 1

Transcript of Everything-as-code. Ein polyglottes Abenteuer. #jax2017

Page 1: Everything-as-code. Ein polyglottes Abenteuer. #jax2017

Everything-as-code.Ein polyglottes Abenteuer.

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

Page 2: Everything-as-code. Ein polyglottes Abenteuer. #jax2017

#whoami

Mario-Leander ReimerCheftechnologe, QAware GmbH• Vollblut Entwickler &&

Architekt

• #CloudNativeNerd

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

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

Page 3: Everything-as-code. Ein polyglottes Abenteuer. #jax2017

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

Page 4: Everything-as-code. Ein polyglottes Abenteuer. #jax2017

Welche Sprache verwenden echte Programmierer?

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

Page 5: Everything-as-code. Ein polyglottes Abenteuer. #jax2017

Meine #FirstSevenLanguages

• Pascal

• Basic

• C / C++

• Assembler

• PHP

• Java

• C#

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

Page 6: Everything-as-code. Ein polyglottes Abenteuer. #jax2017

Meine #LastSevenLanguages

• Java

• Groovy

• TypeScript

• Ruby

• Kotlin

• Scala

• Go

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

Page 7: Everything-as-code. Ein polyglottes Abenteuer. #jax2017

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

Page 8: Everything-as-code. Ein polyglottes Abenteuer. #jax2017

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

Page 9: Everything-as-code. Ein polyglottes Abenteuer. #jax2017

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

Page 10: Everything-as-code. Ein polyglottes Abenteuer. #jax2017

Es gibt keine einstimmige Meinung ...• http://spectrum.ieee.org/computing/software/

the-2016-top-programming-languages

• https://www.sitepoint.com/whats-best-programming-language-learn-2015/

• https://jaxenter.de/programmiersprachen-rankings-q1-2017-54308

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

Page 11: Everything-as-code. Ein polyglottes Abenteuer. #jax2017

Die beste Programmiersprache gibt es nicht!Auf den Kontext kommt es an.

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

Page 12: Everything-as-code. Ein polyglottes Abenteuer. #jax2017

Die IDE ist unsere Werkbank.

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

Page 13: Everything-as-code. Ein polyglottes Abenteuer. #jax2017

Unsere Definition von Software Industrialisierung

• Hat nichts mit billiger Arbeitskraft zu tun!

• Hoher Automatisiersgrad von arbeitsintensiven und wiederkehrenden Arbeitsschritten

• Höhere Software-Qualität durch abgestimmte Tool-Chain

• Mehr Produktivität und Zufriedenheit der Teams

• Bessere Kosten-Effizienz und Wettbewerbsfähigkeit

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

Page 14: Everything-as-code. Ein polyglottes Abenteuer. #jax2017

Wäre es nicht cool wenn ...

open fun everythingAsCode() : Boolean {

everytingIsMadeFromCode() && everythingIsMadeByCode()

}

val softwareIndustrialization = everythingAsCode()

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

Page 15: Everything-as-code. Ein polyglottes Abenteuer. #jax2017

The Quest for an ideal Polyglot Project Archetype

• Welche Sprachen werden in unseren Projekten verwendet?

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

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

• Gibt es bereits Best Practices für den Einsatz in der Praxis?

+ Wishful Greenfield Thinking!

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

Page 16: Everything-as-code. Ein polyglottes Abenteuer. #jax2017

SEU-as-code

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

Page 17: Everything-as-code. Ein polyglottes Abenteuer. #jax2017

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 ausgedrückt

• Gradle Tasks and Groovy Skripte statt Shell-Scripting

• Versionskontrolle der SEU Definition und Skripte

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

Page 18: Everything-as-code. Ein polyglottes Abenteuer. #jax2017

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'}

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

Page 19: Everything-as-code. Ein polyglottes Abenteuer. #jax2017

Build-as-code

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

Page 20: Everything-as-code. Ein polyglottes Abenteuer. #jax2017

Maven ist gut. Gradle ist besser.

• Sehr flexibel und vielseitig einsetzbar.

• Einfache Unterstützung für Polyglotte Projekte.

• Build Skripte sind maximal kurz und prägnant.

• Drastisch reduzierte Build-Zeiten durch Incremental Builds.

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

• Regelmäßige Releases. Stabil und ausgereift.

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

Page 21: Everything-as-code. Ein polyglottes Abenteuer. #jax2017

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 @ JAX 2017.'

}

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

Page 22: Everything-as-code. Ein polyglottes Abenteuer. #jax2017

Main-as-code

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

Page 23: Everything-as-code. Ein polyglottes Abenteuer. #jax2017

Java ist nach wie vor dieprimäre Implementierungssprache!

Und das ist gut so!

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

Page 24: Everything-as-code. Ein polyglottes Abenteuer. #jax2017

Für die Mutigen:Kotlin als ernsthafte Alternative zu Java.

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

Page 25: Everything-as-code. Ein polyglottes Abenteuer. #jax2017

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.

• Wishful Greenfield Thinking.// JAX 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware } 25

Page 26: Everything-as-code. Ein polyglottes Abenteuer. #jax2017

@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)}

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

Page 27: Everything-as-code. Ein polyglottes Abenteuer. #jax2017

Frontend-as-code

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

Page 28: Everything-as-code. Ein polyglottes Abenteuer. #jax2017

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

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

Page 29: Everything-as-code. Ein polyglottes Abenteuer. #jax2017

Test-as-code

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

Page 30: Everything-as-code. Ein polyglottes Abenteuer. #jax2017

Groovy und Spock für Unit & Integration Tests

class 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" }}

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

Page 31: Everything-as-code. Ein polyglottes Abenteuer. #jax2017

Scala und Gatling für 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)}

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

Page 32: Everything-as-code. Ein polyglottes Abenteuer. #jax2017

Pipeline-as-code

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

Page 33: Everything-as-code. Ein polyglottes Abenteuer. #jax2017

Definition der Build-Pipeline per Jenkinsfile

#!/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'

}

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

Page 34: Everything-as-code. Ein polyglottes Abenteuer. #jax2017

Infrastructure-as-code

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

Page 35: Everything-as-code. Ein polyglottes Abenteuer. #jax2017

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.1.tar /app

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

EXPOSE 18080

CMD ./bin/everything-as-code

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

Page 36: Everything-as-code. Ein polyglottes Abenteuer. #jax2017

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

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

Page 37: Everything-as-code. Ein polyglottes Abenteuer. #jax2017

Provisionierung mit Ansible (und Python)

---

# 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

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

Page 38: Everything-as-code. Ein polyglottes Abenteuer. #jax2017

Cluster Orchestration mit Kubernetes

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

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

Page 39: Everything-as-code. Ein polyglottes Abenteuer. #jax2017

Documentation-as-code

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

Page 40: Everything-as-code. Ein polyglottes Abenteuer. #jax2017

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

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

Page 41: Everything-as-code. Ein polyglottes Abenteuer. #jax2017

// 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

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

Page 42: Everything-as-code. Ein polyglottes Abenteuer. #jax2017

AsciidoctorJ und Gradle to the Rescue

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'

options doctype: 'article'

attributes 'source-highlighter': 'coderay'

}

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

Page 43: Everything-as-code. Ein polyglottes Abenteuer. #jax2017

Presentation-as-code

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

Page 44: Everything-as-code. Ein polyglottes Abenteuer. #jax2017

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.

---

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

Page 45: Everything-as-code. Ein polyglottes Abenteuer. #jax2017

Heutige Projekte sind polyglot.

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

Page 46: Everything-as-code. Ein polyglottes Abenteuer. #jax2017

Use the right tool for the job!

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

Page 47: Everything-as-code. Ein polyglottes Abenteuer. #jax2017

Wir alle müssen unsere Hausaufgaben machen.

• Entwickler: Be polyglot, keep learning!

• Architekten: Choose wisely! Die richtige Sprache ist stark abhängig vom jeweiligen Projekt-Kontext, Kundenumfeld und Team.

• Project Managers: Give your techies freedom!

• Universities: Unterrichtet vielsprachig!

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

Page 48: Everything-as-code. Ein polyglottes Abenteuer. #jax2017

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

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

Page 49: Everything-as-code. Ein polyglottes Abenteuer. #jax2017

Cloud Native Night Meetup Termine

[{ topic: 'Wolkenschieber - Operations in der Cloud', speakers: ['Timo Derstappen, Giant Swarm'], datum: 'Dienstag, 16. Mai 2017 um 18:30', wo: 'QAware Office Mainz', url: 'https://www.meetup.com/de-DE/Cloud-Native-Night/events/238824503/'},{ topic: 'Tracing and Monitoring of Cloud-Native Applications', speakers: ['Juraci Paixão Kröhling, Red Hat', 'Alois Mayr, Dynatrace'], datum: 'Dienstag, 25. Mai 2017 um 18:30', wo: 'QAware Office München', url: 'https://www.meetup.com/de-DE/cloud-native-muc/events/239505785/'}]

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

Page 50: Everything-as-code. Ein polyglottes Abenteuer. #jax2017

We are hiring.http://www.qaware.de/karriere/#jobs

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

Page 51: Everything-as-code. Ein polyglottes Abenteuer. #jax2017

Thanks! Questions?

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