Skip to main content
Introduction to Devops

Configuration Management Tools, Virtualization, and Docker

Published: 2026-08-14
Level: postgraduate
Audience: Postgraduate students of software engineering and delivery

Prerequisite Knowledge

This lecture builds on the following concepts from earlier lectures. If any feel unfamiliar, review the linked notes before proceeding.

Previously Covered in This Subject

  • Configuration management and its tools — 17.1 Configuration Management — What It Is and Where It Comes From, with the tool landscape in 17.7.4 Tools for Configuration Management and Infrastructure as Code (Lecture 17)
  • Configuration as code and infrastructure as code — 17.5 Infrastructure as Code and 17.7.3 From Documents to Code: Configuration as Code (Lecture 17)
  • Docker containers and orchestration — 18.4 Docker: Packaging the Service Into an Image and 18.8 How Docker and Kubernetes Work Together (Lecture 18)

Configuration Management Tools, Virtualization, and Docker

19.1 What Every Configuration Management Tool Provides

19.1.1 Common Capabilities

Hook: Imagine a company running two hundred application servers. One night, a security bulletin demands a new firewall rule on every machine. Do you log in to each server one by one with a checklist, or do you change one file and let software fix all two hundred? Configuration management tools exist to make the second path the normal one.

We saw in earlier sessions how configuration and infrastructure used to live as documents — runbooks, setup checklists, and handwritten environment notes — and how the industry moved to writing them as code: configuration as code and infrastructure as code. Configuration management tools are the practical side of that idea: they are the software that actually applies a coded, versioned description of your environment to real machines. Every configuration management tool — Chef, Puppet, Ansible, and others — shares the same core set of capabilities, so it pays to learn the common ground first and then compare individual tools against it. Whatever tool you meet later in your career, it will be doing these same jobs in its own vocabulary.

Intuition — the recipe-card model. Think of a configuration management tool as a chef who owns a stack of recipe cards (the coded descriptions) and a kitchen full of stations (the machines). Each recipe card says exactly what a station must look like: which ingredients (packages) must be on the shelf, which appliances (services) must be switched on, which labels (files) must be in place. The chef's job is not to cook once; it is to walk the kitchen repeatedly and bring every station back to match its card. When a recipe changes, the chef reprints one card — every station gets the new version of the truth. The model breaks where real recipes break: a card cannot say "make it taste good"; it can only describe measurable states — installed, running, present, absent — which is exactly what the tools can check and enforce.

The first common feature is quick provisioning of new servers. Because your servers are described as code, spinning up a fresh machine means applying that code, not following a manual checklist. The second is quick recovery from critical events — when something breaks, the same coded description can rebuild the environment fast. Next, configuration management tools give you version control for the server environment: the state of your servers changes over time in a tracked, reviewable way, exactly like source code. You can also replicate any number of environments easily — if you need another test environment, or a different kind of environment, you just replicate the description.

