AWS Configuration Files

This section provides the following required configuration files:

  • a CloudFormation template for deploying the Commander environment in AWS. You'll need to configure several parameters in the CloudFormation template based on the information in this guide. See CloudFormation Template below.
  • an IAM policy to use when defining the permissions that Commander will use to manage AWS. See AWS Policy below.

CloudFormation Template

Save the following text as a .template file and use it to deploy the Commander environment.

{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Description": "CFT to install Commander using an RDS instance",
        "Parameters": {
            "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."
            },
            "EC2SubnetId": {
                "Type": "AWS::EC2::Subnet::Id",
                "Description": "The SubnetId for the EC2 instance in your Virtual Private Cloud (VPC)",
                "ConstraintDescription": "Must be residing in the selected Virtual Private Cloud."
            },
            "IamInstanceProfile" : {
                "Type" : "String",
                "Default": "",
                "Description" : "The name of an instance profile or a reference to an AWS::IAM::InstanceProfile resource",
                "ConstraintDescription" : "Must be residing in the selected Virtual Private Cloud."
            },
            "RDSSubnetIds": {
                "Type": "List<AWS::EC2::Subnet::Id>",
                "Description": "The SubnetIds for the RDS instance in your Virtual Private Cloud (VPC)",
                "ConstraintDescription": "Must be residing in the selected Virtual Private Cloud."
            },
            "ALBSubnetIds": {
                "Type": "List<AWS::EC2::Subnet::Id>",
                "Description": "The SubnetIds for the Load Balancer instance in your Virtual Private Cloud (VPC)",
                "ConstraintDescription": "Must be residing in the selected Virtual Private Cloud."
            },
            "KeyName": {
                "Description": "Name of an existing EC2 KeyPair to enable RDP access to the instances",
                "Type": "AWS::EC2::KeyPair::KeyName",
                "ConstraintDescription": "must be the name of an existing EC2 KeyPair."
            },
            "DBUser": {
                "NoEcho": "true",
                "Description": "Username for SQL Server database access",
                "Type": "String",
                "MinLength": "1",
                "MaxLength": "16",
                "AllowedPattern": "[a-zA-Z][a-zA-Z0-9]*",
                "ConstraintDescription": "Must begin with a letter and contain only alphanumeric characters and be between 1 and 16 characters in length."
            },
            "DBPassword": {
                "NoEcho": "true",
                "Description": "Password for SQL Server database access",
                "Type": "String",
                "MinLength": "8",
                "MaxLength": "30",
                "AllowedPattern": "[a-zA-Z0-9]*",
                "ConstraintDescription": "Must contain only alphanumeric characters and be between 8 and 30 characters in length."
            },
            "DBAllocatedStorage": {
                "Default": "50",
                "Description": "The size of the database (Gb)",
                "Type": "Number",
                "MinValue": "10",
                "MaxValue": "16384",
                "ConstraintDescription": "must be between 10 and 16384GB."
            },
            "DBInstanceType": {
                "Description": "The database instance type",
                "Type": "String",
                "Default": "db.m5.large",
                "AllowedValues": [
                    "db.m5.large",
                    "db.m5.xlarge",
                    "db.m5.2xlarge",
                    "db.r4.large",
                    "db.r4.xlarge",
                    "db.r4.2xlarge"
                ],
                "ConstraintDescription": "must select a valid database instance type."
            },
            "EC2InstanceType": {
                "Description": "Commander EC2 instance type",
                "Type": "String",
                "Default": "t3.large",
                "AllowedValues": [
                    "t2.large",
                    "t3.large",
                    "m5.xlarge",
                    "c5.xlarge",
                    "c5.2xlarge"
                ],
                "ConstraintDescription": "must be a valid EC2 instance type."
            },
            "WebLocation": {
                "Description": " The IP address range that can be used to access EC2 instance via HTTPS",
                "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."
            },
            "RDPLocation": {
                "Description": "The IP address range that can be used to access EC2 instance via RDP",
                "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."
            },
            "CertificateARN": {
                "Description": "Certificate ARN in AWS in the form of arn:aws:acm:us-west-2:XXXXXXXXXX:certificate/XXXXXX-XXXX-XXXX-XXXX-XXXXXXXXX",
                "Type": "String",
                "ConstraintDescription": "Certificate ARN must be provided"
            }
        },
        "Mappings": {
            "AWSRegion2AMI": {
                "us-east-1": {
                    "AMI": "ami-0bf148826ef491d16"
                },
                "us-east-2": {
                    "AMI": "ami-08b4a0f6e106c1dba"
                },
                "us-west-1": {
                    "AMI": "ami-0f825806081c4725c"
                },
                "us-west-2": {
                    "AMI": "ami-0af80d239cc063c12"
                }
            }
        },
        "Resources": {
            "WebSecurityGroup": {
                "Type": "AWS::EC2::SecurityGroup",
                "Properties": {
                "GroupDescription": "Enable HTTPS and RDP access via port 443,3389",
                "SecurityGroupIngress": [
                    {
                        "IpProtocol": "tcp",
                        "FromPort": "443",
                        "ToPort": "443",
                        "CidrIp": {
                            "Ref": "WebLocation"
                        }
                    },
                    {
                        "IpProtocol": "tcp",
                        "FromPort": "3389",
                        "ToPort": "3389",
                        "CidrIp": {
                            "Ref": "RDPLocation"
                        }
                    }
                ],
                "VpcId": {
                    "Ref": "VpcId"
                }
                }
            },
            "EC2InstanceOne": {
                "Type": "AWS::EC2::Instance",
                "Properties": {
                    "ImageId": {
                        "Fn::FindInMap": [
                            "AWSRegion2AMI",
                            {
                            "Ref": "AWS::Region"
                            },
                            "AMI"
                        ]
                    },
                    "Tenancy": "default",
                    "InstanceType": {
                        "Ref": "EC2InstanceType"
                    },
                    "KeyName": {
                        "Ref": "KeyName"
                    },
                    "NetworkInterfaces": [
                        {
                            "AssociatePublicIpAddress": true, 
                            "DeleteOnTermination": true,
                            "DeviceIndex": "0",
                            "SubnetId": {
                                "Ref": "EC2SubnetId"
                            },
                            "GroupSet": [
                                "Ref": "WebSecurityGroup"    
                            ]
                        }
                    ],
                    "IamInstanceProfile": {
                        "Ref": "IamInstanceProfile"
                    },
                    "Tags": [
                        {
                            "Key": "Name",
                            "Value": "Commander"
                        }
                    ]
                },
                "DependsOn": [
                    "SQLServerDatabase"
                ]
            },
            "DBEC2SecurityGroup": {
                "Type": "AWS::EC2::SecurityGroup",
                "Properties": {
                    "GroupDescription": "Open database for access",
                    "SecurityGroupIngress": [
                        {
                            "IpProtocol": "tcp",
                            "FromPort": "1433",
                            "ToPort": "1433",
                            "SourceSecurityGroupId": {
                                "Ref": "WebSecurityGroup"
                            }
                        }
                    ],
                    "VpcId": {
                        "Ref": "VpcId"
                    }
                }
            },
            "SQLServerDatabase": {
                "Type": "AWS::RDS::DBInstance",
                "Properties": {
                    "Engine": "sqlserver-se",
                    "EngineVersion": "14.00.3035.2.v1",
                    "LicenseModel": "license-included",
                    "Iops": "1000",
                    "StorageType": "io1",
                    "MultiAZ": "true",
                    "MasterUsername": {
                        "Ref": "DBUser"
                    },
                    "MasterUserPassword": {
                        "Ref": "DBPassword"
                    },
                    "DBInstanceClass": {
                        "Ref": "DBInstanceType"
                    },
                    "AllocatedStorage": {
                        "Ref": "DBAllocatedStorage"
                    },
                    "VPCSecurityGroups": [
                        {
                                "Fn::GetAtt": [
                                    "DBEC2SecurityGroup",
                                    "GroupId"
                            ]
                        }
                    ],
                    "DBSubnetGroupName": {
                        "Ref": "DbSubnetGroup"
                    },
                    "Tags": [
                        {
                            "Key": "Name",
                            "Value": "Commander-DB"
                            }
                        ]
                    }
                },
                "DbSubnetGroup": {
                    "Type": "AWS::RDS::DBSubnetGroup",
                    "Properties": {
                    "DBSubnetGroupDescription": "Subnets available for the RDS DB Instance",
                    "SubnetIds": {
                        "Ref": "RDSSubnetIds"
                    }
                }
            },
            "ElasticLoadBalancer": {
                "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer",
                "Properties": {
                    "Scheme": "internet-facing",
                    "Name": {
                        "Fn::Join": [
                            "-",
                            [
                                {
                                    "Ref": "AWS::StackName"
                                },
                                "LoadBalancer"
                            ]
                        ]
                    },
                    "Subnets": {
                        "Ref": "ALBSubnetIds"
                    },
                    "SecurityGroups": [
                        {
                            "Ref": "WebSecurityGroup"
                        }
                    ]
                },
                "DependsOn": [
                    "EC2InstanceOne"
                ]
            },
            "TargetGroupService": {
                "Type": "AWS::ElasticLoadBalancingV2::TargetGroup",
                "Properties": {
                    "Targets": [
                        {
                            "Id": {
                                "Ref": "EC2InstanceOne"
                            },
                            "Port": "443"
                        }
                    ],

                    "Name": {
                        "Fn::Join": [
                            "-",
                            [
                                {
                                    "Ref": "AWS::StackName"
                                },
                                "TgtGrpSrv"
                            ]
                        ]
                    },
                    "Port": "443",
                    "Protocol": "HTTPS",
                    "HealthCheckPath": "/webservices/services/rest/v2/active",
                    "VpcId": {
                        "Ref": "VpcId"
                    }
                },
                "DependsOn": [
                    "EC2InstanceOne"
                ]
            },
            "Listener": {
                "Type": "AWS::ElasticLoadBalancingV2::Listener",
                "Properties": {
                    "DefaultActions": [
                        {
                            "Type": "forward",
                            "TargetGroupArn": {
                                "Ref": "TargetGroupService"
                            }
                        }
                    ],
                    "LoadBalancerArn": {
                        "Ref": "ElasticLoadBalancer"
                    },
                    "Port": "443",
                    "Protocol": "HTTPS",
                    "Certificates": [
                        {
                            "CertificateArn": {
                                "Ref": "CertificateARN"
                            }
                        }
                    ]
                },
                "DependsOn": [
                    "EC2InstanceOne"
                ]
            },
        "ListenerRuleService": {
            "Type": "AWS::ElasticLoadBalancingV2::ListenerRule",
            "Properties": {
                    "Actions": [
                        {
                            "TargetGroupArn": {
                                "Ref": "TargetGroupService"
                            },
                            "Type": "forward"
                        }
                    ],
                    "Conditions": [
                     {
                      "Field": "path-pattern",
                      "Values": [
                            "/"
                      ]
                  }
                    ],

                    "ListenerArn": {
                        "Ref": "Listener"
                    },
                    "Priority": 1
                },
                "DependsOn": [
                 "EC2InstanceOne"
                ]
            }
        },
        "Outputs": {
            "CommanderURL": {
                "Description": "URL for Commander UI",
                "Value": {
                    "Fn::Join": [
                        "",
                        [
                            "https://",
                            {
                            "Fn::GetAtt": [
                                "ElasticLoadBalancer",
                                "DNSName"
                            ]
                            }
                        ]
                    ]
            }
        }
    }
}

  

