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

Clean Infrastructure as Code

Clean Infrastructure as Code

Clean Code und TDD sind aus der modernen, agilen Software-Entwicklung nicht mehr weg zu denken. Doch was für unseren Produktiv-Code eine Selbstverständlichkeit geworden ist, trifft leider mitnichten auf unseren Infrastruktur-Code zu. Egal ob nun Dockerfile, Terraform HCL oder Kubernetes YAML, der dominierende Entwicklungsansatz heißt hier stattdessen: Trial and Error!

In Zeiten der Public Cloud und Kubernetes spielt unser Infrastruktur-Code jedoch eine absolut tragende Rolle, es ist an der Zeit diesen Code auch nach allen Regeln der Kunst zu schreiben und automatisiert zu testen.

Diese Session zeigt anhand vieler Beispiele, welche Ansätze, Muster, Tools und Frameworks dabei helfen können.

M.-Leander Reimer

November 17, 2021
Tweet

More Decks by M.-Leander Reimer

Other Decks in Technology

Transcript

  1. Viele der Prinzipien von Clean Code und Clean Architecture sind

    übertragbar auf Infrastructure as Code. QAware | 3
  2. 3 Architektur Sichten definieren die nötigen Felder für Clean Code,

    Clean Architecture und Qualitätssicherung. QAware | 4
  3. 3 Architektur Sichten definieren die nötigen Felder für Clean Code,

    Clean Architecture und Qualitätssicherung. QAware | 5 Biz Dev Ops
  4. Die TI Architektur mit ihren Technologien und Frameworks, als auch

    die Zuständigkeiten haben sich gewandelt. QAware | 6 Ops
  5. Trial and Error scheint eine weit verbreitete Praktik zu sein

    um Infrastruktur-Code lauffähig zu bekommen. QAware | 8 Write some code Run code Write some code Run code Write some code Run code ? Write Dockerfile docker build docker run Change Dockerfile docker build docker run Change Dockerfile docker build docker run ? Write K8s YAML kubectl apply Change K8s YAML kubectl apply Change K8s YAML kubectl apply ? Write Terraform Definition terraform apply Change Terraform Definition terraform apply Change Terraform Definition terraform apply ?
  6. ATDD und TDD sind bekannte Praktiken in agilen Projekten und

    etabliert auf Ebene der A und T Architektur. QAware | 9
  7. The usual suspects! Es gibt viele mögliche Antworten, Gründe und

    Ausflüchte für “unsauberen” Infrastruktur Code. QAware | 11 ▪ Hohe Cognitive Load und fehlendes Know-How der Teams. – Junge Teams haben Anfangs oft noch nicht das nötige Know-How. Schulungen + Konferenzen! – Reduzierung der Cognitive Load über standardisiertes, Team weites Developer Tooling + CI. ▪ Feature Greed und fehlende Awareness seitens der Product Owner. – Product Owner müssen neben Features auch die nötigen betrieblichen Aktivitäten priorisieren. – Ops related Tasks als Teil der DoD und Acceptance Criteria vereinbaren. ▪ Zeitdruck oder unrealistische Pläne. – Das Standard Argument bzw. Grund für nicht vorhandene Tests. Leider immer noch zu oft! – Technical Debt transparent machen + Scoping von Features. ▪ Hohe Infrastruktur Komplexität für Absicherung von Infrastruktur Code. – Besonders deklarative IaC Ansätze lassen sich nur über Integrationstest absichern. – Hierfür braucht es dedizierte Infrastruktur und Umgebungen: Kosten + Wartung.
  8. Die Architektur und der Code unser Infrastruktur haben einen erheblichen

    Einfluss auf viele der *-illities guter Software. QAware | 12 Software Product Quality (ISO 25010) • Modularity • Reusability • Analysability • Modifiability • Testability • Adaptability • Installability • Replaceability • Confidentiality • Integrity • Non-repudiation • Authenticity • Accountability • Maturity • Availability • Fault Tolerance • Recoverability Maintainability Portability Security Reliability • Co-existence • Interoperability Compatibility • Time Behaviour • Resource Utilization • Capacity Efficiency • Completeness • Correctness • Appropriateness Functional Suitability • Operability • Learnability • UI Aesthetics • Accessibility Usability
  9. KISS Keep it Simple, Stupid. Emergent Design and Evolutionary Architecture

    https://de.slideshare.net/ThoughtWorks/neal-ford-emergent-design-and-evolutionary-architecture
  10. DRY Don’t Repeat Yourself. “Every piece of knowledge or logic

    must have a single, unambiguous representation within a system.” Andy Hunt & Dave Thomas, “The Pragmatic Programmer”
  11. QAware | 18 Clean Code Good overall summary can be

    found at https://gist.github.com/wojteklu/73c6914cc446146b8b533c0988cf8d29 1. Follow standard conventions. 2. Keep it simple stupid. Simpler is always better. Reduce complexity as much as possible. General 1. Keep configurable data at high levels. 2. Prevent over-configurability. 3. Use dependency injection. Design 1. Be consistent. If you do something a certain way, do all similar things in the same way. 2. Use explanatory variables. 3. Avoid negative conditionals. Understandability 1. Don’t be funny. 2. Choose descriptive and unambiguous names. 3. Use pronounceable names. 4. Use searchable names. Names 1. Always try to explain yourself in code. 2. Don't be redundant. 3. Don't add obvious noise. 4. Don't comment out code. Just remove. 5. Use as clarification of code. 6. Use as warning of consequences. Comments 1. Fast. 2. Independent. 3. Repeatable. 4. Self-validating 5. Timely Tests 1. Keep lines short. 2. Use white space to associate related things and disassociate weakly related. 3. Don't break indentation. 4. Dependent definitions should be close. 5. Structure should clearly express modules, layers, components or conceptual architecture. Source Code 1. Prefer data structures. 2. Hide internal structure. 3. Should be small. 4. Small number of variables. Data Structures
  12. Die konzeptionelle Architektur der Infrastruktur hat einen erheblichen Einfluss auf

    den Quellcode und die Struktur. QAware | 19 ▪ In welchen Regionen muss das System laufen? ▪ Welche Teile der Infrastruktur sind redundant? Wo braucht es Replikation? ▪ Wie werden Umgebungen (INT; PROD) modelliert? Accounts? VPCs? Namespaces? ▪ Welche Schichten und Komponenten werden benötigt? Welche Beziehungen gibt es? ▪ Wie werden die Strukturen in Git Repositories und im Quellcode abgebildet?
  13. Die frühe Definition des Tech Stacks und der benötigten Tools

    und Frameworks schafft Klarheit. Weniger ist mehr. QAware | 20 IaaS (AWS EC2, NLB, ALB, ...) CaaS (Amazon Elastic Kubernetes Service) PaaS (Software Infrastructure Blueprints with Helm and Continuous Delivery Toolchain) Application-specific Software Infrastructure Cloud-friendly & cloud-native Applications Architect Build Run Amazon SNS Amazon CloudWatch AWS IAM Amazon EC2 Amazon EBS Amazon S3 Amazon Route 53 Amazon VPC Atlantis
  14. “Too much cognitive load will become a bottleneck for fast

    flow and high productivity for many DevOps teams.” QAware | 23 ▪ Intrinsic Cognitive Load Relates to fundamental aspects and knowledge in the problem space (e.g. used languages, APIs, frameworks) ▪ Extraneous Cognitive Load Relates to the environment (e.g. console command, deployment, configuration) ▪ Germane Cognitive Load Relates to specific aspects of the business domain (aka. „value added“ thinking)
  15. Imperative Tools wie Pulumi oder Amazon CDK bieten modernes Cloud

    Engineering für Software Entwicklern und SREs. ▪ Use your favourite language! Kein Bruch zwischen Anwendungsentwicklung und Cloud Engineering. ▪ Imperative Tools bieten einen einheitlichen Ansatz für Infrastructure as Code und Cloud Engineering für viele Cloud Provider, Docker als auch Kubernetes. ▪ Reduzierung der (Tool-) Komplexität führt zur Reduzierung der Cognitive Load. ▪ Clean Code und allgemeine Praktiken des Software Engineering können einfach auf Infrastruktur Code angewendet werden: Modularisierung, Refactoring, Testing, Automatisierung, CI/CD. ▪ Zahlreiche Optionen: – Pulumi (https://github.com/pulumi/pulumi) – Amazon CDK (https://github.com/aws/aws-cdk) – cdk8s (https://github.com/cdk8s-team/cdk8s) QAware | 24
  16. K8s Deployment und Service in TypeScript mit Pulumi. QAware |

    25 import * as k8s from "@pulumi/kubernetes"; import * as pulumi from "@pulumi/pulumi"; const config = new pulumi.Config(); const isMinikube = config.require("isMinikube"); // nginx container, replicated 1 time. const appName = "nginx"; const appLabels = { app: appName }; const nginx = new k8s.apps.v1.Deployment(appName, { spec: { selector: { matchLabels: appLabels }, replicas: 1, template: { metadata: { labels: appLabels }, spec: { containers: [{ name: appName, image: "nginx:1.15" }] }, }, }, }); // Allocate an IP to the nginx Deployment. const frontend = new k8s.core.v1.Service(appName, { metadata: { labels: nginx.spec.template.metadata.labels }, spec: { type: isMinikube === "true" ? "ClusterIP" : "LoadBalancer", ports: [{ port: 80, targetPort: 80, protocol: "TCP" }], selector: appLabels, }, }); // When "done", this will print the public IP. export let frontendIp: pulumi.Output<string>; if (isMinikube === "true") { frontendIp = frontend.spec.clusterIP; } else { frontendIp = frontend.status.loadBalancer.ingress[0].ip; }
  17. qaware.de QAware GmbH Aschauer Straße 32 81549 München Tel. +49

    89 232315-0 [email protected] twitter.com/qaware linkedin.com/company/qaware-gmbh xing.com/companies/qawaregmbh slideshare.net/qaware github.com/qaware