Everyday ‘Solution Architectural’ Thinking

As an Architect you can expect, at some point in your career, to be involved in a critical frontline, turbulent project or programme. During such times, you need to rely on technical, political and social skills gained over several years of working in the field of ICT.

Today’s blog (prepared on the London-Coventry train)  is a reminder of some of the “basics” that the average Solution Architect must consider when working on complex projects. These ‘system orientated’ considerations remain at the forefront during project engagement elements , requiring consideration during analysis, design and build stages of system construction / delivery at the same time of maintaining the line of sight for the outcome.

As with most things in life, the list presented is obviously subject to the area you operate in, for example, if you are working on a Manufacturing Execution System (MES) solution then your primary focus for the project would be on the real-time supervisory control and data acquisition systems and processes. However, if you are working on a Retail Banking Application then your focus would be biased towards compliance and reporting.

The list presented is not exhaustive and kept general to provide insight. However If we examine most ICT projects, we often find  a common pattern i.e. one of collecting raw data, transforming this into  information then allowing digital processes to consume and generate reports allowing businesses to execute an event or action that adds value to the Organisation.

This movement is presented in the diagram below, with thought  bubbles representing areas of thought which are further listed in the tables below;

Everyday Solution Architectural Focus Points during a project

Continue reading “Everyday ‘Solution Architectural’ Thinking”

The Solution Architecture Life Cycle

Solution Architects as previously mentioned are responsible for working with programmes and projects to ensure a solution to problems is designed, costed, procured, built and delivered into the organisations which often results in delivering a new process outcome and IT capability.

Solution Architects address a wide spectrum of problems and issues ranging from the simple to the complex and thus require a wide range of skills (technical / business).

The work of the Solution Architect can be broken down into distinct stages and categorised into the following areas:


Solution Architecture Life Cycle

Each layer of the Solution Architect Lifecycle is briefly discussed below. However, it must be noted that the focus at each layer will be aligned to the top layer i.e. the problem/issue.


Often a problem requires a working group to establish if something is worth considering e.g. bid on a project or to discuss a ‘pattern’ that is emerging in the technology landscape which requires investigation from the reporting systems e.g. Capacity & Performance / Security incidents.

Solution Architects are often engaged at this stage to provide advice on possible options for resolving a problem and to assist in triggering the next phase of the activity.

Defining the context of the problem/issue

No project or programme of work in real terms commences without a Business Case i.e. a document that captures the reasoning for initiating a project or task with basic costings and outcomes documented. If the problem issue is a Technical one then the Solution Architect is required to elaborate (in simplistic terms) the context of the problem from the systems viewpoint.

Capturing the Requirements

During the requirements capture phase the Solution Architect will spend much of his/her time focusing on the system elements of the requirements and trying to understand the system components characteristics.

During this stage, there will be a bias towards the non-functional elements of the system.

During this stage, a Minimum Viable Product can be elicited from stakeholders, i.e. the minimum components and effort that will be required to deliver the functional and non-functional requirements can be sketched to define further costs analysis.

It must be noted that the requirements must also encapsulate any legal compliance issues e.g. GDPR requirement and any Enterprise Architectural directives.

Defining Product Backlog and or Level 0 Systems Architecture

Once the problem is known, documented and decomposed into a set of clearly defined functional and non-functional requirements a level 0 systems architecture can be produced to outline a solution.

Where possible reusable components should be highlighted to shorten time to market and increase savings to the project.

At this stage, the outcome should be a level 0 design and in many cases, result in a product backlog for the solution

The level 0 design will facilitate the project to determine the cost and effort involved to deliver the outcome required.

Designing the Solution and breaking down the deliverables into sprints

At this stage, a detailed analysis of the Level 0 is undertaken and elaborated further to deliver a detailed design document and the subsequent technical sprints to deliver the project.

Depending on the Solution it may be prudent to produce a low-level design to support the Solution Design.

Options for realising the solution and enacting

I have discussed previously the options that are available for analysis from “do nothing” to “Build” but from a cost / do ability view the option should be selected that leverages existing relationships /services and best value for money.

Delivering Solution into production

Developing, procuring  or modifying a system requires deployment into a production environment and thus the Solution Architect must be capable of defining the environments (test, prod, pre-prod) for the route to live. Often this will involve working with the Service Architects to design the Service and the operational elements (often extrapolated from the NFRs) of the system.

