{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Description": "Observability Solution from CloudWatch: Common CloudWatch Agent with Prometheus 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."
    },
    "PrometheusConfigSSM": {
      "Type": "AWS::SSM::Parameter::Name",
      "Description": "The name of the AWS Systems Manager Parameter Store parameter that contains the Prometheus 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:runShellScript",
              "name": "DownloadPrometheusConfigurationLinux",
              "precondition": {
                "StringEquals": [
                  "platformType",
                  "Linux"
                ]
              },
              "inputs": {
                "runCommand": [
                  "#!/bin/bash",
                  {
                    "Fn::Sub": "echo \"PrometheusConfigSSM value: '${PrometheusConfigSSM}'\""
                  },
                  {
                    "Fn::Sub": "config=$(aws ssm get-parameter --name ${PrometheusConfigSSM} --query 'Parameter.Value' --output text)"
                  },
                  "echo \"$config\" > /opt/aws/amazon-cloudwatch-agent/etc/prometheus.yaml",
                  "echo \"Copied Prometheus configuration into /opt/aws/amazon-cloudwatch-agent/etc/prometheus.yaml\""
                ]
              }
            },
            {
              "action": "aws:runPowerShellScript",
              "name": "DownloadPrometheusConfigurationWindows",
              "precondition": {
                "StringEquals": [
                  "platformType",
                  "Windows"
                ]
              },
              "inputs": {
                "runCommand": [
                  "$ErrorActionPreference = 'Stop'",
                  {
                    "Fn::Sub": "Write-Output \"PrometheusConfigSSM value is '$${PrometheusConfigSSM}'.\""
                  },
                  {
                    "Fn::Sub": "$config = (Get-SSMParameter -Name ${PrometheusConfigSSM}).Value"
                  },
                  "Write-Output \"Copying Prometheus configuration to C:\\ProgramData\\Amazon\\AmazonCloudWatchAgent\\prometheus.yaml.\"",
                  "Set-Content -Path \"C:\\ProgramData\\Amazon\\AmazonCloudWatchAgent\\prometheus.yaml\" -Value $config"
                ]
              }
            },
            {
              "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"
                  }
                ]
              }
            ]
          ]
        }
      }
    }
  }
}