AWS Policy

Paste this text when creating a policy for the IAM role.

Copy
{
    "Version": "2012-10-17",
    "Statement": [{
"Sid": "EmboticsCommanderReadOnlyPolicyForInventory",
"Action": [
"ec2:DescribeRegions",
"ec2:DescribeAvailabilityZones",
"ec2:DescribeVpcs",
"ec2:DescribeSecurityGroups",
"ec2:DescribeSubnets",
"ec2:DescribeInstances",
"ec2:DescribeInstanceStatus",
"ssm:DescribeInstanceInformation",
"ec2:DescribeImages",
"ec2:DescribeKeyPairs",
"ec2:DescribeVolumes",
"ec2:DescribeSnapshots",
"ec2:DescribeReservedInstances",
"ec2:DescribeAccountAttributes",
"elasticloadbalancing:DescribeLoadBalancers",
"elasticloadbalancing:DescribeInstanceHealth",
"elasticloadbalancing:DescribeTargetGroups",
"rds:DescribeDBInstances",
"autoscaling:DescribeAutoScalingGroups",
"cloudformation:DescribeStacks",
"cloudformation:DescribeStackEvents",
"cloudformation:DescribeStackResources",
"cloudformation:ValidateTemplate",
"cloudformation:EstimateTemplateCost",
"ce:GetReservationCoverage",
"ce:GetReservationUtilization",
"ce:GetReservationPurchaseRecommendation",
"sts:GetCallerIdentity"
        ],
        "Effect": "Allow",
        "Resource": "*"
}, {
"Sid": "EmboticsCommanderReadOnlyPolicyOptional",
"Action": [
"ec2:DescribeTags",
"elasticloadbalancing:DescribeTags",
"autoscaling:DescribeTags",
"rds:ListTagsForResource",
"cloudwatch:GetMetricStatistics",
"s3:ListBucket",
"s3:GetObject"
],
"Effect": "Allow",
"Resource": "*"
}, {
"Sid": "EmboticsCommanderWritePolicyForOperations",
"Action": [
"ec2:RunInstances",
"ec2:StartInstances",
"ec2:StopInstances",
"ec2:RebootInstances",
"ec2:TerminateInstances",
"ec2:ModifyInstanceAttribute",
"ec2:DeregisterImage",
"ec2:CreateKeyPair",
"ec2:ImportKeyPair",
"ec2:DeleteKeyPair",
"ec2:AttachVolume",
"ec2:DetachVolume",
"ec2:CreateVolume",
"ec2:DeleteVolume",
"ec2:CreateTags",
"ec2:DeleteTags",
"ec2:GetPasswordData",
"elasticloadbalancing:AddTags",
"elasticloadbalancing:RemoveTags",
"autoscaling:DeleteAutoScalingGroup",
"autoscaling:CreateOrUpdateTags",
"autoscaling:DeleteTags",
"rds:RebootDBInstance",
"rds:DeleteDBInstance",
"rds:AddTagsToResource",
"rds:RemoveTagsFromResource",
"cloudformation:CreateStack",
"cloudformation:UpdateStack",
"cloudformation:DeleteStack"
],
"Effect": "Allow",
"Resource": "*"
},{
"Sid": "EmboticsCommanderPolicyForAssumeRole",
"Action": [
"sts:AssumeRole"
],
"Effect": "Allow",
"Resource": "*"
    }]
}