How to create SSM Documents and use them to install packages massively with Run Command

1. Overview

In our previous tutorials about managing your Ubuntu servers with AWS SSM, we learned how to open shell sessions without having to do SSH logins and how to update your instances in an automated and scalable way using SSM Run Command.

In this tutorial, as the third part of SSM basics on Ubuntu, we will learn how to run custom automation scripts, using SSM Documents and Run Command in AWS Systems Manager.

Our first SSM Document will be for installing packages from the Ubuntu repositories. If you are not new to this, you will know that this is as simple as updating the cached package list and then installing the desired packages.

If we were on the console, the commands would be:

sudo apt update
sudo apt install -y mypackage

This very simple example will help you to install packages massively in your fleet avoiding tedious and error prone work, while helping you to understand the SSM Document basics, allowing you to write your own scripts.

What you’ll need

  • An AWS account
  • Understanding of IAM roles for EC2 instances
  • Understanding SSM basic functionalities: Make sure you have followed the previous two tutorials, since this can only be applied to servers that have become “SSM managed nodes” (in other words, you need to know how to add the IAM SSM policy to your instance profile or role).
  • Some Ubuntu Servers running

What you’ll learn

  • What are SSM Documents
  • How to create your own SSM Document with user parameters
  • How to run SSM Documents with RunCommand

2. Let’s start.

Let’s start by opening the AWS Systems Manager console and clicking on “Fleet management” on the left hand menu. If you have already attached the SSM roles to your instances, you should see them listed under the Managed Nodes table. If you haven’t done so, please check the previous two tutorials first.

If they are not listed here, you may need to check if those instances have attached the right role (i.e. a role with the AmazonSSMManagedInstanceCore profile). Also it is worth checking whether you are in the same region as your machines are.

Note:
If you have correctly attached the SSM role to already running instances and they are still not appearing under Fleet management, it may be because it takes some time for SSM to detect this. The reason behind is because when the machine ins launched with no SSM access role, the SSM agent inside becomes inactive for longer periods of time until it detects connectivity. If this is the case, you can either wait longer or restart the machine.

You should see your instances under Fleet management as shown below:


3. Creation of a SSM Document

Let’s go to the Shared Resources section at the bottom of the left hand menu, and click on the Documents link. Here you will see a list of all the available Documents that are ready to use in AWS Systems Manager.

Since we are going to create our own, click on the Create document button and select
command or session.

Enter the basic information required:

  • Insert a Name: We are going to call it ubuntu-apt-install)
  • Select /AWS::EC2::Instance for the target
  • Select Command Document for the Document type.


4. The content of the SSM Document

Scroll down to the content section and select yaml since the content we are providing here is also in yaml format.

Paste in the following content:

---
schemaVersion: '2.2'
description: "Install packages from Ubuntu repositories"
parameters:
  packages:
    type: String
  reboot:
    type: String
    allowedValues:
    - "False"
    - "True"
mainSteps:
- action: aws:runShellScript
  name: updateRepositories
  inputs:
    runCommand:
    - "sudo apt-get update"
- action: aws:runShellScript
  name: instalPackage
  inputs:
    runCommand:
    - "sudo apt-get install {{ packages }} -y"
- action: aws:runShellScript
  name: reboot
  precondition:
    StringEquals:
    - "{{ reboot }}"
    - "True"
  inputs:
    runCommand:
    - "sudo reboot"

And save by clicking on the button at the bottom right of the screen.

Explanation:

This code has two main sections: parameters and mainSteps.

Parameters:
Since we need the user to enter the packages to be installed we need to include them as parameters needed from the console, before running the script. We also added a second parameter that will ask the user if a reboot is needed or not.

MainActions:
This section is where the magic happens. You can directly enter console commands or a bash script in each line. Every action is one step of the automation that will help you to follow after execution if something goes wrong.

We have three actions in our script. The first one runs sudo apt-get update, to update the package list, then, in the second action, we can run the actual installation: sudo apt-get install {{ packages }} -y.

Note that the double curly brackets are a reference to variables or parameters. The third action has a conditional value that depends on the value entered in the reboot parameter. The actual action is sudo reboot.


5. Run and test

Now that we have created the document, we can run it from different places.

You can run it from the managed nodes table, where you select all the instances, click on Node actions and select run command.

Next screen will ask which command (or Document) you would like to run. This is where we can enter our own parameters.

We will use the search box to find our Document, as shown below:

Select your script from the list and then scroll down for your defined parameters (packages and reboot). For this example, I’m installing nodejs and npm.

Under targets, you can specify on which instances you would run this script. You can select instances manually, by your own defined tags (e.g. role: webservers) or by resource groups.

The rest is optional, as you can add internal comments or configure where to store the output from the machines. You can also configure SNS notifications for getting the results.

Click on Run and follow the next screen’s status.

Note:
If the command fails, you can see the output of each step in the results page and see what failed. Check if you have any mistake in the script (sometimes just copy-paste errors). You can fix them by creating another version. Make sure you update the default version after making the change.


6. That’s all Folks!

On the next screen you will see the progress and if you wait until it finishes, you will see the end result of this script for each instance. You can click on the instance id and see the outputs gotten from the script per each step in the same page.

Now you know how to write your own AWS SSM Document for automating tasks that you would normally do on the terminal and run them massively, automatically and error free.

Additional reading