Slide 1

Slide 1 text

Clean Infrastructure as Code ContainerConf 2021 Mario-Leander Reimer [email protected] @LeanderReimer qaware.de

Slide 2

Slide 2 text

2 Mario-Leander Reimer Principal Software Architect @LeanderReimer #cloudnativenerd #qaware #gernperDude

Slide 3

Slide 3 text

Viele der Prinzipien von Clean Code und Clean Architecture sind übertragbar auf Infrastructure as Code. QAware | 3

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

Die TI Architektur mit ihren Technologien und Frameworks, als auch die Zuständigkeiten haben sich gewandelt. QAware | 6 Ops

Slide 7

Slide 7 text

QAware | 7 Infrastructure as Code in der Praxis

Slide 8

Slide 8 text

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 ?

Slide 9

Slide 9 text

ATDD und TDD sind bekannte Praktiken in agilen Projekten und etabliert auf Ebene der A und T Architektur. QAware | 9

Slide 10

Slide 10 text

Infrastructure as Code ohne Tests ist per se kaputt!

Slide 11

Slide 11 text

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.

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

KISS Keep it Simple, Stupid. Emergent Design and Evolutionary Architecture https://de.slideshare.net/ThoughtWorks/neal-ford-emergent-design-and-evolutionary-architecture

Slide 14

Slide 14 text

SoC Separation of Concerns. Modules, layers and components. Loose Coupling and High Cohesion.

Slide 15

Slide 15 text

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”

Slide 16

Slide 16 text

S O L I D

Slide 17

Slide 17 text

Single Responsibility Principle Open Closed Principle Liskov Substitution Principle Interface Segregation Principle Dependency Inversion Principle

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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?

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

Demos and Examples https://github.com/qaware/clean-infrastructure-as-code

Slide 22

Slide 22 text

Declarative VS Imperative

Slide 23

Slide 23 text

“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)

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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; if (isMinikube === "true") { frontendIp = frontend.spec.clusterIP; } else { frontendIp = frontend.status.loadBalancer.ingress[0].ip; }

Slide 26

Slide 26 text

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