AWSTemplateFormatVersion: '2010-09-09' Description: 'JFrog Artifactory Quick Start Deployment into an Existing VPC (qs-1q037efj0)' Metadata: QuickStartDocumentation: EntrypointName: "Launch into an existing VPC" AWS::CloudFormation::Interface: ParameterGroups: - Label: default: Security configuration Parameters: - KeyPairName - AccessCidr - RemoteAccessCidr - Label: default: Network configuration Parameters: - VpcId - VpcCidr - PublicSubnet1Id - PublicSubnet2Id - PrivateSubnet1Id - PrivateSubnet2Id - PrivateSubnet1Cidr - PrivateSubnet2Cidr - ELBScheme - Label: default: Bastion configuration Parameters: - ProvisionBastionHost - BastionInstanceType - BastionOs - BastionRootVolumeSize - BastionEnableTcpForwarding - NumBastionHosts - BastionEnableX11Forwarding - Label: default: Amazon EC2 configuration Parameters: - VolumeSize - InstanceType - Label: default: JFrog Artifactory configuration Parameters: - ArtifactoryProduct - ArtifactoryVersion - NumberOfSecondary - SmLicenseCertName - ArtifactoryServerName - MasterKey - ExtraJavaOptions - DefaultJavaMemSettings - KeystorePassword - AnsibleVaultPass - Label: default: Amazon RDS configuration Parameters: - DatabaseName - DatabaseEngine - DatabaseUser - DatabasePassword - DatabaseInstance - DatabaseAllocatedStorage - MultiAzDatabase - Label: default: AWS Quick Start configuration Parameters: - QsS3BucketName - QsS3KeyPrefix - QsS3BucketRegion - Label: default: JFrog Xray Configuration Parameters: - InstallXray - XrayVersion - XrayNumberOfInstances - XrayInstanceType - XrayDatabaseUser - XrayDatabasePassword ParameterLabels: KeyPairName: default: SSH key name VpcId: default: VPC ID VpcCidr: default: VPC CIDR PublicSubnet1Id: default: Public subnet 1 ID PublicSubnet2Id: default: Public subnet 2 ID PrivateSubnet1Id: default: Private subnet 1 ID PrivateSubnet2Id: default: Private subnet 2 ID PrivateSubnet1Cidr: default: Private subnet 1 CIDR PrivateSubnet2Cidr: default: Private subnet 2 CIDR AccessCidr: default: Permitted IP range RemoteAccessCidr: default: Remote access CIDR ELBScheme: default: Elastic Load Balancing scheme ProvisionBastionHost: default: Bastion instance BastionInstanceType: default: Bastion instance type BastionRootVolumeSize: default: Bastion root volume size BastionEnableTcpForwarding: default: Bastion enable TCP forwarding BastionEnableX11Forwarding: default: Bastion enable X11 forwarding BastionOs: default: Bastion operating system NumBastionHosts: default: Number of bastion instances VolumeSize: default: EBS root volume size InstanceType: default: EC2 instance type NumberOfSecondary: default: Secondary instances ArtifactoryProduct: default: Artifactory product to install ArtifactoryVersion: default: Artifactory version SmLicenseCertName: default: Artifactory licenses and certificate secret name ArtifactoryServerName: default: Artifactory server name MasterKey: default: Master server key ExtraJavaOptions: default: Extra Java options DefaultJavaMemSettings: default: Default Java memory settings KeystorePassword: default: Java keystore password AnsibleVaultPass: default: Ansible Vault password DatabaseName: default: Database name DatabaseEngine: default: Database engine DatabaseUser: default: Database user DatabasePassword: default: Database password DatabaseInstance: default: Database instance type DatabaseAllocatedStorage: default: Database allocated storage MultiAzDatabase: default: High-availability database QsS3BucketName: default: Quick Start S3 bucket name QsS3KeyPrefix: default: Quick Start S3 key prefix QsS3BucketRegion: default: Quick Start S3 bucket region InstallXray: default: Install JFrog Xray XrayVersion: default: Version of Xray to install XrayNumberOfInstances: default: Number of JFrog Xray instances XrayInstanceType: default: Xray instance type XrayDatabaseUser: default: Xray Database user XrayDatabasePassword: default: Xray Database password Parameters: KeyPairName: Description: Name of an existing key pair, which allows you to connect securely to your instance after it launches. This is the key pair you created in your preferred Region. Type: AWS::EC2::KeyPair::KeyName VpcId: Description: ID of your existing VPC (e.g., vpc-0343606e). Type: "AWS::EC2::VPC::Id" VpcCidr: Description: CIDR block for the VPC. 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 Type: String PublicSubnet1Id: Description: ID of the public subnet in Availability Zone 1 of your existing VPC (e.g., subnet-z0376dab). Type: "AWS::EC2::Subnet::Id" PublicSubnet2Id: Description: ID of the public subnet in Availability Zone 2 of your existing VPC (e.g., subnet-a29c3d84). Type: "AWS::EC2::Subnet::Id" PrivateSubnet1Id: Description: ID of the private subnet in Availability Zone 1 of your existing VPC (e.g., subnet-a0246dcd). Type: "AWS::EC2::Subnet::Id" PrivateSubnet2Id: Description: ID of the private subnet in Availability Zone 2 of your existing VPC (e.g., subnet-b58c3d67). Type: "AWS::EC2::Subnet::Id" PrivateSubnet1Cidr: Description: CIDR of the private subnet in Availability Zone 1 of your existing VPC (e.g., 10.0.0.0/19). 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/19 Type: String PrivateSubnet2Cidr: Description: CIDR of the private subnet in Availability Zone 2 of your existing VPC (e.g., 10.0.32.0/19). 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.32.0/19 Type: String AccessCidr: Description: CIDR IP range that is permitted to access Artifactory. We recommend that you set this value to a trusted IP range. For example, you might want to grant only your corporate network access to the software. 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]))$ Type: String RemoteAccessCidr: Description: Remote CIDR range that allows you to connect to the bastion instance by using SSH. We recommend that you set this value to a trusted IP range. For example, you might want to grant specific ranges inside your corporate network SSH access. 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]))$ Type: String ELBScheme: Description: Choose whether this is internet facing or internal. AllowedValues: - internal - internet-facing Default: internet-facing Type: String ProvisionBastionHost: Description: Choose Disabled to skip creating a bastion instance. Due to the JFrog Container Registry nodes being created in private subnets, the default setting of Enabled this is highly recommended. AllowedValues: - "Enabled" - "Disabled" Default: "Enabled" Type: String BastionInstanceType: Description: Size of the bastion instances. AllowedValues: - t3.nano - t3.micro - t3.small - t3.medium - t3.large - m5.large - m5.xlarge - m5.2xlarge - m5.4xlarge Default: "t3.micro" Type: String BastionRootVolumeSize: Description: Size of the root volume on the bastion instances. Default: 10 Type: Number BastionEnableTcpForwarding: Description: Choose whether to enable TCPForwarding via the bootstrapping of the bastion instance or not. AllowedValues: - "true" - "false" Default: "true" Type: String BastionEnableX11Forwarding: Description: Choose true to enable X11 via the bootstrapping of the bastion host. Setting this value to true will enable X Windows over SSH. X11 forwarding can be useful, but it is also a security risk, so it's recommended that you keep the default (false) setting. AllowedValues: - "true" - "false" Default: "false" Type: String BastionOs: Description: Linux distribution for the Amazon Machine Image (AMI) to be used for the bastion instances. AllowedValues: - "Amazon-Linux2-HVM" - "CentOS-7-HVM" - "Ubuntu-Server-20.04-LTS-HVM" - "SUSE-SLES-15-HVM" Default: "Amazon-Linux2-HVM" Type: String NumBastionHosts: Description: Number of bastion instances to create. AllowedValues: - '1' - '2' - '3' - '4' Default: '1' Type: String VolumeSize: Description: Size in gigabytes of the available storage (min 10GB); the Quick Start will create an Amazon Elastic Block Store (Amazon EBS) volumes of this size. Default: 200 Type: Number InstanceType: Description: EC2 type for the Artifactory instances. AllowedValues: - m5.large - m5.xlarge - m5.2xlarge - m5.4xlarge - m5.8xlarge - m5.12xlarge - m5.16xlarge - m5.24xlarge - m5.metal - m5d.large - m5d.xlarge - m5d.2xlarge - m5d.4xlarge - m5d.8xlarge - m5d.12xlarge - m5d.16xlarge - m5d.24xlarge - m5d.metal - m5a.large - m5a.xlarge - m5a.2xlarge - m5a.4xlarge - m5a.8xlarge - m5a.12xlarge - m5a.16xlarge - m5a.24xlarge ConstraintDescription: Must contain valid instance type. Default: m5.xlarge Type: String NumberOfSecondary: Description: Number of secondary Artifactory servers to complete your HA deployment. To align with Artifactory best practices, the minimum number is two and the maximum is seven. Do not select more instances than you have licenses for. AllowedValues: - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 Default: 2 Type: Number ArtifactoryProduct: Description: JFrog Artifactory product you want to install into an AMI. AllowedValues: - JFrog-Artifactory-Pro - JFrog-Container-Registry Default: JFrog-Artifactory-Pro Type: String ArtifactoryVersion: Description: Version of Artifactory that you want to deploy into the Quick Start. See the release notes to select the version you want to deploy at https://www.jfrog.com/confluence/display/RTF/Release+Notes. AllowedPattern: ^(([0-9]|[1-9][0-9])\.){2}([1-9][0-9]|[0-9])$ ConstraintDescription: A version that matches X.X.X per Artifactory releases Default: 7.12.5 Type: String SmLicenseCertName: Description: Secret name created in AWS Secrets Manager, which contains the SSL certificate, certificate key, and Artifactory licenses. Default: '' Type: String ArtifactoryServerName: Description: Name of your Artifactory server. Ensure that this matches your certificate. Type: String MasterKey: Description: Master key for the Artifactory cluster. Generate a master key by using the command '$openssl rand -hex 16'. AllowedPattern: ^[a-zA-Z0-9]+$ MinLength: '1' MaxLength: '64' ConstraintDescription: Only capital or lowercase letters and numbers, with a Max of 64 characters. NoEcho: 'true' Type: String ExtraJavaOptions: Description: Set Java options to pass to the JVM for Artifactory. For more information, see the Artifactory system requirements at https://www.jfrog.com/confluence/display/RTF/System+Requirements#SystemRequirements-RecommendedHardware. Do not add Xms or Xmx settings without disabling DefaultJavaMemSettings. Default: -Xss256k -XX:+UseG1GC Type: String DefaultJavaMemSettings: Description: Choose false to overwrite the standard memory-calculation options to pass to the Artifactory JVM. If you plan to overwrite them, ensure they are added to the ExtraJavaOptions to prevent the stack provision from failing. ConstraintDescription: True or False AllowedValues: - "true" - "false" Default: "true" Type: String KeystorePassword: Description: Java keystore password. For better security, the password that you specify will replace the default Java key store password. NoEcho: 'true' Type: String AnsibleVaultPass: Description: Ansible Vault password to protect the Artifactory YAML configuration file generated during the Artifactory deployment. This YAML file is stored on the EC2 nodes and secured with this password. NoEcho: 'true' Type: String DatabaseName: Description: Name of your database instance. The name must be unique across all instances owned by your AWS account in the current Region. The database instance identifier is case-insensitive, but it's stored in lowercase (as in "mydbinstance"). AllowedPattern: ^[a-zA-Z]([a-zA-Z0-9])+$ MinLength: '1' MaxLength: '60' ConstraintDescription: 1 to 60 alphanumeric characters First character must be a letter. Default: artdb Type: String DatabaseEngine: Description: Database engine that you want to run, which is currently locked to MySQL. AllowedValues: - Postgres Default: Postgres Type: String DatabaseUser: Description: Login ID for the master user of your database instance. MinLength: '1' MaxLength: '16' AllowedPattern: ^[a-zA-Z]([a-zA-Z0-9])+$ ConstraintDescription: 1 to 16 alphanumeric characters. First character must be a letter. Default: artifactory Type: String DatabasePassword: Description: Password for the Artifactory database user. AllowedPattern: ^[^ \\']+$ MinLength: '8' MaxLength: '12' ConstraintDescription: Must be at least 8 and no more than 12 characters containing letters and (minimum 1 capital letter), numbers and symbols. NoEcho: 'true' Type: String DatabaseInstance: Description: Size of the database to be deployed as part of the Quick Start. AllowedValues: - db.m5.large - db.m5.xlarge - db.m5.2xlarge - db.m5.10xlarge - db.m5.16xlarge - db.m5.large - db.m5.xlarge - db.m5.2xlarge - db.m5.4xlarge - db.m5.12xlarge - db.m5.24xlarge ConstraintDescription: Must be a valid database Instance Type. Default: db.m5.large Type: String DatabaseAllocatedStorage: Description: Size in gigabytes of the available storage for the database instance. MinValue: 5 MaxValue: 1024 Default: 10 Type: Number MultiAzDatabase: Description: Choose false to create an Amazon RDS instance in a single Availability Zone. ConstraintDescription: True or False AllowedValues: - "true" - "false" Default: "true" Type: String QsS3BucketName: Description: S3 bucket name for the Quick Start assets. This string can include numbers, lowercase letters, and hyphens (-). It cannot start or end with a hyphen (-). AllowedPattern: ^[0-9a-z]+([0-9a-z-]*[0-9a-z])*$ ConstraintDescription: Quick Start bucket name can include numbers, lowercase letters, and hyphens (-). It cannot start or end with a hyphen (-). Default: aws-quickstart Type: String QsS3KeyPrefix: Description: S3 key prefix for the Quick Start assets. Quick Start key prefix can include numbers, lowercase letters, uppercase letters, hyphens (-), and forward slash (/). AllowedPattern: ^[0-9a-zA-Z-/]*$ ConstraintDescription: Quick Start key prefix can include numbers, lowercase letters, uppercase letters, hyphens (-), and forward slash (/). Default: quickstart-jfrog-artifactory/ Type: String QsS3BucketRegion: Default: 'us-east-1' Description: AWS Region where the Quick Start S3 bucket (QSS3BucketName) is hosted. If you use your own bucket, you must specify your own value. Type: String InstallXray: Description: Choose true to install JFrog Xray instance(s). ConstraintDescription: True or False AllowedValues: - "true" - "false" Default: "true" Type: String XrayVersion: Description: The version of Xray that you want to deploy into the Quick Start. AllowedPattern: ^(([0-9]|[1-9][0-9])\.){2}([1-9][0-9]|[0-9])$ ConstraintDescription: A version that matches X.X.X per Xray releases. Default: 3.12.1 Type: String XrayNumberOfInstances: Description: The number of Xray instances servers to complete your HA deployment. The minimum number is one; the maximum is seven. Do not select more than instances than you have licenses for. MinValue: 1 MaxValue: 7 Default: 1 Type: Number XrayInstanceType: Description: The EC2 instance type for the Xray instances. AllowedValues: - c5.2xlarge - c5.4xlarge ConstraintDescription: Must contain valid instance type. Default: c5.2xlarge Type: String XrayDatabaseUser: Description: The login ID for the Xray database user. MinLength: '1' MaxLength: '16' AllowedPattern: ^[a-zA-Z]([a-zA-Z0-9])+$ ConstraintDescription: 1 to 16 alphanumeric characters. First character must be a letter. Default: xray Type: String XrayDatabasePassword: Description: The password for the Xray database user. AllowedPattern: ^[^ \\']+$ MinLength: '8' MaxLength: '12' ConstraintDescription: Must be at least 8 and no more than 12 characters containing letters and (minimum 1 capital letter), numbers and symbols. NoEcho: 'true' Type: String Conditions: EnableBastion: !Equals [!Ref 'ProvisionBastionHost', 'Enabled'] IsArtifactory: !Not [!Equals [!Ref ArtifactoryProduct, 'JFrog-Container-Registry']] HasSecondaryNodes: !Not [!Equals [!Ref NumberOfSecondary, '0']] DefaultJava: !Equals [!Ref DefaultJavaMemSettings, "true"] UsingDefaultBucket: !Equals [!Ref QsS3BucketName, 'aws-quickstart'] EnableXray: !Equals [!Ref InstallXray, 'true'] SmLicenseCertNameExists: !Not [!Equals [!Ref 'SmLicenseCertName', '']] Resources: BastionRole: Condition: EnableBastion Type: "AWS::IAM::Role" Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: ec2.amazonaws.com Action: sts:AssumeRole Policies: - PolicyName: QSBucketAccess PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: s3:GetObject Resource: !Sub "arn:${AWS::Partition}:s3:::${QsS3BucketName}/*" - Effect: Allow Action: - logs:CreateLogStream - logs:GetLogEvents - logs:PutLogEvents - logs:DescribeLogGroups - logs:DescribeLogStreams - logs:PutRetentionPolicy - logs:PutMetricFilter - logs:CreateLogGroup Resource: !Sub "arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:*:*" - Effect: Allow Action: - ec2:AssociateAddress - ec2:DescribeAddresses Resource: "*" BastionStack: Condition: EnableBastion Type: AWS::CloudFormation::Stack Properties: TemplateURL: https://aws-quickstart.s3.amazonaws.com/quickstart-jfrog-artifactory/submodules/quickstart-linux-bastion/templates/linux-bastion.template Parameters: VPCID: !Ref VpcId PublicSubnet1ID: !Ref PublicSubnet1Id PublicSubnet2ID: !Ref PublicSubnet2Id KeyPairName: !Ref KeyPairName QSS3BucketName: !Ref QsS3BucketName QSS3KeyPrefix: !Sub '${QsS3KeyPrefix}submodules/quickstart-linux-bastion/' QSS3BucketRegion: !Ref QsS3BucketRegion RemoteAccessCIDR: !Ref RemoteAccessCidr BastionInstanceType: !Ref BastionInstanceType RootVolumeSize: !Ref BastionRootVolumeSize BastionAMIOS: !Ref BastionOs EnableTCPForwarding: !Ref BastionEnableTcpForwarding EnableX11Forwarding: !Ref BastionEnableX11Forwarding AlternativeIAMRole: !Ref BastionRole NumBastionHosts: !Ref NumBastionHosts ArtifactoryS3IAMUser: Type: AWS::IAM::User ArtifactoryIamAcessKey: Type: AWS::IAM::AccessKey Properties: UserName: !Ref ArtifactoryS3IAMUser ArtifactoryCoreInfraStack: Type: AWS::CloudFormation::Stack Properties: TemplateURL: !Sub https://${QsS3BucketName}.s3.${QsS3BucketRegion}.${AWS::URLSuffix}/${QsS3KeyPrefix}templates/jfrog-artifactory-core-infrastructure.template.yaml Parameters: VpcId: !Ref VpcId VpcCidr: !Ref VpcCidr PrivateSubnet1Cidr: !Ref PrivateSubnet1Cidr PrivateSubnet2Cidr: !Ref PrivateSubnet2Cidr PrivateSubnet3Cidr: !Ref PrivateSubnet2Cidr # This should end up in no new rule but required for EKS SubnetIds: !Join [",", [!Ref PrivateSubnet1Id, !Ref PrivateSubnet2Id]] DatabaseAllocatedStorage: !Ref DatabaseAllocatedStorage MultiAzDatabase: !Ref MultiAzDatabase DatabaseEngine: !Ref DatabaseEngine DatabaseUser: !Ref DatabaseUser DatabasePassword: !Ref DatabasePassword DatabaseInstance: !Ref DatabaseInstance DatabaseName: !Ref DatabaseName ArtifactoryS3IAMUser: !Ref ArtifactoryS3IAMUser InstanceType: !Ref InstanceType ArtifactoryElb: Type: AWS::ElasticLoadBalancingV2::LoadBalancer Properties: IpAddressType: ipv4 Name: !Sub ${ArtifactoryProduct}-EC2-ELB Scheme: !Ref ELBScheme Subnets: - !Ref PublicSubnet1Id - !Ref PublicSubnet2Id Type: network ArtifactorySslTargetGroup: Type: AWS::ElasticLoadBalancingV2::TargetGroup Properties: HealthCheckEnabled: True HealthCheckIntervalSeconds: 30 HealthCheckProtocol: TCP HealthCheckTimeoutSeconds: 10 HealthyThresholdCount: 3 HealthCheckPort: "8082" Port: 443 Protocol: TCP TargetType: instance UnhealthyThresholdCount: 3 VpcId: !Ref VpcId ArtifactoryTargetGroup: Type: AWS::ElasticLoadBalancingV2::TargetGroup Properties: HealthCheckEnabled: True HealthCheckIntervalSeconds: 30 HealthCheckProtocol: TCP HealthCheckTimeoutSeconds: 10 HealthyThresholdCount: 3 HealthCheckPort: "8082" Port: 80 Protocol: TCP TargetType: instance UnhealthyThresholdCount: 3 VpcId: !Ref VpcId ArtifactorySslElbListener: Type: AWS::ElasticLoadBalancingV2::Listener Properties: DefaultActions: - TargetGroupArn: !Ref ArtifactorySslTargetGroup Type: forward LoadBalancerArn: !Ref ArtifactoryElb Port: 443 Protocol: TCP ArtifactoryElbListener: Type: AWS::ElasticLoadBalancingV2::Listener Properties: DefaultActions: - TargetGroupArn: !Ref ArtifactoryTargetGroup Type: forward LoadBalancerArn: !Ref ArtifactoryElb Port: 80 Protocol: TCP ArtifactoryInternalElb: Type: AWS::ElasticLoadBalancingV2::LoadBalancer Properties: IpAddressType: ipv4 Name: ArtifactoryInternal-ELB Scheme: internal Subnets: - !Ref PrivateSubnet1Id - !Ref PrivateSubnet2Id Type: network ArtifactoryInternalTargetGroup: Type: AWS::ElasticLoadBalancingV2::TargetGroup Properties: HealthCheckEnabled: True HealthCheckIntervalSeconds: 30 HealthCheckProtocol: TCP HealthCheckTimeoutSeconds: 10 HealthyThresholdCount: 3 HealthCheckPort: "8082" Name: artifactory-internal-http Port: 80 Protocol: TCP TargetType: instance UnhealthyThresholdCount: 3 VpcId: !Ref VpcId ArtifactoryInternalElbListener: Type: AWS::ElasticLoadBalancingV2::Listener Properties: DefaultActions: - TargetGroupArn: !Ref ArtifactoryInternalTargetGroup Type: forward LoadBalancerArn: !Ref ArtifactoryInternalElb Port: 80 Protocol: TCP ArtifactoryEc2Sg: Type: AWS::EC2::SecurityGroup Properties: Tags: - Key: Name Value: !Sub ${ArtifactoryProduct}-ec2-instances-sg GroupDescription: SG for EC2 instances (also permits access using SSH from the bastion host) VpcId: !Ref VpcId SecurityGroupIngress: - IpProtocol: tcp FromPort: 22 ToPort: 22 CidrIp: !Ref VpcCidr - IpProtocol: tcp FromPort: 80 ToPort: 80 CidrIp: !Ref VpcCidr - IpProtocol: tcp FromPort: 80 ToPort: 80 CidrIp: !Ref AccessCidr - IpProtocol: tcp FromPort: 443 ToPort: 443 CidrIp: !Ref AccessCidr - IpProtocol: tcp FromPort: 443 ToPort: 443 CidrIp: !Ref VpcCidr - IpProtocol: tcp FromPort: 8081 ToPort: 8082 CidrIp: !Ref VpcCidr - IpProtocol: tcp FromPort: 8046 ToPort: 8046 CidrIp: !Ref VpcCidr SecurityGroupEgress: - IpProtocol: "-1" CidrIp: 0.0.0.0/0 ArtifactoryHostRole: Type: 'AWS::IAM::Role' Properties: Path: / AssumeRolePolicyDocument: Statement: - Action: - 'sts:AssumeRole' Principal: Service: - ec2.amazonaws.com Effect: Allow Version: 2012-10-17 ManagedPolicyArns: - !Sub 'arn:${AWS::Partition}:iam::aws:policy/service-role/AmazonEC2RoleforSSM' ArtifactoryHostProfile: Type: 'AWS::IAM::InstanceProfile' Properties: Roles: - !Ref ArtifactoryHostRole Path: / ArtifactoryMaster: Type: AWS::CloudFormation::Stack Properties: TemplateURL: !Sub https://${QsS3BucketName}.s3.${QsS3BucketRegion}.${AWS::URLSuffix}/${QsS3KeyPrefix}templates/jfrog-artifactory-ec2-instance.template.yaml Parameters: PrivateSubnet1Id: !Ref PrivateSubnet1Id PrivateSubnet2Id: !Ref PrivateSubnet2Id MinScalingNodes: '1' # Always have 1 MasterNode MaxScalingNodes: '1' # Always have 1 MasterNode DeploymentTag: !If [IsArtifactory, "ArtifactoryMaster", "JcrMaster"] HostRole: !Ref ArtifactoryHostRole QsS3BucketName: !Ref QsS3BucketName QsS3KeyPrefix: !Ref QsS3KeyPrefix QsS3Uri: !Sub - https://${S3Bucket}.s3.${S3Region}.${AWS::URLSuffix}/${QsS3KeyPrefix} - S3Bucket: !If - UsingDefaultBucket - !Sub 'aws-quickstart-${AWS::Region}' - !Ref 'QsS3BucketName' S3Region: !If - UsingDefaultBucket - !Ref 'AWS::Region' - !Ref 'QsS3BucketRegion' AmiId: !Join ['', !Split [".", !Ref ArtifactoryVersion]] ArtifactoryProduct: !Ref ArtifactoryProduct ArtifactoryLicense1: !If [SmLicenseCertNameExists, !Sub '{{resolve:secretsmanager:${SmLicenseCertName}:SecretString:ArtifactoryLicense1}}', ''] ArtifactoryLicense2: !If [SmLicenseCertNameExists, !Sub '{{resolve:secretsmanager:${SmLicenseCertName}:SecretString:ArtifactoryLicense2}}', ''] ArtifactoryLicense3: !If [SmLicenseCertNameExists, !Sub '{{resolve:secretsmanager:${SmLicenseCertName}:SecretString:ArtifactoryLicense3}}', ''] ArtifactoryLicense4: !If [SmLicenseCertNameExists, !Sub '{{resolve:secretsmanager:${SmLicenseCertName}:SecretString:ArtifactoryLicense4}}', ''] ArtifactoryLicense5: !If [SmLicenseCertNameExists, !Sub '{{resolve:secretsmanager:${SmLicenseCertName}:SecretString:ArtifactoryLicense5}}', ''] ArtifactoryLicense6: !If [SmLicenseCertNameExists, !Sub '{{resolve:secretsmanager:${SmLicenseCertName}:SecretString:ArtifactoryLicense6}}', ''] ArtifactoryServerName: !Ref ArtifactoryServerName EnableSSL: !If [SmLicenseCertNameExists, 'true' , 'false'] Certificate: !If [SmLicenseCertNameExists, !Sub '{{resolve:secretsmanager:${SmLicenseCertName}:SecretString:Certificate}}', ''] CertificateKey: !If [SmLicenseCertNameExists, !Sub '{{resolve:secretsmanager:${SmLicenseCertName}:SecretString:CertificateKey}}', ''] CertificateDomain: !If [SmLicenseCertNameExists, !Sub '{{resolve:secretsmanager:${SmLicenseCertName}:SecretString:CertificateDomain}}', ''] ArtifactoryIamAcessKey: !Ref ArtifactoryIamAcessKey SecretAccessKey: !GetAtt ArtifactoryIamAcessKey.SecretAccessKey ArtifactoryS3Bucket: !GetAtt ArtifactoryCoreInfraStack.Outputs.S3Bucket DatabaseUrl: !GetAtt ArtifactoryCoreInfraStack.Outputs.DatabaseUrl DatabaseDriver: !GetAtt ArtifactoryCoreInfraStack.Outputs.DatabaseDriver DatabasePlugin: !GetAtt ArtifactoryCoreInfraStack.Outputs.DatabasePlugin DatabasePluginUrl: !GetAtt ArtifactoryCoreInfraStack.Outputs.DatabasePluginUrl DatabaseType: !GetAtt ArtifactoryCoreInfraStack.Outputs.DatabaseType DatabaseUser: !Ref DatabaseUser DatabasePassword: !Ref DatabasePassword ArtifactoryPrimary: 'true' MasterKey: !Ref MasterKey ExtraJavaOptions: !If [DefaultJava, !Sub "${ArtifactoryCoreInfraStack.Outputs.JavaOpts} ${ExtraJavaOptions}", !Ref ExtraJavaOptions] KeystorePassword: !Ref KeystorePassword ArtifactoryVersion: !Ref ArtifactoryVersion KeyPairName: !Ref KeyPairName HostProfile: !Ref ArtifactoryHostProfile SecurityGroups: !Ref ArtifactoryEc2Sg InstanceType: !Ref InstanceType VolumeSize: !Ref VolumeSize TargetGroupARN: !Ref ArtifactoryTargetGroup SSLTargetGroupARN: !Ref ArtifactorySslTargetGroup InternalTargetGroupARN: !Ref ArtifactoryInternalTargetGroup AnsibleVaultPass: !Ref AnsibleVaultPass ArtifactorySecondary: Condition: HasSecondaryNodes DependsOn: ArtifactoryMaster Type: AWS::CloudFormation::Stack Properties: TemplateURL: !Sub https://${QsS3BucketName}.s3.${QsS3BucketRegion}.${AWS::URLSuffix}/${QsS3KeyPrefix}templates/jfrog-artifactory-ec2-instance.template.yaml Parameters: PrivateSubnet1Id: !Ref PrivateSubnet1Id PrivateSubnet2Id: !Ref PrivateSubnet2Id MinScalingNodes: !Ref NumberOfSecondary MaxScalingNodes: !Ref NumberOfSecondary DeploymentTag: ArtifactorySecondary HostRole: !Ref ArtifactoryHostRole AmiId: !Join ['', !Split [".", !Ref ArtifactoryVersion]] ArtifactoryProduct: !Ref ArtifactoryProduct ArtifactoryLicense1: !If [SmLicenseCertNameExists, !Sub '{{resolve:secretsmanager:${SmLicenseCertName}:SecretString:ArtifactoryLicense1}}', ''] ArtifactoryLicense2: !If [SmLicenseCertNameExists, !Sub '{{resolve:secretsmanager:${SmLicenseCertName}:SecretString:ArtifactoryLicense2}}', ''] ArtifactoryLicense3: !If [SmLicenseCertNameExists, !Sub '{{resolve:secretsmanager:${SmLicenseCertName}:SecretString:ArtifactoryLicense3}}', ''] ArtifactoryLicense4: !If [SmLicenseCertNameExists, !Sub '{{resolve:secretsmanager:${SmLicenseCertName}:SecretString:ArtifactoryLicense4}}', ''] ArtifactoryLicense5: !If [SmLicenseCertNameExists, !Sub '{{resolve:secretsmanager:${SmLicenseCertName}:SecretString:ArtifactoryLicense5}}', ''] ArtifactoryLicense6: !If [SmLicenseCertNameExists, !Sub '{{resolve:secretsmanager:${SmLicenseCertName}:SecretString:ArtifactoryLicense6}}', ''] ArtifactoryServerName: !Ref ArtifactoryServerName EnableSSL: !If [SmLicenseCertNameExists, 'true' , 'false'] Certificate: !If [SmLicenseCertNameExists, !Sub '{{resolve:secretsmanager:${SmLicenseCertName}:SecretString:Certificate}}', ''] CertificateKey: !If [SmLicenseCertNameExists, !Sub '{{resolve:secretsmanager:${SmLicenseCertName}:SecretString:CertificateKey}}', ''] CertificateDomain: !If [SmLicenseCertNameExists, !Sub '{{resolve:secretsmanager:${SmLicenseCertName}:SecretString:CertificateDomain}}', ''] ArtifactoryIamAcessKey: !Ref ArtifactoryIamAcessKey SecretAccessKey: !GetAtt ArtifactoryIamAcessKey.SecretAccessKey ArtifactoryS3Bucket: !GetAtt ArtifactoryCoreInfraStack.Outputs.S3Bucket DatabaseUrl: !GetAtt ArtifactoryCoreInfraStack.Outputs.DatabaseUrl DatabaseDriver: !GetAtt ArtifactoryCoreInfraStack.Outputs.DatabaseDriver DatabasePlugin: !GetAtt ArtifactoryCoreInfraStack.Outputs.DatabasePlugin DatabasePluginUrl: !GetAtt ArtifactoryCoreInfraStack.Outputs.DatabasePluginUrl DatabaseType: !GetAtt ArtifactoryCoreInfraStack.Outputs.DatabaseType DatabaseUser: !Ref DatabaseUser DatabasePassword: !Ref DatabasePassword ArtifactoryPrimary: 'false' MasterKey: !Ref MasterKey ExtraJavaOptions: !If [DefaultJava, !Sub "${ArtifactoryCoreInfraStack.Outputs.JavaOpts} ${ExtraJavaOptions}", !Ref ExtraJavaOptions] KeystorePassword: !Ref KeystorePassword ArtifactoryVersion: !Ref ArtifactoryVersion KeyPairName: !Ref KeyPairName HostProfile: !Ref ArtifactoryHostProfile SecurityGroups: !Ref ArtifactoryEc2Sg InstanceType: !Ref InstanceType VolumeSize: !Ref VolumeSize TargetGroupARN: !Ref ArtifactoryTargetGroup SSLTargetGroupARN: !Ref ArtifactorySslTargetGroup InternalTargetGroupARN: !Ref ArtifactoryInternalTargetGroup AnsibleVaultPass: !Ref AnsibleVaultPass QsS3BucketName: !Ref QsS3BucketName QsS3KeyPrefix: !Ref QsS3KeyPrefix QsS3Uri: !Sub - https://${S3Bucket}.s3.${S3Region}.${AWS::URLSuffix}/${QsS3KeyPrefix} - S3Bucket: !If - UsingDefaultBucket - !Sub 'aws-quickstart-${AWS::Region}' - !Ref 'QsS3BucketName' S3Region: !If - UsingDefaultBucket - !Ref 'AWS::Region' - !Ref 'QsS3BucketRegion' XrayHostRole: Condition: EnableXray Type: 'AWS::IAM::Role' Properties: Path: / AssumeRolePolicyDocument: Statement: - Action: - 'sts:AssumeRole' Principal: Service: - ec2.amazonaws.com Effect: Allow Version: 2012-10-17 ManagedPolicyArns: - !Sub 'arn:${AWS::Partition}:iam::aws:policy/service-role/AmazonEC2RoleforSSM' XrayHostProfile: Condition: EnableXray Type: 'AWS::IAM::InstanceProfile' Properties: Roles: - !Ref XrayHostRole Path: / XrayExistingVpcStack: Condition: EnableXray DependsOn: ArtifactorySecondary Type: AWS::CloudFormation::Stack Properties: TemplateURL: !Sub https://${QsS3BucketName}.s3.${QsS3BucketRegion}.${AWS::URLSuffix}/${QsS3KeyPrefix}templates/jfrog-xray-ec2-instance.template.yaml Parameters: PrivateSubnet1Id: !Ref PrivateSubnet1Id PrivateSubnet2Id: !Ref PrivateSubnet2Id KeyPairName: !Ref KeyPairName MinScalingNodes: !Ref XrayNumberOfInstances MaxScalingNodes: !Ref XrayNumberOfInstances DeploymentTag: 'xray' QsS3BucketName: !Ref QsS3BucketName QsS3KeyPrefix: !Ref QsS3KeyPrefix QsS3Uri: !Sub - https://${S3Bucket}.s3.${S3Region}.${AWS::URLSuffix}/${QsS3KeyPrefix} - S3Bucket: !If - UsingDefaultBucket - !Sub 'aws-quickstart-${AWS::Region}' - !Ref 'QsS3BucketName' S3Region: !If - UsingDefaultBucket - !Ref 'AWS::Region' - !Ref 'QsS3BucketRegion' DatabaseDriver: !GetAtt ArtifactoryCoreInfraStack.Outputs.DatabaseDriver DatabaseType: !GetAtt ArtifactoryCoreInfraStack.Outputs.DatabaseType DatabaseUser: !Ref DatabaseUser DatabasePassword: !Ref DatabasePassword MasterKey: !Ref MasterKey SecurityGroups: !Ref ArtifactoryEc2Sg VolumeSize: !Ref VolumeSize XrayInstanceType: !Ref XrayInstanceType JfrogInternalUrl: !Sub "http://${ArtifactoryInternalElb.DNSName}" AnsibleVaultPass: !Ref AnsibleVaultPass XrayDatabaseUser: !Ref XrayDatabaseUser XrayDatabasePassword: !Ref XrayDatabasePassword XrayMasterDatabaseUrl: !GetAtt ArtifactoryCoreInfraStack.Outputs.XrayMasterDatabaseUrl XrayDatabaseUrl: !GetAtt ArtifactoryCoreInfraStack.Outputs.XrayDatabaseUrl XrayFirstNode: 'true' XrayVersion: !Ref XrayVersion XrayAmiId: !Join ['', !Split [".", !Ref XrayVersion]] XrayHostRole: !Ref XrayHostRole XrayHostProfile: !Ref XrayHostProfile Outputs: ArtifactoryUrl: Description: URL of the ELB to access Artifactory Value: !If [SmLicenseCertNameExists, !Sub "https://${ArtifactoryElb.DNSName}", !Sub "http://${ArtifactoryElb.DNSName}"] Export: Name: !Sub '${AWS::StackName}-ArtifactoryUrl' ArtifactoryInternalUrl: Description: URL of the internal ELB to access Artifactory Value: !Sub "http://${ArtifactoryInternalElb.DNSName}" Export: Name: !Sub '${AWS::StackName}-ArtifactoryInternalUrl' DatabaseType: Description: Type of database Value: !GetAtt ArtifactoryCoreInfraStack.Outputs.DatabaseType Export: Name: !Sub '${AWS::StackName}-DatabaseType' DatabaseDriver: Description: Database driver Value: !GetAtt ArtifactoryCoreInfraStack.Outputs.DatabaseDriver Export: Name: !Sub '${AWS::StackName}-DatabaseDriver' DatabaseUrl: Description: Database driver Value: !GetAtt ArtifactoryCoreInfraStack.Outputs.DatabaseUrl Export: Name: !Sub '${AWS::StackName}-DatabaseUrl' ArtifactoryTargetGroup: Description: Artifactory target group Value: !Ref ArtifactoryTargetGroup Export: Name: !Sub '${AWS::StackName}-ArtifactoryTargetGroup' ArtifactorySslTargetGroup: Description: Artifactory SSL target group Value: !Ref ArtifactorySslTargetGroup Export: Name: !Sub '${AWS::StackName}-ArtifactorySslTargetGroup' ArtifactoryEc2Sg: Description: Artifactory EC2 sercurity group Value: !Ref ArtifactoryEc2Sg Export: Name: !Sub '${AWS::StackName}-ArtifactoryEc2Sg' BastionIp: Value: !If - EnableBastion - !GetAtt BastionStack.Outputs.EIP1 - "" XrayMasterDatabaseUrl: Description: Database driver Value: !GetAtt ArtifactoryCoreInfraStack.Outputs.XrayMasterDatabaseUrl Export: Name: !Sub '${AWS::StackName}-XrayMasterDatabaseUrl' XrayDatabaseUrl: Description: Database driver Value: !GetAtt ArtifactoryCoreInfraStack.Outputs.XrayDatabaseUrl Export: Name: !Sub '${AWS::StackName}-XrayDatabaseUrl'