Using Ansible to Manage Configuration Across 50 Servers

Managing a handful of Linux hosts manually can feel perfectly reasonable. At 50 servers, the same approach becomes a source of drift, missed security updates, inconsistent packages, and long evenings spent comparing configuration files. Ansible provides a practical way to turn those machines into a controlled, repeatable fleet.

The value is less about writing clever YAML and more about establishing reliable operating habits. A good Ansible repository records what each server should do, applies changes in a predictable order, and leaves enough evidence for another administrator to understand what happened.

Australian organisations often run workloads across Sydney and Melbourne cloud regions, with offices and users spread across Brisbane, Perth, Adelaide, and regional areas. That makes consistent configuration especially useful when latency, maintenance windows, and support coverage vary across locations.

This guide focuses on the design decisions that matter when moving from a few machines to 50: inventory structure, reusable roles, secrets, testing, controlled deployment, and the monitoring needed to confirm that configuration remains correct after Ansible finishes.

Why fleet size changes the operating model

Fifty servers are large enough for small inconsistencies to become operational incidents. One web server may have a different PHP module, an older TLS setting, or a missing monitoring agent. These differences are often invisible until traffic is redirected to the wrong host or a recovery process depends on a package that was never installed.

Ansible works over SSH or WinRM and generally does not require an agent on every managed node. Its agentless design reduces the software footprint, while its declarative modules describe an intended state rather than a sequence of fragile shell commands.

The first goal should be visibility. Before automating changes, identify operating systems, environments, applications, ownership, network zones, backup requirements, and maintenance windows. Automation applied to an incomplete inventory can make mistakes faster, which is still a mistake.

Build an inventory that reflects reality

A flat inventory file may be adequate for ten hosts, but groups become essential at 50. Group machines by function and environment, such as web, database, monitoring, development, staging, and production. Hosts can belong to multiple groups, allowing a common baseline to coexist with application-specific settings.

Use stable names and meaningful variables. A hostname such as prod-syd-web-03 communicates more than an automatically assigned cloud identifier, while variables such as ansible_user, app_port, and backup_policy make intent visible. Avoid placing temporary facts in the inventory simply because they are convenient during an incident.

Cloud inventory plugins can synchronise hosts from providers and tags. That is useful when servers are frequently created or replaced, though dynamic discovery should be paired with naming and tagging standards. A server without the correct environment tag should not silently join a production play.

Separate common policy from application detail

Roles provide the main structure for maintainable Ansible code. A baseline role might configure time synchronisation, approved repositories, SSH policy, unattended security updates, log forwarding, and the monitoring agent. Application roles can then install Nginx, PostgreSQL, PHP-FPM, or a custom service without duplicating the baseline.

Keep variables close to their purpose and define sensible defaults. Environment-specific values belong in group variables or encrypted data, not scattered through task files. Templates should be readable and should expose the settings an operator is likely to review, such as bind addresses, worker counts, retention periods, and service ports.

Idempotence is a key test. Running a playbook twice should produce no changes the second time unless the managed state has changed. Prefer Ansible modules such as package, service, template, user, and lineinfile over unrestricted shell commands. When a command is unavoidable, use conditions and change detection so Ansible can report accurately.

Treat secrets and access as production concerns

A 50-server deployment usually involves database passwords, API tokens, private keys, certificates, and cloud credentials. These values should never be committed as clear text to a shared Git repository. Ansible Vault can encrypt sensitive variables, while a secrets manager may be more appropriate for larger teams or frequent rotation.

Use a dedicated automation account with narrowly defined privileges. SSH keys should be managed deliberately, and administrative access should be logged. In Australian workplaces, access reviews often need to account for contractors, managed-service providers, and staff working across different time zones, so ownership should be explicit rather than assumed.

A useful pattern is to keep secrets separate from ordinary configuration and load them only in the playbooks that need them. Test vault access in a non-production environment, document the recovery process, and ensure that a lost controller does not mean lost access to every server.

Make deployment safe and observable

Start with --check mode where module support is reliable, then use --diff carefully. Configuration diffs are useful for review, but they must not expose passwords or private material in terminal output or CI logs. Linting with tools such as ansible-lint can catch risky patterns before they reach a server.

Deploy in batches rather than changing all 50 machines at once. A canary group of one or two hosts can reveal a package conflict, a distribution-specific path, or an unexpected service restart. After the canary passes health checks, continue with a controlled serial rollout.

Maintenance windows matter in Australia, especially when users span multiple states and daylight-saving rules differ between jurisdictions. Define schedules in a single reference timezone, communicate changes in local time, and avoid assuming that a Sydney window is convenient for Perth staff or customers.

Connect configuration with monitoring and recovery

Configuration management establishes a desired state, but monitoring verifies that the service remains useful. Ansible should install and configure checks for disk capacity, memory pressure, certificate expiry, service availability, backup freshness, and log forwarding. A successful playbook run does not prove that an application is responding correctly.

Storage deserves particular attention. A server can have a correct mount configuration while the underlying disks are failing or backups are incomplete. Lessons from building a home NAS are relevant here: capacity planning, drive health, redundancy, and recovery testing all matter more than simply having storage attached.

