DEV Community

John  Ajera
John Ajera

Posted on

Customizing the Message of the Day (MOTD) on AWS EC2 Instances Using Terraform

Introduction

When launching AWS EC2 instances, having a Message of the Day (MOTD) can provide useful system information at login. This is particularly useful for cloud-based environments, where instances are frequently provisioned and accessed by multiple users.

In this guide, we will cover how to customize the MOTD for Amazon Linux 2, Amazon Linux 2023, and Ubuntu 22.04 using Terraform with cloud-init and EC2 Instance Connect (no SSH keys required).

Repository

This project is available on GitHub: tf-aws-ec2-motd-demo. The repository contains the full Terraform configuration and cloud-init script for deploying EC2 instances with a customized MOTD.

Why Customize the MOTD?

A well-configured MOTD can:

  • Display system information (e.g., instance ID, IP address, CPU load)
  • Provide reminders or warnings for users
  • Offer a quick overview of the instance status
  • Improve administrative efficiency for cloud environments

Where MOTD Files Are Stored and Execution Order

Each operating system handles MOTD differently. The files are stored in different locations and executed in a specific order:

  • Amazon Linux 2 & Amazon Linux 2023:

    • The MOTD scripts are stored in /etc/update-motd.d/.
    • Files in this directory are executed in numerical order.
    • Default files include:
    • 30-banner (displays the Amazon Linux banner)
    • 50-amazon-linux-extras-news (news updates from Amazon Linux Extras)
    • 70-available-updates (package update notifications)
    • 99-system-info (custom MOTD script, added via cloud-init)
    • The final MOTD is displayed by concatenating the outputs of these scripts in order.
  • Ubuntu 22.04:

    • Uses /etc/update-motd.d/ as well but has additional MOTD management with update-motd.
    • The execution order follows the script numbering:
    • 00-header (displays system details)
    • 10-help-text (Ubuntu-specific help text)
    • 50-motd-news (news updates from Canonical)
    • 99-system-info (custom MOTD script, added via cloud-init)
    • Ubuntu dynamically generates /etc/motd by running all executable scripts in /etc/update-motd.d/ in numerical order and writing their output to /run/motd.dynamic.
    • The contents of /run/motd.dynamic are displayed upon user login.

Naming Convention and Execution Order

The naming convention of MOTD scripts follows a numeric order, ensuring that scripts execute sequentially:

  • Lower-numbered scripts run first.
  • Higher-numbered scripts run later.
  • If multiple scripts have the same numeric prefix, they execute alphabetically.

For example:

  • Amazon Linux default scripts:

    • 30-banner
    • 50-amazon-linux-extras-news
    • 70-available-updates
    • 99-system-info (custom script added via cloud-init)
  • Ubuntu default scripts:

    • 00-header
    • 10-help-text
    • 50-motd-news
    • 99-system-info (custom script added via cloud-init)

If needed, you can use numbers beyond 99, such as 100-custom-script, to ensure that your script executes after all other system scripts.

By naming our custom MOTD script 99-system-info, we ensure that it executes after all default system scripts. This prevents other scripts from overriding or modifying the MOTD output.

Implementing MOTD with Terraform and Cloud-Init

AWS EC2 allows you to pass user_data scripts that run at instance launch. We will use Terraform to deploy EC2 instances with a cloud-init YAML file that configures a dynamic MOTD and enables EC2 Instance Connect.

1️⃣ Define Cloud-Init Configuration

Save the following cloud-init YAML as external/cloud-init.yaml in your Terraform module directory:

#cloud-config
package_update: true
package_upgrade: true
package_reboot_if_required: true

write_files:
  - path: /etc/update-motd.d/99-system-info
    content: |
      #!/bin/bash

      OS_VERSION=$(grep -E '^PRETTY_NAME=' /etc/os-release | cut -d= -f2 | tr -d '"')
      INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
      AZ=$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone)
      PUBLIC_IP=$(curl -s --fail http://169.254.169.254/latest/meta-data/public-ipv4 2>/dev/null || echo "None")
      PRIVATE_IP=$(curl -s http://169.254.169.254/latest/meta-data/local-ipv4)
      CPU_LOAD=$(uptime | awk -F'load average:' '{ print $2 }')
      MEMORY_USAGE=$(free -h | awk '/Mem:/ {print $3 "/" $2}')
      DISK_USAGE=$(df -h --output=used,size / | tail -n 1 | awk '{print $1 "/" $2}')
      NETWORK_INTERFACES=$(ip -br link show | awk '{print $1}' | grep -v lo)

      echo "Welcome to your instance"
      echo ""
      echo "OS Version: $OS_VERSION"
      echo "Instance ID: $INSTANCE_ID"
      echo "Availability Zone: $AZ"
      echo "Public IP: $PUBLIC_IP"
      echo "Private IP: $PRIVATE_IP"
      echo ""
      echo "System Information:"
      echo "  - CPU Load: $CPU_LOAD"
      echo "  - Memory Usage: $MEMORY_USAGE"
      echo "  - Disk Usage: $DISK_USAGE"
      echo "  - Network Interfaces: $NETWORK_INTERFACES"
      echo ""
    permissions: '0755'
Enter fullscreen mode Exit fullscreen mode

Conclusion

By using Terraform, cloud-init, and EC2 Instance Connect, administrators can configure dynamic MOTD messages on Amazon Linux 2, Amazon Linux 2023, and Ubuntu 22.04 without SSH keys. This method ensures that system information is readily available at login via the AWS Console.

For the full working Terraform code, visit: tf-aws-ec2-motd-demo.

Would you like more AWS automation tips? Let me know in the comments!

Top comments (0)