Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Everything-as-code – Polyglotte Entwicklung in der Praxis

Everything-as-code – Polyglotte Entwicklung in der Praxis

Als zeitgemäßer Entwickler muss man eine Vielzahl an Sprachen sicher beherrschen. Wir definieren unsere Entwicklungsumgebung mit Gradle, wir bauen unsere Software in Java, Kotlin und JavaScript. Wir verwenden Groovy und Scala um unsere Software zu testen. Die Build-Pipeline wird per DSL und JSON definiert. Mit YAML und Python beschreiben wir die Infrastruktur und das Deployment unserer Anwendungen. Die Dokumentation unserer Architekturen erledigen wir mit AsciiDoc und JRuby.

Use the right tool for the job! Das ist das Motto dieser Session. Jede Sprache hat Stärken in einer bestimmten Domäne. Diese Stärken gilt es zu nutzen. Aber einfach blind jede gerade angesagte Sprache oder Technologie einzusetzen ist sicher nicht die Lösung. Dieser Vortrag führt durch die einzelnen Entwicklungs-Phasen eines Microservice und zeigt dabei einen in der Praxis erprobten, stabilen und gut integrierten polyglotten Technologie-Stack um moderne Enterprise Applikationen schnell und einfach zu entwickeln.

M.-Leander Reimer

December 12, 2017
Tweet

More Decks by M.-Leander Reimer

Other Decks in Programming

Transcript

  1. #whoami Mario-Leander Reimer Cheftechnologe, QAware GmbH - Senior Developer &&

    Architect - 20+ Jahre Erfahrung - #CloudNativeNerd - Open Source Enthusiast [email protected] http://github.com/lreimer http://speakerdeck.com/lreimer // IT-Tage 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }
  2. Software Industrialization ist eine Schlüsselanforderung für erfolgreiches DevOps und Continuous

    Delivery. // IT-Tage 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }
  3. Ein Software-Fließband produziert und liefert die fertige Software an. //

    IT-Tage 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }
  4. 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 // IT-Tage 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }
  5. val softwareIndustrialization = everythingAsCode() open fun everythingAsCode() = everythingIsMadeFromCode() &&

    everythingIsMadeByCode() private fun everythingIsMadeFromCode() = true private fun everythingIsMadeByCode() = true // IT-Tage 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }
  6. Auf die Domäne kommt es an! Eine beste Programmiersprache gibt

    es nicht. // IT-Tage 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }
  7. 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! // IT-Tage 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }
  8. 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 // IT-Tage 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }
  9. 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' } // IT-Tage 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }
  10. # language: en Functionality: 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 | // IT-Tage 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }
  11. 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. // IT-Tage 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }
  12. 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.' } // IT-Tage 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }
  13. Java ist nach wie vor unsere primäre Implementierungssprache! Und das

    ist gut so! // IT-Tage 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }
  14. Aber: Kotlin als Alternative zu Java ist einen Blick wert!

    // IT-Tage 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }
  15. 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. // IT-Tage 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }
  16. @JsonIgnoreProperties(ignoreUnknown = true) data class Book(val title: String, val isbn:

    String, val author: String) @ApplicationScoped open 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) } // IT-Tage 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }
  17. 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 // IT-Tage 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }
  18. Grovy + Spock eignen sich für Unit, Integration, Acceptance und

    UI-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" } } // IT-Tage 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }
  19. Scala und Gatling für lesbare und performante Last-Tests class 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) } // IT-Tage 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }
  20. 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' } // IT-Tage 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }
  21. 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" } } } // IT-Tage 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }
  22. Docker, Docker, Docker, ... FROM qaware-oss-docker-registry.bintray.io/base/alpine-k8s-openjdk8:8u121 MAINTAINER M.-Leander Reimer <[email protected]>

    RUN mkdir -p /app ADD build/distributions/everything-as-code-1.2.3.tar /app WORKDIR /app/everything-as-code-1.2.3 RUN chmod 755 bin/everything-as-code EXPOSE 18080 CMD ./bin/everything-as-code // IT-Tage 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }
  23. Cluster Orchestration mit K8s et.al. --- apiVersion: extensions/v1beta1 kind: Deployment

    metadata: name: everything-as-code spec: 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 // IT-Tage 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }
  24. 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 // IT-Tage 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }
  25. 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 // IT-Tage 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }
  26. 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 // IT-Tage 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }
  27. // 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 forces that software architects must consider in their decisions. === Requirements Overview === Quality Goals === Stakeholders <<<< include::02_architecture_constraints.adoc[] // further includes for the remaining sections // IT-Tage 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }
  28. 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' } // IT-Tage 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }
  29. 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 describe def bookApp = model.addSoftwareSystem("Book Application", "The best source to get info on books.") // create the various types of people (roles) that use the software system def 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]") // IT-Tage 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }
  30. 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. --- // IT-Tage 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }
  31. Alles mit Augenmaß! Der richtige Technologie-Stack hängt vom Team, dem

    Projekt-Kontext und unseren Kunden ab. // IT-Tage 2017 // Everything-as-code -> { created with ❤ and ☕ by @LeanderReimer @qaware }