If we were to take all the elements above and assign time that the Solution Architect would be involved in the project then we could produce a graph like the one below;


In summary, the Solution Architect is an important role and requires skills that evolve with each engagement and has a role to play from problem realisation to delivery into service of a solution.

The article from https://dalbanger.wordpress.com/2017/05/07/the-solution-architecture-life-cycle/

AccessToken Vs ID Token Vs Refresh Token, What? Why? When?


This article demonstrates different types of tokens in OpenID Connect. At the end of this article, you will have clear understanding on the below points,
  1. About JSON Web Tokens (JWT)
  2. What is Access Token?
  3. Example of Access Token
  4. Why we need Access Token?
  5. What is ID Token?
  6. Example of ID Token
  7. Why we need ID Token?
  8. What is Refresh Token?
  9. Example of Refresh Token
  10. Why we need Refresh Token?
Related reads

About JSON Web Tokens (JWT)

JWT i.e. Json Web Tokens, are an important piece in ensuring trust and security in your application. JWT allows claims such as user data to be represented in a secure manner.
A JWT is represented as a sequence of base64url encoded values that are separated by dot character. It’s ideal format is like “Header.Payload.Signature”, where header keeps metadata for the token. The payload is basically the claims of the entity (typically user) and a signature for the signed token.
The Signed token is generated by combining the encoded JWT header and Payload and it is signed by using encryption algorithm like HMAC SHA–256. The signature private key is always held by server so it will be able to verify existing token as well as sign new token.
JWT could be used as an opaque identifier and could be inspected for additional information – such as identity attributes which it represents as claims.
Sample JWT token format could look like,
AccessToken Vs ID Token Vs Refresh Token

What is Access Token?

Access tokens are credentials used to access protected resources.
Access tokens are used as bearer tokens. A bearer token means that the bearer (who holds the access token) can access authorized resources without further identification.
Because of this, it is important that bearer tokens be protected.
These tokens usually have a short lifespan for security purpose. When it expires, the user must authenticate again to get a new access token limiting the exposure of the fact that it is a bearer token.
Access token must never be used for authentication. Access tokens cannot tell if the user has authenticated. The only user information the access token processes is the user id, located in sub claims.
The application receives an access token after a user successfully authenticates and authorizes access. Itis usually in JWT format but do not have to be.
The application should treat access tokens as opaque strings since they are meant for APIs. Your application should not attempt to decode them or expect receive token in a
particular format.
This token does not contain any information about the user itself besides theirs ID (“sub”).It only contains authorization information about which actions the application is allowed to perform at the API (“scope”). This is what makes it useful for securing an API, but not for authenticating a user.
An access token is put in the Authorization header of your request, usually looks like Bearer “access_token” that the API you are calling can verify and grant you access.
Example of Access Token
Here is the sample response from the token endpoint! The response includes the ID token and access token. Your application can use the access token to make API requests on behalf of the user.

Continue reading “AccessToken Vs ID Token Vs Refresh Token, What? Why? When?”

Service-to-service communication

The article is from Microsoft.

Moving from the front-end client, we now address back-end microservices communicate with each other.

When constructing a cloud-native application, you’ll want to be sensitive to how back-end services communicate with each other. Ideally, the less inter-service communication, the better. However, avoidance isn’t always possible as back-end services often rely on one another to complete an operation.

There are several widely accepted approaches to implementing cross-service communication. The type of communication interaction will often determine the best approach.

Consider the following interaction types:

  • Query – when a calling microservice requires a response from a called microservice, such as, “Hey, give me the buyer information for a given customer Id.”
  • Command – when the calling microservice needs another microservice to execute an action but doesn’t require a response, such as, “Hey, just ship this order.”
  • Event – when a microservice, called the publisher, raises an event that state has changed or an action has occurred. Other microservices, called subscribers, who are interested, can react to the event appropriately. The publisher and the subscribers aren’t aware of each other.

Microservice systems typically use a combination of these interaction types when executing operations that require cross-service interaction. Let’s take a close look at each and how you might implement them.


Many times, one microservice might need to query another, requiring an immediate response to complete an operation. A shopping basket microservice may need product information and a price to add an item to its basket. There are many approaches for implementing query operations.

Request/Response Messaging

One option for implementing this scenario is for the calling back-end microservice to make direct HTTP requests to the microservices it needs to query, shown in Figure 4-8.

Direct HTTP communication