Formalize — the capability set every tool shares. Treat this list as the definition of the whole category; every later comparison reduces to it.

  • Quick provisioning — a new server goes from bare metal to configured in minutes by running code, not by hours of manual setup.
  • Quick recovery — after a crash, misconfiguration, or deleted file, the same coded description rebuilds the environment to a known-good state.
  • Version control for the environment — server state changes over time in a tracked, reviewable history, exactly like source code; you can see who changed what and roll back.
  • Environment replication — test, staging, and production environments are copies of the same description plus small per-environment overrides.
  • Automation that keeps the desired state intact — every tool has its own server (the tool's server, not your application server). That server runs an automation framework: with the help of automation, the configuration management server keeps the desired state intact. The desired state is the configuration you have declared — the packages that must be installed, the services that must be running, the files that must exist.
  • Idempotent behavior — a node exhibits idempotency: applying the same configuration twice produces the same result, and applying it to an already-correct node changes nothing. Run the same declaration a hundred times and the node converges to the same end state every time.
  • Templating — you define one template and distribute it globally to all your environments, then layer whatever extra configuration each environment needs on top of that template. The template holds the 90% that is common; each environment adds its 10%.
  • Extensibility — whenever you need more, you can increase the number of environments or replicate existing ones without redoing the base work.

Scope — what these capabilities assume. The whole model assumes that your environments can be described as code: the packages, services, files, and settings must be declarable and checkable. The model weakens when that assumption fails:

  • State you cannot express — data inside a database, user-generated content, or long-running session state is not something a configuration declaration reinstates; the tool can ensure a database package is installed, not that the database is populated.
  • Machines you cannot reach or instrument — a black-box network router that refuses agents and SSH cannot be managed by an agent-based tool at all (this drives the agentless story we meet with Ansible).
  • One tool for everything is a myth — configuration management keeps machines in their desired state; it does not load balance traffic, scale instances, or orchestrate containers. Those jobs belong to orchestration tools such as Kubernetes.

19.1.2 Terminology: Nodes and Servers

Before comparing tools, fix two words so that everything stays unambiguous. A node is the infrastructure — the server or machine — on which your application runs. A server, in this context, means the configuration management tool's server: the central piece that stores and distributes the configuration. So Chef has a Chef server, Puppet has a Puppet master, and Ansible has an automation engine; the machines being managed are always the nodes.

Confusion flag (the professor's terminology fix): this is a classic point of confusion, so the professor fixed it before the tools discussion began. When someone says "server" in this lecture, they almost always mean the configuration management tool's server, not the machine running your application. The application machine has its own name — node — and the two must never be swapped in an exam answer. Node = where the application runs; server = the tool's central hub.

Visual intuition. Picture a wheel: the configuration management server is the hub, and every managed machine is a spoke node around it. The hub holds the description of how every spoke should look; each spoke connects back to the hub to receive its instructions. Chef calls its hub a Chef server, Puppet calls its hub a Puppet master, and Ansible's hub is an automation engine — but in all three pictures the hub-versus-spoke relationship is identical. The one-sentence takeaway: every tool in this lecture has exactly one hub (the tool's server) and many spokes (the nodes).

Pitfalls:

  • Swapping node and server — saying "the node stores the cookbooks" is wrong; cookbooks live on the tool's server, nodes consume them. Keep the wheel picture: hub stores, spokes apply.
  • Expecting configuration management to scale instances — a tool that keeps ten nodes in their desired state does not start an eleventh node under load. Provisioning new machines and routing traffic between them is orchestration's job.
  • Treating the desired state as a one-time setup script — the declaration is a standing contract that is re-applied; thinking of it as "run once at install time" misses the entire recovery story of the next sections.
  • Forgetting version control — a desired-state description that lives nowhere but a human's head is not configuration as code; the version-controlled repo is what makes quick recovery and audit possible.

Recap + bridge: every configuration management tool is built around the same wheel: a coded, versioned description of the desired state, a tool server that stores it, and nodes whose behavior is idempotently brought back to that state — with quick provisioning, quick recovery, templating, and extensibility on top. With that common ground fixed, the next section asks the obvious question: if all tools share these capabilities, what makes Chef, Puppet, and Ansible different? The answer begins with Chef.

Real-world & domain connection. This capability set is the backbone of modern infrastructure teams everywhere: cloud platforms (AWS, Azure, Google Cloud) and on-premises datacenters alike are provisioned and kept consistent with these tools, and the version-controlled, auditable history they provide is what lets organizations satisfy compliance regulations — you can answer "exactly what changed on that production machine, who changed it, and when" in minutes. The periodic table of the DevOps toolchain (shared in an earlier session) shows how crowded this space is; the capability list above is the frame you use to judge any tool on that table.

19.2 Chef: Agent-Based Configuration as Code

19.2.1 Why Chef

Hook: You are an operations engineer responsible for three hundred machines spread across a datacenter, a private cloud, and AWS. One application needs Java 7, another needs a patched web server, and a third must never be touched after 5 p.m. How do you declare all of that in one place, in code, so that every machine stays exactly as you declared — even after someone breaks it?

Chef provides automated infrastructure provisioning — it genuinely supports infrastructure as code. It also supports configuration as code. The tool uses the Ruby domain-specific language (DSL) to express configuration, which is reasonably easy to read, although — as we will see — not as easy as Ansible's language, which reads more like a newspaper or a textbook. Chef is compatible with physical, virtual, and cloud machines: the node can be a physical machine, a virtual machine, or a cloud instance. It also has the capability to interact with any cloud technology — you are not restricted to AWS, Azure, or Google Cloud; Chef can be integrated with whichever cloud services you use. And on top of all that, it is open source — you download the Chef kit, do the configuration setup on your local system, and start using it.

Real-world: who still runs Chef. Organizations still using Chef as their configuration management tool include Facebook, named first in the lecture, and then Etsy and Indiegogo (the names came through the recording garbled — heard as "Itzy" and "Idigogo" — but the organizations referenced are the e-commerce marketplace Etsy and the crowdfunding platform Indiegogo). Others are out there too; the professor picked these as the recognizable names to show that Chef runs at large scale, not just in small shops.

Intuition — the audience matters. One thing worth knowing about Chef's perspective: when Chef was launched, it was built purely with operations people in mind. The workflow, the terms, the way everything interconnects — all of it was designed from an operations viewpoint, not a developer viewpoint. Puppet and Ansible lean more toward the developer perspective, which makes them easier to pick up if you come from development or testing. Chef is easiest for operations people who live with operational task lists; a developer or tester joining the DevOps world will likely find Chef harder than Puppet or Ansible. Keep this in the back of your head: when a scenario question asks "which tool fits this team's background?", the audience of the tool is a real selection axis.

19.2.2 Components: Chef Server, Nodes, and Workstation

Chef has three main components: the Chef server, the nodes (the actual servers where applications run), and the Chef workstation.

The three roles in Chef.

  • Chef server — the hub for configuration data. It stores the cookbooks for all the nodes and the policies that are applied to those nodes. It also holds metadata that describes the registered nodes — the information about which nodes are going to be managed by this Chef server. If a node is not registered here, the server does not know it exists.
  • Nodes — the machines managed by Chef. On each node, a Chef client has to be installed, which is why Chef is called agent-based: an agent is a service running continuously inside the node. The Chef client is the service responsible for configuring the node to its desired state.
  • Chef workstation — where the user interacts with Chef. This is the place where you start writing and testing the cookbooks. A DevOps engineer or an operations person creates the cookbooks here.

Analogy — the kitchen theme (the professor's analogy). Chef follows a naming theme: because the tool is called Chef, its terminology comes from the kitchen. You have a cookbook, and inside the cookbook you write recipes — the names map directly to kitchen tools. A cookbook is the book of recipes for one scenario; a recipe is one concrete procedure, the way a recipe card is one concrete dish. Remembering the theme keeps the vocabulary straight: if you forget what a cookbook holds, think of the kitchen shelf — a cookbook sits on the shelf, and inside it are the recipes.

Worked example 1 — restoring JRE7 after it is deleted.

Step 1 — declare the desired state. The organization's policy says every node of this type must have JRE7 (the Java Runtime Environment, version 7) installed. That requirement lives in a cookbook stored on the Chef server.

Step 2 — a human breaks the state. By mistake, JRE7 is deleted on the node — perhaps a cleanup script removed it, or someone uninstalled it while debugging.

Step 3 — the client notices the gap. When the cookbook is shared from the Chef server to the Chef client (on the node's next check-in), the client compares the current status against the desired state: is JRE7 available?

Step 4 — the client repairs the gap. It is not available, so the client makes it available again — reinstalling JRE7 from the declared source.

Sense-check: the node was broken at a random moment by a random human action, and a continuously running service repaired it without any ticket, login, or manual command — that is the whole "desired state" idea in one example.

19.2.3 Cookbooks, Recipes, Supermarket, and Chef Repo

A cookbook is a program — the fundamental unit of configuration and policy distribution. It defines a scenario and contains everything that is required to support that scenario. Chef uses Ruby as the reference language for creating cookbooks and defining the recipes inside them, and it supports an extended domain-specific language for specific resources. Cookbook files use the extension .rb — a signal that you are writing Ruby code.

The Chef Supermarket is the location where the community contributes, shares, and manages cookbooks on an open platform — the same way GitHub hosts public repositories you can search and reuse. Whether an organization actually reuses those cookbooks varies: some organizations happily reuse open cookbooks, while others want to stay private and author their own. The choice is a policy decision, not a technical limit.

The chef repo is the repository structure in which cookbooks are authored, tested, and maintained, and from which the policy is uploaded to the Chef server. Because you are writing configuration as code, the chef repo should be synchronized with a version control system such as git and managed like any other codebase: commit messages, code review, rollbacks, and history all apply to your infrastructure description.

19.2.4 How Chef Works: The Workflow

The Chef workflow (inputs → steps → output).

Inputs: a human-written cookbook (a program in Ruby) plus metadata about the nodes the Chef server manages.

Steps:

  1. On the workstation, you write a cookbook — a program — and the code inside it is called a recipe. In the recipe you describe the policy: for a particular system, say a Windows system, what kind of policy do you want? Packages, services, files, users — each is declared.
  2. You write the cookbook, test it, and provide it to the Chef server. The server holds metadata about the nodes it manages.
  3. Whenever a node asks for its cookbook, the Chef server replies with the cookbook.
  4. The service running inside the node — the Chef client — runs that cookbook against the node and makes sure the node is configured back to its desired state.

Output: every node converges to the declared policy, and re-converges whenever reality drifts away from it.

Summarizing the surrounding architecture: the Chef server works over the web and has a web UI; you store your cookbooks, your ad hoc run lists, your policies, and your secrets there. The workstation is where you author the cookbooks; under those cookbooks you have recipes, policy files, controls, and tests. The workstation and the chef repo are connected because everything is stored in the repo. Around that core you have tools like Test Kitchen, Cookstyle, and Foodcritic (more on those below). Chef can manage any type of node on which your application runs — a physical server, a storage device, a virtual platform, a public cloud, a network device, even a container — but it is agent-based, so you must install the Chef client on each and every node. That "each and every" is the price of the agent-based model.

19.2.5 Chef Workstation Tools

The Chef workstation comes with a set of tools. The Chef Development Kit is a package that contains everything needed to start using Chef — the same idea as a JRE kit for Java; it includes the Chef client and the Chef and Knife command-line tools.

  • The chef command-line tool works with the items in the chef repo: you can push cookbooks to the repo and retrieve cookbooks from it.
  • Knife is also a command-line tool, but it is there to interact directly with the nodes — for those times when you need to make ad hoc changes on an end node — and to work with objects on the Chef server. In other words, Knife is the connection between the Chef workstation and both the Chef server and the nodes.
  • Test Kitchen is a testing harness for rapid validation of your Chef node — you test a cookbook against a disposable test machine before it ever touches production.
  • InSpec is, as its name suggests, an open source security and compliance automation framework — this addresses the classic friction between operations and development where operations cross-checks every release for compliance: are all the norms and checklists followed, is the password encrypted rather than left open, are the network settings done? Because any change in configuration or infrastructure impacts the application, security and compliance matter from the configuration management perspective, and InSpec automates those checks.
  • Chef Run is a tool for running ad hoc tasks: instead of writing a cookbook with recipes, you create four or five ad hoc commands and run them directly via Chef Run.
  • Cookstyle and Foodcritic are the linting companions: they scan your cookbook code for style problems and common errors before the cookbook ships.

19.2.6 Worked Examples

Worked example 2 — a cookbook that keeps Apache 2 running.

Step 1 — declare a package and a service together. A cookbook can declare both parts of a web-serving setup in one place:

  • The package part says: package Apache 2, action is to install. If Apache 2 is missing, installing is the corrective action.
  • The service part says: service for Apache 2, action is enable start — meaning "register this service to start with the machine and make sure this Apache 2 instance is always started."

Step 2 — a human or another program stops Apache. Apache gets shut down — maybe a tired admin ran service apache2 stop, maybe a script crashed.

Step 3 — the client re-applies the standing declaration. The next time the Chef client asks for a cookbook, the server provides the cookbook, the client runs it, and the Apache instance is started automatically again. The service action re-asserts the desired state: running.

Step 4 — the pattern, named. Notice the key idea: the cookbook is not a one-time setup script. It is a standing declaration of the desired state that gets re-applied on every check-in. The machine cannot stay broken, because the declaration is still in force.

Sense-check: install-then-enable-start covers both failure modes in one declaration — the package action fixes a missing Apache, the service action fixes a stopped Apache — and neither requires a human at the console.

19.2.7 Exam Notes

Exam note: there will not be direct questions like "what component of Chef provides such-and-such a service". The exam is not tool-perspective, because tools are not restricted — the DevOps toolchain is huge and changing. Instead, you may get a scenario question where you have to explain whether an organization should use configuration management or infrastructure management, and what kind of tools will help them achieve the goal. Prepare the concepts — desired state, agent-based, idempotency, cookbook/recipe structure — rather than memorizing command syntax.

Recap + bridge: Chef is the agent-based, operations-first tool: cookbooks (programs) hold recipes (policies), the Chef server stores them, and a Chef client on every node continuously pulls and re-applies them, restoring the desired state when JRE7 disappears or Apache stops. The kitchen vocabulary and the three-component architecture are the examinable shape. The next section asks what happens when you cannot install an agent inside every device — which is exactly the question Puppet's agentless Bolt service starts to answer.

Real-world & domain connection. Chef's model is the classic agent-based pattern used at large scale by Facebook, Etsy, and Indiegogo — companies whose server fleets are too big for manual care and whose compliance needs (who changed what, when) require the audit trail that code-based configuration gives. The same pattern generalizes beyond this course: any agent-based tool (Chef, Puppet, CFEngine, even agent-based monitoring agents) pays an installation and upkeep cost per node in exchange for a continuous, self-healing guarantee on every node.

19.3 Puppet: Master–Agent Pull-Based Configuration

19.3.1 Why Puppet and the Master–Agent Model

Hook: Your company's network is built from routers and switches that ship as sealed boxes — you cannot open them, and you certainly cannot install software inside them. Yet those devices need configuration management too. If every configuration management tool demanded an agent on the machine, these devices would be unmanageable. So the industry built a second pattern: manage machines without installing anything on them.

Keep in mind that Chef is agent-based, and Puppet is agent-based too — but Puppet has launched an extra service, Puppet Bolt, that lets you use it in an agentless way as well. Why does agentless matter? Think about devices like routers or other network gear that come as a black box: you cannot open them and install something inside. For such devices, installing an agent is simply not possible. In that case, organizations opt for a configuration management tool that supports an agentless approach — Ansible is one of them.

The reasons to choose Puppet are the same ones we saw for the whole category: it supports infrastructure provisioning, meaning infrastructure as code, and configuration as code. Puppet gives you an automatic way to inspect, deliver, operate, and future-proof all of your infrastructure, which helps you deliver applications faster. It is open source, with good documentation and tutorials, and free to start using.

The master–agent split. In Puppet the server is called the Puppet master. The master is a Ruby application that compiles configurations for any number of Puppet agent nodes — the nodes installed where your applications run. The Puppet server is an application that runs on the Java virtual machine, so a JVM foundation is the prerequisite: you need Java installed. The Puppet master supports specific platforms for itself — Red Hat Enterprise Linux, Fedora, Debian, and Ubuntu — but that does not mean you cannot manage servers of other kinds: you can manage Windows, macOS, or any platform; it is only the master that must live on one of the supported ones.

The Puppet agent runs on the managed nodes as a background service. Periodically, the agent sends the facts to the master and requests a catalog. This is the pull-based approach: the agent pulls the configuration details from the Puppet master, rather than the master pushing them to the agent. Both Chef and Puppet work this way.

19.3.2 The Catalog: Moving from Current State to Desired State

The master compiles the catalog using several sources of information, returns the catalog to the agent, and the agent runs that catalog and makes sure the node is back to the desired state. So what does the catalog do? The catalog is what moves the node from its current state to its desired state. For each resource that should be managed on the node, the catalog describes the desired state — whether a resource should be on, whether a resource file should be at a certain location, and so on. The catalog also specifies dependency information: which resources must be managed in a certain order. The agent uses this document, which it downloads from the master, to configure the node. The puppet apply command compiles its own catalog on the node — useful for testing a manifest locally without a master.

Intuition — the route map analogy. Think of the catalog as a route map handed to a courier. The map does not describe the courier's current position; it describes the target route: which stops (resources) exist, and in which order the stops must be visited (dependencies). Every time the courier receives the map, they drive the route and end up at the destination — the desired state. If someone detours the courier (a deleted file, a stopped service), the next map delivery puts them back on course. The map is the declaration; the driving is the agent's work.

19.3.3 Facter: Facts About Every Node

Facter is the cross-platform system profiling library in Puppet. It describes the node: what kind of operating system it is, what the architecture is, what the patch level is. The agent has its own Facter to describe what kind of node it is; Facter discovers and reports per-node facts, and those facts are available in your Puppet manifest as variables. Before requesting a catalog, the agent uses Facter to collect the system information, sends it to the master, and then requests the catalog.

Here is an example of a fact for one node: for the operating system fact, the architecture is x86_64, the family is Red Hat, the hardware is such-and-such, the name is CentOS, the release is this particular version, and SELinux is enabled with the value false. That is one fact — one structured description of one machine.

Where does this help? First, when a node requests a catalog, it has to describe what kind of node it is; the master understands "for this fact, this is the catalog" and provides the right catalog for that node. Second, suppose you want to update JRE7 to JRE8 on all the machines, on all the nodes, that have hardware x86_64 and a major version of 6. With facts, the master can globally distribute that change: update JRE7 to JRE8 for every node matching hardware x86_64, CentOS, and major version 6. When you want to distribute information or change something on all nodes belonging to one particular operating system, Facter lets you do it in one place — it lets you perform parallel jobs.

Worked example 3 — one global change, every matching node, in one shot.

Step 1 — the fleet. The organization runs six CentOS machines — all with x86_64 hardware and major version 6 of the OS. Each runs Facter and reports the same class of facts: architecture = x86_64, osfamily = Red Hat, operatingsystem = CentOS, operatingsystemmajrelease = 6.

Step 2 — the change. The team wants to move every node in this class from JRE7 to JRE8. The rule is written once in a manifest: for any node whose facts say x86_64 + CentOS + major version 6, install JRE8 (and remove JRE7).

Step 3 — distribution. Each agent sends its facts and requests its catalog. The master matches the facts against the rule and hands each matching node a catalog containing the JRE8 change. All six CentOS machines get updated at once — one change in one place, instead of someone touching each machine by hand.

Step 4 — the naming of the pattern. Because Facter decides which catalog a node gets, this is parallel change distribution: the master fans the same change out to every node that matches the fact filter, and nodes that do not match (say, Ubuntu boxes) are untouched.

Sense-check: a fleet-wide upgrade became one rule plus the normal pull cycle — the facts are what let one rule address exactly the right machines and no others.

19.3.4 Resources and Manifests

Puppet code is composed primarily of resource declarations. A resource describes something about the state of the system — for example, that a certain user or file should exist. Here is an example of a user resource. You declare the resource as user. For this resource you write: user, the name of the user; the state for this user is ensure present, with user ID 1000 and group ID 1000. Whenever this user is created, by default it will have a shell to work in, and that shell is /bin/bash, with the home directory /home/. So the user resource pins down the desired state of that account — the account exists, it owns ID 1000, it belongs to group 1000, and it gets a working shell and home directory. There are other resource kinds too: an application resource, a web server resource where you can have Apache, and so on — every resource describes something about the desired state of the system.

A manifest is the Puppet program. Just as a cookbook is a program and the code inside it is the recipe, the catalog is a program and the code you write inside it is the manifest. Manifests are composed of Puppet code, and their files use the extension .pp. The default main manifest in a Puppet install via apt is /etc/puppet — that is the default manifest you get.

Here is an example of a manifest — a file resource. The file is the devops file, and you want to make sure the resource file is in this desired state: the file at this path should always be present (the exact path came through the recording garbled, but the resource attributes — which are the point of the example — are clear): the owner should be the user sonika, the group should be the group bits — meaning all the people in that group should be able to access the file — the mode is 664, and the content is fixed: "This is a test file created using puppet. Puppet is really cool."

Worked example 4 — the devops file manifest keeps re-creating itself.

Step 1 — declare the resource. The manifest says: for the file resource devops at its path, ensure present, owner sonika, group bits, mode 664, and the fixed content "This is a test file created using puppet. Puppet is really cool."

Step 2 — a human deletes the file. By mistake, the devops file gets deleted from the node.

Step 3 — the pull cycle restores it. The agent node sends its facts and asks for a catalog. This manifest is present in that catalog, because the declaration says the resource must always be present on the node. The Puppet agent runs the catalog and, automatically, creates the file, applies the group, the ID, and the mode, and writes the content.

Step 4 — the pattern, named. That is automation by writing code: a file that keeps re-creating itself to match the declared state. Nobody logged in to restore it; the declaration itself is the recovery procedure.

Sense-check: every attribute of the file — existence, ownership, group, permissions, content — is pinned down by the manifest, so the agent can both check and repair each attribute independently.

19.3.5 Puppet Forge and the Puppet Architecture

The Puppet Forge was launched in 2012 and is one of the most utilized resources in the Puppet world. It is a repository for modules written both by Puppet and by the Puppet user community — the same idea as Chef Supermarket: you can take the code and reuse it. Modules solve a wide variety of problems, and using them saves time and effort because of reuse. The Puppet Forge has over 5,500 modules published, and you can start reusing those right away (in the comparison discussion later, the count was put at almost 6,000 plus). The Puppet module tool provides a command-line interface for managing modules from the Forge.

The Puppet architecture is again a client-server architecture. The server side is the Puppet master; the client side is the Puppet agent node. You also have a configuration repository from which all the catalogs are managed — the master accesses the catalogs from there. Whenever the Puppet agent sends its facts to the master periodically, the master, based on those facts, accesses the catalogs and sends the right catalog to the agent; the agent runs the catalog and keeps the node at the desired state.

Visual intuition. Picture the cycle as a clock: the agent ticks on a schedule, each tick sending facts up and receiving a catalog back down — facts up, catalog down, apply, wait, repeat. The master sits at the center, holding the module repository and the catalog logic; the configuration repository is the archive the master reads from. The same clock face works for Chef (cookbook down, apply, wait), which is why both are called pull-based.

19.3.6 Student Questions and Answers

Q: What challenges do you see with this file resource manifest? What if the file gets updated directly on one of the nodes? A: The file should be restricted to the authorized user. If that authorized user updates the file on the node, the user's primary job is to update the content here in the manifest as well. Otherwise, when the manifest runs again it overwrites the file — it will either overwrite the existing file or create the file and dump the content in — and the latest content will be lost. So anyone who changes the file directly on the node must also change the manifest, or the manifest will keep re-imposing the old content. The manifest is the source of truth; the node's copy is a derivative that will be corrected on the next pull.

Q: Does Chef help to load balance and create multiple instances to make sure high availability? A: No. The purpose of Chef is to manage and maintain the configurations related to any type of node, even containers. It does not help you load balance or create multiple instances for high availability. You will understand orchestration better when you reach Kubernetes — managing configurations and orchestrating containers are different concerns, and orchestration tools are the ones that handle load balancing and scaling. The rejected picture — "a configuration tool spins up instances and spreads traffic" — sounded plausible because both families of tools manage clusters of machines, but the division of labor is sharp: configuration management keeps each machine's state right; orchestration keeps the fleet's size and traffic right.

Q: A student's comment said that if we do not modify the file, the configurations will not be at the desired state — what if configurations get corrupted? A: That point is correct, and it is the right reading of the discussion: configurations that are changed by the node are provided by the master. The master supplies the configuration, the node runs it, and the node returns to the desired state. So the master is the source of truth for configuration; the node applies what the master provides. Corrupted, deleted, or hand-edited files are all the same failure class — reality drifted from the declaration, and the next pull cycle corrects it.

Pitfalls:

  • Editing files directly on nodes — a direct edit looks like progress until the next pull, when the manifest overwrites it and the "lost" content surprises the person who made the edit. The fix is a process rule: change the manifest first, then let the node converge.
  • Expecting configuration management to scale the fleet — load balancing, instance creation, and high availability are orchestration's job (Kubernetes territory), not the configuration tool's. State and fleet are different concerns.
  • Forgetting that Puppet is pull-based — the agent polls on its schedule; a broken node is repaired only at the next poll, not the instant it breaks. That lag is the motivation for Ansible's push model in the next section.
  • Treating facts as optional — without Facter's per-node facts, the master cannot choose the right catalog, and global fact-filtered changes (the JRE7-to-JRE8 update) become impossible.

19.3.7 Exam Notes

Exam note: again, no direct questions on Puppet, Chef, or Ansible internals. The instructor shared a periodic table of the DevOps toolchain in an earlier session precisely because there are so many tools in the market — nobody can be restricted to just Puppet, Chef, or Ansible. Expect the scenario-style questions: should this situation use configuration management or infrastructure management, and which kind of tools will help achieve the goal. The Puppet-specific concepts worth keeping ready: the master–agent pull model, the catalog as the desired-state document, Facter's facts as variables, and resource/manifest basics.

Recap + bridge: Puppet keeps the agent-based idea but changes the geometry: agents pull catalogs from the master on a schedule, facts describe each node, and the catalog moves the node from current to desired state — with the master as the source of truth that repairs corruption and overwrites drift. The story so far covers two pull-based, agent-based tools. The next section introduces the tool that flips both choices — no agents at all, and the server pushes instead of the node pulling.

Real-world & domain connection. Puppet is one of the oldest configuration management tools (introduced in 2005) and is still widely deployed in enterprise fleets, where its mature module ecosystem (Puppet Forge) and model-driven style fit organizations with large server estates and strong change-control culture. The black-box-device problem that motivated agentless support is real: network gear, load balancers, and appliances ship without any installable agent, so organizations managing mixed fleets routinely keep an agentless tool alongside an agent-based one.

19.4 Ansible: Agentless Push-Based Automation

19.4.1 Why Ansible

Hook: The previous two tools both ask you to install a small program on every machine you manage. What if the machine is a router you cannot open, a device that refuses extra software, or simply a machine your security team refuses to put an agent on? And what if you want a tool a developer can read like a newspaper? Ansible was built to answer both questions at once.

Ansible was introduced specifically to support the agentless architecture. With Ansible, you can now manage even black box devices without installing anything inside them. It uses no agents and no extra custom security infrastructure, which makes it easy to deploy. Ansible was also purely designed with a developer mindset in mind — easy for a developer, a tester, or any user who knows nothing about configuration and infrastructure.

The user interface is a big part of that ease. You write some code related to your infrastructure and you just launch it — that is the term Ansible uses. Ansible Tower is the UI, and it lets you see the progress of your launch, with log files underneath the window so you can drill into what stage your playbook is at. Ansible also integrates with GitHub, which gives great integration on top of the UI. The interaction is high level and the language is very simple: YAML, written in the form of an Ansible Playbook. (The naming differs by tool: Chef calls it a cookbook, Puppet has catalogs, Ansible calls it a playbook.)

Ansible also supports multi-tier deployment: it models your IT infrastructure by describing how all of your systems interrelate, rather than just managing one system at a time, and it supports your application across those tiers.

19.4.2 Ansible Architecture: Inventory, APIs, Modules, Plugins

The automation engine and its four parts. Ansible has an automation engine — you can also call it the Ansible server. Inside it you have four working parts:

  • Inventory — the inventory holds the information about the servers or nodes that should be managed by the Ansible server. Whatever nodes you want to maintain and manage, the inventory is the place to store that information. Think of it as the address book of the fleet: who exists, what group each machine belongs to (web servers, database servers).
  • APIs — Ansible APIs to access the services and the user interface; the connection between all the different services of the Ansible server happens with API calls, which is why some organizations integrate Postman with Ansible — Postman is the tool they use to drive and test those API calls.
  • Modules — a module is a typical abstract routine task — like dealing with packages: what needs to be done for these packages, what is the desired state for those packages or resources, you write it into the modules. Modules are the small, reusable action units (install a package, start a service, copy a file).
  • Plugins — the plugins connect Ansible with or integrate Ansible into other tools and technologies — GitHub, Postman, and others. They are the integration layer of the engine.

How does it work? The users — your DevOps team — write an Ansible playbook. The playbook has a modular structure, with modules inside it. The playbooks are given to the Ansible server, and the inventory tells the server which nodes exist. Based on the playbooks and the particular inventory, the Ansible server manages the end nodes. The end nodes can be your public or private cloud, configuration databases, hosts, physical servers, networking devices — anything. With the help of the Ansible server you can manage all of it.

Visual intuition. Picture a control room: the automation engine is the console, the inventory is the roster of every machine on the wall, the playbooks are the procedure manuals, modules are the individual buttons on the console, and plugins are the cables linking the console to outside systems (GitHub, Postman). One operator at the console — no agents stationed at any of the machines — launches procedures that reach out over the network to every machine on the roster.

19.4.3 Playbooks, Plays, Tasks, Facts, and Handlers

A few terms are used over and over with Ansible. The playbook is the entry point for Ansible provisioning: the automation is defined through tasks using YAML format, and that is the playbook. Inside the playbook you write tasks. A play is when you are provisioning or executing that playbook — in simple words, the execution of a playbook is a play. A task is a block that defines a single server procedure to execute — for example, install a package, and with that package make sure it is on. Facts, as with Puppet, are global variables that contain information about the system: what is the network interface, what is the operating system, which architecture family it belongs to, what is the major and minor version of the operating system. Handlers are used to trigger service status changes — like restarting or stopping a particular service. The key Ansible idiom is notify → handler: a task marks a change (say, the config file was rewritten) and notifies a handler, which runs only when notified — so a service is restarted only if the configuration actually changed, not on every run.

19.4.4 Worked Example: The Apache Playbook

Worked example 5 — the Apache playbook, read like common English.

Step 1 — the inventory. First look at an inventory example: you can have web servers — one web server, a second web server — and a DB server that needs to be managed, and you mention all of them in the inventory. The inventory groups them, for example, under webservers and dbservers.

Step 2 — read the playbook. If you read it, it is just common English. You have hosts: the host type is web servers, and serial is five — that means update five machines at a time (rolling updates instead of all-at-once). The roles are common or web app. For the host content servers, the roles are common or content. And then there is another playbook, written only for the web servers.

Step 3 — the web-server declaration. This web server should be on HTTP port 80; the maximum clients should be 200. Then the task list begins:

  • The name of the task: ensure Apache is at the latest version — and from where you access that, you can mention like yum, HTTP, latest, to get that Apache. So: package httpd, state latest, from the yum repository.
  • Write the Apache config file — you can mention where to have it; this task places the configuration that pins port 80 and the 200-client limit.
  • Notify: restart Apache — this task is the notifier: if the config file actually changed, send the notification to restart Apache.
  • Make sure Apache is running — the service state is started; if it is turned off, this service will run to keep it started.
  • The handlers — handlers automatically start and restart; under the handlers it is written: restart Apache, service httpd restarted.

Step 4 — the whole picture. So with a handful of plain-English lines, a whole web server's desired state is declared: port, client limits, package version, config file, service state, and the handler that restarts Apache whenever the config changes.

Sense-check: every line of the playbook names a real, checkable fact about the machine — package version, port, service state, config content — and the notify-handler pair makes restarts happen exactly when they should and not otherwise.

19.4.5 Push-Based Model and the Puppet vs Ansible Comparison

One more point about how Ansible differs in mechanics: Ansible is push-based, not pull-based. No agent needs to read from the Ansible server; instead, the Ansible server periodically sends the playbooks or modules to the nodes. Push-based means that before the nodes even reach out, the server is already sending the details to the nodes — the nodes are not waiting, and that keeps them at the desired state.

Push vs pull, compared with a concrete failure (the professor's point). Take an example: say Apache is shut down. In Puppet, the agent sends facts periodically; once the facts are sent, the server replies and the Puppet agent runs — so recovery waits for the next poll. In Ansible, as soon as Apache is stopped, the server can push the playbooks and the desired state of the configuration resources; the server does not have to wait until the node reaches out. So push-based is more optimized in that sense: the server drives the timing, and the repair can begin immediately instead of at the next scheduled check-in.

Now the comparison of Puppet versus Ansible:

Dimension Puppet Ansible
Introduced 2005 2012
Agent model Agent-based (with agentless flavor via Puppet Bolt) Agentless
Control model Model-driven, built with system administrators in mind Easier to set up and understand, more end-user friendly
Push or pull Pull-based (agents poll the master) Push-based (server sends to nodes)
Language Puppet DSL (manifests) — sits in the middle for readability YAML playbooks — simplest to read
Complexity Moderate — more complex than Ansible, less than Chef Least complex of the three
Knowledge base Mature Still growing
Module ecosystem Puppet Forge — almost 6,000 plus modules Ansible Galaxy — still growing on the same model

On personal experience — and this matches the professor's framing — coming from a development background with little exposure to configuration or infrastructure, Ansible is the easiest to understand: the YAML files are simpler than the Ruby DSL of Chef, and the UI is great. Chef feels complex at first because of how many tools and services orbit it, and Puppet sits in the middle: easy to understand, but still agent-based, so you have to grasp those concepts too.

The professor's analogy — YAML reads like a newspaper or textbook. The professor's shorthand for language readability: Ansible's YAML playbooks read like a newspaper or a textbook — you scan a page and understand it immediately. Chef's Ruby DSL is denser, harder for a developer to parse at a glance, and Puppet sits in the middle. When a scenario question asks which tool a mixed team will adopt fastest, this readability axis is a legitimate part of the answer.

19.4.6 Terraform: A Brief Mention

The configuration management story is not only Chef, Puppet, and Ansible: Terraform is nowadays grabbing more and more of the market for infrastructure configuration. It is easy to integrate with clouds and easy to understand — many industry experts say so, even for someone who never studied it. It is mentioned here only briefly: the goal of the syllabus coverage is to show what the tools provide in common and when to pick one over another, not to survey every tool in the market and confuse everyone. The useful decision axes to remember: agent-based versus agentless, pull-based versus push-based, and how easy the language is to read.

19.4.7 Student Questions and Answers

Q: What is your experience with Terraform — did you find the interactions easy? A: I never looked at any tutorials or documents and never learned about Terraform, but I heard from many industry experts that Terraform is easy to integrate with clouds and easy to understand. If you have any documentation related to Terraform from when you start using it, it would be great if you could share it, so the rest of the class can learn from it too. The takeaway for the course: Terraform's rising market share is real, and the syllabus treats it as an example of the tool-space's growth — not as another tool to master.

19.4.8 Exam Notes

Exam note: the exam will not ask you to name the component of Ansible or Puppet that provides a certain service, because tools are not restricted — the periodic table of the DevOps toolchain shows how many tools exist. Scenario questions are the likely form: should an organization choose configuration management or infrastructure management in this situation, and what kind of tools would help them achieve the goal. The distinctions covered here — agent-based versus agentless, pull-based versus push-based, model-driven versus developer-friendly, YAML versus Ruby DSL — are the vocabulary you use to justify such an answer.

Recap + bridge: Ansible is the agentless, push-based, developer-friendly corner of the triangle: the automation engine holds the inventory, playbooks (YAML) declare tasks, modules do the work, handlers restart services on notification, and the server pushes the playbooks to nodes — so repairs start immediately rather than at the next poll. The next section leaves the tool triangle and climbs the stack: instead of configuring machines, what if you could stop buying machines one-per-application altogether? That is the virtualization story.

Real-world & domain connection. Ansible is the default choice for teams that manage mixed fleets — cloud instances, physical servers, and network devices — because the agentless model removes the per-node install step, and its API-driven automation engine integrates with the surrounding toolchain (GitHub for versioned playbooks, Postman for API testing, Ansible Tower for a visible launch UI). In the industry at large, Terraform's rise for cloud infrastructure configuration (AWS, Azure, GCP) shows the same market dynamic the professor points at: the tools change, so the examinable skill is choosing along the axes — agent-based vs agentless, pull vs push, readable vs powerful — not memorizing one tool.

19.5 Virtualization: From Physical Servers to Containers

19.5.1 Before Virtualization: The Physical Server Model

Hook: A company runs three services — a web server, a database, and a mail server for notifications — and buys three machines. Each machine is a full computer, and each one sits at about 30% use, mostly idle. Three machines purchased, three power bills, three racks of space, and 70% of each machine's power doing nothing. How much of that waste can software eliminate?

Before virtualization, the pattern was one physical server per job. You had a physical server; on top of it you hosted an operating system; on the OS you had the binaries and libraries your application depends on; and on top of that your application ran. The problems with this model are well known:

  • Huge cost — every application needs its own machine. Buy a server for the web service, another for the database, another for the mail service; each purchase includes hardware, power, cooling, and rack space.
  • Slow deployment — a new machine takes time to procure and set up. Ordering hardware, installing the OS, patching it, installing the runtime and libraries — the lead time is days to weeks, not minutes.
  • Hard to migrate — moving the application elsewhere means rebuilding the environment from scratch on new hardware. There is no portable unit of "the application plus its world"; the world is welded to one physical box.

19.5.2 What Virtualization Is and Why It Exists

Virtualization is the technology that lets you create useful IT services using resources that are traditionally bound to hardware. It allows you to use physical machines at their full capacity: instead of one machine sitting mostly idle for one service, you distribute the capabilities of that physical machine among many users or environments. The underlying capacity gets optimized — each environment uses a slice, and the machine as a whole is far more fully used.

Formalize — the definition and its three marks. The definition the exam tests: virtualization is creating useful IT services from resources that are traditionally bound to hardware, distributing a physical machine's capabilities among many environments. The definition connects directly to the cloud picture the professor quizzed the class on — a diagram whose three corners are scalable services, metered usage, and shared resources, with the box in the middle labeled virtualization:

  • Shared resources — many environments run on one physical machine, sharing its CPU, memory, and disk.
  • Scalable services — because environments are software objects, you can create, grow, shrink, and destroy them quickly — scaling becomes a configuration action, not a hardware purchase.
  • Metered usage — because each environment consumes a slice of the shared machine, its usage can be measured and billed — the pay-for-what-you-use model of cloud computing.

The three marks are one idea seen from three sides: virtualization is what makes resources sharable, scalable, and meterable at the same time.

Scope — what virtualization can and cannot promise. Virtualization optimizes capacity: it packs many under-used workloads onto fewer machines and makes environments cheap to create, move, and scale. It does not eliminate the costs that stay bound to each environment:

  • Each environment still carries its own operating system (in hardware-level virtualization), so kernel memory is duplicated per environment.
  • Neighboring environments share the same physical machine, so a noisy neighbor can degrade performance — capacity sharing is not isolation.
  • The host machine is still a single point of failure for everything on it; virtualization redistributes risk rather than removing it (which is why production setups spread replicas across machines).

19.5.3 Worked Example: Consolidating Web, Database, and Exchange Servers

Worked example 6 — three physical servers become two.

Step 1 — the starting fleet. Suppose an application needs three kinds of servers: a web server, a database server, and an exchange server for notifications. Without virtualization you need three different physical servers — server one, server two, server three — with the web service on one, the database on another, and the exchange service on the third.

Step 2 — the waste, measured. Notice: all these services are using only about 30% of their respective servers' capacity — each machine is mostly idle. Three machines purchased, three power bills, and roughly 70% of each machine unused.

Step 3 — virtualization redistributes the capacity. With virtualization, you optimize those capacities by distributing the capabilities among multiple environments. On a single server — server one — you can have two virtual machines: on one VM your web service, on the other your database service. Then server two hosts the exchange service. Each environment uses a slice of a machine; the machine as a whole runs at far better use of its capacity.

Step 4 — the count. Count the machines: the third server is gone, and its cost with it. Two servers now do the work of three, and each server runs at much better usage. The professor's summary line: the third server's cost disappears — its capacity got distributed among the remaining environments.

Sense-check: 3 × 30% ≈ 90% total demand now sits on 2 × (roughly 45–50%) — the same work, one machine fewer, and still headroom for growth on both machines.

19.5.4 Hardware-Level Virtualization

The first step beyond the physical model is hardware-level virtualization. You have a physical server — it could be anything: your private cloud, your server, your laptop. On that you install the host operating system, and over that you need a hypervisor layer. Then you can start creating virtual machines: this is the first VM, with Ubuntu as a guest OS, with its binaries and libraries, and then your application one; then a Debian guest OS with binaries and libraries and application two; then another guest OS with binaries and libraries and application three. On the same physical server you are now running applications one, two, and three, each in its own isolated guest.

Formalize — the stack. Layer by layer, from the metal up:

  1. Physical server — the real hardware: CPU, memory, disk.
  2. Host operating system — the OS installed directly on the hardware.
  3. Hypervisor — the virtualization layer that sits over the host OS and hands out slices of hardware to guests. (The reference text notes that a hypervisor can also run directly on bare metal, with no host OS underneath; the extra OS layer adds overhead, which is why bare-metal hypervisors are common in production.)
  4. Virtual machines (VMs) — each VM is a full guest operating system — Ubuntu, Debian, another OS — plus the binaries and libraries it needs, plus your application on top.

Each guest OS is emulated as a physical machine: a VM image is a file containing a bootable operating system and its software, and launching that image gives you a running VM instance.

The benefits are real: it is more cost effective and easy to scale. But there are limitations. The kernel resources are still duplicated: if the host operating system is Ubuntu, the Ubuntu kernel resources are duplicated inside every virtual machine, because each guest OS carries its own kernel. And application portability issues are still there, because each VM is still bounded to the hardware underneath it — the full guest OS travels with the application, which is heavy.

19.5.5 OS-Level (Kernel-Level) Virtualization

Can we avoid duplicating the kernel? That is exactly what OS-level virtualization — also called kernel-level or operating-system-level virtualization — does. You have the physical server and the host operating system, and now a container engine sits on top of the host OS. The container engine helps you create containers — with only the binaries and libraries that are needed — and on top of those, your applications. Application one, application two, application three — these are nothing but containers.

Because the kernel is shared from the host, you are optimizing the kernel-level resources: no kernel is duplicated per application. The containers are lightweight, they are easy to port, they are fast to deploy. The market solution for this kind of virtualization is Docker — which is why, whenever there is a containerized solution, people say Docker.

The Xerox analogy (the professor's analogy) — brand names becoming generic names. Xerox, Canon, and others all make photocopiers, yet people say "Xerox" instead of "photocopy". The same happened with containerization: Docker became the generic name, but it is not the only solution — other tools and technologies support operating-system-level virtualization too. Per the syllabus, though, the focus is Docker. So when someone says "Dockerize it", hear "containerize it" — the technology is the container, the brand is just the best-known maker.

Visual intuition — the two stacks side by side. Draw the physical layer, then the host OS, then the next layer up. In hardware-level virtualization the next layer is a hypervisor and above it sit three full guest OS boxes, each with its own kernel (three kernels running on one machine). In OS-level virtualization the next layer is a container engine and above it sit three small boxes holding only binaries, libraries, and the application — no kernels in the boxes, because all three share the host's one kernel. The visual difference is exactly the cost difference: three heavy guest OS boxes versus three light containers.

Pitfalls:

  • Treating "virtualization" as synonymous with "hypervisor" — virtualization is the general idea (distributing hardware-bound resources among environments); hypervisor-based VMs are one implementation, containers are another. The exam's diagram question put "virtualization" in the box shared by scalable, metered, shared resources — the general idea, not one product.
  • Forgetting which layer duplicates kernels — hardware-level virtualization duplicates the kernel once per guest OS; OS-level virtualization shares the host kernel and duplicates nothing. Mixing these up inverts the whole container argument.
  • Claiming containers are VMs without an OS — a container is not a VM; it is an isolated set of binaries and libraries running on a shared kernel. That is why containers are lightweight, but also why a container cannot run a different kernel than its host.
  • Reading the consolidation example as "one server per service forever" — the example is about packing under-used workloads; a service that legitimately needs an entire machine's resources will not fit the same packing math.

19.5.6 Worked Example: JRE6 and JRE7 Containers

Worked example 7 — two applications, two runtimes, one kernel.

Step 1 — the conflicting requirements. Say we have two applications with different runtime requirements: application one is running on JRE6 and application two is running on JRE7. Each application needs a different Java Runtime Environment version — and versions of Java do not always coexist comfortably on one host.

Step 2 — the two alternatives, rejected. Without containers you would need to install both runtimes on the same host — fighting version conflicts in one shared environment. And with hardware-level virtualization you would duplicate kernels for no reason: two full guest OSes to solve a runtime-version problem.

Step 3 — the container solution. With OS-level virtualization you create container A with JRE6 and application A on top, and container B with JRE7 and application B on top. Each application gets exactly the runtime it needs, in its own isolated box.

Step 4 — what is saved. You are not duplicating kernels — both containers share the host kernel — and each application gets exactly the runtime it needs. The result: more cost effective, faster deployment speed, and great portability.

Sense-check: the only thing each container carries is the runtime difference that matters (JRE6 vs JRE7) plus the application; everything else — the kernel — is shared, so the isolation is exactly as deep as the conflict was.

Recap + bridge: virtualization broke the one-application-per-physical-server rule by distributing a machine's capacity among environments: hardware-level virtualization did it with full guest OSes (cost-effective, scalable, but kernel-duplicating and heavy), and OS-level virtualization went further with containers — binaries and libraries only, sharing the host kernel, lightweight, portable, and fast to deploy. The next section takes the container from concept to practice: Docker, the tool that made containers mainstream.

Real-world & domain connection. This is the economic backbone of modern infrastructure: cloud providers pool physical servers into shared, metered, scalable services precisely because virtualization lets many customers share one machine (the NIST cloud picture — resource pooling, rapid elasticity, measured service — is built on virtualization). And the JRE6/JRE7 container example is the daily reality of platform teams: microservices with different language runtimes, library versions, and patch levels ship as containers side by side on shared hosts. Every "works on my machine" complaint ends the day the application ships as a container.

19.6 Docker: Containers in Practice

19.6.1 Why Docker and Its Role in DevOps

Hook: A developer's application runs perfectly on her laptop, passes all tests in the pipeline, and then breaks in production because the production server has a different library version. How do you package the application so that every environment runs exactly the same bits, down to the last dependency? And why does the answer to that question matter to DevOps?

Docker is a helping hand for the DevOps culture, because DevOps wants faster delivery. You can have a fully automated pipeline, but the deployment step still differs: deploying to a VM versus deploying to a containerized solution — the containerized path is faster, portable, and lightweight. In the Docker picture, shipment is easy: you can ship anywhere using any technology, and you can have interconnection between your containers — containers can communicate among each other, which matters when one service depends on another.

Why Docker? It is an open platform for developing, shipping, and running applications. It enables you to separate your application from your infrastructure, so you can deliver software quickly. Because the application is completely separated from the hardware and OS level, by taking advantage of Docker's way of shipping, testing, and deploying code quickly, you significantly reduce the delay between writing a code and running it into the production environment. And remember the Xerox lesson from the virtualization section: containerization is to Docker what photocopying is to Xerox — Docker became the generic name, but it is not the only container solution in the market. Per the syllabus, though, Docker is the one in focus.

Interview insight (the professor's warning) — what actually gets asked about Docker. In interviews, nobody asks you the commands — but they do ask, do you know what the image is, do you know what a container is, and when do we build this image? Those conceptual questions are the ones that matter, and they are the ones covered below. The same holds for the exam: the conceptual shape — image, container, service, and when you build an image — beats any command syntax.

19.6.2 The Docker Engine: Client, Daemon, REST API, and CLI

Docker is a client-server application. The server side is a type of long-running program called a daemon — the Docker daemon. The REST API specifies the interface that programs can use to talk to the daemon and instruct it what to do — it is the communication channel between other programs and the server. The command-line interface (CLI) is how you run Docker commands. With the help of the Docker daemon you can manage containers, images, data volumes, and networks.

The build flow through the three layers.

  1. With the client, you write code, and you build the image with the help of the CLI.
  2. The command goes to the REST API — the well-defined program-to-program interface.
  3. The REST API converts it into the language the Docker daemon understands, and the Docker daemon executes it.

Concretely, the Docker client issues commands like docker run, docker build, and docker pull. The Docker host is the daemon, where the images live — this image is for one operating system, that image has different packages. Once you run an image you get a container: the instant running instance of an image is nothing but a container. You can build these images yourself, or you can reuse an image from the registry — an open source registry from which you get an image and just run it, or you can create your own image. Whatever specification you want in that image you can mention — "I want Python in this particular image".

Visual intuition. Picture a restaurant chain: the client is the customer at the counter, the CLI is the menu and the order slip, the REST API is the standardized order chute between counter and kitchen, and the daemon is the kitchen that actually cooks. Orders (docker run, docker build, docker pull) go in one end, and finished dishes — containers — come out the other.

19.6.3 Images, Containers, and Services

The relation between image and container is central.

The three objects, precisely defined.

  • Image — an executable package: a read-only template with certain instructions. To build your own image you create a Dockerfile — a file in which you write the code or script describing everything you want in the image; once you write it and build it, you get an image. Because an image is read-only, it can be shared, versioned, and reused without ever changing.
  • Container — launched by running an image; it is the running instance of that particular image. When you do docker run, it creates the container from that image. You can create, start, stop, move, or delete a container using the Docker API or the command-line interface. The image is the template; the container is the living copy.
  • Service — really just a container in production. A service runs one image, but it codifies why this particular image should run: what are the ports for this image that should be used, and how many replicas — how many container instances. You can scale a service by mentioning the number of container instances and assigning more compute resources.

Worked example 8 — a service definition (version 3 style).

Step 1 — the production question. A team is putting a containerized app into production. "Run this image" is not enough; production wants answers: how many instances, how much compute each, what happens on failure, which ports, which network?

Step 2 — the declaration. The service definition answers every question at once:

  • Image: the image to run.
  • Replicas: 5 — this particular image should have five instances, five containers running from it.
  • Resource limits: 0.01 CPU and 50M memory — each container is capped at 0.01 of a CPU and 50 MB of memory.
  • Restart policy: on failure — if a container fails, it should restart again.
  • Ports — the ports this service should use for incoming traffic.
  • Network: webnet — the containers join the named webnet network, so the service's instances can talk to each other and be reached by other services.

Step 3 — the scaling move. Want more capacity? Change the number of replicas and assign more compute resources; the service declaration is the single knob for scale.

Sense-check: a service is the production-facing declaration of an image — everything the image leaves open (instances, resources, restart behavior, ports, network) is pinned down by the service.

19.6.4 The Dockerfile

The Dockerfile is nothing but a script describing what exactly you want in the container. It has information about all the resources the container needs — the network interface, the disk drives, the runtime. A typical example reads like a short checklist.

Worked example 9 — the Dockerfile checklist, line by line.

FROM python
      WORKDIR app
      COPY app
      RUN pip install -r requirements.txt
      EXPOSE <port>
      ENV name world
      CMD python app.py
  • FROM python — start from the official Python image; everything else is layered on top of this base.
  • WORKDIR app — set the working directory inside the container to app; every following command runs from there.
  • COPY app — copy the application code from the build context into the container.
  • RUN pip install -r requirements.txt — install the dependencies the application needs (the particular requirements.txt that was mentioned).
  • EXPOSE — declare the port the container listens on.
  • ENV name world — set an environment variable inside the container (here name = world), which the application can read at run time.
  • CMD python app.py — the command that runs when the container starts; whenever you launch this container, that CMD is available — the container starts by running the application.

Sense-check: each line of the Dockerfile maps to one aspect of the container's world — base image, files, dependencies, network, environment, startup behavior — and the final line is the one that actually starts the app.

That is what a Dockerfile does: it is written to create an image. Either you do it this way — build your own image from a Dockerfile — or you get an image from the repositories (Docker Hub and friends, covered below).

19.6.5 Docker Swarm and Stacks

Docker Swarm is the orchestration component of Docker — it is the same kind of thing as Kubernetes. Kubernetes is not the only orchestration solution for containerized workloads with great configurability: Swarm is one more component that ships with Docker. Kubernetes became popular because of its open source nature and the extra features and services it supports; Swarm provides the same core functionality, with fewer of those extras.

Swarm's architecture: you have managers that manage the worker nodes. A Swarm is a group of machines that are running Docker and joined into a cluster — that is the prerequisite: you create a Swarm from machines on which Docker is already running, join them into a cluster, and then you have a Swarm architecture. Docker commands get executed on the cluster by a Swarm manager. The machines in a Swarm can be physical or virtual; after joining a Swarm, machines are referred to as nodes. The Swarm can manage strategies like finding the best node and load balancing. When you want to make a change globally, you can do it with the help of the Swarm, because the Swarm has all the details about all the worker nodes.

Worked example 10 — the Swarm global change: JRE7 to JRE8 in one shot.

Step 1 — the fleet. The worker nodes are nothing but running instances of your containers, and on a certain type of container you want to change JRE7 to JRE8.

Step 2 — the old way. Without Swarm, someone would go machine by machine, changing the image manually — touching every node by hand.

Step 3 — the Swarm way. With the Swarm architecture you write the change once. The Swarm knows all the worker nodes and their details, so all the nodes with the matching facts get updated to JRE8 in one shot — no one has to go machine by machine and change the image manually.

Sense-check: this is the orchestration-level twin of Puppet's Facter example from the configuration-management half of the lecture — one declaration, many matching nodes — but at the container level, driven by the cluster rather than by a config master.

A stack is one more concept. A stack is a group of interrelated services that share dependencies and can be orchestrated and scaled together. For example, one particular service — a payment gateway — needs a web server, a database server, and a backend server, and all of these have their lifecycle together; you can put all these services in one stack. A single stack is capable of defining and coordinating the functionality of an entire application.

Q: How are a service, a stack, and a Swarm related? A: The stack is the largest unit: a group of interrelated services that share dependencies and a lifecycle. A service is the production declaration of one image (replicas, resources, ports, network). The Swarm is the cluster underneath — the group of Docker-running machines whose manager executes the orchestration. So the mental staircase runs: image → container → service → stack, all running on a Swarm cluster that the manager coordinates.

19.6.6 Docker Cloud, Docker Store, and Docker Hub

Docker Cloud is a hosted registry service that provides build and testing facilities for Dockerized application images. You access Docker Cloud through a Docker ID — and a Docker ID is part of a proprietary enterprise solution: you pay for licenses and then you can access Docker Cloud. From there you can manage the builds and images, create Swarms, manage infrastructure, nodes, and apps, and you can integrate Docker Cloud with AWS and Microsoft Azure services.

Docker Store is for developers and operators — a repository where you achieve reusability, but an enterprise solution. It is the best way to discover high-quality Docker content: independent software vendors can use Docker Store to distribute and sell their Dockerized content. Why is the quality high? Because the content is tested and verified by the software vendors and by Docker itself; once it fulfills all the security and quality norms, it gets published. It is a paid service: vendors get access to Docker's large and growing customer base, customers can try or buy the software, Docker handles the checkout and licensing support, and seamless updates and upgrades can be delivered to customers. You can even become Docker Certified through their tutorials and video sessions.

Docker Hub is a cloud-based registry service, and it is freely accessible: here you can reuse content published by the open community. Hub allows links to code repositories, building and testing images, storing the image, and linking to Docker Cloud to deploy the image to a host. It is a centralized solution for container image discovery, distribution, change management, user and team collaboration, and workflow automation throughout the development pipeline, and you can access the open source Docker solutions available there.

Hub vs Store — the difference in one line. The difference between the two registries comes down to who published the content. Docker Hub is contributed by the community — anyone can push new images, so there is no guarantee around quality or compatibility. Docker Store content is submitted and approved by qualified store vendor partners, published and maintained by an entity, and certified against quality assurance norms. The common thing: whatever official images are published by Docker are available on both Hub and Store.

19.6.7 Exam Notes

Exam note: for Docker, the conceptual questions are the ones that matter — what is an image (an executable, read-only template), what is a container (the running instance of an image), when do you build an image (when your specification is not covered by an existing registry image), and how image, container, service, Swarm, and stack relate to each other. Nobody asks the commands in an interview, and the same holds for the exam: prepare the concepts and the architecture, not the syntax. Also remember the role of orchestration (Swarm, and Kubernetes more broadly) versus configuration management — a tool like Chef or Puppet keeps node configurations at the desired state, but it does not load balance or scale instances; that is orchestration's job.

Recap + bridge: Docker separates the application from the infrastructure: images are read-only templates, containers are their running instances, services declare how an image runs in production (replicas, limits, restart, ports, network), the Dockerfile builds images, Swarm clusters machines into managers and worker nodes for orchestration, and stacks group interdependent services with one lifecycle. This closes the lecture's arc: configuration management (Chef, Puppet, Ansible) keeps machines at their declared state; virtualization and containers make machines cheap, portable, and packable; and orchestration (Swarm, Kubernetes) runs the containerized fleet at scale — with the exam guidance summary next.

Real-world & domain connection. Docker is the default shipping container of modern software: Netflix, Uber, and most cloud-native companies build and ship every service as a container image, and the image-then-container-then-service pattern is exactly what Kubernetes orchestrates in production. The Hub-versus-Store distinction maps to a real supply-chain decision — trust the open community or pay for vendor-certified content — and the Dockerfile's FROM-WORKDIR-COPY-RUN-EXPOSE-CMD checklist is the single most common shape of container builds in industry, whether the final deployment target is Docker Swarm, Kubernetes, or a cloud's managed container service (AWS, Azure, Google Cloud all run containers on Docker's model).

Exam Guidance Summary

What the exam will ask about configuration management tools. There will be no direct questions on Puppet, Chef, or Ansible — nothing like "which component provides such-and-such a service". The exam is not tool-perspective, because the tools are not restricted: the DevOps toolchain is huge, and a periodic table of the toolchain was shared earlier precisely so no one fixates on a single tool. Instead, expect scenario questions: you may have to explain whether an organization should use configuration management or infrastructure management, and what kind of tools will help them achieve so-and-so a goal. To answer well, keep the concepts ready: desired state, idempotent behavior, agent-based versus agentless, pull-based versus push-based, configuration as code and infrastructure as code, and the comparison axes between Chef, Puppet, and Ansible (language readability, setup complexity, knowledge base maturity, module ecosystems).

Sample questions from the recap quiz — these are the definition-style questions to expect:

Q: The technology used to distribute service requests to resources is referred to as load performing, load scheduling, or load balancing — which is it? A: Load balancing. Distributing service requests to resources is load balancing, and this one was expected to be known for sure — the professor flagged it as a question the class should answer without hesitation.

Q: In the diagram with scalable services, metered usage, and shared resources, what goes in the box — automated configuration management, abstraction, virtualization, or all of these? A: Virtualization. Several different answers came back first — the class offered automated configuration management, abstraction, and "all of these" before landing on the correct one — but the correct answer is virtualization. The diagram's three corners (scalable services, metered usage, shared resources) are the three marks of the virtualization definition, which is why the box in the middle holds that single word.

Virtualization. Know the definition (creating useful IT services from resources traditionally bound to hardware, distributing a physical machine's capabilities among many environments), the physical-server problems it solves (huge cost, slow deployment, hard to migrate), the hardware-level approach with its duplicated kernels, and the OS-level container approach with its lightweight, portable containers.

Docker. Prepare the conceptual questions: what is an image, what is a container, when do you build an image. Commands will not be asked — in interviews or in the exam.

Configuration management versus infrastructure management. A recurring scenario theme: decide whether the situation calls for configuration management (keeping existing machines at their declared desired state) or infrastructure management/provisioning, and which tool characteristics fit the situation — agent-based or agentless, pull-based or push-based, developer-friendly language or operations-first workflow. The tools themselves (Chef, Puppet, Ansible, Terraform) are not restricted, so justify with concepts, not product trivia.

Final session. The next session is the last one for the subject — a recap is planned, with time set aside to go through last year's question paper, so arriving with questions ready is the right preparation.

Key Industry Applications

  • Chef at scale: Chef is still used by Facebook, Etsy, and Indiegogo; the ecosystem spans physical, virtual, and cloud nodes at large scale — a reminder that agent-based configuration management runs some of the biggest fleets in the industry.
  • Community module ecosystems as a reuse channel: Puppet Forge has almost 6,000 plus modules, Ansible Galaxy is growing on the same model, and Chef Supermarket works like GitHub for cookbooks — in practice, teams rarely write everything from scratch; they assemble from community modules and contribute back.
  • Ansible in the developer workflow: Ansible integrates with GitHub and can be driven through its APIs with tools like Postman; Ansible Tower gives a UI with progress and logs for playbook launches — the agentless, API-driven shape makes it a natural fit for teams that live in code repositories and API tools.
  • Terraform's market rise: Terraform is increasingly chosen for cloud infrastructure configuration because of its easy cloud integration, even though it is not covered in depth in this syllabus — the market moves faster than the course, and the decision axes (agent vs agentless, push vs pull, language readability) transfer to any new tool.
  • Docker in production: Docker separates application from infrastructure and is used for fast, portable deployments; services in production declare replicas, resource limits (for example 0.01 CPU and 50M memory), restart policies, ports, and networks — the service definition from the lecture is the actual production pattern.
  • Docker's registries in the supply chain: Docker Cloud integrates with AWS and Microsoft Azure; Docker Store is a paid marketplace where independent software vendors distribute Dockerized content and users can even become Docker Certified; Docker Hub is the free community registry — the Hub-versus-Store choice is a real quality-versus-cost decision.
  • Orchestration owns the fleet: Docker Swarm and, more popularly, Kubernetes handle clustering, load balancing, and scaling, which configuration management tools do not do — production systems run configuration management and orchestration side by side, each doing its own job.
  • The Xerox lesson: Docker became the generic name for containerization, but it is not the only operating-system-level virtualization solution in the market — knowing the technology beneath the brand is what survives tool turnover.

ITD Lecture 19 notes · Configuration Management Tools, Virtualization, and Docker

Introduction to Devops· postgraduate· 2026-08-14

Sections Breakdown

119.1 What Every Configuration Management Tool Provides

All configuration management tools share the same core capability set — quick provisioning, quick recovery, version-controlled environments, replication, automation that keeps the desired state intact, idempotency, templating, and extensibility — and the section fixes the node-versus-server terminology used throughout the lecture.

219.2 Chef: Agent-Based Configuration as Code

Chef is the agent-based, operations-first configuration management tool: cookbooks (programs in Ruby DSL) hold recipes, the Chef server stores cookbooks and policies, and a Chef client on every node continuously re-applies them to restore the desired state.

319.3 Puppet: Master–Agent Pull-Based Configuration

Puppet is agent-based and pull-based: agents send Facter facts to the Puppet master and pull a compiled catalog describing each resource's desired state and dependency order, with the master as the source of truth that corrects drift.

419.4 Ansible: Agentless Push-Based Automation

Ansible is the agentless, push-based configuration management tool built with a developer mindset: the automation engine holds the inventory, YAML playbooks declare tasks, modules perform the work, and the server pushes playbooks to nodes so repairs start immediately.

519.5 Virtualization: From Physical Servers to Containers

Virtualization creates useful IT services from hardware-bound resources, distributing a physical machine's capacity among many environments; hardware-level virtualization uses hypervisors and full guest OSes, while OS-level virtualization shares the host kernel with lightweight containers.

619.6 Docker: Containers in Practice

Docker separates the application from the infrastructure: images are read-only executable templates, containers are their running instances, services declare replicas and resource limits, Dockerfiles build images, and Swarm clusters machines for orchestration.

7Exam Guidance Summary

The exam is not tool-perspective: expect scenario questions on configuration management versus infrastructure management, plus definition questions on load balancing and virtualization; the final session reviews last year's question paper.

8Key Industry Applications

Real-world connections: Chef at Facebook, Etsy, and Indiegogo; community module ecosystems; Ansible's developer workflow; Terraform's market rise; Docker in production and its registries; and orchestration versus configuration management.

Postgraduate students of software engineering and delivery

Exam Revision Notes

Below is the distilled, exam-ready core. Every entry comes from the full explanation above. Use this section for rapid review; return to the main notes when a point needs more context.

What Every Configuration Management Tool Provides

Must-know: Every configuration management tool provides quick provisioning, quick recovery, version-controlled environments, replication, automation enforcing the desired state, idempotent behavior, templating, and extensibility. A node is where the application runs; a server is the configuration management tool's server.

⚠️ Top pitfall: Swapping node and server: the tool's server stores the configuration; the nodes are the managed machines that apply it. Also confusing configuration management (keeps desired state) with orchestration (load balancing, scaling instances).

Self-check: If applying the same configuration twice to an already-correct machine changes nothing, which capability is at work?

Connects to: Section 19.2, Section 19.3, Section 19.4

Chef: Agent-Based Configuration as Code

Must-know: Chef is agent-based: a Chef client runs inside every node, compares the node's current state with the desired state declared in cookbooks, and repairs any drift (JRE7 deleted is reinstalled; Apache stopped is restarted). Cookbooks are programs containing recipes; the Chef server stores cookbooks and policies; the workstation authors them.

⚠️ Top pitfall: Confusing cookbook and recipe: the cookbook is the unit of distribution (the program), the recipe is the code inside it describing the policy for one system. Also forgetting that Chef requires an agent (Chef client) on every node.

Self-check: Apache 2 is stopped by a script on a Chef-managed node. What restarts it, and when?

Connects to: Section 19.1, Section 19.3, Section 19.4

Puppet: Master–Agent Pull-Based Configuration

Must-know: Puppet's pull cycle: agent sends facts (Facter) to the master, master compiles and returns the catalog (desired state of each resource plus dependency order), agent applies it. The master is the source of truth, so any change on the node — deletion, corruption, direct edit — is reverted at the next pull unless the manifest is updated too. Facter facts enable one-shot global changes to all matching nodes.

⚠️ Top pitfall: Editing a file directly on the node: the manifest overwrites it at the next pull and the latest content is lost — change the manifest, not the node. Also confusing configuration management (desired state) with orchestration (load balancing, scaling instances for high availability).

Self-check: A file resource declares ensure present, owner sonika, group bits, mode 664, and fixed content. A user edits the file on the node with newer content. What happens at the next catalog run?

Connects to: Section 19.1, Section 19.2, Section 19.4

Ansible: Agentless Push-Based Automation

Must-know: Ansible is agentless (no installs on nodes, so black-box devices are manageable), push-based (the server sends playbooks to nodes, so recovery starts immediately instead of waiting for the next poll), and developer-friendly (YAML playbooks read like plain English). Architecture: automation engine with inventory, APIs, modules, and plugins; terms: playbook (entry point), play (execution), task (one procedure), facts (global variables), handlers (trigger service restarts, typically via notify).

⚠️ Top pitfall: Confusing push and pull: in Ansible the server pushes to the nodes and does not wait for nodes to reach out; in Puppet/Chef agents poll on a schedule, so recovery lags behind failure. Also confusing play, playbook, and task: playbook is the file, play is its execution, task is one procedure.

Self-check: Apache is stopped on a node managed by Ansible. Why can the repair begin immediately, unlike with Puppet?

Connects to: Section 19.2, Section 19.3, Section 19.5

Virtualization: From Physical Servers to Containers

Must-know: Virtualization = creating useful IT services from resources traditionally bound to hardware, distributing a physical machine's capabilities among many environments; it answers the cloud diagram (scalable services, metered usage, shared resources). It solves the physical-server problems of huge cost, slow deployment, and hard migration. Hardware-level virtualization (hypervisor, guest OSes, duplicated kernels) vs OS-level virtualization (container engine, shared host kernel, lightweight portable containers).

⚠️ Top pitfall: Confusing the two levels: hardware-level virtualization duplicates the kernel per guest OS; OS-level virtualization shares the host kernel. Also calling a container a VM without an OS — a container is isolated binaries and libraries on a shared kernel.

Self-check: Two applications need JRE6 and JRE7 respectively. How do containers solve this without duplicating kernels?

Connects to: Section 19.4, Section 19.6

Docker: Containers in Practice

Must-know: An image is an executable, read-only template; a container is the running instance of an image; a service is a container in production codifying ports and replicas; you build an image when your specification is not covered by an existing registry image. Dockerfile lines: FROM, WORKDIR, COPY, RUN pip install -r requirements.txt, EXPOSE, ENV, CMD. Swarm: managers + worker nodes in a cluster for orchestration; stack: interdependent services with a shared lifecycle. Docker Hub = free community registry, Docker Store = paid certified marketplace, Docker Cloud = hosted build/test registry.

⚠️ Top pitfall: Answering Docker questions with commands — interviews and exams ask concepts: what is an image, what is a container, when do you build an image. Also confusing Hub (community, no quality guarantee) with Store (vendor-approved, certified), and configuration management (desired state) with orchestration (load balancing, scaling).

Self-check: A service definition declares five replicas, 0.01 CPU, 50M memory, restart on failure, ports, and network webnet. What do the replicas refer to?

Connects to: Section 19.5, Section 19.3, Section 19.4

Exam Guidance Summary

Must-know: No direct tool-component questions; scenario questions on configuration management vs infrastructure management with tool-justification vocabulary (agent vs agentless, pull vs push, language readability). Definition answers: distributing service requests to resources is load balancing; the box in the scalable/metered/shared diagram is virtualization.

⚠️ Top pitfall: Studying tool internals or command syntax — the exam explicitly does not test those; concepts and scenario judgment do.

Self-check: A question shows scalable services, metered usage, and shared resources with an empty box in the middle. What goes in the box?

Connects to: Section 19.1, Section 19.5, Section 19.6

Key Industry Applications

Must-know: Real-world names and patterns: Facebook/Etsy/Indiegogo run Chef; Forge, Galaxy, and Supermarket are the community reuse channels; Terraform leads cloud infrastructure configuration; Docker services declare replicas and resource limits in production; orchestration (Swarm, Kubernetes) handles clustering, load balancing, and scaling that configuration management tools do not.

⚠️ Top pitfall: Attributing orchestration jobs (load balancing, scaling) to configuration management tools — the division of labor between the two families is a key exam-ready distinction.

Self-check: Which family of tools handles load balancing and scaling of containers: configuration management or orchestration?

Connects to: Section 19.2, Section 19.3, Section 19.4, Section 19.5, Section 19.6

Was this lecture useful?

Loading comments…
🤖

BitsNotes AI Assistant

Subject Notes Assistant

Configure AI Chat

Choose how to access the chatbot
Have your own API key?

Switch to "Bring Your Own Key" tab above for unlimited access with any OpenAI-compatible provider.

🔑 Enter API key above to fetch live models from provider, or enter model name manually.
OpenAI-Compatible API Support

Choose any provider preset (Gemini, DeepSeek, Kimi, GLM, MiniMax, Qwen, OpenAI, Groq, Ollama, etc.) or enter a custom endpoint URL.

Security & Privacy First

Your API key is sent directly from your browser to your specified provider. BitsNotes servers never store or see your key.