Everything-as-code. Ein polyglottes Abenteuer. #jax2017
-
Upload
mario-leander-reimer -
Category
Software
-
view
101 -
download
0
Transcript of 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
#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
// JAX 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware } 3
Welche Sprache verwenden echte Programmierer?
// JAX 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware } 4
Meine #FirstSevenLanguages
• Pascal
• Basic
• C / C++
• Assembler
• PHP
• Java
• C#
// JAX 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware } 5
Meine #LastSevenLanguages
• Java
• Groovy
• TypeScript
• Ruby
• Kotlin
• Scala
• Go
// JAX 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware } 6
// JAX 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware } 7
// JAX 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware } 8
// JAX 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware } 9
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
Die beste Programmiersprache gibt es nicht!Auf den Kontext kommt es an.
// JAX 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware } 11
Die IDE ist unsere Werkbank.
// JAX 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware } 12
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
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
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
SEU-as-code
// JAX 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware } 16
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
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
Build-as-code
// JAX 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware } 19
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
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
Main-as-code
// JAX 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware } 22
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
Für die Mutigen:Kotlin als ernsthafte Alternative zu Java.
// JAX 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware } 24
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
@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
Frontend-as-code
// JAX 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware } 27
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
Test-as-code
// JAX 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware } 29
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
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
Pipeline-as-code
// JAX 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware } 32
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
Infrastructure-as-code
// JAX 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware } 34
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
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
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
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
Documentation-as-code
// JAX 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware } 39
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
// 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
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
Presentation-as-code
// JAX 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware } 43
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
Heutige Projekte sind polyglot.
// JAX 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware } 45
Use the right tool for the job!
// JAX 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware } 46
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
Fork me on GitHub.https://github.com/lreimer/everything-as-code
// JAX 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware } 48
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
We are hiring.http://www.qaware.de/karriere/#jobs
// JAX 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware } 50
Thanks! Questions?
// JAX 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware } 51