Figure 4-8. Direct HTTP communication

While direct HTTP calls between microservices are relatively simple to implement, care should be taken to minimize this practice. To start, these calls are always synchronous and will block the operation until a result is returned or the request times outs. What were once self-contained, independent services, able to evolve independently and deploy frequently, now become coupled to each other. As coupling among microservices increase, their architectural benefits diminish.

Executing an infrequent request that makes a single direct HTTP call to another microservice might be acceptable for some systems. However, high-volume calls that invoke direct HTTP calls to multiple microservices aren’t advisable. They can increase latency and negatively impact the performance, scalability, and availability of your system. Even worse, a long series of direct HTTP communication can lead to deep and complex chains of synchronous microservices calls, shown in Figure 4-9:

Chaining HTTP queries Continue reading “Service-to-service communication”

Front-end client communication

The article is from Microsoft.

In a cloud-native system, front-end clients (mobile, web, and desktop applications) require a communication channel to interact with independent back-end microservices.

What are the options?

To keep things simple, a front-end client could directly communicate with the back-end microservices, shown in Figure 4-2.

Direct client to service communication

Figure 4-2. Direct client to service communication

With this approach, each microservice has a public endpoint that is accessible by front-end clients. In a production environment, you’d place a load balancer in front of the microservices, routing traffic proportionately.

While simple to implement, direct client communication would be acceptable only for simple microservice applications. This pattern tightly couples front-end clients to core back-end services, opening the door for a number of problems, including:

  • Client susceptibility to back-end service refactoring.
  • A wider attack surface as core back-end services are directly exposed.
  • Duplication of cross-cutting concerns across each microservice.
  • Overly complex client code – clients must keep track of multiple endpoints and handle failures in a resilient way.

Instead, a widely accepted cloud design pattern is to implement an API Gateway Service between the front-end applications and back-end services. The pattern is shown in Figure 4-3.

API Gateway Pattern Continue reading “Front-end client communication”

Cloud Native

The article is from Microsoft.

Stop what you’re doing and text ten of your colleagues. Ask them to define the term “Cloud Native”. Good chance you’ll get ten different answers.

Cloud native is all about changing the way you think about constructing critical business systems.

Cloud-native systems are designed to embrace rapid change, large scale, and resilience.

The Cloud Native Computing Foundation provides an official definition:

Cloud-native technologies empower organizations to build and run scalable applications in modern, dynamic environments such as public, private, and hybrid clouds. Containers, service meshes, microservices, immutable infrastructure, and declarative APIs exemplify this approach.

These techniques enable loosely coupled systems that are resilient, manageable, and observable. Combined with robust automation, they allow engineers to make high-impact changes frequently and predictably with minimal toil.

Applications have become increasingly complex with users demanding more and more. Users expect rapid responsiveness, innovative features, and zero downtime. Performance problems, recurring errors, and the inability to move fast are no longer acceptable. They’ll easily move to your competitor.

Cloud native is about speed and agility. Business systems are evolving from enabling business capabilities to being weapons of strategic transformation that accelerate business velocity and growth. It’s imperative to get ideas to market immediately.

Here are some companies who have implemented these techniques. Think about the speed, agility, and scalability they’ve achieved.

Table 1
Company Experience
Netflix Has 600+ services in production. Deploys hundred times per day.
Uber Has 1,000+ services in production. Deploys several thousand times each week.
WeChat Has 3,000+ services in production. Deploys 1,000 times a day.

As you can see, Netflix, Uber, and WeChat expose systems that consist of hundreds of independent microservices. This architectural style enables them to rapidly respond to market conditions. They can instantaneously update small areas of a live, complex application, and individually scale those areas as needed.

The speed and agility of cloud native come about from a number of factors. Foremost is cloud infrastructure. Five additional foundational pillars shown in Figure 1-3 also provide the bedrock for cloud-native systems.

Cloud-native foundational pillars Continue reading “Cloud Native”

桥接模式 (Bridge Pattern)-结构型模式第五篇

