Start Building for Free
CircleCI.comAcademyBlogCommunitySupport

Introduction to YAML configuration

1 week ago4 min read
Cloud
Server v4+
On This Page

The crux of connecting CircleCI to your project is a config.yml, which is held in a .circleci directory. CircleCI configuration files are written in YAML, a more human-friendly data serialization format for programming languages. YAML is a strict superset of JSON, so anything you can do in JSON, you can also do in YAML. CircleCI YAML configurations will largely consist of key-value pairs, and nested key-value pairs.

The most basic configuration file will need a CircleCI version, an execution environment, and a job to run.

CircleCI version

Your .circleci/config.yml will start off with the version of CircleCI you wish to use. CircleCI cloud and newer server versions should be using CircleCI 2.1.

# CircleCI configuration file

version: 2.1

Execution environment

Next, your configuration needs a job to run, and an execution environment for that job to run in. The following are CircleCI’s supported execution environments:

  • Docker

  • Linux VM (virtual machine)

  • macOS

  • Windows

  • GPU

  • Arm

Some limitations exist depending on the execution environment in your configuration. Visit the Introduction to Execution Environments page to get started and find information on each execution environment.

In the .circleci/config.yml file, we will add a Docker execution environment to our job build.

# CircleCI configuration file
version: 2.1

jobs:
  build:
    docker:
    # Primary container image where all steps run
     - image: cimg/base:2022.05

jobs is a collection of steps which are executed as a unit, either within a fresh container, or a virtual machine. In this example, jobs is being built within a Docker container, which is set up in the configuration using nested key-pairs. docker is calling a pre-built CircleCI Docker image, cimg/base, an Ubuntu Docker image. The image in this example contains the minimum tools required to operate a build on CircleCI, as well as Docker.

Images are used by either a Docker or machine executor. In our example, we are using a Docker convenience image that spins up an Ubuntu environment. If we used macOS as an execution environment, we could use a machine image instead, which would spin up a dedicated virtual machine with Xcode preinstalled, as in the example below.

# CircleCI configuration file
version: 2.1

jobs:
  build:
    macos:
      xcode: 13.3.0

You will notice that the key-value pairs do not follow the same syntax. Each execution environment will be set up a little differently. You can refer to our execution environment documentation, or visit the CircleCI developer hub to find a list of convenience images and machine images, and their syntax.

The developer hub also has a list of available CircleCI orbs, which are shareable packages of configuration you can use to simplify your builds. Visit the Slack Orb Tutorial page for instructions on how to set up one of the most popular orbs.

CircleCI jobs and workflows

The last thing we need for a basic CircleCI configuration is a job to actually run. Jobs are orchestrated using workflows, which is a set of rules defining a collection of jobs and their run order. Using the Docker configuration example, we can add steps to our job. Steps are a list of commands to run inside the Docker container.

# CircleCI configuration file
version: 2.1

jobs:
  build:
    docker:
     - image: cimg/base:2022.05
    steps:
        - run: echo "Say hello to YAML!"

This very basic example is only running one job, build, which means there is also only one workflow running in the background. If a second job is added, workflows will need to be defined explicitly, to orchestrate the run order. Job names can be updated to reflect the job when workflows is added. If there is only one job defined, the job must be named build, as in the example above.

A second job, and workflows defining run order, is shown in the example below.

# CircleCI configuration file
version: 2.1

jobs:
  # Job one with a unique name
  say_hello:
    docker:
     - image: cimg/base:2022.05
    steps:
      - run: echo "Say hello to YAML!"
  # Job two with a unique name
  say_goodbye:
    docker:
     - image: cimg/base:2022.05
    steps:
      - run: echo "Say goodbye to YAML!"

workflows:
  # Name of workflow
  hello_and_goodbye:
    # List of jobs that will run
    jobs:
      - say_hello
      - say_goodbye

If you have a CircleCI account, you can create a new project and add these examples to a .circleci/config.yaml file. You can see the strings printed out in the job’s build pipeline in the CircleCI web UI.

YAML can be quite picky about indentations. You can use a YAML checker to parse your YAML and make sure it is valid.

If you would like a more complex configuration tutorial, visit the Configuration Tutorial page. Before starting this tutorial, you should already have a CircleCI account set up, as you will follow along in the CircleCI web UI. You can also find a variety of configuration examples on the Sample Configuration page.

VS Code extension

If you use VS Code, you might find the official CircleCI extension useful when writing, editing, navigating and troubleshooting your YAML Config files.

The extension provides real-time syntax highlighting and validation, improved navigation through go-to-definition and go-to-reference commands, usage hints and autocomplete suggestions.

Screenshot showing the definition available on hover

Authenticating the extension with your CircleCI account will also allow you to visualize and manage your CircleCI pipelines directly from VS Code, and be notified of workflow status changes. The CircleCI VS Code extension is available to download on the VS Code marketplace.

Fun with YAML

Below are some fun examples of other YAML syntax that might become handy as you create more complex configuration files.

Multi-line strings

If the value is a multi-line string, use the > character, followed by any number of lines. This is especially useful for lengthy commands.

haiku: >
  Please consider me
  As one who loved poetry
  Oh, and persimmons.

Note: Quotes are not necessary when using multiline strings.

Sequences

Keys and values are not restricted to scalars. You may also map a scalar to a sequence.

scalar:
  - never
  - gonna
  - give
  - you
  - up

Items in sequences can also be key-value pairs.

simulation:
  - within: "a simulation"
  - without:
      a_glitch: "in the matrix"

Note: Remember to properly indent a key-value pair when it is the value of an item in a sequence.

Anchors and aliases

To DRY up your .circleci/config.yml, use anchors and aliases. Anchors are identified by an & character, and aliases by an * character.

song:
  - &name Al
  - You
  - can
  - call
  - me
  - *name

When the above list is read by a YAML parser, the literal output looks like this.

song:
  - Al
  - You
  - can
  - call
  - me
  - Al

Merging maps

Anchors and aliases work for scalar values, but to save maps or sequences, use << to inject the alias.

default: &default
  school: hogwarts

harry:
  <<: *default
  house: gryffindor

draco:
  <<: *default
  house: slytherin

You can also merge multiple maps.

name: &harry_name
  first_name: Harry
  last_name: Potter

address: &harry_address
  street: 4, Privet Drive
  district: Little Whinging
  county: Surrey
  country: England

harry_data:
  <<: [*harry_name, *harry_address]

Note: As mentioned in a YAML repository issue, it is possible to merge maps, but not sequences (also called arrays or lists). For a more complex example, see this gist.


Suggest an edit to this page

Make a contribution
Learn how to contribute