AWS Cloud Operations & Migrations Blog

Enable Modular and Reusable Configuration Using Composite AWS Systems Manager Documents

By Melonia Mendonca, Software Development Engineer at Amazon Web Services

AWS Systems Manager (SSM) documents enable infrastructure as code that allows you to configure, manage, and automate your AWS and on-premises resources using AWS Systems Manager services. These SSM Documents define the actions that you want to perform on managed instances. Systems Manager offers a variety of pre-defined public documents and provides the ability to customize the documents as well.

Systems Manager lets you execute composite documents as part of your configurations. Composite documents are SSM documents that perform the task of executing one or more secondary documents. Using composite documents, you can do the following:

  • Enable modularity – Documents can be broken into small common tasks, and then they can be called from composite documents.
  • Enable reusability – Having the ability to invoke other documents removes the requirement to duplicate the plugin calls within custom documents.
  • Store documents in remote locations– GitHub and Amazon S3 can be used to save documents because these documents in remote locations can be invoked using composite documents.
  • Use YAML in place of JSON in documents – AWS Systems Manager also allows the use of documents written in YAML format that are stored in remote locations.

AWS-RunDocument is a new document you can use to execute documents that are stored in Systems Manager, private or public GitHub, or Amazon S3. This is achieved by using aws:downloadContent and aws:runDocument plugins. The aws:runDocument plugin executes documents that reside in Systems Manager or in the local path.

In this blog post, I’ll show you how to create custom composite documents using the aws:runDocument plugin. I’ll demonstrate how to execute documents created in Systems Manager by invoking them from the composite document. I’ll also walk through the method of executing documents that are in GitHub by using the AWS-RunDocument document.

Walkthrough 1 – Compose a custom document using SSM documents

In this example, I’ll show you how to compose a document that updates SSM Agent and then runs baseline patch and eventually configures an AWS package. Before the introduction of composite documents, this could be done one of two ways. You could send three separate commands to execute these public documents – AWS-UpdateSSMAgent, AWS-RunPatchBaseline, and AWS-ConfigureAWSPackage.  Alternatively, you could add the plugin references in another document, but you would have to duplicate the document and not use the pre-defined, public document provided. With the use of composite documents, these documents are executed by sending a single composite document.

Step 1: Create the composite document
I’ll use the aws:runDocument plugin to compose plugins in my document. The plugin has the following parameters:

  • documentType – This indicates the type of document. The document could be locally available – LocalPath or from SSM – SSMDocument. In this example, this parameter will be SSMDocument.
  • documentPath – This is the path to the document. It is either the absolute path to the document on disk, or the name of the document if the type is SSMDocument. In this walkthrough, we will use the path to specify the names of the documents – AWS-UpdateSSMAgent, AWS-RunPatchBaseline, and AWS-ConfigureAWSPackage.
  • documentParameters – The parameters for the secondary document. This should be specified as parameter type StringMap with key and value pairs.

The document appears as follows. I have named it composite-document.json. This document can be executed on Windows.

~/tmp/docs/composite-document.json 

{
  "schemaVersion": "2.2",
  "description": "Compose SSM documents",
  "parameters": {},
  "mainSteps": [
    {
      "action": "aws:runDocument",
      "name": "AgentUpdate",
      "inputs": {
        "documentType": "SSMDocument",
        "documentPath": "AWS-UpdateSSMAgent"
      }
    },
    {
      "action": "aws:runDocument",
      "name": "ApplyPatchBaseline",
      "inputs": {
        "documentType": "SSMDocument",
        "documentPath": "AWS-RunPatchBaseline",
        "documentParameters": "{\"Operation\":\"Install\"}"
      }
    },
    {
      "action":"aws:runDocument",
      "name" : "ConfigureAWSPVDriver",
      "inputs":{
        "documentType":"SSMDocument",
        "documentPath":"AWS-ConfigureAWSPackage",
        "documentParameters": "{\"action\":\"Install\", \"name\":\"AWSPVDriver\"}"
      }
    }
  ]
}

You can navigate to the AWS Systems Manager console and paste this document to create a document. You can also do this using the create-document command in the AWS CLI:

aws ssm create-document --name composite-document --content file://~/tmp/docs/composite-document.json --document-type Command

Step 2: Run the command and check the output

After the command is sent, each action will be executed to produce the following output.

Or you can use the send-command command from the AWS CLI. I am targeting all my Windows value instances by using tagging. To do this I created a new tag – PlatformType. For more information on using tags when you send commands, see Sending Commands to a Fleet in the AWS Systems Manager documentation.

aws ssm send-command --document-name "composite-document" --targets Key=tag:PlatformType,Values=Windows

Walkthrough 2 – Compose an SSM custom document using documents from GitHub

In a previous blog post, I reviewed the method of executing scripts from GitHub. Today, I’ll demonstrate how to execute Systems Manager documents from GitHub. This method can be used to execute documents from Amazon S3, too. In this composite document, I will update SSM Agent to the latest version and then install Apache and My SQL. The document to install this software resides in GitHub and is written in YAML.

Step 1:  Create composite document
To create a document from a remote resource like GitHub, I’ll use the pre-defined AWS-RunDocument document. This document has the following parameters to help us specify the information to download the document.

  • Source Type: Location of the script – GitHub or Amazon S3. For this example, the value here is GitHub.
  • Source Info: This parameter provides information for accessing the document. The repository mentioned earlier is public and thus, this should be the owner, repository, and the path to the document.
  • Document Parameters: If the document to be executed takes parameters, they can be specified here. In this case, it will be left blank.

You can use the composite document below to install the SSM Agent, Apache and MySQL on the instance.

~/tmp/docs/composite-document-mysql.json 
{
  "schemaVersion": "2.2",
  "description": "Composite documents from GitHub",
  "parameters": {
  },
  "mainSteps": [
    {
      "action": "aws:runDocument",
      "name": "AgentUpdate",
      "inputs": {
        "documentType": "SSMDocument",
        "documentPath": "AWS-UpdateSSMAgent"
      }
    },
    {
      "action": "aws:runDocument",
      "name": "InstallApacheandMySQL",
      "inputs": {
        "documentType": "SSMDocument",
        "documentPath": "AWS-RunDocument",
        "documentParameters" : "{\"sourceType\":\"GitHub\", \"sourceInfo\":\"{\\\"owner\\\":\\\"mmendonca3\\\",\\\"repository\\\":\\\"dummy-test-public\\\", \\\"path\\\":\\\"documents/bootstrap/StateManagerBootstrap.yml\\\"}\"}"
    }
  }
  ]
}

You can create it using the AWS Systems Manager console or AWS CLI. The command to create this document would be:

aws ssm create-document --name composite-document-mysql --content file://~/tmp/docs/composite-document-mysql.json --document-type Command

Step 2: Run Command and check the output
On sending a command to execute this document, the agent gets updated to the latest version, downloads the document, and then executes it.

The command to run this is follows:

aws ssm send-command --document-name "composite-document-mysql" --targets Key=tag:PlatformType,Values=AmazonLinux

Conclusion

In this blog post, I have shown you how to enable management as code by using composite documents. You can create composite documents to reuse your documents easily, and enable modularity. Documents created using AWS Systems Manager can be referenced using composite documents. Those documents on GitHub and Amazon S3, written in JSON or YAML, can be executed using the AWS-RunDocument document.

About the Author

Melonia Mendonca is a Software Development Engineer with the Amazon EC2 Systems Manager team. She is a passionate engineer who enjoys the ability to innovate encouraged by Amazon. Outside of work, Melonia likes traveling, playing board games and trying different restaurants/cuisines.