Bridge Pattern
  1. 《设计模式》系列序——写给未来的自己
  2. 工厂方法模式(Factory Method)-创建型模式第一篇
  3. 抽象工厂模式(Abstract Factory Pattern)-创建型模式第二篇
  4. 单例模式(Singleton Pattern)-创建型模式第三篇
  5. 建造者模式(Builder Pattern)-创建型模式第四篇
  6. 原型模式(Prototype Pattern)-创建型模式第五篇
  7. 装饰者模式 (Decorator Pattern)-结构型模式第一篇
  8. 组合模式 (Composite Pattern)-结构型模式第二篇
  9. 适配器模式 (Adapter Pattern)-结构型模式第三篇
  10. 代理模式 (Proxy Pattern)-结构型模式第四篇
  11. 桥接模式 (Bridge Pattern)-结构型模式第五篇






Bridge Pattern Continue reading “桥接模式 (Bridge Pattern)-结构型模式第五篇”

Evaluate vSphere vs. OpenStack for your organization


VMware vSphere and open source project OpenStack present two different ways of structuring an infrastructure. In the vSphere vs. OpenStack debate, choosing the right infrastructure for your organization’s data center comes down to your staff’s expertise, your existing infrastructure requirements, your storage setup and whether you can compromise with vSphere Integrated OpenStack.

VSphere is the predominant virtualization software. It encompasses VMware’s server virtualization product suite, including its ESXi hypervisor, vCenter Server, an HTML5-based management interface and other popular virtualization components.

OpenStack is a collection of open source software, providing a cloud framework that enables you to create and manage both public and private cloud infrastructures. Although you can build a cloud computing environment off of a VMware vSphere infrastructure, OpenStack forms a cloud OS that can organize, provision and manage large resource pools. It also comes with many compute, storage, networking, content delivery, security and analytics resources.

To decide between vSphere vs. OpenStack, you must decide whether your organization needs a primarily cloud or virtualized environment, compare vSphere and OpenStack features and capabilities and evaluate the long-term cost of committing to each.

The cloud vs. virtualization debate

To decide between using cloud infrastructure or virtualized infrastructure, first consider the infrastructure your organization already runs. Identify the costs that could arise as a result of altering or exchanging infrastructure styles and consider the expertise of your IT staff.

If you already use VMware, consider extending a VMware facility to support cloud bursting, which creates business continuity and protects your VMware investment while also enabling you to take advantage of the cloud. However, you must understand how to incorporate cloud automation into your IT processes before attempting to introduce cloud bursting.

Many have implemented VMware Integrated OpenStack to get the best of both vSphere and OpenStack. VIO is an OpenStack distribution for companies that want to deploy and manage an OpenStack private cloud atop an existing vSphere infrastructure.


Public cloud prices have also dropped since public cloud first hit the market. Still, you must weigh the cost difference of paying for a monthly cloud subscription versus an upfront fixed-cost purchase of hardware.

VSphere, OpenStack and containers

VMware was late to introduce cloud products compared to other vendors — specifically, OpenStack, its competitor in private cloud deployments. OpenStack sandboxes are common and easy to deploy; however, OpenStack has struggled with managing scale, user friendliness and feature completeness.

Containers have represented a struggle for many vendors, including OpenStack and VMware. The OpenStack community has developed several service modules to run container instances on OpenStack. Certain releases of the platform, such as 2017’s Ocata release, include container management services that enable you to run container orchestrators such as Apache Mesos, Docker and Kubernetes.

In 2019, VMware introduced its Project Pacific initiative to build Kubernetes and container management capabilities natively into vSphere. Earlier initiatives, such as Pivotal Container Service, also focused on incorporating Kubernetes support into vSphere and aimed to simplify Kubernetes deployment and management.

Storage differences between vSphere vs. OpenStack

A major difference between vSphere and OpenStack is how each handles storage, backup and disaster recovery.

VSphere maps storage to ESXi, where each ESXi host accesses its storage through a logical unit number mapped to a data store. This approach includes a degree of storage management automation, and you can rebalance VMs across a vSphere cluster based on storage capacity and I/O. You can use a number of APIs to enable your hypervisor to direct storage and manage VMs more effectively.

OpenStack environments, on the other hand, require persistent block storage. This approach requires external storage that supports OpenStack’s Cinder API. However, OpenStack does have the direct object storage that VMware vSphere lacks.

With OpenStack, you save on storage infrastructure costs, but it can increase management costs. The reverse is true with vSphere. Consider your organization’s priorities and resource allocation when you think about the storage requirements of vSphere vs. OpenStack.

Compromising with VMware Integrated OpenStack