Use tags to support operational tasks such as configuration, packages, monitoring, and security. This allows an administrator to make a targeted change without running every role. Keep playbook output in a central CI system or automation platform so changes can be traced to a commit, operator, and timestamp.

Establish a disciplined operating routine

Ansible becomes dependable when it is treated as code rather than a collection of commands on an administrator’s laptop. Store it in Git, review changes through pull requests, test roles against supported operating system versions, and document the expected variables for each service.

The following practices provide a sensible baseline for a 50-server estate:

  • Keep production inventory and credentials protected, reviewed, and separate from development data.
  • Use reusable roles with clear defaults, handlers, tags, and idempotent tasks.
  • Apply changes to a canary host before beginning a wider serial rollout.
  • Run syntax checks, linting, and automated tests in CI before merging playbook changes.
  • Record package, operating system, application, and ownership metadata for every host.
  • Pair configuration changes with monitoring checks, backups, and a tested rollback procedure.
  • Review configuration drift regularly instead of waiting for an outage to expose it.

A mature workflow also includes periodic cleanup. Retire hosts from inventory when they are decommissioned, remove obsolete variables, update role documentation, and verify that old SSH keys and cloud permissions are revoked. Infrastructure is constantly changing, and stale automation can be as dangerous as missing automation.

The most effective first project is usually a narrow one: standardise the operating system baseline across a representative group, then add monitoring and security controls. Once that process is reliable, application roles and more complex deployment workflows can be introduced without turning the entire fleet into a single high-risk experiment.

For teams that need a broader infrastructure perspective, practical systems notes can provide another useful reference point while designing operational processes. The important outcome is a repository that explains the environment clearly and can be executed by someone other than its original author.

Start by inventorying the 50 servers, selecting a small canary group, and committing the first baseline role to version control. From there, each repeatable fix becomes shared operational knowledge, and configuration management becomes a dependable part of daily systems administration rather than an emergency measure.

Experience

Information Technology Consulting

Independent Practice

Provides IT consulting services focused on infrastructure planning, cloud migration strategy, and systems architecture. Engagements draw on years of hands-on sysadmin and development experience across Linux, Windows, and hybrid environments.

K9 Search & Rescue Volunteer

Ongoing

Active participant in K9 Search & Rescue operations, combining technical logistics skills with field support for canine search teams.

Karl Katzke's Blog

October 2006 – May 2014

Published a long-running personal technology blog covering cloud vs. in-house infrastructure, F# and Mono on OSX, hardware vendor critiques, RAID card performance analysis, and sysadmin storytelling. Notable posts include "When Sysadmins Ruled the Earth" (May 15, 2014) and "Getting Started with F# and Mono on OSX" (December 22, 2012).

Credentials

A small badge icon with a shield shape in muted blue tones on a light background

Systems Administration

Deep experience with Linux (RHEL, SLES, CentOS), high-availability clusters, and STONITH configurations.

A small badge icon with a gear shape in muted blue tones on a light background

Cloud Infrastructure

Practical knowledge of AWS EC2, reserved instances, and cost analysis for cloud vs. on-premises deployments.

A small badge icon with a code symbol in muted blue tones on a light background

Development

Proficient in F#, PHP (Symfony), and cross-platform tooling including Mono and MonoDevelop on OSX.

Studies

F# & Functional Programming

Self-directed, 2012

Explored strongly typed functional programming with F# on OSX using the Mono runtime. Published a detailed getting-started guide covering toolchain setup and cross-platform game development research.

High-Availability & Cluster Management

Professional Development, 2009

Configured and documented crm_mon email alerting for STONITH events on SLES11-HAE clusters, integrating with Nagios monitoring for production environments.

Hardware & Storage Performance

Ongoing

Conducted hands-on benchmarking of SATA/SAS RAID controllers including HighPoint RocketRaid 2740 and LSI/SuperMicro AOC-USASLP2-H8iR, comparing against software RAID configurations.

Skills

A small icon representing a server with clean geometric lines in slate blue

Linux Administration

RHEL, SLES, CentOS — package management, kernel tuning, HA clustering, and monitoring integration.

A small icon representing a cloud shape with clean geometric lines in slate blue

Cloud Architecture

AWS EC2, reserved-instance planning, cost modeling, and hybrid infrastructure strategy.

A small icon representing code brackets with clean geometric lines in slate blue

F# & .NET/Mono

Functional programming on OSX, MonoDevelop toolchain, and cross-platform game-dev exploration.

A small icon representing a database cylinder with clean geometric lines in slate blue

PHP & Symfony

Web application development with the Symfony framework and the broader PHP ecosystem.

A small icon representing a storage drive with clean geometric lines in slate blue

Storage & RAID

SATA/SAS controller evaluation, md RAID configuration, and performance benchmarking.

A small icon representing a shield with clean geometric lines in slate blue

High Availability

Pacemaker, STONITH, crm_mon alerting, and Nagios integration for production cluster monitoring.