DEV Community

Nnamdi Felix Ibe
Nnamdi Felix Ibe

Posted on

100 Days of DevOps and Cloud (AWS), Day 8: Ansible's 'ping' Isn't a Ping, and the AWS Stop Flag Reads Backwards

Ansible's whole pitch is that it manages servers without installing an agent on any of them. That single design choice is most of why it took over, and Day 8 started with getting it running and proving it could actually reach a host.

Two tasks today. Install Ansible on a Linux control node and confirm it can communicate with a managed server, then enable stop protection for an EC2 instance so nobody can accidentally knock it offline. The tasks come from the KodeKloud Engineer platform, as with the rest of this series.

Ansible: install it, then prove it can reach a host

Ansible is a configuration and automation tool. You describe the state you want a server to be in, and it makes the server match. The part that made it win is that it is agentless. There is no daemon to install on the machines you manage, it just needs SSH access and a working Python on the far end. You install it in one place, the control node, and reach everything else from there.

Ansible is written in Python, so Python and pip come first:

# Update packages, then install Python and pip
sudo yum update -y
sudo yum install -y python3 python3-pip

# Confirm what you have
python3 --version
pip3 --version
Enter fullscreen mode Exit fullscreen mode

Then install Ansible itself. In the lab, I pinned an exact version:

# Install a specific Ansible version, system-wide
sudo pip3 install ansible==2.9.27 --prefix /usr/local
ansible --version
Enter fullscreen mode Exit fullscreen mode

Pinning the version is the right instinct. An automation tool that silently upgrades underneath you is how a playbook that worked last week breaks today, so naming the version keeps runs reproducible.

Two honest caveats, because this is where the lab and the real world split.

First, that version is old. Ansible 2.9 is years behind now. On a fresh setup, you would reach for the current release, which ships as a package called ansible-core, the modern engine that the RHEL package manager provides in the 2.16 and up range.

Second, Red Hat does not recommend installing Ansible with sudo pip system-wide, because pip does not respect what the system package manager owns and can quietly clash with it. The supported routes are sudo dnf install ansible-core for a system install, or pip inside a Python virtual environment when you want the newest upstream version without touching system packages. The lab wanted the pip method, so that is what I ran, but on anything real, I would use dnf or a venv.

With Ansible installed, it needs to know what it is managing. That is the inventory file, a plain list of hosts grouped under a label:

# Create an inventory file
vi inventory

# [servers]
# 192.168.1.10
# 192.168.1.11
Enter fullscreen mode Exit fullscreen mode

Then the moment of truth, the ping module:

# Check Ansible can reach every host in the 'servers' group
ansible -i inventory servers -m ping
Enter fullscreen mode Exit fullscreen mode

Here is the trap hiding in the name. Ansible's ping is not an ICMP ping. It does not bounce a packet off the network. It logs into each host over SSH, checks that a usable Python is there, and returns pong only if all of that worked. So a green pong is proof of a full working connection, SSH and Python both, not just that the box is reachable. It is a stronger signal than a normal ping, and it fails for different reasons too, usually broken SSH auth or a missing Python rather than a dropped packet.

EC2 stop protection: a safety switch with a backwards name

Over on AWS, the task was to protect an important instance from being stopped by accident. AWS calls this stop protection, and turning it on is a single command:

# Enable stop protection
aws ec2 modify-instance-attribute \
  --instance-id i-1234567890abcdef0 \
  --disable-api-stop
Enter fullscreen mode Exit fullscreen mode

Read that flag twice, because it catches everyone. --disable-api-stop sounds like it switches stopping off in some harmful way. It is actually the switch that turns protection on. It disables the stop API for that one instance, so the instance cannot be stopped until you remove the protection. To turn it back off later, you use the mirror flag, --no-disable-api-stop.

The note I was working from verified this by trying to stop the instance and watching the call fail. That works, but it is a nervous way to check, because if the protection had not actually applied, you would have just stopped your box. The calmer check is to ask AWS directly:

# Confirm protection is on without risking a stop
aws ec2 describe-instance-attribute \
  --instance-id i-1234567890abcdef0 \
  --attribute disableApiStop
Enter fullscreen mode Exit fullscreen mode

If that returns true, protection is on, and any stop-instances call will now be refused with an error instead of quietly taking the instance down.

A few things worth knowing before you rely on it.

Stop protection and termination protection are two separate switches. Stop uses --disable-api-stop, termination uses --disable-api-termination. Turning on one does nothing for the other, so an instance you want fully locked down needs both.

It also does not apply everywhere. You cannot enable stop protection on an instance with an instance-store root volume or on a Spot Instance. For the standard EBS-backed on-demand instances most people run, you are covered.

The actual lesson

Both tasks were about trust, pointing in opposite directions. Ansible's ping earns your trust by doing more than the name suggests, a real login instead of a network poke. AWS's stop flag tests your trust by being named the opposite of what it does. The habit that carries you through both is the same one: read what a command actually does instead of what its name implies.

So here is Day 8's question. Would you rather assume a command does what it sounds like and find out the hard way in production, or spend the extra minute confirming what it really does before you depend on it?

Day 8 down. Ninety-two to go

Top comments (0)