{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Description": "Observability Solution from CloudWatch: Common CloudWatch Agent installation. Version: 1.0.0.",
  "Parameters": {
    "InstanceIds": {
      "Type": "CommaDelimitedList",
      "Description": "A comma-separated list of Amazon EC2 instance IDs where you want to install the CloudWatch agent and its configuration."
    },
    "TagKey": {
      "Type": "String",
      "Description": "The key of the tag that identifies the Amazon EC2 instances where you want to install the CloudWatch agent and its configuration. Use this parameter if you prefer to target instances by tag instead of instance ID."
    },
    "TagValue": {
      "Type": "String",
      "Description": "The value of the tag corresponding to the TagKey parameter. This is used to identify the instances where the CloudWatch agent and its configuration will be installed."
    },
    "CloudWatchAgentConfigSSM": {
      "Type": "AWS::SSM::Parameter::Name",
      "Description": "The name of the AWS Systems Manager Parameter Store parameter that contains the CloudWatch agent configuration to be installed on the targeted instances."
    }
  },
  "Conditions": {
    "HasCloudWatchAgentConfigSSM": {
      "Fn::Not": [
        {
          "Fn::Equals": [
            {
              "Ref": "CloudWatchAgentConfigSSM"
            },
            ""
          ]
        }
      ]
    },
    "IsTargetInstanceIds": {
      "Fn::Not": [
        {
          "Fn::Equals": [
            {
              "Fn::Join": [
                "",
                {
                  "Ref": "InstanceIds"
                }
              ]
            },
            ""
          ]
        }
      ]
    }
  },
  "Resources": {
    "InstallAndManageCloudWatchAgentDocument": {
      "Type": "AWS::SSM::Document",
      "Properties": {
        "DocumentFormat": "YAML",
        "Content": {
          "schemaVersion": "2.2",
          "description": "A composite document for installing and configuring the CloudWatch Agent.",
          "mainSteps": [
            {
              "action": "aws:runDocument",
              "name": "InstallCloudWatchAgent",
              "inputs": {
                "documentType": "SSMDocument",
                "documentPath": "AWS-ConfigureAWSPackage",
                "documentParameters": {
                  "action": "Install",
                  "name": "AmazonCloudWatchAgent"
                }
              }
            },
            {
              "action": "aws:runDocument",
              "name": "StopCloudWatchAgent",
              "inputs": {
                "documentType": "SSMDocument",
                "documentPath": "AmazonCloudWatch-ManageAgent",
                "documentParameters": {
                  "action": "stop",
                  "mode": "ec2"
                }
              }
            },
            {
              "action": "aws:runDocument",
              "name": "StartCloudWatchAgent",
              "inputs": {
                "documentType": "SSMDocument",
                "documentPath": "AmazonCloudWatch-ManageAgent",
                "documentParameters": {
                  "action": "configure",
                  "mode": "ec2",
                  "optionalRestart": "yes",
                  "optionalConfigurationSource": "ssm",
                  "optionalConfigurationLocation": {
                    "Fn::If": [
                      "HasCloudWatchAgentConfigSSM",
                      {
                        "Ref": "CloudWatchAgentConfigSSM"
                      },
                      ""
                    ]
                  }
                }
              }
            }
          ]
        },
        "DocumentType": "Command"
      }
    },
    "SystemAssociationForInstallAndConfigureCloudWatchAgent": {
      "Type": "AWS::SSM::Association",
      "Properties": {
        "Name": {
          "Ref": "InstallAndManageCloudWatchAgentDocument"
        },
        "AssociationName": "InstallAndManageCloudWatchAgent",
        "ScheduleExpression": "rate(30 days)",
        "Targets": {
          "Fn::If": [
            "IsTargetInstanceIds",
            [
              {
                "Key": "InstanceIds",
                "Values": {
                  "Ref": "InstanceIds"
                }
              }
            ],
            [
              {
                "Key": {
                  "Fn::Join": [
                    "",
                    [
                      "tag:",
                      {
                        "Ref": "TagKey"
                      }
                    ]
                  ]
                },
                "Values": [
                  {
                    "Ref": "TagValue"
                  }
                ]
              }
            ]
          ]
        }
      }
    }
  }
}