Many have implemented VMware Integrated OpenStack (VIO) to get the best of both vSphere and OpenStack. VIO is an OpenStack distribution for companies that want to deploy and manage an OpenStack private cloud atop an existing vSphere infrastructure. It provides developers with OpenStack APIs that can access a VMware virtualized infrastructure and has been tested and supported by VMware.

IT managers and experts have praised VIO for combining the maturity of a VMware environment with the agility of OpenStack. It has utilities that can automate patching and upgrading, and it offers critical VMware products, including vSphere, NSX and VSAN, through OpenStack APIs. Most importantly, it eliminates the requirement to have separate platforms for older, legacy applications that remain critical to an organization and for newer, more modern applications.

However, VIO features can be expensive. You can gain access to VIO with a vSphere Enterprise Plus license, but it doesn’t include support. VIO support is purchased on a per-CPU basis. Newer versions of VIO with more support features are more expensive than older versions without such updates.

Markdown Syntax


Nearly all Markdown applications support the basic syntax outlined in John Gruber’s original design document. There are minor variations and discrepancies between Markdown processors, those are noted inline wherever possible.


To create a heading, add number signs (#) in front of a word or phrase. The number of number signs you use should correspond to the heading level. For example, to create a heading level three (<h3>), use three number signs (e.g., ### My Header).

Markdown HTML Rendered Output
# Heading level 1 <h1>Heading level 1</h1> Heading level 1
## Heading level 2 <h2>Heading level 2</h2> Heading level 2
### Heading level 3 <h3>Heading level 3</h3> Heading level 3
#### Heading level 4 <h4>Heading level 4</h4> Heading level 4
##### Heading level 5 <h5>Heading level 5</h5> Heading level 5
###### Heading level 6 <h6>Heading level 6</h6> Heading level 6

Alternate Syntax

Alternatively, on the line below the text, add any number of == characters for heading level 1 or — characters for heading level 2.

Markdown HTML Rendered Output
Heading level 1
<h1>Heading level 1</h1> Heading level 1
Heading level 2
<h2>Heading level 2</h2> Heading level 2

Heading Best Practices

Markdown applications don’t agree on how to handle a missing space between the number signs (#) and the heading name. For compatibility, always put a space between the number signs and the heading name.

  Do this   Don’t do this
# Here’s a Heading #Here’s a Heading


To create paragraphs, use a blank line to separate one or more lines of text.

Markdown HTML Rendered Output
I really like using Markdown.

I think I’ll use it to format all of my documents from now on.

<p>I really like using Markdown.</p>

<p>I think I’ll use it to format all of my documents from now on.</p>

I really like using Markdown.

I think I’ll use it to format all of my documents from now on.

Paragraph Best Practices

Unless the paragraph is in a list, don’t indent paragraphs with spaces or tabs.

  Do this   Don’t do this
Don’t put tabs or spaces in front of your paragraphs.

Keep lines left-aligned like this.

    This can result in unexpected formatting problems.

Don’t add tabs or spaces in front of paragraphs.

Line Breaks

To create a line break (<br>), end a line with two or more spaces, and then type return.

Markdown HTML Rendered Output
This is the first line.
And this is the second line.
<p>This is the first line.<br>
And this is the second line.</p>
This is the first line.
And this is the second line.

Line Break Best Practices

You can use two or more spaces (commonly referred to as “trailing whitespace”) for line breaks in nearly every Markdown application, but it’s controversial. It’s hard to see trailing whitespace in an editor, and many people accidentally or intentionally put two spaces after every sentence. For this reason, you may want to use something other than trailing whitespace for line breaks. Fortunately, there is another option supported by nearly every Markdown application: the <br> HTML tag.

For compatibility, use trailing white space or the <br> HTML tag at the end of the line.

There are two other options I don’t recommend using. CommonMark and a few other lightweight markup languages let you type a backslash () at the end of the line, but not all Markdown applications support this, so it isn’t a great option from a compatibility perspective. And at least a couple lightweight markup languages don’t require anything at the end of the line — just type return and they’ll create a line break.

  Do this   Don’t do this
First line with two spaces after.
And the next line.First line with the HTML tag after.<br>
And the next line.
First line with a backslash after.
And the next line.First line with nothing after.
And the next line.


You can add emphasis by making text bold or italic.


To bold text, add two asterisks or underscores before and after a word or phrase. To bold the middle of a word for emphasis, add two asterisks without spaces around the letters.

Markdown HTML Rendered Output
I just love **bold text**. I just love <strong>bold text</strong>. I just love bold text.
I just love __bold text__. I just love <strong>bold text</strong>. I just love bold text.
Love**is**bold Love<strong>is</strong>bold Loveisbold

Bold Best Practices

Markdown applications don’t agree on how to handle underscores in the middle of a word. For compatibility, use asterisks to bold the middle of a word for emphasis.

  Do this   Don’t do this
Love**is**bold Love__is__bold


To italicize text, add one asterisk or underscore before and after a word or phrase. To italicize the middle of a word for emphasis, add one asterisk without spaces around the letters.

Markdown HTML Rendered Output
Italicized text is the *cat’s meow*. Italicized text is the <em>cat’s meow</em>. Italicized text is the cat’s meow.
Italicized text is the _cat’s meow_. Italicized text is the <em>cat’s meow</em>. Italicized text is the cat’s meow.
A*cat*meow A<em>cat</em>meow Acatmeow

Italic Best Practices

Markdown applications don’t agree on how to handle underscores in the middle of a word. For compatibility, use asterisks to italicize the middle of a word for emphasis.

  Do this   Don’t do this
A*cat*meow A_cat_meow

Bold and Italic

To emphasize text with bold and italics at the same time, add three asterisks or underscores before and after a word or phrase. To bold and italicize the middle of a word for emphasis, add three asterisks without spaces around the letters.

Markdown HTML Rendered Output
This text is ***really important***. This text is <strong><em>really important</em></strong>. This text is really important.
This text is ___really important___. This text is <strong><em>really important</em></strong>. This text is really important.
This text is __*really important*__. This text is <strong><em>really important</em></strong>. This text is really important.
This text is **_really important_**. This text is <strong><em>really important</em></strong>. This text is really important.
This is really***very***important text. This is really<strong><em>very</em></strong>important text. This is reallyveryimportant text.

Bold and Italic Best Practices

Markdown applications don’t agree on how to handle underscores in the middle of a word. For compatibility, use asterisks to bold and italicize the middle of a word for emphasis. Continue reading “Markdown Syntax”

YAML Syntax


YAML is used for configuration files, blueprints, and also in page settings.

YAML is to configuration what markdown is to markup. It’s basically a human-readable structured data format. It is less complex and ungainly than XML or JSON, but provides similar capabilities. It essentially allows you to provide powerful configuration settings, without having to learn a more complex code type like CSS, JavaScript, and PHP.

YAML is built from the ground up to be simple to use. At its core, a YAML file is used to describe data. One of the benefits of using YAML is that the information in a single YAML file can be easily translated to multiple language types.

YAML Basic Rules

There are some rules that YAML has in place to avoid issues related to ambiguity in relation to various languages and editing programs. These rules make it possible for a single YAML file to be interpreted consistently, regardless of which application and/or library is being used to interpret it.

  • YAML files should end in .yaml.
  • YAML is case sensitive.
  • YAML does not allow the use of tabs.

Basic Data Types

YAML excels at working with mappings (hashes / dictionaries), sequences (arrays / lists), and scalars (strings / numbers). While it can be used with most programming languages, it works best with languages that are built around these data structure types. This includes: PHP, Python, Perl, JavaScript, and Ruby.


Scalars are a pretty basic concept. They are the strings and numbers that make up the data on the page. A scalar could be a boolean property, like true, integer (number) such as 5, or a string of text, like a sentence or the title of your website.

Scalars are often called variables in programming. If you were making a list of types of animals, they would be the names given to those animals.

Most scalars are unquoted, but if you are typing a string that uses punctuation and other elements that can be confused with YAML syntax (dashes, colons, etc.) you may want to quote this data using single ‘ or double ” quotation marks. Double quotation marks allow you to use escapings to represent ASCII and Unicode characters.

integer: 25
string: "25"
float: 25.0
boolean: true

TIP: Words true, false, null, ~ and dates have special meaning in YAML. Please quote them if you do not want to use them as a boolean, null or datetime type. Same is true with version numbers, they should be quoted to separate them from float values.


Here is a simple sequence you. It is a basic list with each item in the list placed in its own line with an opening dash.

- Cat
- Dog
- Goldfish

This sequence places each item in the list at the same level. If you want to create a nested sequence with items and sub-items, you can do so by placing a single space before each dash in the sub-items. YAML uses spaces, NOT tabs, for indentation. You can see an example of this below. Continue reading “YAML Syntax”