

{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Description": "AWS CloudFormation Template for the USM Anywhere Sensor. This template will create an instance of the USM Anywhere Sensor AMI with appropriate security restrictions. The AMI will create a read-only instance role. You can access the USM Sensor by going to the CloudFormation Template Resource tab and clicking the link in the URL field that directs you to the AWS Console Instance details page. Then, from the lower instance Description tab, enter the IP address of the instance your browser.",
    "Conditions": {
        "trafficMirroringEnabled": {
            "Fn::Equals": [
                "Yes",
                { "Ref": "TrafficMirroring" }
            ]
        },
        "publicIPEnabled": {
            "Fn::Equals": [
                "Yes",
                { "Ref": "PublicIP" }
            ]
        },
        "staticIPEnabled": {
            "Fn::Equals": [
                "Static",
                { "Ref": "IPAssignmentType" }
            ]
        }
    },
    "Parameters":
    {
        "SSHLocation":
        {
            "Description": "The IP address range that can be used to access the USM Anywhere Sensor that you are deploying in your AWS Account through the CLI. For security considerations, 0.0.0.0/0 is not recommended, so please restrict to a smaller IP range if possible.",
            "Type": "String",
            "MinLength": "9",
            "MaxLength": "18",
            "Default": "0.0.0.0/0",
            "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
            "ConstraintDescription": "Must be a valid IP CIDR range of the form x.x.x.x/x."
        },
        "KeyName":
        {
            "Description": "Name of an existing EC2 key pair to enable SSH access to your USM Anywhere Sensor",
            "Type": "AWS::EC2::KeyPair::KeyName",
            "ConstraintDescription": "Must be the name of an existing EC2 KeyPair."
        },
        "APITermination":
        {
            "Description": "API termination protection",
            "Type": "String",
            "Default": "true",
            "AllowedValues": [
                "false",
                "true"
            ]
        },
        "HTTPLocation": {
            "Description": "The IP address range that can be used to access the USM Anywhere Sensor that you are deploying in your AWS Account through the UI. For security considerations, 0.0.0.0/0 is not recommended, so please restrict to a smaller IP range if possible.",
            "Type": "String",
            "MinLength": "9",
            "MaxLength": "18",
            "Default": "0.0.0.0/0",
            "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
            "ConstraintDescription": "Must be a valid IP CIDR range of the form x.x.x.x/x."
        },
        "PublicIP": {
            "AllowedValues": [
                "Yes",
                "No"
            ],
            "Default": "No",
            "Description": "If you choose to deploy your sensor with a public IP address, the subnet you select must have 'Auto-assign public IPv4 address' enabled.",
            "Type": "String"
        },
        "VpcId":
        {
            "Type": "AWS::EC2::VPC::Id",
            "Description": "VpcId of your existing Virtual Private Cloud (VPC).",
            "ConstraintDescription": "Must be the VPC Id of an existing Virtual Private Cloud."
        },
        "SubnetId":
        {
            "Type": "AWS::EC2::Subnet::Id",
            "Description": "SubnetId of an existing subnet (for the primary network) in your Virtual Private Cloud (VPC).",
            "ConstraintDescription": "Must be an existing subnet in the selected Virtual Private Cloud."
        },
        "TrafficMirroring": {
            "AllowedValues": [
                "Yes",
                "No"
            ],
            "Default": "No",
            "Description": "Whether or not deploy the USM Anywhere sensor ready to use traffic mirroring. This option will deploy a m5.xlarge and a second network interface.",
            "Type": "String"
        },
        "IPAssignmentType": {
            "AllowedValues": [
                "DHCP",
                "Static"
            ],
            "Default": "DHCP",
            "Description": "Choose how to assign the private IP address to the sensor. DHCP will automatically assign an IP from the subnet range. Static allows you to specify a fixed IP address.",
            "Type": "String"
        },
        "StaticPrivateIP": {
            "Description": "Static private IP address for the sensor (only used when IP Assignment Type is set to Static). Must be within the selected subnet's CIDR range and available.",
            "Type": "String",
            "Default": "",
            "AllowedPattern": "^$|(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$",
            "ConstraintDescription": "Must be a valid IP address (e.g., 10.0.1.100) or leave empty for DHCP."
        },
        
        
        "NodeName":
        {
            "Description": "Please provide a name for this USM Anywhere Sensor.",
            "Type": "String",
            "MinLength": "1",
            "MaxLength": "63",
            "AllowedPattern": "^[a-zA-Z0-9](([a-zA-Z0-9\\-]*[a-zA-Z0-9]+)*)$",
            "ConstraintDescription": "It has to be a valid hostname according to RFC 1123: It can only contain numbers, letters, and dashes up to 63 characters."
        }
    },
    "Metadata":
    {
        "AWS::CloudFormation::Interface" :
        {
            "ParameterGroups" : [
                {
                    "Label"      : { "default" : "AlienVault Node Settings" },
                    "Parameters" : [ "NodeName", "KeyName", "TrafficMirroring" ]
                },
                {
                    "Label"      : { "default" : "Network Settings" },
                    "Parameters" : [ "VpcId", "SubnetId", "IPAssignmentType", "StaticPrivateIP", "PublicIP" ]
                },
                {
                    "Label"      : { "default" : "Security Settings" },
                    "Parameters" : [ "HTTPLocation", "SSHLocation", "APITermination" ]
                }
            ],
            "ParameterLabels" :
            {
                "NodeName"         : { "default" : "USM Anywhere Sensor Name" },
                "APITermination"   : { "default" : "API Termination Protection" },
                "KeyName"          : { "default" : "Key Name" },
                "VpcId"            : { "default" : "VPC ID" },
                "SubnetId"         : { "default" : "Subnet ID" },
                "IPAssignmentType" : { "default" : "IP Assignment Type" },
                "StaticPrivateIP"  : { "default" : "Static Private IP Address" },
                "PublicIP"         : { "default" : "Deploy Public IP" },
                "HTTPLocation"     : { "default" : "HTTP Access Range" },
                "SSHLocation"      : { "default" : "SSH Access Range" },
                "TrafficMirroring" : { "default" : "Traffic Mirroring Mode" },
                "Environment"      : { "default" : "Deployment Environment" }
            }
        }
    },
    "Mappings":
    {
        "RegionMap": {
    "us-gov-west-1": {
        "AMI": "ami-01c6b0c48c84ccd11"
    }
}
    },
    "Resources":
    {
        "USMInstance": {
            "Type": "AWS::EC2::Instance",
            "Metadata": {},
            "DependsOn" : [
                
                "USMConnectionSG",
                "USMLogServicesSG"
            ],
            "Properties":
            {
                "BlockDeviceMappings": [
                    {
                        "DeviceName": "/dev/sda1",
                        "Ebs": {
                            "VolumeType": "gp3",
                            "VolumeSize": "50",
                            "DeleteOnTermination": "true",
                            "Encrypted": "true"
                        }
                    }
                ],
                "NetworkInterfaces" : [
                    {
                        "AssociatePublicIpAddress": {
                            "Fn::If": [
                                "publicIPEnabled",
                                "true",
                                "false"
                            ]
                        },
                        "DeviceIndex": "0",
                        "GroupSet": [
                            
                            {
                                "Ref": "USMConnectionSG"
                            },
                            {
                                "Ref": "USMLogServicesSG"
                            }
                        ],
                        "SubnetId": { "Ref" : "SubnetId" },
                        "PrivateIpAddress": {
                            "Fn::If": [
                                "staticIPEnabled",
                                { "Ref": "StaticPrivateIP" },
                                { "Ref": "AWS::NoValue" }
                            ]
                        }
                    }
                ],
                "InstanceType": {
                    "Fn::If": [
                        "trafficMirroringEnabled",
                        "m5.xlarge",
                        "m5.large"
                    ]
                },
                "KeyName":
                {
                    "Ref": "KeyName"
                },
                "ImageId": {
                    "Fn::FindInMap":
                    [
                        "RegionMap",
                        {
                            "Ref": "AWS::Region"
                        },
                        "AMI"
                    ]
                },
                "IamInstanceProfile": {
                    "Ref": "USMInstanceProfile"
                },
                "UserData": {
                    "Fn::Base64": {
                        "Fn::Join": [
                            "",
                            [
                                "{",
                                "\"nodeName\"     :\"",  { "Ref" : "NodeName" }, "\",",
                                
                                "\"environment\"  :\"prod-gov\",",
                                
                                "\"av_profile\"   :\"sensor\",",
                                "\"version\"   :\"2.0\",",
                                "\"av_resources\" :\"wyns\"",
                                "}"
                            ]
                        ]
                    }
                },
                "MetadataOptions": {
                    "HttpTokens": "required",
                    "HttpEndpoint": "enabled"
                },
                "DisableApiTermination":
                {
                    "Ref": "APITermination"
                },
                "Tags": [
                    {
                        "Key": "Name",
                        "Value": {
                            "Ref": "AWS::StackName"
                        }
                    }
                ]
            }
        },
        "ReadOnlyRoleWithCloudTrailManagement": {
            "Type": "AWS::IAM::Role",
            "Properties": {
                "AssumeRolePolicyDocument": {
                    "Version": "2012-10-17",
                    "Statement": [
                        {
                            "Effect": "Allow",
                            "Principal": {
                                "Service": [
                                    "ec2.amazonaws.com"
                                ]
                            },
                            "Action": [
                                "sts:AssumeRole"
                            ]
                        }
                    ]
                },
                "Path": "/",
                "Policies": [
                    {
                        "PolicyName": "ReadOnlyPolicyWithCloudTrailManagement",
                        "PolicyDocument": {
                            "Version": "2012-10-17",
                            "Statement": [
                                {
                                    "Action": [
                                        "guardduty:Get*",
                                        "guardduty:List*",
                                        "cloudtrail:Describe*",
                                        "cloudtrail:Get*",
                                        "cloudtrail:List*",
                                        "cloudwatch:Describe*",
                                        "cloudwatch:Get*",
                                        "cloudwatch:List*",
                                        "logs:Describe*",
                                        "logs:Get*",
                                        "logs:TestMetricFilter",
                                        "ec2:Describe*",
                                        "elasticloadbalancing:Describe*",
                                        "iam:List*",
                                        "iam:Get*",
                                        "rds:Describe*",
                                        "s3:Get*",
                                        "s3:List*",
                                        "tag:GetTagValues",
                                        "ec2:AttachVolume",
                                        "ec2:DetachVolume"
                                    ],
                                    "Effect": "Allow",
                                    "Resource": "*"
                                }
                            ]
                        }
                    }
                ]
            }
        },
        "USMInstanceProfile": {
            "Type": "AWS::IAM::InstanceProfile",
            "Properties": {
                "Path": "/",
                "Roles": [
                    {
                        "Ref": "ReadOnlyRoleWithCloudTrailManagement"
                    }
                ]
            }
        },
        "TrafficInterface" : {
          "Condition": "trafficMirroringEnabled",
          "Type" : "AWS::EC2::NetworkInterface",
          "Properties" : {
            "SubnetId" : { "Ref" : "SubnetId" },
            "Description" :"Interface for VPC Traffic Mirroring",
            "GroupSet" : [ {"Ref" : "USMTrafficInterfaceSG"} ],
            "SourceDestCheck" : "true"
          },
          "DependsOn" : [
            "USMTrafficInterfaceSG"
          ]
        },
        "NetworkInterfaceAttachment" : {
            "Condition": "trafficMirroringEnabled",
            "Type" : "AWS::EC2::NetworkInterfaceAttachment",
            "Properties" : {
                "InstanceId" : {"Ref" : "USMInstance"},
                "NetworkInterfaceId" : {"Ref" : "TrafficInterface"},
                "DeviceIndex" : "1"
            },
            "DependsOn" : [
                "TrafficInterface",
                "USMInstance"
            ]
        },
        "USMEnableLogServicesSG": {
            "Type": "AWS::EC2::SecurityGroup",
            "Properties": {
                "VpcId": {
                    "Ref": "VpcId"
                },
                "GroupDescription": "Enable USM Log Services. Assign this Security Group to the instance you want to allow Syslog UDP/TCP/TLS and Graylog connectivity to your USM Sensor."
            }
        },
        "USMEnableTrafficMirroringSG": {
            "Type": "AWS::EC2::SecurityGroup",
            "Properties": {
                "VpcId": {
                    "Ref": "VpcId"
                },
                "GroupDescription": "Enable USM Traffic Mirroring. Assign this Security Group to the instance you want to allow Traffic Mirroring connectivity to your USM Sensor Traffic Network Interface."
            }
        },
        "USMTrafficInterfaceSG": {
            "Condition": "trafficMirroringEnabled",
            "Type": "AWS::EC2::SecurityGroup",
            "Properties": {
                "VpcId": {
                    "Ref": "VpcId"
                },
                "GroupDescription": "Enable USM Traffic Mirror Connectivity on your USM Sensor Traffic Network Interface."
            }
        },
        "SGAllowVXLanTrafficSG": {
            "Condition": "trafficMirroringEnabled",
            "DependsOn": "USMTrafficInterfaceSG",
            "Type": "AWS::EC2::SecurityGroupIngress",
            "Properties": {
                "GroupId": {
                    "Fn::GetAtt": [
                        "USMTrafficInterfaceSG",
                        "GroupId"
                    ]
                },
                "IpProtocol": "udp",
                "FromPort": "4789",
                "ToPort": "4789",
                "SourceSecurityGroupId": {
                    "Fn::GetAtt": [
                        "USMEnableTrafficMirroringSG",
                        "GroupId"
                    ]
                }
            }
        },

        "USMConnectionSG": {
            "Type": "AWS::EC2::SecurityGroup",
            "Properties": {
                "VpcId": {
                    "Ref": "VpcId"
                },
                "GroupDescription": "Enable SSH and HTTP connectivity on your USM Sensor Instance."
            }
        },
        "SGIngressHTTPUSMConnectionSG": {
            "DependsOn": "USMConnectionSG",
            "Type": "AWS::EC2::SecurityGroupIngress",
            "Properties": {
                "GroupId": {
                    "Fn::GetAtt": [
                        "USMConnectionSG",
                        "GroupId"
                    ]
                },
                "IpProtocol": "tcp",
                "FromPort": "80",
                "ToPort": "80",
                "CidrIp": {
                    "Ref": "HTTPLocation"
                }
            }
        },
        "SGIngressSSHUSMConnectionSG": {
            "DependsOn": "SGIngressHTTPUSMConnectionSG",
            "Type": "AWS::EC2::SecurityGroupIngress",
            "Properties": {
                "GroupId": {
                    "Fn::GetAtt": [
                        "USMConnectionSG",
                        "GroupId"
                    ]
                },
                "IpProtocol": "tcp",
                "FromPort": "22",
                "ToPort": "22",
                "CidrIp": {
                    "Ref": "SSHLocation"
                }
            }
        },
        "USMLogServicesSG": {
            "Type": "AWS::EC2::SecurityGroup",
            "Properties": {
                "VpcId": {
                    "Ref": "VpcId"
                },
                "GroupDescription": "Enable Syslog UDP/TCP/TLS and Graylog connectivity in your USM Sensor Instance."
            }
        },
        "SGIngressSyslogUSMLogServicesSG": {
            "DependsOn": "USMLogServicesSG",
            "Type": "AWS::EC2::SecurityGroupIngress",
            "Properties": {
                "GroupId": {
                    "Fn::GetAtt": [
                        "USMLogServicesSG",
                        "GroupId"
                    ]
                },
                "IpProtocol": "udp",
                "FromPort": "514",
                "ToPort": "514",
                "SourceSecurityGroupId": {
                    "Fn::GetAtt": [
                        "USMEnableLogServicesSG",
                        "GroupId"
                    ]
                }
            }
        },
        "SGIngressTCPSyslogUSMLogServicesSG": {
            "DependsOn": "USMLogServicesSG",
            "Type": "AWS::EC2::SecurityGroupIngress",
            "Properties": {
                "GroupId": {
                    "Fn::GetAtt": [
                        "USMLogServicesSG",
                        "GroupId"
                    ]
                },
                "IpProtocol": "tcp",
                "FromPort": "601",
                "ToPort": "602",
                "SourceSecurityGroupId": {
                    "Fn::GetAtt": [
                        "USMEnableLogServicesSG",
                        "GroupId"
                    ]
                }
            }
        },
        "SGIngressTLSSyslogUSMLogServicesSG": {
            "DependsOn": "USMLogServicesSG",
            "Type": "AWS::EC2::SecurityGroupIngress",
            "Properties": {
                "GroupId": {
                    "Fn::GetAtt": [
                        "USMLogServicesSG",
                        "GroupId"
                    ]
                },
                "IpProtocol": "tcp",
                "FromPort": "6514",
                "ToPort": "6515",
                "SourceSecurityGroupId": {
                    "Fn::GetAtt": [
                        "USMEnableLogServicesSG",
                        "GroupId"
                    ]
                }
            }
        },
        "SGIngressGraylogUSMLogServicesSG": {
            "DependsOn": "USMLogServicesSG",
            "Type": "AWS::EC2::SecurityGroupIngress",
            "Properties": {
                "GroupId": {
                    "Fn::GetAtt": [
                        "USMLogServicesSG",
                        "GroupId"
                    ]
                },
                "IpProtocol": "udp",
                "FromPort": "12201",
                "ToPort": "12201",
                "SourceSecurityGroupId": {
                    "Fn::GetAtt": [
                        "USMEnableLogServicesSG",
                        "GroupId"
                    ]
                }
            }
        },
        "IngressTCPNXLogUSMSG": {
            "DependsOn": "USMLogServicesSG",
            "Type": "AWS::EC2::SecurityGroupIngress",
            "Properties": {
                "GroupId": {
                    "Fn::GetAtt": [
                        "USMLogServicesSG",
                        "GroupId"
                    ]
                },
                "IpProtocol": "tcp",
                "FromPort": "5986",
                "ToPort": "5986",
                "SourceSecurityGroupId": {
                    "Fn::GetAtt": [
                        "USMEnableLogServicesSG",
                        "GroupId"
                    ]
                }
            }
        },
        "IngressTCPSyslogWECUSMSG": {
            "DependsOn": "USMLogServicesSG",
            "Type": "AWS::EC2::SecurityGroupIngress",
            "Properties": {
                "GroupId": {
                    "Fn::GetAtt": [
                        "USMLogServicesSG",
                        "GroupId"
                    ]
                },
                "IpProtocol": "tcp",
                "FromPort": "5987",
                "ToPort": "5987",
                "SourceSecurityGroupId": {
                    "Fn::GetAtt": [
                        "USMEnableLogServicesSG",
                        "GroupId"
                    ]
                }
            }
        },
        
        "DataStorage": {
            "Type": "AWS::EC2::Volume",
            "DeletionPolicy": "RetainExceptOnCreate",
            "DependsOn": "USMInstance",
            "Properties": {
                "VolumeType": "gp3",
                "Size": "128",
                "Encrypted": "true",
                "AvailabilityZone": {
                    "Fn::GetAtt": [
                        "USMInstance",
                        "AvailabilityZone"
                    ]
                },
                "Tags":[
                  { "Key": "USMInstanceId", "Value": { "Ref": "USMInstance" }},
                  {
                    "Key": "Name",
                    "Value": {
                        "Ref": "AWS::StackName"
                    }
                }
                ]
            }
        }
    },
    "Outputs": {
        "URL": {
            "Value": {
                "Fn::If": [
                    "publicIPEnabled",
                    {
                        "Fn::Join": [
                            "",
                            [
                                "http://",
                                {
                                    "Fn::GetAtt": [
                                        "USMInstance",
                                        "PublicIp"
                                    ]
                                }
                            ]
                        ]
                    },
                    {
                        "Fn::Join": [
                            "",
                            [
                                "http://console.amazonaws-us-gov.com/ec2/home?region=",
                                {
                                    "Ref": "AWS::Region"
                                },
                                "#Instances:search=",
                                {
                                    "Ref": "USMInstance"
                                }
                            ]
                        ]
                    }
                ]
            },
            "Description": "Visit this page to perform the initial configuration of your USM Anywhere Sensor."
        },
        "CLIUser": {
            "Description": "Default Command Line Interface User.",
            "Value": "sysadmin"
        },
        "CLIUserKey": {
            "Description": "Default Command Line Interface User SSH key.",
            "Value": {
                "Ref": "KeyName"
            }
        },
        "InstanceZone": {
            "Description": "Availability Zone where the instance is deployed.",
            "Value": {
                "Fn::GetAtt": [
                    "USMInstance",
                    "AvailabilityZone"
                ]
            }
        },
        "AssignedPrivateIP": {
            "Description": "Private IP address assigned to the USM Sensor instance.",
            "Value": {
                "Fn::GetAtt": [
                    "USMInstance",
                    "PrivateIp"
                ]
            }
        },
        "IPAssignmentMethod": {
            "Description": "Method used for IP assignment (DHCP or Static).",
            "Value": {
                "Ref": "IPAssignmentType"
            }
        }
    }
}