AWSTemplateFormatVersion: 2010-09-09 Description: >- This template creates a Multi-AZ, multi-subnet VPC infrastructure with UIPath Orchestrator deployed in private Subnets, with an ALB behind a Route53 in public subnets. (qs-1r2g41216) Metadata: QuickStartDocumentation: EntrypointName: Launch into an existing VPC Order: 1 AWS::CloudFormation::Interface: ParameterGroups: - Label: default: Network configuration Parameters: - VPCCIDR - VPCID - PrivateSubnetID - PublicSubnetID - Label: default: Robot VM configuration Parameters: - KeyPairName - InstanceType - Label: default: UiPath Robot configuration Parameters: - RobotVersion - RobotType - AdminPassword - OrchestratorURL - OrchestratorTenant - OrchestratorAPIUser - OrchestratorAPIPassword - Label: default: Quick Start S3 bucket configuration Parameters: - QSS3BucketName - QSS3KeyPrefix ParameterLabels: VPCCIDR: default: VPC CIDR VPCID: default: VPC ID PrivateSubnetID: default: Private subnet PublicSubnetID: default: Public subnet KeyPairName: default: Instance key pair InstanceType: default: Instance type RobotType: default: UiPath Robot type (attended or unattended) RobotVersion: default: UiPath Robot version. OrchestratorURL: default: URL of an existing and licensed Orchestrator OrchestratorTenant: default: UiPath Robot tenant name OrchestratorAPIUser: default: UiPath Orchestrator API username OrchestratorAPIPassword: default: UiPath Orchestrator API password AdminPassword: default: Administrator password QSS3BucketName: default: Template-hosting S3 bucket QSS3KeyPrefix: default: Template folder Parameters: VPCCIDR: AllowedPattern: '^([0-9]{1,3}\.){2}([0]{1}.)[0]{1}(\/[16]{2})$' ConstraintDescription: CIDR block parameter must be in the format x.x.0.0/16. Default: 10.0.0.0/16 Description: VPC CIDR block, in format x.x.0.0/16. Type: String VPCID: Type: AWS::EC2::VPC::Id Description: ID of the VPC where the UiPath Robot is created. PrivateSubnetID: Type: 'AWS::EC2::Subnet::Id' Description: Private subnet with UiPath Robot. PublicSubnetID: Type: 'AWS::EC2::Subnet::Id' Description: Public subnet with bastion host to access UiPath Robot. KeyPairName: Description: Key pair used to log in to virtual machine (VM) instances. Type: 'AWS::EC2::KeyPair::KeyName' InstanceType: AllowedValues: - t2.micro - t2.small - t2.medium - t2.large - m4.large - m4.xlarge - m4.2xlarge - m4.4xlarge - m4.10xlarge - c4.large - c4.xlarge - c4.2xlarge - c4.4xlarge - c4.8xlarge - r4.large - r4.xlarge - r4.2xlarge - r4.4xlarge - r4.8xlarge ConstraintDescription: Must be a valid Amazon EC2 instance type from the list. Default: t2.medium Description: EC2 instance type. Type: String AdminPassword: Description: Windows administrator password for UiPath Robot. Type: String NoEcho: 'true' MinLength: '6' MaxLength: '124' AllowedPattern: >- (?=^.{6,124}$)((?=.*\d)(?=.*[A-Z])(?=.*[a-z])|(?=.*\d)(?=.*[^A-Za-z0-9])(?=.*[a-z])|(?=.*[^A-Za-z0-9])(?=.*[A-Z])(?=.*[a-z])|(?=.*\d)(?=.*[A-Z])(?=.*[^A-Za-z0-9]))^.* ConstraintDescription: >- Windows administrator password must contain more than six characters, including at least one uppercase letter. RobotType: Type: String Default: Attended AllowedValues: - Attended - Unattended Description: >- Choose the type of UiPath Robot you want to install (attended or unattended). RobotVersion: Description: UIPath Robot version to install. Type: String Default: 23.4.0 AllowedValues: - 23.4.0 ConstraintDescription: Robot version can only contain characters *0–9* and *.* (period). OrchestratorURL: Type: String Description: UiPath Orchestrator URL. OrchestratorTenant: Type: String Default: default Description: Tenant name where the UiPath Robot is created. OrchestratorAPIUser: Type: String Description: UiPath Orchestrator API username. This must have a role with permissions to add and create robots. OrchestratorAPIPassword: Type: String Description: UiPath Orchestrator API password. NoEcho: 'true' 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 (-). Description: Name of the S3 bucket for your copy of the Quick Start assets. Keep the default name unless you are customizing the template. Changing the name updates code references to point to a new Quick Start location. This name can include numbers, lowercase letters, uppercase letters, and hyphens, but do not start or end with a hyphen (-). See https://aws-quickstart.github.io/option1.html. Type: String Default: aws-quickstart QSS3BucketRegion: Default: us-east-1 Description: >- AWS Region where the Quick Start S3 bucket (QSS3BucketName) is hosted. Keep the default Region unless you are customizing the template. Changing this Region updates code references to point to a new Quick Start location. When using your own bucket, specify the Region. See https://aws-quickstart.github.io/option1.html. Type: String AllowedPattern: (us(-gov)?|ap|ca|cn|eu|sa)-(central|(north|south)?(east|west)?)-\d ConstraintDescription: Must be a valid AWS Region code. QSS3KeyPrefix: AllowedPattern: '^[0-9a-zA-Z-/]*/$' ConstraintDescription: >- The Quick Start S3 key prefix can include numbers, lowercase letters, uppercase letters, hyphens (-), and forward slashes (/). Default: quickstart-uipath-robot/ Description: >- S3 key prefix that is used to simulate a directory for your copy of the Quick Start assets. Keep the default prefix unless you are customizing the template. Changing this prefix updates code references to point to a new Quick Start location. This prefix can include numbers, lowercase letters, uppercase letters, hyphens (-), and forward slashes (/). See https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html and https://aws-quickstart.github.io/option1.html. Type: String Conditions: UsingDefaultBucket: !Equals - !Ref QSS3BucketName - aws-quickstart Resources: LambdaRoleStack: Type: 'AWS::CloudFormation::Stack' Properties: TemplateURL: !Sub - >- https://${S3Bucket}.s3.${S3Region}.${AWS::URLSuffix}/${QSS3KeyPrefix}templates/lambda-role.template.yaml - S3Bucket: !If - UsingDefaultBucket - !Sub '${QSS3BucketName}-${AWS::Region}' - !Ref QSS3BucketName S3Region: !If - UsingDefaultBucket - !Ref 'AWS::Region' - !Ref QSS3BucketRegion SecurityStack: Type: 'AWS::CloudFormation::Stack' Properties: TemplateURL: !Sub - >- https://${S3Bucket}.s3.${S3Region}.${AWS::URLSuffix}/${QSS3KeyPrefix}templates/security.template.yaml - S3Bucket: !If - UsingDefaultBucket - !Sub '${QSS3BucketName}-${AWS::Region}' - !Ref QSS3BucketName S3Region: !If - UsingDefaultBucket - !Ref 'AWS::Region' - !Ref QSS3BucketRegion Parameters: VPCID: !Ref VPCID VPCCIDR: !Ref VPCCIDR FindAMIFunction: Type: 'AWS::Lambda::Function' Properties: Description: Finds a matching AMI Id Handler: index.handler Role: !GetAtt - LambdaRoleStack - Outputs.CustomLambdaRoleArn Code: ZipFile: !Join - |+ - - import boto3 - import json - import cfnresponse - 'def create(properties, physical_id):' - ' regionName = properties[''RegionName'']' - ' imageName = properties[''ImageName'']' - ' architecture = properties[''Architecture'']' - ' virtualizationType = properties[''VirtualizationType'']' - ' owners = properties[''Owners'']' - ' imageId = ''''' - ' ec2 = boto3.client(''ec2'', regionName)' - ' images = ec2.describe_images(' - ' ExecutableUsers=[''all''],' - ' Filters=[' - ' { ''Name'': ''name'', ''Values'': [imageName] },' - ' { ''Name'': ''state'', ''Values'': [''available''] },' - ' { ''Name'': ''architecture'', ''Values'': [architecture] },' - ' { ''Name'': ''virtualization-type'', ''Values'': [virtualizationType] }' - ' ],' - ' Owners=[owners]' - ' )[''Images'']' - ' if len(images) > 0:' - ' imageId = images[0][''ImageId'']' - ' print(regionName, imageId)' - ' returnAttribute = {}' - ' returnAttribute[''ImageId''] = imageId' - ' returnAttribute[''Action''] = ''CREATE''' - ' return cfnresponse.SUCCESS, imageId, returnAttribute' - 'def update(properties, physical_id):' - ' imageId = physical_id' - ' returnAttribute = {}' - ' returnAttribute[''ImageId''] = imageId' - ' returnAttribute[''Action''] = ''UPDATE''' - ' return cfnresponse.SUCCESS, imageId, returnAttribute' - 'def delete(properties, physical_id):' - ' imageId = physical_id' - ' returnAttribute = {}' - ' returnAttribute[''ImageId''] = imageId' - ' returnAttribute[''Action''] = ''DELETE''' - ' return cfnresponse.SUCCESS, imageId, returnAttribute' - 'def handler(event, context):' - ' print(''Received event: '' + json.dumps(event))' - ' status = cfnresponse.FAILED' - ' new_physical_id = None' - ' returnAttribute = {}' - ' try:' - ' properties = event.get(''ResourceProperties'')' - ' physical_id = event.get(''PhysicalResourceId'')' - ' status, new_physical_id, returnAttribute = {' - ' ''Create'': create,' - ' ''Update'': update,' - ' ''Delete'': delete' - ' }.get(event[''RequestType''], lambda x, y: (cfnresponse.FAILED, None))(properties, physical_id)' - ' except Exception as e:' - ' print(''Exception: '' + str(e))' - ' status = cfnresponse.FAILED' - ' finally:' - ' cfnresponse.send(event, context, status, returnAttribute, new_physical_id)' Runtime: python3.9 Timeout: 30 TracingConfig: Mode: Active ServerStack: Type: 'AWS::CloudFormation::Stack' Properties: TemplateURL: !Sub - >- https://${S3Bucket}.s3.${S3Region}.${AWS::URLSuffix}/${QSS3KeyPrefix}templates/server.template.yaml - S3Bucket: !If - UsingDefaultBucket - !Sub '${QSS3BucketName}-${AWS::Region}' - !Ref QSS3BucketName S3Region: !If - UsingDefaultBucket - !Ref 'AWS::Region' - !Ref QSS3BucketRegion Parameters: PrivateSubnetID: !Ref PrivateSubnetID PublicSubnetID: !Ref PublicSubnetID GatewaySecurityGroup: !GetAtt - SecurityStack - Outputs.SecurityGroup KeyPairName: !Ref KeyPairName InstanceType: !Ref InstanceType FindAMIFunctionArn: !GetAtt - FindAMIFunction - Arn AdminPassword: !Ref AdminPassword RobotType: !Ref RobotType RobotVersion: !Ref RobotVersion QSS3BucketName: !Ref QSS3BucketName QSS3BucketRegion: !Ref QSS3BucketRegion QSS3KeyPrefix: !Ref QSS3KeyPrefix OrchestratorURL: !Ref OrchestratorURL OrchestratorTenant: !Ref OrchestratorTenant OrchestratorAPIUser: !Ref OrchestratorAPIUser OrchestratorAPIPassword: !Ref OrchestratorAPIPassword Outputs: BastionHostPublicIP: Description: Public IP of bastion host in public subnet 1. Value: !GetAtt - ServerStack - Outputs.BastionHostPublicIP UiPathRobotPrivateIP: Description: Private IP of UiPath Robot in private subnet 1. Value: !GetAtt - ServerStack - Outputs.UiPathRobotPrivateIP Postdeployment: Description: See the deployment guide for post-deployment steps. Value: https://aws.amazon.com/quickstart/?quickstart-all.sort-by=item.additionalFields.sortDate&quickstart-all.sort-order=desc&awsm.page-quickstart-all=5