--- AWSTemplateFormatVersion: 2010-09-09 Description: >- Cisco Systems Duo Network Gateway (existing VPC). This template deploys a Duo Network Gateway cluster into an existing VPC with a Multi-AZ active-active Auto Scaling group using a Redis cluster for shared state. See the Quick Start documentation for more details. **WARNING** You will be billed for the On-Demand instances and related AWS resources if you create a stack from this template. (qs-1qtp7fd41) Metadata: QuickStartDocumentation: EntrypointName: "Launch into an existing VPC" 'AWS::CloudFormation::Interface': ParameterGroups: - Label: default: VPC Network configuration Parameters: - VPCCIDR - VPCID - PublicSubnet1ID - PublicSubnet2ID - PrivateSubnet1ID - PrivateSubnet2ID - Label: default: Duo Network Gateway configuration Parameters: - ACMSSLCertificateArn - AdminServerInstanceType - AdminServerRemoteAccessCIDR - AdminServerSubdomain - AuthToken - ConfigYAMLPath - DomainName - HostedZoneID - KeyPairName - NumReplicas - NumShards - PortalServerInstanceType - PortalServerName - PortalServerRemoteAccessCIDR - PortalServerSubdomain - RedisCacheNodeType - RedisEngineVersion - SnapshotName - SnapshotRetentionLimit - Label: default: AWS Quick Start configuration Parameters: - QSS3BucketName - QSS3BucketRegion - QSS3KeyPrefix ParameterLabels: VPCCIDR: default: VPC CIDR VPCID: default: 'ID of the VPC' PublicSubnet1ID: default: Public subnet 1 ID for application load balancer PublicSubnet2ID: default: Public subnet 2 ID for application load balancer PrivateSubnet1ID: default: Private subnet 1 ID for Duo Network Gateway servers PrivateSubnet2ID: default: Private subnet 2 ID for Duo Network Gateway servers QSS3BucketName: default: Quick Start S3 bucket name QSS3BucketRegion: default: Quick Start S3 bucket Region QSS3KeyPrefix: default: Quick Start S3 key prefix ACMSSLCertificateArn: default: 'ARN of the load balancer''s SSL certificate' AdminServerInstanceType: default: Admin server EC2 instance type AdminServerRemoteAccessCIDR: default: Allowed CIDR block for external access to the load balancer AdminServerSubdomain: default: 'Subdomain for the admin server' AuthToken: default: Auth token for the Redis cluster ConfigYAMLPath: default: S3 bucket path of the Duo Network Gateway config file DomainName: default: 'Fully qualified domain name for the Duo Network Gateway load balancer' HostedZoneID: default: 'Route 53-hosted zone ID of the domain name' KeyPairName: default: Name of an existing EC2 key pair NumReplicas: default: Number of replicas per shard in Redis replication group NumShards: default: Number of shards in the cluster PortalServerInstanceType: default: Portal server EC2 instance type PortalServerName: default: Name tag of portal server PortalServerRemoteAccessCIDR: default: Allowed CIDR block for external access to load balancer PortalServerSubdomain: default: 'Subdomain for portal server' RedisCacheNodeType: default: Type of Redis cache node RedisEngineVersion: default: Redis replication group version SnapshotName: default: (Optional) Redis snapshot name SnapshotRetentionLimit: default: Redis snapshot retention limit Parameters: ACMSSLCertificateArn: Default: '' Description: 'Amazon Resource Name (ARN) of the load balancer''s SSL certificate. If you don''t provide values for DomainName and HostedZoneID, provide a value for ACMSSLCertificateArn.' Type: String AdminServerInstanceType: AllowedValues: - t3.micro - t3.small - t3.medium - t3.large - m5.large - m5.xlarge - m5.2xlarge - m5.4xlarge - m5.8xlarge - c5.large - c5.xlarge - c5.2xlarge - c5.4xlarge - c5.9xlarge - r5.large - r5.xlarge - r5.2xlarge - r5.4xlarge ConstraintDescription: Must be a valid EC2 instance type. Default: t3.medium Description: Admin server EC2 instance type. Type: String AdminServerRemoteAccessCIDR: AllowedPattern: '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))$' ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/x. Description: The allowed CIDR block for remote access to the Duo Network Gateway admin server. Always restrict traffic on the admin server’s port 8443 to authorized network ranges only, not widely to the internet. Type: String AdminServerSubdomain: Default: '' Description: 'Subdomain for the admin server. Fully qualified domain name for the admin server will be created by adding the DomainName parameter value as a suffix. For example, if the provided value is ''adminserver'' and the DomainName parameter value is ''corp.com'', then the fully qualified domain name for the admin server will be ''adminserver.corp.com''.' Type: String AuthToken: AllowedPattern: '[a-zA-Z0-9]*' ConstraintDescription: 'Must be 16-128 characters, including at least three uppercase, lowercase, nonalphanumeric, and digits.' Default: DuoRedisAuthToken Description: The auth token for the Redis cluster. MaxLength: 128 MinLength: 16 NoEcho: true Type: String ConfigYAMLPath: Description: (Optional) S3 bucket path of the scripted configuration YAML file. (e.g. https://duoconfigbucket.s3.amazonaws.com/scripts/config/dng_config.yml). Type: String DomainName: Default: '' Description: 'Fully qualified domain name for the Duo Network Gateway load balancer. If you don''t provide a value for ACMSSLCertificateArn, use the HostedZoneID. If you provide a value for this, you must also provide a corresponding HostedZoneID.' MaxLength: 128 Type: String HostedZoneID: Default: '' Description: 'Route 53-hosted zone ID of the domain name. If you don''t provide an ACMSSLCertificateArn value, the Quick Start creates the ACM certificate for you using HostedZoneID in conjunction with DomainName. This HostedZoneID should be for the corresponding DomainName parameter value.' Type: String KeyPairName: ConstraintDescription: Name of an existing EC2 key pair. Type: 'AWS::EC2::KeyPair::KeyName' NumReplicas: Default: 1 Description: Number of replicas per shard. MaxValue: 5 MinValue: 0 Type: Number NumShards: Default: 1 Description: Number of shards in the cluster. MaxValue: 250 MinValue: 1 Type: Number PortalServerInstanceType: AllowedValues: - t3.micro - t3.small - t3.medium - t3.large - m5.large - m5.xlarge - m5.2xlarge - m5.4xlarge - m5.8xlarge - c5.xlarge - c5.2xlarge - c5.4xlarge - c5.9xlarge - r5.large - r5.xlarge - r5.2xlarge - r5.4xlarge - r5.8xlarge ConstraintDescription: Must be a valid EC2 instance type. Default: t3.medium Description: Portal server EC2 instance type. Type: String PortalServerName: Default: PortalServer Description: The value used for the name tag of the portal server. Type: String PortalServerRemoteAccessCIDR: AllowedPattern: '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))$' ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/x. Description: Allowed CIDR block for external access to the load balancer. Type: String PortalServerSubdomain: Default: '' Description: 'Subdomain for the portal server. Fully qualified domain name for the portal server will be created by adding the DomainName parameter value as a suffix. For example, if the provided value is ''portalserver'' and the DomainName parameter value is ''corp.com'', then the fully qualified domain name for the portal server will be ''portalserver.corp.com''.' Type: String PrivateSubnet1ID: Description: 'ID of the private subnet 1 that you want to provision the admin and portal servers into (e.g., subnet-a0246dcd).' Type: 'AWS::EC2::Subnet::Id' PrivateSubnet2ID: Description: 'ID of the private subnet 2 that you want to provision the admin and portal servers into (e.g., subnet-a0234dcs).' Type: 'AWS::EC2::Subnet::Id' PublicSubnet1ID: Description: 'ID of the public subnet 1 that you want to provision the load balancers of admin and portal servers into (e.g., subnet-a0246dcd).' Type: 'AWS::EC2::Subnet::Id' PublicSubnet2ID: Description: 'ID of the public subnet 1 that you want to provision the load balancers of admin and portal servers into (e.g., subnet-a0246dcd).' Type: 'AWS::EC2::Subnet::Id' QSS3BucketName: AllowedPattern: '^[0-9a-zA-Z]+([0-9a-zA-Z-]*[0-9a-zA-Z])*$' ConstraintDescription: 'Quick Start bucket name can include numbers, lowercase letters, uppercase letters, and hyphens (-). It cannot start or end with a hyphen (-).' Default: aws-quickstart Description: 'S3 bucket name for the Quick Start assets. Quick Start bucket name can include numbers, lowercase letters, uppercase letters, and hyphens (-). It cannot start or end with a hyphen (-).' Type: String QSS3BucketRegion: Default: us-east-1 Description: 'The AWS Region where the Quick Start S3 bucket (QSS3BucketName) is hosted. When using your own bucket, you must specify this value.' Type: String QSS3KeyPrefix: AllowedPattern: '^[0-9a-zA-Z-/]*$' ConstraintDescription: 'Quick Start key prefix can include numbers, lowercase letters, uppercase letters, hyphens (-), and forward slash (/).' Default: quickstart-cisco-duo-network-gateway/ Description: 'S3 key prefix for the Quick Start assets. Quick Start key prefix can include numbers, lowercase letters, uppercase letters, hyphens (-), and forward slash (/).' Type: String RedisCacheNodeType: AllowedValues: - cache.m5.large - cache.m5.xlarge - cache.m5.2xlarge - cache.m5.4xlarge - cache.m5.12xlarge - cache.m5.24xlarge - cache.c1.xlarge - cache.t3.micro - cache.t3.small - cache.t3.medium Default: cache.t3.medium Description: Choose a value for the type of Redis Cache node. Type: String RedisEngineVersion: AllowedValues: - 3.2.6 Default: 3.2.6 Description: Redis replication group version. Type: String SnapshotName: Default: '' Description: (Optional) Name of a snapshot from which you want to restore (leave blank to create an empty cache). Type: String SnapshotRetentionLimit: Default: 35 Description: Number of days that Amazon ElastiCache retains automatic Redis snapshots before deleting them (set to 0 to disable backups). MaxValue: 35 MinValue: 0 Type: Number VPCCIDR: AllowedPattern: '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$' ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28. Default: 10.0.0.0/16 Description: CIDR block for the VPC. Type: String VPCID: Description: 'ID of the VPC (e.g., vpc-0343606e).' Type: 'AWS::EC2::VPC::Id' Conditions: UsingDefaultBucket: !Equals - !Ref QSS3BucketName - aws-quickstart Resources: RedisServerStack: Type: AWS::CloudFormation::Stack Properties: TemplateURL: !Sub - >- https://${S3Bucket}.s3.${S3Region}.${AWS::URLSuffix}/${QSS3KeyPrefix}templates/redis-cluster.template.yaml - S3Region: !If - UsingDefaultBucket - !Ref 'AWS::Region' - !Ref QSS3BucketRegion S3Bucket: !If - UsingDefaultBucket - !Sub '${QSS3BucketName}-${AWS::Region}' - !Ref QSS3BucketName Parameters: PrivateSubnet1ID: !Ref PrivateSubnet1ID PrivateSubnet2ID: !Ref PrivateSubnet2ID RemoteAccessCIDR: !Ref VPCCIDR VPCID: !Ref VPCID RedisAuth: !Ref AuthToken RedisCacheNodeType: !Ref RedisCacheNodeType RedisEngineVersion: !Ref RedisEngineVersion NumShards: !Ref NumShards NumReplicas: !Ref NumReplicas SnapshotName: !Ref SnapshotName SnapshotRetentionLimit: !Ref SnapshotRetentionLimit PortalServerStack: Type: AWS::CloudFormation::Stack Properties: TemplateURL: !Sub - >- https://${S3Bucket}.s3.${S3Region}.${AWS::URLSuffix}/${QSS3KeyPrefix}templates/quickstart-cisco-duo-network-gateway-portal-servers.template.yaml - S3Region: !If - UsingDefaultBucket - !Ref 'AWS::Region' - !Ref QSS3BucketRegion S3Bucket: !If - UsingDefaultBucket - !Sub '${QSS3BucketName}-${AWS::Region}' - !Ref QSS3BucketName Parameters: QSS3BucketRegion: !Ref QSS3BucketRegion PortalServerInstanceType: !Ref PortalServerInstanceType KeyPairName: !Ref KeyPairName PrivateSubnet1ID: !Ref PrivateSubnet1ID PrivateSubnet2ID: !Ref PrivateSubnet2ID PublicSubnet1ID: !Ref PublicSubnet1ID PublicSubnet2ID: !Ref PublicSubnet2ID QSS3BucketName: Ref: QSS3BucketName QSS3KeyPrefix: Ref: QSS3KeyPrefix VPCID: !Ref VPCID VPCCIDR: !Ref VPCCIDR RemoteAccessCIDR: Ref: PortalServerRemoteAccessCIDR RedisHost: !GetAtt RedisServerStack.Outputs.PrimaryEndPointAddress RedisPort: !GetAtt RedisServerStack.Outputs.PrimaryEndPointPort RedisAuth: !GetAtt RedisServerStack.Outputs.RedisAuthToken PortalServerName: !Ref PortalServerName DomainName: !Sub '${PortalServerSubdomain}.${DomainName}' HostedZoneID: !Ref HostedZoneID ACMSSLCertificateArn: !Ref ACMSSLCertificateArn AdminServerStack: Type: AWS::CloudFormation::Stack Properties: TemplateURL: !Sub - >- https://${S3Bucket}.s3.${S3Region}.${AWS::URLSuffix}/${QSS3KeyPrefix}templates/admin-server.template.yaml - S3Region: !If - UsingDefaultBucket - !Ref 'AWS::Region' - !Ref QSS3BucketRegion S3Bucket: !If - UsingDefaultBucket - !Sub '${QSS3BucketName}-${AWS::Region}' - !Ref QSS3BucketName Parameters: AdminServerInstanceType: !Ref AdminServerInstanceType ConfigYAMLPath: !Ref ConfigYAMLPath KeyPairName: !Ref KeyPairName QSS3BucketName: Ref: QSS3BucketName QSS3KeyPrefix: Ref: QSS3KeyPrefix PrivateSubnet1ID: !Ref PrivateSubnet1ID PublicSubnet1ID: !Ref PublicSubnet1ID PublicSubnet2ID: !Ref PublicSubnet2ID RemoteAccessCIDR: Ref: AdminServerRemoteAccessCIDR VPCID: !Ref VPCID RedisHost: !GetAtt RedisServerStack.Outputs.PrimaryEndPointAddress RedisPort: !GetAtt RedisServerStack.Outputs.PrimaryEndPointPort RedisAuth: !GetAtt RedisServerStack.Outputs.RedisAuthToken DomainName: !Sub '${AdminServerSubdomain}.${DomainName}' HostedZoneID: !Ref HostedZoneID ACMSSLCertificateArn: !Ref ACMSSLCertificateArn Outputs: AdminServerWebURL: Description: "The admin server web server URL." Value: Fn::GetAtt: - AdminServerStack - Outputs.AdminServerLoadBalancer PortalServerWebURL: Description: "The portal server web server URL." Value: Fn::GetAtt: - PortalServerStack - Outputs.DNGLoadBalancer