Deploy Gateways Via AWS Organizations With CloudFormation StackSets
Overview
Prerequisites
Procedure
Prepare CloudFormation templates
AWSTemplateFormatVersion: '2010-09-09'
Description: StrongDM self-registering gateway with VPC creation
Parameters:
# StrongDM variables
SDMListenPort:
Type: Number
Default: 5000
MinValue: 1024
MaxValue: 65535
Description: The TCP port that will be exposed to the internet
SDMAdminToken:
AllowedPattern: (.+)
Type: String
Description: Paste your StrongDM admin token to create the gateway
LatestAmiId:
Type: 'AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>'
Default: '/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2'
CommonVpcCIDR:
Type: String
MinLength: 9
MaxLength: 18
AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})"
ConstraintDescription: Must be a valid CIDR range in the form x.x.x.x/x
Default: 10.112.0.0/16
PublicACIDR:
Type: String
MinLength: 9
MaxLength: 18
AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})"
ConstraintDescription: Must be a valid CIDR range in the form x.x.x.x/x
Default: 10.112.0.0/22
PublicBCIDR:
Type: String
MinLength: 9
MaxLength: 18
AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})"
ConstraintDescription: Must be a valid CIDR range in the form x.x.x.x/x
Default: 10.112.4.0/22
PrivateACIDR:
Type: String
MinLength: 9
MaxLength: 18
AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})"
ConstraintDescription: Must be a valid CIDR range in the form x.x.x.x/x
Default: 10.112.12.0/22
PrivateBCIDR:
Type: String
MinLength: 9
MaxLength: 18
AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})"
ConstraintDescription: Must be a valid CIDR range in the form x.x.x.x/x
Default: 10.112.16.0/22
# Organization structure for parameters
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
-
Label:
default: "StrongDM Configuration"
Parameters:
- SDMAdminToken
- SDMListenPort
Resources:
VPC:
Type: "AWS::EC2::VPC"
Properties:
EnableDnsSupport: true
EnableDnsHostnames: true
CidrBlock: !Ref CommonVpcCIDR
Tags:
- Key: Name
Value: ACBL VPC
IGW:
Type: "AWS::EC2::InternetGateway"
GatewayAttach:
Type: "AWS::EC2::VPCGatewayAttachment"
Properties:
InternetGatewayId: !Ref IGW
VpcId: !Ref VPC
SubnetPublicSharedA:
Type: "AWS::EC2::Subnet"
Properties:
AvailabilityZone: !Select [0, !GetAZs ]
CidrBlock: !Ref PublicACIDR
MapPublicIpOnLaunch: true
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub "Public A - ${PublicACIDR}"
SubnetPublicSharedB:
Type: "AWS::EC2::Subnet"
Properties:
AvailabilityZone: !Select [1, !GetAZs ]
CidrBlock: !Ref PublicBCIDR
MapPublicIpOnLaunch: true
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub "Public B - ${PublicBCIDR}"
SubnetPrivateSharedA:
Type: "AWS::EC2::Subnet"
Properties:
AvailabilityZone: !Select [0, !GetAZs ]
CidrBlock: !Ref PrivateACIDR
MapPublicIpOnLaunch: false
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub "Private A - ${PrivateACIDR}"
SubnetPrivateSharedB:
Type: "AWS::EC2::Subnet"
Properties:
AvailabilityZone: !Select [1, !GetAZs ]
CidrBlock: !Ref PrivateBCIDR
MapPublicIpOnLaunch: false
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub "Private B - ${PrivateBCIDR}"
SubnetRouteTableAssociatePublicA:
Type: "AWS::EC2::SubnetRouteTableAssociation"
Properties:
RouteTableId: !Ref RouteTablePublic
SubnetId: !Ref SubnetPublicSharedA
SubnetRouteTableAssociatePublicB:
Type: "AWS::EC2::SubnetRouteTableAssociation"
Properties:
RouteTableId: !Ref RouteTablePublic
SubnetId: !Ref SubnetPublicSharedB
SubnetRouteTableAssociatePrivateA:
Type: "AWS::EC2::SubnetRouteTableAssociation"
Properties:
RouteTableId: !Ref RouteTablePrivate
SubnetId: !Ref SubnetPrivateSharedA
SubnetRouteTableAssociatePrivateB:
Type: "AWS::EC2::SubnetRouteTableAssociation"
Properties:
RouteTableId: !Ref RouteTablePrivate
SubnetId: !Ref SubnetPrivateSharedB
RouteDefaultPublic:
Type: "AWS::EC2::Route"
DependsOn: GatewayAttach
Properties:
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref IGW
RouteTableId: !Ref RouteTablePublic
RouteDefaultPrivate:
Type: "AWS::EC2::Route"
Properties:
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId: !Ref NatGateway
RouteTableId: !Ref RouteTablePrivate
RouteTablePublic:
Type: "AWS::EC2::RouteTable"
Properties:
VpcId: !Ref VPC
RouteTablePrivate:
Type: "AWS::EC2::RouteTable"
Properties:
VpcId: !Ref VPC
EIPNatGW:
DependsOn: GatewayAttach
Type: "AWS::EC2::EIP"
Properties:
Domain: vpc
NatGateway:
DependsOn: GatewayAttach
Type: "AWS::EC2::NatGateway"
Properties:
AllocationId: !GetAtt EIPNatGW.AllocationId
SubnetId: !Ref SubnetPublicSharedB
EC2SecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: "Expose StrongDM listening port"
VpcId: !Ref VPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: !Ref SDMListenPort
ToPort: !Ref SDMListenPort
CidrIp: 0.0.0.0/0
SDMGWONE:
Type: AWS::EC2::Instance
Properties:
InstanceType: t3.medium
Tags:
- Key: "Name"
Value: "StrongDM Gateway One"
NetworkInterfaces:
- DeviceIndex: '0'
SubnetId: !Ref SubnetPublicSharedA
AssociatePublicIpAddress: 'true'
DeleteOnTermination: 'true'
GroupSet: [!Ref EC2SecurityGroup]
ImageId: !Ref LatestAmiId
UserData:
Fn::Base64:
!Sub |
#!/bin/bash -xe
# set environment variables
mkdir -p /home/ec2-user/.sdm
touch /home/ec2-user/.sdm/sdm.log
export TARGET_USER=ec2-user
export SDM_LISTEN_PORT=${SDMListenPort}
export SDM_GATEWAY_NAME=AWS-CloudFormation-$(date +%s)
export SDM_HOSTNAME="$(curl http://169.254.169.254/latest/meta-data/public-hostname)"
export SDM_HOME="/home/ec2-user/.sdm"
# downloads sdm binary
yum update -y && yum install -y unzip curl
curl -J -O -L https://app.strongdm.com/releases/cli/linux && unzip sdmcli* && rm sdmcli*
# Generate a gateway token
export SDM_RELAY_TOKEN="$(./sdm --admin-token=${SDMAdminToken} relay create-gateway --name $SDM_GATEWAY_NAME $SDM_HOSTNAME:$SDM_LISTEN_PORT 0.0.0.0:$SDM_LISTEN_PORT)"
chown -R ec2-user:ec2-user /home/ec2-user/.sdm
# Install SDM
./sdm install --node --token=$SDM_RELAY_TOKEN --user $TARGET_USER
SDMGWTWO:
Type: AWS::EC2::Instance
Properties:
InstanceType: t3.medium
Tags:
- Key: "Name"
Value: "StrongDM Gateway TWO"
NetworkInterfaces:
- DeviceIndex: '0'
SubnetId: !Ref SubnetPublicSharedB
AssociatePublicIpAddress: 'true'
DeleteOnTermination: 'true'
GroupSet: [!Ref EC2SecurityGroup]
ImageId: !Ref LatestAmiId
UserData:
Fn::Base64:
!Sub |
#!/bin/bash -xe
# set environment variables
mkdir -p /home/ec2-user/.sdm
touch /home/ec2-user/.sdm/sdm.log
export TARGET_USER=ec2-user
export SDM_LISTEN_PORT=${SDMListenPort}
export SDM_GATEWAY_NAME=AWS-CloudFormation-$(date +%s)
export SDM_HOSTNAME="$(curl http://169.254.169.254/latest/meta-data/public-hostname)"
export SDM_HOME="/home/ec2-user/.sdm"
# downloads sdm binary
yum update -y && yum install -y unzip curl
curl -J -O -L https://app.strongdm.com/releases/cli/linux && unzip sdmcli* && rm sdmcli*
# Generate a gateway token
export SDM_RELAY_TOKEN="$(./sdm --admin-token=${SDMAdminToken} relay create-gateway --name $SDM_GATEWAY_NAME $SDM_HOSTNAME:$SDM_LISTEN_PORT 0.0.0.0:$SDM_LISTEN_PORT)"
chown -R ec2-user:ec2-user /home/ec2-user/.sdm
# Install SDM
./sdm install --node --token=$SDM_RELAY_TOKEN --user $TARGET_USER
Outputs:
VpcId:
Description: ID of the created VPC
Value: !Ref VPC
SecurityGroupId:
Description: Security Group ID for StrongDM gateway
Value: !GetAtt [ EC2SecurityGroup, GroupId ]Gather necessary parameters and input to deploy
Prepare IAM permissions
Create StackSets
Configure deployment options
Deploy StackSets
Validate deployment
Last updated
Was this helpful?

