<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="/feed.xml" rel="self" type="application/atom+xml" /><link href="/" rel="alternate" type="text/html" /><updated>2026-01-05T14:22:05+00:00</updated><id>/feed.xml</id><title type="html">Daniel Schleicher</title><subtitle>I am a Senior Solutions Architect at AWS, focusing  on software-defined cars. In this field, I am interested in  applying cloud computing principles for automotive applications,  and advancing the software development process of automotive  applications utilizing virtualized hardware.</subtitle><entry><title type="html">How Creating a Ubiquitous Language Ensures AI Builds What You Actually Want</title><link href="/software/engineering,/ai,/spec-driven/development/2026/01/04/removing-ambiguity-with-spec-driven-development.html" rel="alternate" type="text/html" title="How Creating a Ubiquitous Language Ensures AI Builds What You Actually Want" /><published>2026-01-04T08:00:00+00:00</published><updated>2026-01-04T08:00:00+00:00</updated><id>/software/engineering,/ai,/spec-driven/development/2026/01/04/removing-ambiguity-with-spec-driven-development</id><content type="html" xml:base="/software/engineering,/ai,/spec-driven/development/2026/01/04/removing-ambiguity-with-spec-driven-development.html"><![CDATA[<p>Recently, I read <a href="https://brooker.co.za/blog/2025/12/16/natural-language.html">Marc Brooker’s blog post on Natural Language Programming</a>, which I highly recommend to anyone wanting to understand how programming and software development are currently evolving. One analogy Marc uses to describe the future of programming particularly stuck with me: With a spec-driven development approach, it becomes possible to actively include computers in the discussion about the design of a software system.</p>

<p>In this view, LLMs are no longer just code generators. They become participants in a discussion about how a system should behave. Spec-driven development is thus less of a new development methodology and more of a technological extension of existing human workflows.</p>

<p>Successful software systems are rarely created by someone immediately typing perfect code into an editor. They emerge from communication through specifications, user stories, and shared discussions at the whiteboard. The formal implementation in code is often just the last step of a long, creative process.</p>

<p>Marc Brooker rightly emphasizes that success comes from iteration, context accumulation, and collaboration. What is new is that we can now use technology to let computers participate in the very same conversations humans already have when describing how a software system should behave. We position LLMs here as active conversation partners and critical reviewers, not as autonomous authors who blindly take work off our hands.</p>

<p>But as soon as we make natural language the primary tool for specification, we encounter a central problem: Conversations in natural language are inherently ambiguous.</p>

<h2 id="the-emergence-of-a-ubiquitous-language">The Emergence of a Ubiquitous Language</h2>

<p>When humans discuss a problem together, ambiguous terms must be clarified to enable effective communication within the current domain. We all know this from meetings: Someone says “customer” but means “account.” Another says “order” but refers only to the “shopping cart.”</p>

<p>In my experience, clarification happens in an iterative process: If a term is used for the first time and interpreted differently by different conversation partners, a need arises to explicitly define its meaning for the ongoing discussion. Through this step-by-step definition of terms for a concrete problem area, a common language emerges that is used by all participants.</p>

<p>In Domain-Driven Design (DDD), this common language is called Ubiquitous Language. It applies within a delimited area, the so-called Bounded Context. A bounded context in DDD is a boundary within which a specific domain model and ubiquitous language apply consistently. For example, in an e-commerce system, an Order Management bounded context defines what an Order means and enforces its lifecycle rules, while Payment and Shipping use different models and terminology for the same real-world concept.</p>

<p>Handling the ambiguity of natural language was long reserved exclusively for humans. With the advent of LLMs and spec-driven development, machines can now participate in this clarification process by making ambiguities explicit within a given Bounded Context, asking in the Order Management context whether the term “order” refers to a customer commitment at checkout or to a payment or shipping artifact used in downstream contexts.</p>

<h2 id="collaborative-clarification-as-engineering-work">Collaborative Clarification as Engineering Work</h2>

<p>This leads to a new interaction loop in software development that I consider genuine engineering work rather than administrative overhead. With tools like Kiro, work on a new feature often starts with a simple prompt that captures the initial idea and intent in natural language, which Kiro then elaborates into a specification.</p>

<p>From there, ambiguities surface quickly. The LLM supports the team by highlighting terms that can be interpreted in more than one way in the current bounded context, such as whether an “order” refers to a customer commitment in Order Management or to a payment or shipping concept elsewhere. The human clarifies the intent, and once that clarification is made, the terminology becomes stable. These agreed-upon terms act as anchors in all subsequent artifacts, making inconsistencies visible as soon as they appear.</p>

<h2 id="practical-application-with-a-custom-kiro-power">Practical Application with a Custom Kiro Power</h2>

<p>To translate this theoretical approach into practice, I developed the <a href="https://github.com/schleidl/spec-ambiguity-resolver-kiro-power"><strong>Spec Ambiguity Resolver</strong></a> a Kiro Power that helps establish and maintain a ubiquitous language throughout the entire development lifecycle.</p>

<p>The power is active during all phases of spec-driven development: specification writing, design document creation, task breakdown, and implementation. It works by maintaining a living glossary file (<code class="language-plaintext highlighter-rouge">domain-terms.md</code>) that serves as the single source of truth for the project’s ubiquitous language.</p>

<p>Let’s return to our Order Management example to see how this works in practice. When the team starts writing their specification and uses the term “order,” the power immediately flags this as potentially ambiguous:</p>

<blockquote>
  <p>“I noticed the term ‘order’ appears in the specification. To establish our ubiquitous language, we should define what ‘order’ means in this project context so all participants, including me as the coding AI, share the same understanding.</p>

  <p>Based on the context, I propose this definition:</p>

  <p><strong>Order</strong>: A customer commitment created at checkout in the Order Management bounded context, including items, quantities, pricing, and delivery address. This represents the customer’s intent to purchase.</p>

  <p>Does this definition accurately capture what ‘order’ means in your project? Would you like to adjust it before I add it to our ubiquitous language?”</p>
</blockquote>

<p>This interaction is crucial: the power never autonomously creates definitions. It proposes them based on context and waits for explicit human approval. This ensures the ubiquitous language represents genuine semantic agreement, not just AI-generated documentation.</p>

<p>Once approved, the definition is added to <code class="language-plaintext highlighter-rouge">domain-terms.md</code>. From that point forward, the power ensures consistency: if someone later uses “order” to mean something different (like a payment record or shipping manifest), it flags the inconsistency and prompts clarification. Should the team discover they need separate concepts, they can establish distinct terms like “Customer Order” and “Fulfillment Order,” each with its own precise definition within its bounded context.</p>

<p>The power doesn’t impose a rigid formal language. Instead, it helps the team build their own shared vocabulary organically as they work, making ambiguities visible before they propagate into code. The result is that humans and AI collaborate on clarification, while domain semantics remain stable and traceable from requirements through implementation.</p>

<h2 id="from-ubiquitous-language-to-implementation">From Ubiquitous Language to Implementation</h2>

<p>Why invest this effort in establishing a ubiquitous language before writing the first line of code? Because precise semantic agreement fundamentally constrains implementation decisions in a positive sense.</p>

<p>When the entire team, including AI coding agents, shares an explicit understanding of what “order” means in the Order Management context, entire classes of architectural mistakes become impossible. The AI agent implementing the checkout flow knows exactly what data structure to create, what lifecycle states are valid, and which operations belong to this concept versus others like payment processing or shipping.</p>

<p>This semantic precision enables several critical capabilities:</p>

<p><strong>Refactoring with Confidence</strong>: When “order” has a precise definition in <code class="language-plaintext highlighter-rouge">domain-terms.md</code>, we know exactly which code belongs together. Refactoring becomes safer because the boundaries between concepts are explicit. We can confidently move order validation logic into the Order class, knowing it won’t accidentally include payment processing concerns.</p>

<p><strong>AI-Generated Code Quality</strong>: When an AI coding agent reads the ubiquitous language before implementation, it generates code that accurately reflects the domain model. Instead of generic class names like <code class="language-plaintext highlighter-rouge">DataProcessor</code> or <code class="language-plaintext highlighter-rouge">RequestHandler</code>, it creates <code class="language-plaintext highlighter-rouge">CustomerOrder</code> with methods like <code class="language-plaintext highlighter-rouge">confirmPurchaseIntent()</code> that mirror the team’s shared vocabulary.</p>

<p><strong>Long-term Maintainability</strong>: Code that speaks the domain language remains comprehensible as the team evolves. A developer joining the project six months later can read <code class="language-plaintext highlighter-rouge">domain-terms.md</code>, understand the ubiquitous language, and immediately recognize those same terms throughout the codebase. The semantic agreement established during specification persists into the implementation.</p>

<h2 id="conclusion-precision-before-code">Conclusion: Precision Before Code</h2>

<p>The greatest leverage in modern software development with AI lies not in accelerating typing, but in establishing semantic agreement before implementation begins. Kiro has already taken a giant leap in this direction with its spec-driven development workflow, which structures the development process around creating clear specifications, design documents, and task lists before any code is written. This blog post explored how we can extend this foundation by establishing a ubiquitous language, a shared vocabulary that ensures all project participants, including AI coding agents, share the same understanding of domain terms throughout the entire development lifecycle. Reducing ambiguity through a ubiquitous language is genuine design work, the mandatory prerequisite for safe automation.</p>

<p>LLMs are amplifiers. When we give an AI agent ambiguous instructions where “order” could mean a dozen different things, it amplifies the chaos by generating code that reflects our confusion. But when we first establish that “order” means precisely “a customer commitment in the Order Management context,” the AI amplifies our clarity by generating code that accurately implements this shared understanding.</p>

<p>Spec-driven development with tools like the Spec Ambiguity Resolver ultimately means using the machine as a partner in thinking more precisely. The AI doesn’t just execute our specifications, it participates in refining them by making ambiguities visible, proposing definitions for our review, and maintaining consistency across the entire project lifecycle.</p>

<p>The result is software where the code speaks the same language as the specifications, where AI agents and human developers share the same semantic foundation, and where the ubiquitous language established in early conversations persists all the way through to implementation. This is how we move from natural language programming to truly collaborative software development.</p>]]></content><author><name></name></author><category term="Software" /><category term="Engineering," /><category term="AI," /><category term="Spec-Driven" /><category term="Development" /><summary type="html"><![CDATA[Recently, I read Marc Brooker’s blog post on Natural Language Programming, which I highly recommend to anyone wanting to understand how programming and software development are currently evolving. One analogy Marc uses to describe the future of programming particularly stuck with me: With a spec-driven development approach, it becomes possible to actively include computers in the discussion about the design of a software system.]]></summary></entry><entry><title type="html">The Future of Automotive Software: Introducing the Automotive Coding Assistant</title><link href="/generative-ai,/automotive,/assistant/2024/10/21/concept-for-an-automotive-coding-assistant.html" rel="alternate" type="text/html" title="The Future of Automotive Software: Introducing the Automotive Coding Assistant" /><published>2024-10-21T08:24:47+00:00</published><updated>2024-10-21T08:24:47+00:00</updated><id>/generative-ai,/automotive,/assistant/2024/10/21/concept-for-an-automotive-coding-assistant</id><content type="html" xml:base="/generative-ai,/automotive,/assistant/2024/10/21/concept-for-an-automotive-coding-assistant.html"><![CDATA[<p>The automotive industry is in the midst of a transformation. As vehicles become smarter and more reliant on software, developers are increasingly at the center of innovation. The challenge? Developing automotive software requires compliance with stringent safety standards like ISO 26262, ASPICE, and AUTOSAR. This article details the concept of an automotive embedded coding assistant and how it can support developers in creating compliant embedded C/C++ code, following requirements from standards like AUTOSAR, which reference MISRA C guidelines.</p>

<p>The need for an automotive coding assistant is driven by several converging trends. The automotive sector is transitioning from traditional mechanical engineering to a software-defined vehicle (SDV) model, where a car’s value is increasingly defined by its software features. This shift demands scalable development practices to manage the complexity of autonomous driving, electric powertrains, and advanced connectivity. Recent advances in AI and machine learning now enable assistants to deeply understand automotive software, helping developers focus on innovation rather than repetitive tasks or extensive documentation searches.</p>

<h2 id="what-is-an-automotive-coding-assistant">What Is an Automotive Coding Assistant?</h2>

<p>An automotive coding assistant is an intelligent companion for developers in the automotive industry, designed to streamline coding processes, boost productivity, and ensure high-quality code. It leverages advances in generative AI, natural language processing, and machine learning to help developers solve the many challenges of automotive software development. Imagine a virtual collaborator that can provide suggestions and write code for AUTOSAR components or walk you through regulatory compliance standards and their implications for the respective code.</p>

<h2 id="potential-challenges-and-considerations">Potential Challenges and Considerations</h2>

<p>While the promise of an automotive coding assistant is enormous, there are challenges to address. The assistant must be designed with a deep understanding of safety and security requirements, which are non-negotiable in the automotive space. Developers may have concerns about the reliability of AI recommendations. Trust can be built by providing clear references to the sources of each suggestion, such as code repositories or official documentation.</p>

<h2 id="sketch-of-an-automotive-software-development-assistant">Sketch of an Automotive Software Development Assistant</h2>

<p>The assistant can generate code snippets based on developer goals, whether it’s a simple vehicle sensor readout or a complex algorithm for battery management. It helps refactor legacy code to improve compliance, readability, and maintainability. Moreover, the assistant identifies existing code implementations that fulfill certain functions while meeting regulatory requirements, enabling developers to reuse proven solutions.</p>

<p>Current automotive coding assistants and Large Language Models (LLMs) can generate C/C++ code but aren’t specifically trained for embedded automotive systems. Enhancements can be made by fine-tuning existing models to align with automotive standards or by using prompt engineering to guide the model’s responses. An agent can act as an intermediary, enhancing developer prompts with relevant requirements to ensure the generated code meets industry standards. This mechanism can also be used to make existing code compliant with regulatory standards.</p>

<p>Another important feature is finding existing compliant code implementations in private code repositories. This is done using a process called retrieval-augmented generation (RAG). Essentially, the codebase is analyzed and broken down into searchable components, which are stored in a specialized database. The assistant can then search this database to quickly find and recommend the most relevant code snippets, making it easier for developers to reuse proven, compliant solutions in their projects.</p>

<h2 id="conclusion-driving-into-the-future">Conclusion: Driving Into the Future</h2>

<p>The automotive coding assistant is more than just a tool—it’s a partner for every developer navigating the complexities of the automotive software landscape. As the industry continues its shift toward software-defined vehicles, the need for such intelligent assistants will only grow. They promise to reduce development time, enhance safety, and ultimately accelerate the journey toward a future of connected, autonomous, and intelligent vehicles.</p>]]></content><author><name></name></author><category term="generative-ai," /><category term="automotive," /><category term="assistant" /><summary type="html"><![CDATA[The automotive industry is in the midst of a transformation. As vehicles become smarter and more reliant on software, developers are increasingly at the center of innovation. The challenge? Developing automotive software requires compliance with stringent safety standards like ISO 26262, ASPICE, and AUTOSAR. This article details the concept of an automotive embedded coding assistant and how it can support developers in creating compliant embedded C/C++ code, following requirements from standards like AUTOSAR, which reference MISRA C guidelines.]]></summary></entry><entry><title type="html">Is a Multi-Cloud Strategy Just About Using Multiple Clouds?</title><link href="/aws,/multi-region/2024/03/05/multi-cloud-strategy.html" rel="alternate" type="text/html" title="Is a Multi-Cloud Strategy Just About Using Multiple Clouds?" /><published>2024-03-05T08:24:47+00:00</published><updated>2024-03-05T08:24:47+00:00</updated><id>/aws,/multi-region/2024/03/05/multi-cloud-strategy</id><content type="html" xml:base="/aws,/multi-region/2024/03/05/multi-cloud-strategy.html"><![CDATA[<p>Many companies today have contracts with multiple cloud providers. There are several reasons for this trend. The primary reason I hear is that companies don’t want to be locked into just one cloud provider and become 100% dependent on it. Additionally, they want to leverage the unique features and strengths of different cloud providers and be prepared for unforeseen events, such as a service from one provider being shut down on short notice. However, the investment required to technically maintain multiple cloud providers and make them accessible on demand to their developers is significant. This expenditure can reduce a company’s ability to innovate and drive the development of its core products. Being locked into one cloud provider might be the least of a company’s concerns if it can’t keep up with the pace of innovation of its competitors. This article presents a people-centric approach to multi-cloud, showing how to stay competitive and leverage multiple cloud providers’ strengths simultaneously.</p>

<p>Following a strategy of delivering high-quality software faster, traditional companies in any industry struggle to catch up and accelerate. Many traditional companies improve yearly in delivering high-quality software. However, digital-native companies still have the ability to accelerate faster, making it nearly impossible for traditional companies to overtake them.</p>

<p>Giving software developers the option to choose between cloud providers involves investing in setting up and maintaining multiple cloud environments. These environments must meet the company’s security, compliance rules, regulations, and best practices. For example, a microservice runtime like Kubernetes might need to be maintained multiple times, or a VPN connection to a company-owned data center might need to be set up and maintained multiple times. All of this comes at a cost of time and money.</p>

<p>Considering the bigger picture, many companies are better off going all-in with one cloud provider as their initial (multi)-cloud strategy. Reducing complexity allows developers to focus on the core business, driving innovation and speeding up software development. Companies that worry too much about future vendor lock-in may miss out on new market opportunities their competitors are pursuing. Being prepared to switch easily between cloud providers does not prevent a company from becoming irrelevant.</p>

<p>Some companies focus on providing what they believe are the right tools for their developers to thrive and create business value. However, I propose turning the focus to the developers themselves. Developers typically know best how to achieve their tasks when they have clear and measurable goals. Companies should listen to their developers, remove roadblocks, and provide them with the freedom, time, commitment, and learning opportunities they need.</p>

<p>A concise multi-cloud strategy could be:</p>

<h3 id="acme-corp-multi-cloud-strategy">ACME Corp (Multi)-Cloud Strategy</h3>
<hr />

<p>We don’t invest time and resources in preparing for a vendor lock-in scenario with a fully integrated multi-cloud setup. Instead, we focus on enhancing our teams’ software delivery performance. Besides mitigating the risk of optimizing for a problem that might never occur, we can react to market changes much faster. Adopting a new cloud provider is one option we have in our portfolio.</p>

<p>We measure our software delivery performance using the four key metrics described in the book Accelerate. We improve step by step, working on mastering the 24 capabilities outlined in the book.</p>

<hr />

<p>To emphasize the importance of focusing on developers and their productivity, consider this example: Suppose a company needs to switch cloud providers due to a price increase. A company that previously focused on creating an integrated cloud platform across multiple vendors might feel that their upfront investment is paying off. However, if this company did not invest in the continuous training and learning of its development teams, their skills may not be suited to seamlessly transition from one cloud provider to another. Additionally, these teams might struggle to adapt and learn how the new cloud provider operates.</p>

<p>In conclusion, let’s compare the approaches of two companies: The first company went all-in with one cloud provider, focusing on developing its developers’ hard and soft skills. As a result, its developers can more easily learn the new cloud platform, plan, and make decisions on how to migrate applications from one cloud provider to another. The second company focused on creating a platform that integrates multiple cloud providers but did not invest in its developers’ continuous learning and skill improvement. Now, this company faces the challenge of having a tool that can speed up the transition from one cloud provider to another, but its developers lack the necessary skills to operate on the new cloud platform and struggle to learn and adapt to the new environment.</p>]]></content><author><name></name></author><category term="AWS," /><category term="Multi-Region" /><summary type="html"><![CDATA[Many companies today have contracts with multiple cloud providers. There are several reasons for this trend. The primary reason I hear is that companies don’t want to be locked into just one cloud provider and become 100% dependent on it. Additionally, they want to leverage the unique features and strengths of different cloud providers and be prepared for unforeseen events, such as a service from one provider being shut down on short notice. However, the investment required to technically maintain multiple cloud providers and make them accessible on demand to their developers is significant. This expenditure can reduce a company’s ability to innovate and drive the development of its core products. Being locked into one cloud provider might be the least of a company’s concerns if it can’t keep up with the pace of innovation of its competitors. This article presents a people-centric approach to multi-cloud, showing how to stay competitive and leverage multiple cloud providers’ strengths simultaneously.]]></summary></entry><entry><title type="html">The Do It Yourself 99.999% Availability Guide</title><link href="/aws,/load/balancer,/availability/2024/03/04/do-it-yourself-availability-guide.html" rel="alternate" type="text/html" title="The Do It Yourself 99.999% Availability Guide" /><published>2024-03-04T08:24:47+00:00</published><updated>2024-03-04T08:24:47+00:00</updated><id>/aws,/load/balancer,/availability/2024/03/04/do-it-yourself-availability-guide</id><content type="html" xml:base="/aws,/load/balancer,/availability/2024/03/04/do-it-yourself-availability-guide.html"><![CDATA[<p>Migrating workloads to the cloud, AWS customers encounter many questions
regarding resilience, availability, and fault tolerance. In this
article, I expose the weak spots of cloud-native and, thus, distributed
applications in terms of resilience and provide solution options for
each one. Traditional data centers provide uptime guarantees for their
servers and network, a practice also common for virtually any <a href="https://aws.amazon.com/de/legal/service-level-agreements/">AWS
service</a>.
However, in contrast to traditional data centers, cloud providers have a
different design focus for their infrastructure. Cloud providers
optimize their offerings, like databases, to be easy to repair, whereas
traditional data centers aim for maximum uptime. Therefore, the failure
tolerance and resiliency of cloud applications must be top priorities.
Applications should be designed with these requirements in mind to
successfully host them in the cloud. For instance, <a href="https://aws.amazon.com/rds/">Amazon
RDS</a> (Relational Database Service) allows
for replication across multiple Availability Zones, enhancing database
resilience and uptime without manual intervention.</p>

<h2 id="running-example">Running Example</h2>

<p>Let’s begin with a running example that I will use throughout this
article. The image below illustrates an artificial architecture of an
online shop on the left, including systems responsible for payment
(Payment Service) and delivery (Delivery Service). We assume initially
that one instance of each service is running in the cloud. All services
are cloud-native apps, as defined by the 12-factor app methodology
(<a href="https://12factor.net/">https://12factor.net</a>), running in a single
Amazon AWS region. All communication is REST-based.</p>

<p><img src="/docs/assets/images/running-example.png" alt="running example" />
<em>Image 1: Running example</em></p>

<p>With this setup, customers can select products, place them into the
shopping cart managed by the Shopping Cart Service, and initiate a
workflow to purchase the products in the cart. This process involves the
Payment Service to handle payment and the Delivery Service to manage
delivery.</p>

<p>Murphy’s law states, “Anything that can go wrong will go wrong.” With
only one instance of each service running, several potential failures
can occur. Below, I describe each failure scenario and propose possible
countermeasures, focusing primarily on the Delivery Service.</p>

<h2 id="instance-failures">Instance Failures</h2>

<p>Failure of the Delivery Service software can cause all invocations to
fail immediately. A possible solution is to run multiple instances to
enhance resilience. To distribute requests from the Shopping Cart
Service evenly, a Load Balancer is necessary (see Image 2). There are
two types of load balancers: middleware components such as <a href="https://docs.aws.amazon.com/elasticloadbalancing/latest/application/introduction.html">Application
Load Balancer
(ALB)</a>
and client-side load balancers. With this setup, every Delivery Service
instance must be capable of processing all incoming requests, affecting
its internal architecture. For example, it’s not feasible for a Delivery
Service instance to maintain sessions with the Shopping Cart Service
since each request might be routed to different Delivery Service
instances. The goal is to design the Delivery Service so that shutting
down one or more instances won’t significantly impact its ability to
process requests.</p>

<p><img src="/docs/assets/images/load-balancer.png" alt="load balancer" />
<em>Image 2: Load balancers distribute requests evenly to all instances of
the Delivery Service</em></p>

<p>Besides running additional instances for resilience, the Shopping Cart
Service can implement the circuit breaker pattern. This pattern involves
temporarily reducing requests to the Delivery Service upon detecting
slower response times and resuming normal operation after a predefined
interval, assessing whether the Delivery Service has recovered
(<a href="https://martinfowler.com/bliki/CircuitBreaker.html">https://martinfowler.com/bliki/CircuitBreaker.html</a>).</p>

<p>Another potential failure is the loss of an entire cloud availability
zone hosting the Delivery Service. Cloud vendors offer availability
zones to enhance application availability. Distributing application
instances across multiple zones can mitigate the impact of a zone
failure, with load balancers in place to detect and reroute traffic in
the event of a regional outage (see Image 3).</p>

<p><img src="/docs/assets/images/second-az.png" alt="load balancer" />
<em>Image 3: Addition of Availability Zones</em></p>

<h2 id="network-failures">Network Failures</h2>

<p>To address network failures, the Shopping Cart Service must maintain
communication with the Delivery Service, achievable through
message-oriented middleware (MOM) (see Image 4). MOM systems, such as
queuing and publish-subscribe systems, facilitate reliable messaging
between services, with queues serving as buffers to manage message flow.
<a href="https://aws.amazon.com/sqs/">Amazon SQS</a> (Simple Queue Service) and
<a href="https://aws.amazon.com/sns/">Amazon SNS</a> (Simple Notification Service)
are prime examples of MOM systems, facilitating reliable messaging
between services, with queues serving as buffers to manage message flow.</p>

<p>Image 4 shows a message queue being set in place between the Shopping
Cart Service and the Delivery Service. We don’t need the load balancer
in between because the instances of the Delivery Service can process
messages when they are able to.</p>

<p><img src="/docs/assets/images/queuing.png" alt="load balancer" />
<em>Image 4: Introduction of queuing system</em></p>

<p>Thus, they are not overwhelmed by incoming messages because the message
queue acts as a buffer for them. With the addition of the message queue
the Shopping Cart Service can send messages to the Delivery Service even
in the rare case the Delivery Service is not available due to a network
outage.</p>

<h2 id="working-with-service-level-agreements-slas">Working with Service Level Agreements (SLAs)</h2>

<p>Managing microservices in the cloud involves planning for unplanned
downtimes. Although downtimes are inevitable, they can be managed within
the downtime budget defined in each microservice’s SLA. For instance,
the Shopping Cart Service could have a companion microservice to store
and retry pending requests to the Delivery Service, ensuring minimal
customer impact. Teams should strive to meet their SLAs precisely,
avoiding reliance on better-than-expected uptime.</p>

<h2 id="compensating-actions">Compensating Actions</h2>

<p>For extended downtimes that threaten SLA compliance, the Delivery
Service team could implement compensating actions, such as offering
vouchers to affected customers, to maintain customer satisfaction.</p>

<h2 id="conclusion">Conclusion</h2>

<p>Implementing the measures outlined above can significantly improve
system uptime, challenging the notion that service downtimes must be
cumulatively calculated. The introduction of a message queue between
services and the resilience of the companion service ensure that the
system remains functional and responsive, even during service
disruptions.</p>

<p>Do you have further ideas on making a cloud application more reliable?
We would love to read it in the comments!</p>]]></content><author><name></name></author><category term="AWS," /><category term="Load" /><category term="Balancer," /><category term="availability" /><summary type="html"><![CDATA[Migrating workloads to the cloud, AWS customers encounter many questions regarding resilience, availability, and fault tolerance. In this article, I expose the weak spots of cloud-native and, thus, distributed applications in terms of resilience and provide solution options for each one. Traditional data centers provide uptime guarantees for their servers and network, a practice also common for virtually any AWS service. However, in contrast to traditional data centers, cloud providers have a different design focus for their infrastructure. Cloud providers optimize their offerings, like databases, to be easy to repair, whereas traditional data centers aim for maximum uptime. Therefore, the failure tolerance and resiliency of cloud applications must be top priorities. Applications should be designed with these requirements in mind to successfully host them in the cloud. For instance, Amazon RDS (Relational Database Service) allows for replication across multiple Availability Zones, enhancing database resilience and uptime without manual intervention.]]></summary></entry><entry><title type="html">The Mental Model of the Cloud: Why Cloud Computing Is Fundamentally Different Than Traditional Data Centers</title><link href="/cloud/computing/2024/01/21/mental-model-for-the-cloud.html" rel="alternate" type="text/html" title="The Mental Model of the Cloud: Why Cloud Computing Is Fundamentally Different Than Traditional Data Centers" /><published>2024-01-21T19:27:38+00:00</published><updated>2024-01-21T19:27:38+00:00</updated><id>/cloud/computing/2024/01/21/mental-model-for-the-cloud</id><content type="html" xml:base="/cloud/computing/2024/01/21/mental-model-for-the-cloud.html"><![CDATA[<p>Designing cloud-native applications requires having a mental model of how a cloud is implemented. This mental model is fundamentally different than the one used to design applications running in a traditional data center. This article shows the differences between both mental models, focusing on the network architecture part.</p>

<p>The image below shows a mental model of a traditional data center. The blue boxes resemble physical servers, each running four virtual machines (VMs). As a means of logically separating different servers running different kinds of applications, these servers run in different network zones. Customers can rent a physical host or single VMs residing in a specific network zone. Within one network zone, it is possible to access any VM from any other VM. Thus, customers need to implement intrusion prevention measures. There might be cases where VMs of different customers run on the same physical host.</p>

<p>The only way to communicate between network zones is via the firewalls between them. The firewalls refuse any messages that have not been explicitly allowed before. In order to allow a message to pass through a firewall, a firewall rule needs to be created. A firewall rule can, for example, state that all VMs on a specific physical host can pass. Firewalls can be deployed as virtual appliances or in the form of a hardware firewall.</p>

<p><img src="/docs/assets/images/datacenter.png" alt="data center mental model" /></p>

<p>In contrast to that, a cloud data center does not have network zones with firewalls between them. Networking is fully virtualized. Each customer can create multiple virtual network zones called Virtual Private Clouds or VPCs. An arbitrary number of resources like VMs can be put into these VPCs. In the image below, the VMs marked with a dot of the same color are assigned to the same VPC. It is possible that different VMs running on the same physical host are assigned to different VPCs.</p>

<p><img src="/docs/assets/images/cloud.png" alt="cloud mental model" /></p>

<p>Each customer is able to design what traffic can enter and leave a VPC. At AWS, Security Groups are the means to restrict and allow traffic to and from the resources assigned to a VPC, for example.</p>

<p>Additional Resources:
A white paper with details of how virtual networking is implemented at AWS using the AWS Nitro System:
<a href="https://docs.aws.amazon.com/pdfs/whitepapers/latest/security-design-of-aws-nitro-system/security-design-of-aws-nitro-system.pdf">https://docs.aws.amazon.com/pdfs/whitepapers/latest/security-design-of-aws-nitro-system/security-design-of-aws-nitro-system.pdf</a></p>

<p>A paper showing how AWS used formal verification methods to prove the correctness of the boot code for the AWS Nitro System:</p>

<p><a href="https://link.springer.com/chapter/10.1007/978-3-319-96142-2_28">https://link.springer.com/chapter/10.1007/978-3-319-96142-2_28</a></p>]]></content><author><name></name></author><category term="Cloud" /><category term="computing" /><summary type="html"><![CDATA[Designing cloud-native applications requires having a mental model of how a cloud is implemented. This mental model is fundamentally different than the one used to design applications running in a traditional data center. This article shows the differences between both mental models, focusing on the network architecture part.]]></summary></entry><entry><title type="html">Business Impact of Introducing Kubernetes</title><link href="/kubernetes/2023/11/23/evaluating-kubernetes.html" rel="alternate" type="text/html" title="Business Impact of Introducing Kubernetes" /><published>2023-11-23T19:27:38+00:00</published><updated>2023-11-23T19:27:38+00:00</updated><id>/kubernetes/2023/11/23/evaluating-kubernetes</id><content type="html" xml:base="/kubernetes/2023/11/23/evaluating-kubernetes.html"><![CDATA[<p><strong>Kubernetes Setup Time and Its Impact on Market Entry:</strong></p>

<p>When considering Kubernetes for application development, it’s essential to assess how its setup time impacts the project’s time-to-market. In addition subsequent maintenance of the respective infrastructure needs to be considered. Kubernetes, known for its robust container orchestration capabilities, involves a detailed and time-consuming setup process. This article focuses on analyzing this aspect and its implications on reaching the market efficiently.</p>

<p><strong>Understanding Kubernetes Setup Duration:</strong>
   The setup process for Kubernetes is comprehensive. It starts with an initial learning and planning phase that can take up to 30-40 hours, attributed to the extensive documentation and complex nature of Kubernetes. Following this, installation, configuration, security setups, testing, and integration with CI/CD pipelines collectively contribute to a setup time that can reach 150 hours.</p>

<p>In addition the effort needed to maintain a Kubernetes cluster should not be neglected. A new Kubernetes version is released every 4 months.</p>

<p><strong>Time-to-Market Considerations for Small-Scale Applications:</strong>
   For smaller applications with a development timeline shorter than the Kubernetes setup time, the additional delay in market entry might not be favorable. The extended period needed to deploy Kubernetes could outweigh the benefits for projects where speed to market is a critical factor. However, if these applications are expected to scale significantly or require specific operational capabilities, the long-term advantages of Kubernetes, such as scalability and robust infrastructure management, could justify the initial time investment.</p>

<p><strong>Large, Complex Applications:</strong>
   In the case of larger applications, especially those built on microservices architecture, Kubernetes presents clear benefits. The platform’s ability to manage complex deployments efficiently can be a game-changer, facilitating faster updates and deployments in the long run. Here, the initial setup time is offset by the operational efficiencies and scalability that Kubernetes brings to the project, ultimately aiding in a more streamlined and effective market entry over the project’s lifecycle.</p>

<p><strong>Conclusion:</strong>
Choosing Kubernetes requires balancing the technical requirements of the application with strategic business goals, particularly time-to-market. While the initial setup phase is time-intensive and may pose challenges for rapid deployment, Kubernetes offers substantial long-term benefits for applications that require scalability and complex operational management. The decision to implement Kubernetes should be aligned with both the immediate market entry goals and the anticipated future needs of the project.</p>]]></content><author><name></name></author><category term="Kubernetes" /><summary type="html"><![CDATA[Kubernetes Setup Time and Its Impact on Market Entry:]]></summary></entry><entry><title type="html">Conceptual: How to test and react to the content of a WebRTC stream</title><link href="/aws,/cdk,/cloudformation/2023/10/25/Test-WebRTC-Selenium.html" rel="alternate" type="text/html" title="Conceptual: How to test and react to the content of a WebRTC stream" /><published>2023-10-25T19:27:38+00:00</published><updated>2023-10-25T19:27:38+00:00</updated><id>/aws,/cdk,/cloudformation/2023/10/25/Test-WebRTC-Selenium</id><content type="html" xml:base="/aws,/cdk,/cloudformation/2023/10/25/Test-WebRTC-Selenium.html"><![CDATA[<p><a href="https://webrtc.org/">WebRTC</a> is a Technology I came across recently. It can for example be used to stream video and audio from a server like an EC2 instance to a browser. In addition WebRTC provides a channel to send generic data between the server and the browser. Creating applications using WebRTC bears the problem of how to create automated UI tests reacing to the content of the stream. This post describes a concept how to do this using Selenium and OpenCV.</p>

<p><a href="https://www.selenium.dev/">Selenium</a> is a framework to automate browser based UI tests. UI Developers use it to create regression tests for their designs. <a href="https://opencv.org/">OpenCV</a> is a library that can be used to detect and classify objects in images.</p>

<p>Using both tools we are able to create a test that can react to the content of a WebRTC stream. The test can for example check if a video stream is showing a certain object.</p>

<p>This is a minimal example showing the interaction between selenium and OpenCV. It opens a browser, takes a screenshot, detects faces in the screenshot and draws rectangles around them. To make it work you need to download the <a href="https://raw.githubusercontent.com/kipr/opencv/master/data/haarcascades/haarcascade_frontalface_default.xml">haarcascade_frontalface_default.xml</a> file and place it in the same directory as the script and install the selenium and openCV modules.</p>

<pre><code class="language-bash:">pip install selenium opencv-python


```python:
from selenium import webdriver
import cv2

# Initialize Selenium and open a webpage
driver = webdriver.Chrome()
driver.get('https://en.wikipedia.org/wiki/Jean-Luc_Picard')

# Take a screenshot and save it as 'screenshot.png'
screenshot = driver.get_screenshot_as_png()
screenshot_path = "screenshot.png"
with open(screenshot_path, "wb") as file:
    file.write(screenshot)

# Process the image using OpenCV
image = cv2.imread(screenshot_path)

# Initialize Haar cascade for face detection
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# Detect faces
faces = face_cascade.detectMultiScale(gray_image, 1.1, 4)

# Draw rectangles around detected faces
for (x, y, w, h) in faces:
    cv2.rectangle(image, (x, y), (x+w, y+h), (255, 0, 0), 2)

# Save the processed image
cv2.imwrite("faces_detected.png", image)

# Close the browser
driver.quit()
</code></pre>]]></content><author><name></name></author><category term="AWS," /><category term="CDK," /><category term="CloudFormation" /><summary type="html"><![CDATA[WebRTC is a Technology I came across recently. It can for example be used to stream video and audio from a server like an EC2 instance to a browser. In addition WebRTC provides a channel to send generic data between the server and the browser. Creating applications using WebRTC bears the problem of how to create automated UI tests reacing to the content of the stream. This post describes a concept how to do this using Selenium and OpenCV.]]></summary></entry><entry><title type="html">AWS Cloud Development Kit Constructs</title><link href="/aws,/cdk,/cloudformation/2023/10/24/CDK-Constructs-Concept.html" rel="alternate" type="text/html" title="AWS Cloud Development Kit Constructs" /><published>2023-10-24T14:27:38+00:00</published><updated>2023-10-24T14:27:38+00:00</updated><id>/aws,/cdk,/cloudformation/2023/10/24/CDK-Constructs-Concept</id><content type="html" xml:base="/aws,/cdk,/cloudformation/2023/10/24/CDK-Constructs-Concept.html"><![CDATA[<p>Taking a deeper look at <a href="https://aws.amazon.com/workspaces/">Amazon Workspaces</a> the virtual desktop solution by Amazon I came across the question whether the creation of an Amazon Workspace can be automated using AWS Cloud Development Kit (CDK) or AWS CloudFormation. The short answer is yes it is possible to create a virtual desktop using <a href="https://aws.amazon.com/cloudformation/">AWS Cloudformation</a>. However, automating the creation of an Amazon Workspace is not straight forward using CDK. The documentation states that there is no L2 construct for Amazon Workspaces available in CDK which brings us to the purpose of this short article.</p>

<p>In CDK there is a concept of a <a href="https://docs.aws.amazon.com/cdk/v2/guide/constructs.html#constructs_lib">Construct</a>. Constructs are collected in the CDK Construct Library. There are three types of CDK Constructs, L1, L2, and L3. The letter L stands for level.</p>

<p>I am going to explain these Construct layers in a minute. There is one other important concept of CDK that needs to be understood in order to be able to grasp and understand the Construct concept. At compile time a CDK program is translated to an AWS CloudFormation script in the background. This AWS Cloudformation script is then executed and resources are deployed on AWS.</p>

<p>With that in mind we can have deeper look at the Constructs concept. 
Using an L1 construct a CDK developer can directly create and work with an AWS Cloudformation resource. The developer can recognize classes that are L1 Constructs by the prefix “Cfn”.</p>

<p>Please see the example below from the AWS documentation:</p>
<pre><code class="language-TypeScript">const bucket = new s3.CfnBucket(this, "MyBucket", {
  bucketName: "MyBucket",
  corsConfiguration: {
    corsRules: [{
          allowedOrigins: ["*"],
          allowedMethods: ["GET"]
    }]
  }
});
</code></pre>
<p>A L2 Construct is much more convenient, because some variable needed to initialize the respective AWS CloudFormation resource are already prefilled in the background with default values. See this example from the respective documentation using an L2 Construct:</p>

<pre><code class="language-TypeScript">import * as s3 from 'aws-cdk-lib/aws-s3';

// "this" is HelloCdkStack
new s3.Bucket(this, 'MyFirstBucket', {
  versioned: true
});
</code></pre>
<p>The most interesting type of Constructs are L3 Constructs. These Constructs represent patterns. Patterns are implementing solutions to more complex reccurring problems. The documentation gives an example for an AWS Fargate container cluster with a load balancer in front of it. Developers can also create their own patterns and use this tool to for example create a base line infrastructure for an development team to use and build-upon.</p>]]></content><author><name></name></author><category term="AWS," /><category term="CDK," /><category term="CloudFormation" /><summary type="html"><![CDATA[Taking a deeper look at Amazon Workspaces the virtual desktop solution by Amazon I came across the question whether the creation of an Amazon Workspace can be automated using AWS Cloud Development Kit (CDK) or AWS CloudFormation. The short answer is yes it is possible to create a virtual desktop using AWS Cloudformation. However, automating the creation of an Amazon Workspace is not straight forward using CDK. The documentation states that there is no L2 construct for Amazon Workspaces available in CDK which brings us to the purpose of this short article.]]></summary></entry><entry><title type="html">VirtIO in context of ECU virtualization on AWS</title><link href="/aws,/ecu,/virtualization,/virtio/2023/10/05/virtio.html" rel="alternate" type="text/html" title="VirtIO in context of ECU virtualization on AWS" /><published>2023-10-05T08:24:47+00:00</published><updated>2023-10-05T08:24:47+00:00</updated><id>/aws,/ecu,/virtualization,/virtio/2023/10/05/virtio</id><content type="html" xml:base="/aws,/ecu,/virtualization,/virtio/2023/10/05/virtio.html"><![CDATA[<p>Virtio, defined by the <a href="https://docs.oasis-open.org/virtio/virtio/v1.1/csprd01/virtio-v1.1-csprd01.html">OASIS Standard</a>, outlines a suite of virtualization devices. It establishes an architecture that paravirtualizes hardware devices, with the best explanation available <a href="https://developer.ibm.com/articles/l-virtio/">here</a>.</p>

<p>In practice, Virtio devices can be addressed and utilized just like actual hardware devices. Virtio serves as the standard Input/Output (IO) virtualization framework for the Linux KVM (Kernel-based Virtual Machine) hypervisor. A hypervisor offers a management layer that enables the operation of multiple virtual machines on a single hardware unit. Virtio provides specifications for various device types, such as block storage and network devices, thereby eliminating the need to use different frameworks for different device types.</p>

<p>Moreover, Virtio is recognized for delivering superior <a href="https://wiki.libvirt.org/Virtio.html">performance</a> as it belongs to a class of virtualization frameworks that employ paravirtualization techniques, presenting an edge over fully virtualized device abstractions.</p>]]></content><author><name></name></author><category term="AWS," /><category term="ECU," /><category term="virtualization," /><category term="virtio" /><summary type="html"><![CDATA[Virtio, defined by the OASIS Standard, outlines a suite of virtualization devices. It establishes an architecture that paravirtualizes hardware devices, with the best explanation available here.]]></summary></entry><entry><title type="html">Leveraging ARM Virtual Hardware (AVH) to Run Microcontroller Code in the Cloud</title><link href="/aws,/ecu,/virtualization/2023/10/01/arm-virtual-hardware.html" rel="alternate" type="text/html" title="Leveraging ARM Virtual Hardware (AVH) to Run Microcontroller Code in the Cloud" /><published>2023-10-01T12:24:47+00:00</published><updated>2023-10-01T12:24:47+00:00</updated><id>/aws,/ecu,/virtualization/2023/10/01/arm-virtual-hardware</id><content type="html" xml:base="/aws,/ecu,/virtualization/2023/10/01/arm-virtual-hardware.html"><![CDATA[<p>With this post, I intend to shed light on the seemingly dark jungle of ARM SoC and CPU types, particularly in the automotive industry. Additionally, it hints at how to run microcontroller application code on cloud servers using <a href="https://www.qemu.org/">QEMU</a> or <a href="https://www.arm.com/products/development-tools/simulation/virtual-hardware">ARM Virtual Hardware</a>.</p>

<h2 id="accelerating-ecu-development-with-virtualization">Accelerating ECU Development with Virtualization</h2>

<p>Striving to reduce development times for Electronic Control Units (ECUs), AWS Automotive customers are contemplating providing a virtualized version of a new hardware platform to software developers well ahead of the real hardware’s availability. This approach enables software development teams in two ways:</p>
<ol>
  <li>They can begin creating software right from the start of a new ECU development project</li>
  <li>They have a means of providing each developer with multiple development environments to experiment with.</li>
</ol>

<p><a href="https://www.arm.com/">ARM</a> is one of the leading suppliers in the automotive industry, licensing its CPU architecture for use in vehicle microcontrollers as well as In-Vehicle Infotainment systems.</p>

<h2 id="an-overview-of-arm-cpu-families">An Overview of ARM CPU Families</h2>

<p>ARM boasts a number of CPU families. One such family is the Cortex-family. Targeting microcontrollers, ARM provides the Cortex-M group of 32-bit RISC processor cores, which are used as main microcontroller cores but can also act in an SoC as a hidden CPU for a dedicated purpose, like a power management controller.</p>

<p>Another member of the Cortex-family is the Cortex-A group of 32-bit and 64-bit RISC ARM processor cores. These processor cores are designed to be multi-purpose CPUs. AWS employs 64-bit cores from this family for the Graviton EC2 instance family. The 64-bit Cortex-A cores implement the ARMv8 architecture, which encompasses a number of features important for modern, multi-purpose operating systems like Linux to function.</p>

<h2 id="deploying-to-aws-and-handling-cpu-architecture-differences">Deploying to AWS and Handling CPU Architecture Differences</h2>

<p>Since AWS utilizes CPUs implementing the ARMv8 architecture, software targeted for vehicle ECUs equipped with Cortex-A CPUs can be directly deployed to AWS without recompilation. In contrast, software targeting vehicle ECUs equipped with Cortex-M CPUs cannot directly run on AWS ARM CPUs, like the Graviton CPU, due to the fundamental differences in the CPU instruction set design.</p>

<h2 id="emulating-arm-architecture">Emulating ARM Architecture</h2>

<p>To navigate this issue, one can use an emulator like <a href="https://www.qemu.org/">QEMU</a> or <a href="https://www.arm.com/products/development-tools/simulation/virtual-hardware">ARM Virtual Hardware</a>. Unlike QEMU, AVH supports many more ARM CPU architectures as well as so-called AVH Fixed Virtual Platforms (AVH FVPs). Beyond the respective ARM CPU architecture and instruction set, AVH FVPs provide a simulation of an ARM-Based SoC (System on Chip). SoCs complement the CPU with peripherals useful for the intended use case for which the SoC is designed. For ARM Virtual Hardware, there is an Amazon Machine Image available on the AWS Marketplace. Please follow the instructions <a href="https://arm-software.github.io/AVH/main/infrastructure/html/AWS.html">here</a> to run an example speech recognition model on a virtualized</p>]]></content><author><name></name></author><category term="AWS," /><category term="ECU," /><category term="virtualization" /><summary type="html"><![CDATA[With this post, I intend to shed light on the seemingly dark jungle of ARM SoC and CPU types, particularly in the automotive industry. Additionally, it hints at how to run microcontroller application code on cloud servers using QEMU or ARM Virtual Hardware.]]></summary></entry></feed>