--- AWSTemplateFormatVersion: 2010-09-09 Description: 'Atlassian Confluence Data Center. (qs-1qup6ra2n)' Metadata: QuickStartDocumentation: EntrypointName: "Launch into an existing VPC" AWS::CloudFormation::Interface: ParameterGroups: - Label: default: Confluence setup Parameters: - CollaborativeEditingMode - ConfluenceVersion - Label: default: Cluster nodes Parameters: - CloudWatchIntegration - ClusterNodeInstanceType - ClusterNodeMax - ClusterNodeMin - ClusterNodeVolumeSize - SynchronyClusterNodeMax - SynchronyClusterNodeMin - SynchronyNodeInstanceType - DeploymentAutomationRepository - DeploymentAutomationBranch - DeploymentAutomationPlaybook - DeploymentAutomationCustomParams - DeploymentAutomationKeyName - Label: default: Database Parameters: - DBEngine - DBEngineVersion - DBInstanceClass - DBIops - DBMasterUserPassword - DBMultiAZ - DBPassword - DBStorage - DBStorageEncrypted - DBStorageType - Label: default: Bastion host utilization Parameters: - BastionHostRequired - KeyPairName - Label: default: Networking Parameters: - CidrBlock - InternetFacingLoadBalancer - SSLCertificateARN - Label: default: DNS Parameters: - CustomDnsName - HostedZone - Label: default: Advanced (Optional) Parameters: - AutologinCookieAge - Label: default: Application tuning Parameters: - TomcatContextPath - CatalinaOpts - JvmHeapOverride - JvmHeapOverrideSynchrony - DBPoolMaxSize - DBPoolMinSize - DBTimeout - DBIdleTestPeriod - DBMaxStatements - DBValidate - DBPreferredTestQuery - DBAcquireIncrement - MailEnabled - TomcatAcceptCount - TomcatConnectionTimeout - TomcatDefaultConnectorPort - TomcatEnableLookups - TomcatMaxThreads - TomcatMinSpareThreads - TomcatProtocol - TomcatRedirectPort - Label: default: AWS Quick Start configuration Parameters: - QSS3BucketName - QSS3KeyPrefix - ExportPrefix ParameterLabels: AutologinCookieAge: default: Remember Me cookie expiry CatalinaOpts: default: Catalina options CidrBlock: default: Permitted IP range CloudWatchIntegration: default: Enable CloudWatch integration ClusterNodeMax: default: Maximum number of cluster nodes ClusterNodeMin: default: Minimum number of cluster nodes ClusterNodeInstanceType: default: Cluster node instance type ClusterNodeVolumeSize: default: Cluster node instance volume size CollaborativeEditingMode: default: Collaborative editing mode ConfluenceVersion: default: Version * CustomDnsName: default: Existing DNS name DBAcquireIncrement: default: DB Acquire Increment DBIdleTestPeriod: default: DB Idle Test Period DBEngine: default: Database engine DBEngineVersion: default: The database engine version to use DBInstanceClass: default: Database instance class DBIops: default: RDS Provisioned IOPS DBMasterUserPassword: default: Master (admin) password * DBMaxStatements: default: DB Max Statements DBMultiAZ: default: Enable RDS Multi-AZ deployment DBPassword: default: Application user database password * DBPoolMaxSize: default: DB Pool Maximum Size DBPoolMinSize: default: DB Pool Minimum Size DBPreferredTestQuery: default: DB Preferred Test Query DBStorage: default: Database storage DBStorageEncrypted: default: Database encryption DBStorageType: default: Database storage type DBTimeout: default: DB Timeout DBValidate: default: DB Validate DeploymentAutomationRepository: default: Deployment Automation Git Repository URL DeploymentAutomationBranch: default: Deployment Automation Branch DeploymentAutomationPlaybook: default: Ansible playbook DeploymentAutomationCustomParams: default: Custom command-line parameters for Ansible DeploymentAutomationKeyName: default: SSH keyname to use with the repository ExportPrefix: default: ASI identifier HostedZone: default: Route 53 Hosted Zone InternetFacingLoadBalancer: default: Make instance internet facing JvmHeapOverride: default: Confluence Heap Size Override JvmHeapOverrideSynchrony: default: Synchrony Heap Size Override BastionHostRequired: default: Use Bastion host KeyPairName: default: SSH Key Pair Name MailEnabled: default: Enable App to Process Email SSLCertificateARN: default: SSL Certificate ARN SynchronyClusterNodeMax: default: Maximum number of Synchrony cluster nodes SynchronyClusterNodeMin: default: Minimum number of Synchrony cluster nodes SynchronyNodeInstanceType: default: Synchrony cluster node instance type TomcatAcceptCount: default: Tomcat Accept Count TomcatConnectionTimeout: default: Tomcat Connection Timeout TomcatContextPath: default: Tomcat Context Path TomcatDefaultConnectorPort: default: Tomcat Default Connector Port TomcatEnableLookups: default: Tomcat Enable DNS Lookups TomcatMaxThreads: default: Tomcat Maximum Threads TomcatMinSpareThreads: default: Tomcat Minimum Spare Threads TomcatProtocol: default: Tomcat Protocol TomcatRedirectPort: default: Tomcat Redirect Port QSS3BucketName: default: Quick Start S3 Bucket Name QSS3KeyPrefix: default: Quick Start S3 Key Prefix Parameters: AutologinCookieAge: Default: '' Description: Sets the Remember Me (autologin) cookie expiry length in seconds. If blank this defaults to 1 year. Type: String CatalinaOpts: Default: '' Description: Java options that are passed to the Java virtual machine (JVM) that runs Confluence. Type: String CidrBlock: 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. Description: CIDR block allowed to access the Atlassian product. This should be set to a trusted IP range; if you want to give public access use '0.0.0.0/0'. MinLength: 9 MaxLength: 18 Type: String CloudWatchIntegration: Default: "Metrics and Logs" Type: String Description: "Enables CloudWatch metrics with or without log gathering. If cost is an issue, you can disable this altogether." AllowedValues: ["Off", "Metrics Only", "Metrics and Logs"] ConstraintDescription: "Must be 'Off', 'Metrics Only', or 'Metrics and Logs'" ClusterNodeInstanceType: Default: c5.xlarge AllowedValues: - c4.large - c4.xlarge - c4.2xlarge - c4.4xlarge - c4.8xlarge - c5.large - c5.xlarge - c5.2xlarge - c5.4xlarge - c5.9xlarge - c5.18xlarge - c5d.large - c5d.xlarge - c5d.2xlarge - c5d.4xlarge - c5d.9xlarge - c5d.18xlarge - d2.xlarge - d2.2xlarge - d2.4xlarge - d2.8xlarge - h1.2xlarge - h1.4xlarge - h1.8xlarge - h1.16xlarge - i3.large - i3.xlarge - i3.2xlarge - i3.4xlarge - i3.8xlarge - i3.16xlarge - i3.metal - m4.large - m4.xlarge - m4.2xlarge - m4.4xlarge - m4.10xlarge - m4.16xlarge - m5.large - m5.xlarge - m5.2xlarge - m5.4xlarge - m5.12xlarge - m5.24xlarge - m5d.large - m5d.xlarge - m5d.2xlarge - m5d.4xlarge - m5d.12xlarge - m5d.24xlarge - r4.large - r4.xlarge - r4.2xlarge - r4.4xlarge - r4.8xlarge - r4.16xlarge - r5.large - r5.xlarge - r5.2xlarge - r5.4xlarge - r5.12xlarge - r5.24xlarge - r5d.large - r5d.xlarge - r5d.2xlarge - r5d.4xlarge - r5d.12xlarge - r5d.24xlarge - t2.medium - t2.large - t2.xlarge - t2.2xlarge - t3.medium - t3.large - t3.xlarge - t3.2xlarge - x1.16xlarge - x1.32xlarge - x1e.xlarge - x1e.2xlarge - x1e.4xlarge - x1e.8xlarge - x1e.16xlarge - x1e.32xlarge - z1d.large - z1d.xlarge - z1d.2xlarge - z1d.3xlarge - z1d.6xlarge - z1d.12xlarge ConstraintDescription: Must be an EC2 instance type from the selection list Description: Instance type for the cluster application nodes (note - for "synchrony-local" collaborative editing you must choose an instance size with over 5 GB RAM). Type: String ClusterNodeMax: Description: Maximum number of nodes in the cluster. Default: 1 Type: Number ClusterNodeMin: Default: 1 Description: Set to 1 for new deployment. Can be updated post launch. Type: Number ClusterNodeVolumeSize: Default: 50 Description: Size of cluster node root volume in GB (note - size based upon Application indexes x 4). Type: Number CollaborativeEditingMode: Default: synchrony-local AllowedValues: - none - synchrony-local - synchrony-separate-nodes Description: Collaborative Editing can be off, run locally on the Confluence nodes (requires Confluence version 6.12+ and 1 GB heap free for Synchrony), or run on a separately autoscaled group of nodes. Type: String ConfluenceVersion: Default: '7.13.7' AllowedPattern: '(\d+\.\d+\.\d+(-?.*))' ConstraintDescription: "Must be a valid Confluence version number, for example 6.13.2. Find valid versions at https://confluence.atlassian.com/display/DOC/Confluence+Release+Notes" Description: The version of Confluence to install Type: String CustomDnsName: Default: '' Description: '(Optional) Use custom existing DNS name for your Data Center instance. This will take precedence over HostedZone. Please note: you must own the domain and configure it to point at the load balancer.' Type: String DBEngine: Default: 'PostgreSQL' Description: 'The database engine to use. The default is PostgreSQL (Amazon RDS for PostgreSQL). You can choose Amazon Aurora PostgreSQL.' AllowedValues: - 'Amazon Aurora PostgreSQL' - 'PostgreSQL' ConstraintDescription: Must be 'Amazon Aurora PostgreSQL' or 'PostgreSQL'. Type: String DBEngineVersion: Default: 10 AllowedValues: - 9 - 10 - 11 Description: "The database engine version to use; we'll install a suitable minor version for your chosen engine. Make sure that the Confluence version you're installing supports the database engine selected. (Warning: Amazon RDS for PostgreSQL 9.6 will reach end of life on January 31st, 2022. Deployments after this date should not be made using this version. If you wish to upgrade to a major version from 9 see: https://confluence.atlassian.com/x/1IRlQQ)" Type: String DBInstanceClass: Default: db.m4.large AllowedValues: - db.m5.large - db.m5.xlarge - db.m5.2xlarge - db.m5.4xlarge - db.m5.12xlarge - db.m5.24xlarge - db.m4.large - db.m4.xlarge - db.m4.2xlarge - db.m4.4xlarge - db.m4.10xlarge - db.m4.16xlarge - db.r5.large - db.r5.xlarge - db.r5.2xlarge - db.r5.4xlarge - db.r5.12xlarge - db.r5.24xlarge - db.r4.large - db.r4.xlarge - db.r4.2xlarge - db.r4.4xlarge - db.r4.8xlarge - db.r4.16xlarge - db.t3.medium - db.t3.large - db.t3.xlarge - db.t3.2xlarge - db.t2.medium - db.t2.large - db.t2.xlarge - db.t2.2xlarge ConstraintDescription: Must be a valid RDS instance class from the list. Description: RDS instance type (must be R4 family if using Amazon Aurora). Type: String DBIops: Default: 1000 ConstraintDescription: Must be in the range 1000 - 30000. Description: 'Must be in the range of 1000 - 30000 and a multiple of 1000. This value is only used with Provisioned IOPS. Note: The ratio of IOPS per allocated-storage must be between 3.00 and 10.00. Not used for Amazon Aurora.' MinValue: 1000 MaxValue: 30000 Type: Number DBMasterUserPassword: AllowedPattern: >- ^(?=^.{8,255}$)(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^A-Za-z0-9])(?!.*[@/"']).*$ ConstraintDescription: >- Must be at least 8 characters and include 1 uppercase, 1 lowercase, 1 number, and 1 of the following symbols: ! # $ { * : [ = , ] - _ + % & Description: "Password for the master ('postgres') account. Must be at least 8 characters and include 1 uppercase, 1 lowercase, 1 number, and 1 of the following symbols: ! # $ { * : [ = , ] - _ + % &" MinLength: 8 MaxLength: 128 NoEcho: true Type: String DBMultiAZ: Description: When DBEngine is 'PostgreSQL', this will determine whether to provision a multi-AZ RDS instance. When DBEngine is 'Amazon Aurora PostgreSQL', this will determine whether to provision a single or a multiple-node Amazon Aurora cluster. Default: "true" AllowedValues: - "true" - "false" ConstraintDescription: Must be 'true' or 'false'. Type: String DBPassword: AllowedPattern: '(?=^.{6,255}$)((?=.*\\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: 'Must be at least 8 characters and include 1 uppercase, 1 lowercase, 1 number, and 1 of the following symbols: ! # $ { * : [ = , ] - _ @ + % &' Description: "Database password used by Confluence. Must be at least 8 characters and include 1 uppercase, 1 lowercase, 1 number, and 1 of the following symbols: ! # $ { * : [ = , ] - _ @ + % &" MinLength: 8 MaxLength: 128 NoEcho: true Type: String DBPoolMaxSize: Default: 60 Description: The maximum number of database connections that can be opened at any time. See https://confluence.atlassian.com/doc/performance-tuning-130289.html for reference on tuning database parameters. Type: Number DBPoolMinSize: Default: 20 Description: The minimum number of idle database connections that are kept open at any time. Type: Number DBTimeout: Default: 30 Description: Number of seconds that Connections in excess of minPoolSize should be permitted to remain idle in the pool before being culled. Type: Number DBIdleTestPeriod: Default: 100 Description: If greater than 0, this is the frequency (in seconds) that c3po will test all idle, pooled but unchecked-out connections. Type: Number DBMaxStatements: Default: 0 Description: "The size of c3p0's global PreparedStatement cache. It controls the total number of statements cached, for all connections. If set, it should be a fairly large number, as each pooled Connection requires its own, distinct flock of cached statements." Type: Number DBValidate: Default: "false" AllowedValues: - "true" - "false" Description: If true, a connection test will be performed at every connection checkout to verify that the connection is valid. Type: String DBPreferredTestQuery: Default: 'select version();' Description: The query that will be executed for all connection tests. Type: String DBAcquireIncrement: Default: 1 Description: Determines how many connections at a time c3p0 will try to acquire when the pool is exhausted. Type: Number DBStorage: Default: 200 Description: Database allocated storage size, in gigabytes (GB). If you choose Provisioned IOPS, storage should be between 100 and 6144. Not used for Amazon Aurora. Type: Number DBStorageEncrypted: Default: "false" AllowedValues: - "true" - "false" Description: Whether or not to encrypt the database. Type: String DBStorageType: Default: General Purpose (SSD) AllowedValues: - General Purpose (SSD) - Provisioned IOPS ConstraintDescription: Must be 'General Purpose (SSD)' or 'Provisioned IOPS'. Description: Database storage type. Not used for Amazon Aurora. Type: String DeploymentAutomationRepository: Default: 'https://bitbucket.org/atlassian/dc-deployments-automation.git' Type: String Description: The deployment automation repository to use for per-node initialization. Leave this as default unless you have customizations. DeploymentAutomationBranch: Default: "master" Type: String Description: The deployment automation repository branch to pull from. DeploymentAutomationPlaybook: Default: "aws_confluence_dc_node.yml" Type: String Description: The Ansible playbook to invoke to initialize the application node on first start. DeploymentAutomationCustomParams: Default: "" Type: String Description: Additional command-line options for the `ansible-playbook` command. See https://bitbucket.org/atlassian/dc-deployments-automation/src/master/README.md for more information about overriding parameters. (Optional) DeploymentAutomationKeyName: Default: "" Type: String Description: Named Key Pair name to use with this repository. The key should be imported into the SSM parameter store. (Optional) ExportPrefix: Default: 'ATL-' Description: Identifier used in all variables exported from this deployment’s Atlassian Standard Infrastructure (VPCID, SubnetIDs, KeyName). Use different identifier to deploy multiple Atlassian Standard Infrastructures in the same AWS region. Type: String HostedZone: Default: '' ConstraintDescription: Must be the name of an existing Amazon Route 53 Hosted Zone. Description: (Optional) The domain name of the Amazon Route 53 PRIVATE Hosted Zone in which to create cnames. Type: String InternetFacingLoadBalancer: Default: "true" AllowedValues: ["true", "false"] ConstraintDescription: Must be 'true' or 'false'. Description: Controls whether the load balancer should be visible to the internet (true) or only within the VPC (false). Type: String JvmHeapOverride: Default: '' Description: The heap size to use, in MB (e.g., 1024m) or GB (e.g., 1g), to override the default amount of memory to allocate to the JVM for your instance type. Type: String JvmHeapOverrideSynchrony: Default: '' Description: The heap size to use, in MiB (e.g., 1024m) or GiB (e.g., 1g), to override the default amount of memory to allocate to the JVM for Synchrony. Type: String BastionHostRequired: Default: "true" AllowedValues: - "true" - "false" Description: Whether to grant access to Confluence EC2 instances through the ASI's Bastion host (if it exists). If 'true', remember to provide an EC2 Key Pair. If your ASI does not have a Bastion host, set this to 'false'. Type: String KeyPairName: ConstraintDescription: Must be the name of an existing EC2 Key Pair. Note the supplied value must not include the file extension. Description: Public/private EC2 Key Pairs (without file extension) to allow you to securely access the Bastion host. Type: String Default: '' MailEnabled: AllowedValues: - "true" - "false" ConstraintDescription: Must be 'true' or 'false'. Default: "true" Description: Enable mail processing and sending. Type: String SSLCertificateARN: Default: '' Description: "Amazon Resource Name (ARN) of your SSL certificate. If you want to use your own certificate that you generated outside of Amazon, you need to first import it to AWS Certificate Manager. After a successful import, you'll receive the ARN. If you want to create a certificate with AWS Certificate Manager (ACM certificate), you will receive the ARN after it's successfully created." MinLength: 0 MaxLength: 90 Type: String SynchronyClusterNodeMax: Description: Maximum number of Synchrony cluster nodes. Default: 1 Type: Number SynchronyClusterNodeMin: Description: Minimum number of Synchrony cluster nodes. Default: 1 Type: Number SynchronyNodeInstanceType: Default: t3.medium AllowedValues: - c4.large - c4.xlarge - c4.2xlarge - c4.4xlarge - c4.8xlarge - c5.large - c5.xlarge - c5.2xlarge - c5.4xlarge - c5.9xlarge - c5.18xlarge - c5d.large - c5d.xlarge - c5d.2xlarge - c5d.4xlarge - c5d.9xlarge - c5d.18xlarge - d2.xlarge - d2.2xlarge - d2.4xlarge - d2.8xlarge - h1.2xlarge - h1.4xlarge - h1.8xlarge - h1.16xlarge - i3.large - i3.xlarge - i3.2xlarge - i3.4xlarge - i3.8xlarge - i3.16xlarge - i3.metal - m4.large - m4.xlarge - m4.2xlarge - m4.4xlarge - m4.10xlarge - m4.16xlarge - m5.large - m5.xlarge - m5.2xlarge - m5.4xlarge - m5.12xlarge - m5.24xlarge - m5d.large - m5d.xlarge - m5d.2xlarge - m5d.4xlarge - m5d.12xlarge - m5d.24xlarge - r4.large - r4.xlarge - r4.2xlarge - r4.4xlarge - r4.8xlarge - r4.16xlarge - r5.large - r5.xlarge - r5.2xlarge - r5.4xlarge - r5.12xlarge - r5.24xlarge - r5d.large - r5d.xlarge - r5d.2xlarge - r5d.4xlarge - r5d.12xlarge - r5d.24xlarge - t2.medium - t2.large - t2.xlarge - t2.2xlarge - t3.medium - t3.large - t3.xlarge - t3.2xlarge - x1.16xlarge - x1.32xlarge - x1e.xlarge - x1e.2xlarge - x1e.4xlarge - x1e.8xlarge - x1e.16xlarge - x1e.32xlarge - z1d.large - z1d.xlarge - z1d.2xlarge - z1d.3xlarge - z1d.6xlarge - z1d.12xlarge ConstraintDescription: Must be an EC2 instance type from the selection list Description: Synchrony cluster node instance type. Type: String TomcatAcceptCount: Default: 10 Description: The maximum queue length for incoming connection requests when all possible request processing threads are in use. Type: Number TomcatConnectionTimeout: Default: 20000 Description: The number of milliseconds this connector will wait, after accepting a connection, for the request URI line to be presented. Type: Number TomcatContextPath: Default: '' AllowedPattern: '^(\/[A-z_\-0-9\.]+)?$' Description: The context path of this web application, which is matched against the beginning of each request URI to select the appropriate web application for processing. If used, must include leading "/". See http://tomcat.apache.org/tomcat-8.0-doc/config/http.html for reference on tuning tomcat parameters. Type: String TomcatDefaultConnectorPort: Default: 8080 Description: The port on which to serve the application. Type: Number TomcatEnableLookups: Default: "false" AllowedValues: - "true" - "false" Description: Set to true if you want calls to request.getRemoteHost() to perform DNS lookups in order to return the actual host name of the remote client. Type: String TomcatMaxThreads: Default: 48 Description: The maximum number of request processing threads to be created by this connector, which therefore determines the maximum number of simultaneous requests that can be handled. Type: Number TomcatMinSpareThreads: Default: 10 Description: The minimum number of threads always kept running. Type: Number TomcatProtocol: Default: 'HTTP/1.1' Description: Sets the protocol to handle incoming traffic. Type: String TomcatRedirectPort: Default: 8443 Description: The port number for Catalina to use when automatically redirecting a non-SSL connector actioning a redirect to a SSL URI. Type: Number QSS3BucketName: Default: 'aws-quickstart' 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: 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 QSS3KeyPrefix: Default: 'quickstart-atlassian-confluence/' AllowedPattern: ^[0-9a-zA-Z-/]*$ ConstraintDescription: Quick Start key prefix can include numbers, lowercase letters, uppercase letters, hyphens (-), and forward slash (/). 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 Conditions: DisableMail: !Not [!Equals [!Ref MailEnabled, true]] DoSSL: !Not [!Equals [!Ref SSLCertificateARN, '']] EnableCloudWatch: !Not [!Equals [!Ref CloudWatchIntegration, 'Off']] EnableCloudWatchLogs: !Equals [!Ref CloudWatchIntegration, 'Metrics and Logs'] KeyProvided: !Not [!Equals [!Ref KeyPairName, '']] OverrideHeap: !Not [!Equals [!Ref JvmHeapOverride, '']] OverrideHeapSynchrony: !Not [!Equals [!Ref JvmHeapOverrideSynchrony, '']] UseContextPath: !Not [!Equals [!Ref TomcatContextPath, '']] UseCustomDnsName: !Not [!Equals [!Ref CustomDnsName, '']] UseDatabaseEncryption: !Equals [!Ref DBStorageEncrypted, true] UseHostedZone: !Not [!Equals [!Ref HostedZone, '']] UsePublicIp: !Equals [!Ref InternetFacingLoadBalancer, 'true'] UseSynchronyAutoScalingGroup: !Equals [!Ref CollaborativeEditingMode, 'synchrony-separate-nodes'] GovCloudCondition: !Equals [!Ref 'AWS::Region', 'us-gov-west-1'] DBEngineAurora: !Equals [!Ref DBEngine, "Amazon Aurora PostgreSQL"] DBEnginePostgres: !Equals [!Ref DBEngine, "PostgreSQL"] UseBastionHost: !And - !Equals [!Ref BastionHostRequired, true] - !Condition KeyProvided Mappings: AWSInstanceType2Arch: c4.large: Arch: HVM64 Jvmheap: 2304m c4.xlarge: Arch: HVM64 Jvmheap: 4608m c4.2xlarge: Arch: HVM64 Jvmheap: 12288m c4.4xlarge: Arch: HVM64 Jvmheap: 12288m c4.8xlarge: Arch: HVM64 Jvmheap: 12288m c5.large: Arch: HVM64 Jvmheap: 2048m c5.xlarge: Arch: HVM64 Jvmheap: 5120m c5.2xlarge: Arch: HVM64 Jvmheap: 12288m c5.4xlarge: Arch: HVM64 Jvmheap: 12288m c5.9xlarge: Arch: HVM64 Jvmheap: 12288m c5.18xlarge: Arch: HVM64 Jvmheap: 12288m c5d.large: Arch: HVM64 Jvmheap: 2048m c5d.xlarge: Arch: HVM64 Jvmheap: 5120m c5d.2xlarge: Arch: HVM64 Jvmheap: 12288m c5d.4xlarge: Arch: HVM64 Jvmheap: 12288m c5d.9xlarge: Arch: HVM64 Jvmheap: 12288m c5d.18xlarge: Arch: HVM64 Jvmheap: 12288m d2.xlarge: Arch: HVM64 Jvmheap: 12288m d2.2xlarge: Arch: HVM64 Jvmheap: 12288m d2.4xlarge: Arch: HVM64 Jvmheap: 12288m d2.8xlarge: Arch: HVM64 Jvmheap: 12288m h1.2xlarge: Arch: HVM64 Jvmheap: 12288m h1.4xlarge: Arch: HVM64 Jvmheap: 12288m h1.8xlarge: Arch: HVM64 Jvmheap: 12288m h1.16xlarge: Arch: HVM64 Jvmheap: 12288m i3.large: Arch: HVM64 Jvmheap: 12288m i3.xlarge: Arch: HVM64 Jvmheap: 12288m i3.2xlarge: Arch: HVM64 Jvmheap: 12288m i3.4xlarge: Arch: HVM64 Jvmheap: 12288m i3.8xlarge: Arch: HVM64 Jvmheap: 12288m i3.16xlarge: Arch: HVM64 Jvmheap: 12288m i3.metal: Arch: HVM64 Jvmheap: 12288m m4.large: Arch: HVM64 Jvmheap: 5120m m4.xlarge: Arch: HVM64 Jvmheap: 12288m m4.2xlarge: Arch: HVM64 Jvmheap: 12288m m4.4xlarge: Arch: HVM64 Jvmheap: 12288m m4.10xlarge: Arch: HVM64 Jvmheap: 12288m m4.16xlarge: Arch: HVM64 Jvmheap: 12288m m5.large: Arch: HVM64 Jvmheap: 5120m m5.xlarge: Arch: HVM64 Jvmheap: 12288m m5.2xlarge: Arch: HVM64 Jvmheap: 12288m m5.4xlarge: Arch: HVM64 Jvmheap: 12288m m5.12xlarge: Arch: HVM64 Jvmheap: 12288m m5.24xlarge: Arch: HVM64 Jvmheap: 12288m m5d.large: Arch: HVM64 Jvmheap: 5120m m5d.xlarge: Arch: HVM64 Jvmheap: 12288m m5d.2xlarge: Arch: HVM64 Jvmheap: 12288m m5d.4xlarge: Arch: HVM64 Jvmheap: 12288m m5d.12xlarge: Arch: HVM64 Jvmheap: 12288m m5d.24xlarge: Arch: HVM64 Jvmheap: 12288m r4.large: Arch: HVM64 Jvmheap: 12288m r4.xlarge: Arch: HVM64 Jvmheap: 12288m r4.2xlarge: Arch: HVM64 Jvmheap: 12288m r4.4xlarge: Arch: HVM64 Jvmheap: 12288m r4.8xlarge: Arch: HVM64 Jvmheap: 12288m r4.16xlarge: Arch: HVM64 Jvmheap: 12288m r5.large: Arch: HVM64 Jvmheap: 12288m r5.xlarge: Arch: HVM64 Jvmheap: 12288m r5.2xlarge: Arch: HVM64 Jvmheap: 12288m r5.4xlarge: Arch: HVM64 Jvmheap: 12288m r5.12xlarge: Arch: HVM64 Jvmheap: 12288m r5.24xlarge: Arch: HVM64 Jvmheap: 12288m r5d.large: Arch: HVM64 Jvmheap: 12288m r5d.xlarge: Arch: HVM64 Jvmheap: 12288m r5d.2xlarge: Arch: HVM64 Jvmheap: 12288m r5d.4xlarge: Arch: HVM64 Jvmheap: 12288m r5d.12xlarge: Arch: HVM64 Jvmheap: 12288m r5d.24xlarge: Arch: HVM64 Jvmheap: 12288m t2.medium: Arch: HVM64 Jvmheap: 2048m t2.large: Arch: HVM64 Jvmheap: 5120m t2.xlarge: Arch: HVM64 Jvmheap: 12288m t2.2xlarge: Arch: HVM64 Jvmheap: 12288m t3.medium: Arch: HVM64 Jvmheap: 2048m t3.large: Arch: HVM64 Jvmheap: 5120m t3.xlarge: Arch: HVM64 Jvmheap: 12288m t3.2xlarge: Arch: HVM64 Jvmheap: 12288m x1.16xlarge: Arch: HVM64 Jvmheap: 12288m x1.32xlarge: Arch: HVM64 Jvmheap: 12288m x1e.xlarge: Arch: HVM64 Jvmheap: 12288m x1e.2xlarge: Arch: HVM64 Jvmheap: 12288m x1e.4xlarge: Arch: HVM64 Jvmheap: 12288m x1e.8xlarge: Arch: HVM64 Jvmheap: 12288m x1e.16xlarge: Arch: HVM64 Jvmheap: 12288m x1e.32xlarge: Arch: HVM64 Jvmheap: 12288m z1d.large: Arch: HVM64 Jvmheap: 12288m z1d.xlarge: Arch: HVM64 Jvmheap: 12288m z1d.2xlarge: Arch: HVM64 Jvmheap: 12288m z1d.3xlarge: Arch: HVM64 Jvmheap: 12288m z1d.6xlarge: Arch: HVM64 Jvmheap: 12288m z1d.12xlarge: Arch: HVM64 Jvmheap: 12288m AWSRegionArch2AMI: ap-northeast-1: HVM64: ami-08d56ac42e2d4a08b ap-northeast-2: HVM64: ami-0eb7a369386789460 ap-south-1: HVM64: ami-0dafa01c8100180f8 ap-southeast-1: HVM64: ami-04fc979a55e14b094 ap-southeast-2: HVM64: ami-042c4533fa25c105a ca-central-1: HVM64: ami-040d8c460f4fc4a9f eu-central-1: HVM64: ami-00e232b942edaf8f9 eu-north-1: HVM64: ami-0e3f1570eb0a9bc7f eu-west-1: HVM64: ami-09d5dd12541e69077 eu-west-2: HVM64: ami-098a393b6fa6e700b eu-west-3: HVM64: ami-05cb6b584fc3c8ac8 sa-east-1: HVM64: ami-088911543b10876a4 us-east-1: HVM64: ami-038b3df3312ddf25d us-east-2: HVM64: ami-07b1d7739c91ed3fc us-west-1: HVM64: ami-0729cd65c1a99b0c9 us-west-2: HVM64: ami-090bc08d7ae1f3881 us-gov-west-1: HVM64: ami-0bbf3595bb2fb39ec us-gov-east-1: HVM64: ami-0cc17d57bec8c6017 Resources: ConfluenceClusterNodeRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: [ec2.amazonaws.com] Action: ['sts:AssumeRole'] ManagedPolicyArns: - !Sub 'arn:${AWS::Partition}:iam::aws:policy/AmazonSSMManagedInstanceCore' - !Sub "arn:${AWS::Partition}:iam::aws:policy/CloudWatchAgentServerPolicy" Path: / Policies: - PolicyName: ConfluenceClusterNodePolicy PolicyDocument: Version: 2012-10-17 Statement: - Action: - ec2:CreateTags - s3:ListBucket Effect: Allow Resource: - !Sub "arn:${AWS::Partition}:ec2:*:${AWS::AccountId}:instance/*" - !Sub "arn:${AWS::Partition}:ec2:*:${AWS::AccountId}:vpc/*" - !Sub "arn:${AWS::Partition}:s3:::/atlassian-software/releases/confluence" - Action: - autoscaling:CreateOrUpdateTags - route53:ListResourceRecordSets - s3:ListBucket Effect: Allow Resource: - !Sub "arn:${AWS::Partition}:route53:::hostedzone/*" - !Sub "arn:${AWS::Partition}:autoscaling:*:${AWS::AccountId}:autoScalingGroup:*:autoScalingGroupName/*" - !Sub "arn:${AWS::Partition}:s3:::/aws-deployment-test/releases/confluence" - Action: - ec2:DescribeInstances - ec2:DescribeTags - autoscaling:DescribeTags - route53:ListHostedZones Effect: Allow Resource: "*" - Action: - route53:ChangeResourceRecordSets - s3:ListBucket Effect: Allow Resource: - !Sub "arn:${AWS::Partition}:route53:::hostedzone/*" - !Sub "arn:${AWS::Partition}:route53:::healthcheck/*" - !Sub "arn:${AWS::Partition}:route53:::change/*" - !Sub "arn:${AWS::Partition}:route53:::delegationset/*" - !Sub "arn:${AWS::Partition}:s3:::/atlassian-software/snapshots/confluence" - Action: s3:Get* Effect: Allow Resource: !Sub "arn:${AWS::Partition}:s3:::/aws-deployment-test/releases/confluence/*" - Action: s3:Get* Effect: Allow Resource: !Sub "arn:${AWS::Partition}:s3:::/atlassian-software/releases/confluence/*" - Action: s3:Get* Effect: Allow Resource: !Sub "arn:${AWS::Partition}:s3:::/atlassian-software/snapshots/confluence/*" - PolicyName: SSMParameterPutAccess PolicyDocument: Version: 2012-10-17 Statement: - Action: - 'ssm:PutParameter' Effect: Allow Resource: !Sub "arn:${AWS::Partition}:ssm:${AWS::Region}:${AWS::AccountId}:parameter/${AWS::StackName}/pinned-ansible-sha" ConfluenceClusterNodeInstanceProfile: Type: AWS::IAM::InstanceProfile Properties: Path: / Roles: [!Ref ConfluenceClusterNodeRole] # Confluence node config ClusterNodeGroup: Type: AWS::AutoScaling::AutoScalingGroup CreationPolicy: ResourceSignal: Count: !Ref ClusterNodeMin Timeout: PT15M Properties: DesiredCapacity: !Ref ClusterNodeMin LaunchConfigurationName: !Ref ClusterNodeLaunchConfig MinSize: !Ref ClusterNodeMin MaxSize: !Ref ClusterNodeMax TargetGroupARNs: [!Ref MainTargetGroup] VPCZoneIdentifier: !Split - "," - Fn::ImportValue: !Sub "${ExportPrefix}PriNets" Tags: - Key: Name Value: !Sub ["${StackName} Confluence Node", StackName: !Ref 'AWS::StackName'] PropagateAtLaunch: true - Key: Cluster Value: !Ref AWS::StackName PropagateAtLaunch: true # NOTE: The leading COMMIT/TIMESTAMP are used to locate the position to update; see scripts/update-tags.py - Key: "atl:quickstart:commit-id" Value: "COMMIT: 897142a7630be8e7b723d3d530a482dce454f607" PropagateAtLaunch: true - Key: "atl:quickstart:timestamp" Value: "TIMESTAMP: 2022-04-14T15:46:09Z" PropagateAtLaunch: true ClusterNodeLaunchConfig: Type: AWS::AutoScaling::LaunchConfiguration DependsOn: - EFSMountAz1 - EFSMountAz2 - AnsibleRepoPinSHA Metadata: AWS::CloudFormation::Init: config: files: /etc/atl: mode: "000640" owner: root group: root content: !Join - "\n" - - "ATL_PRODUCT_FAMILY=confluence" - "ATL_JDBC_DRIVER=org.postgresql.Driver" - "ATL_JDBC_DB_NAME=confluence" - "ATL_JDBC_USER=atlconfluence" - "ATL_APP_DATA_MOUNT_ENABLED=false" - "ATL_CONFLUENCE_DATA_CENTER=true" - "ATL_ENABLED_PRODUCTS=Confluence" - "ATL_ENABLED_SHARED_HOMES=" - "ATL_HAZELCAST_NETWORK_AWS_TAG_KEY=Cluster" - "ATL_HAZELCAST_NETWORK_AWS_HOST_HEADER=ec2.amazonaws.com" - "ATL_RELEASE_S3_BUCKET=atlassian-software" - "ATL_RELEASE_S3_PATH=releases/confluence" - "ATL_SSL_SELF_CERT_ENABLED=false" - "" - !Sub ["ATL_PRODUCT_VERSION=${ConfluenceVersion}", ConfluenceVersion: !Ref ConfluenceVersion] - !Sub ["ATL_EFS_ID=${ElasticFileSystem}", ElasticFileSystem: !Ref "ElasticFileSystem"] - !If [DoSSL, "ATL_SSL_PROXY=true", !Ref "AWS::NoValue"] - !If [UseSynchronyAutoScalingGroup, !Sub ["ATL_SYNCHRONY_SERVICE_URL=${Protocol}://${LoadBalancerName}/synchrony/v1", {Protocol: !If [DoSSL, "https", "http"], LoadBalancerName: !If [UseCustomDnsName, !Ref CustomDnsName, !If [UseHostedZone, !Ref LoadBalancerCname, !If [UseCustomDnsName, !Ref CustomDnsName, !GetAtt LoadBalancer.DNSName]]]}], !Ref "AWS::NoValue"] - !Sub ["ATL_AWS_STACK_NAME=${StackName}", StackName: !Ref "AWS::StackName"] - !Sub ["ATL_AUTOLOGIN_COOKIE_AGE=${AutologinCookieAge}", AutologinCookieAge: !Ref AutologinCookieAge] - !Sub ["ATL_CATALINA_OPTS=\"${CatalinaOpts} ${MailOpts}\"", { CatalinaOpts: !Ref CatalinaOpts, MailOpts: !If [DisableMail, '-Datlassian.mail.senddisabled=true -Datlassian.mail.fetchdisabled=true -Datlassian.mail.popdisabled=true -Dconfluence.disable.mailpolling=true', ''] }] - !Sub ["ATL_DB_ACQUIREINCREMENT=${DBAcquireIncrement}", DBAcquireIncrement: !Ref DBAcquireIncrement] - !Sub ["ATL_DB_ENGINE=${DBEngine}", DBEngine: !If [DBEngineAurora, aurora_postgres, !If [DBEnginePostgres, rds_postgres, '']]] - !Sub ["ATL_DB_HOST=${DBEndpointAddress}", DBEndpointAddress: !GetAtt DB.Outputs.RDSEndPointAddress] - !Sub ["ATL_DB_IDLETESTPERIOD=${DBIdleTestPeriod}", DBIdleTestPeriod: !Ref DBIdleTestPeriod] - !Sub ["ATL_DB_MAXSTATEMENTS=${DBMaxStatements}", DBMaxStatements: !Ref DBMaxStatements] - !Sub ["ATL_DB_ROOT_PASSWORD='${DBMasterUserPassword}'", DBMasterUserPassword: !Ref DBMasterUserPassword] - !Sub ["ATL_DB_POOLMAXSIZE=${DBPoolMaxSize}", DBPoolMaxSize: !Ref DBPoolMaxSize] - !Sub ["ATL_DB_POOLMINSIZE=${DBPoolMinSize}", DBPoolMinSize: !Ref DBPoolMinSize] - !Sub ["ATL_DB_PORT=${DBEndpointPort}", DBEndpointPort: !GetAtt DB.Outputs.RDSEndPointPort] - !Sub ["ATL_DB_PREFERREDTESTQUERY=\"${DBPreferredTestQuery}\"", DBPreferredTestQuery: !Ref DBPreferredTestQuery] - !Sub ["ATL_DB_TIMEOUT=${DBTimeout}", DBTimeout: !Ref DBTimeout] - !Sub ["ATL_DB_VALIDATE=${DBValidate}", DBValidate: !Ref DBValidate] - !Sub ["ATL_HAZELCAST_NETWORK_AWS_IAM_REGION=${HazelcastAWSRegion}", HazelcastAWSRegion: !Ref "AWS::Region"] - !Sub ["ATL_HAZELCAST_NETWORK_AWS_IAM_ROLE=${ConfluenceClusterNodeRole}", ConfluenceClusterNodeRole: !Ref ConfluenceClusterNodeRole] - !Sub ["ATL_HAZELCAST_NETWORK_AWS_TAG_VALUE=${HazelcastAWSTagValue}", HazelcastAWSTagValue: !Ref "AWS::StackName"] - !Sub ["ATL_HOSTEDZONE=${HostedZone}", HostedZone: !Ref HostedZone] - !Sub ["ATL_JDBC_PASSWORD='${DBPassword}'", DBPassword: !Ref DBPassword] - !Sub ["ATL_JVM_HEAP=${AtlJvmHeap}", AtlJvmHeap: !If [OverrideHeap, !Ref 'JvmHeapOverride', !FindInMap [AWSInstanceType2Arch, !Ref ClusterNodeInstanceType, Jvmheap]]] - !Sub ["ATL_PROXY_NAME=${AtlProxyName}", AtlProxyName: !If [UseCustomDnsName, !Ref CustomDnsName, !If [UseHostedZone, !Ref LoadBalancerCname, !GetAtt LoadBalancer.DNSName]]] - !Sub ["ATL_TOMCAT_ACCEPTCOUNT=${TomcatAcceptCount}", TomcatAcceptCount: !Ref TomcatAcceptCount] - !Sub ["ATL_TOMCAT_CONNECTIONTIMEOUT=${TomcatConnectionTimeout}", TomcatConnectionTimeout: !Ref TomcatConnectionTimeout] - !Sub ["ATL_TOMCAT_CONTEXTPATH=${TomcatContextPath}", TomcatContextPath: !Ref TomcatContextPath] - !Sub ["ATL_TOMCAT_DEFAULTCONNECTORPORT=${TomcatDefaultConnectorPort}", TomcatDefaultConnectorPort: !Ref TomcatDefaultConnectorPort] - !Sub ["ATL_TOMCAT_ENABLELOOKUPS=${TomcatEnableLookups}", TomcatEnableLookups: !Ref TomcatEnableLookups] - !Sub ["ATL_TOMCAT_MAXTHREADS=${TomcatMaxThreads}", TomcatMaxThreads: !Ref TomcatMaxThreads] - !Sub ["ATL_TOMCAT_MINSPARETHREADS=${TomcatMinSpareThreads}", TomcatMinSpareThreads: !Ref TomcatMinSpareThreads] - !Sub ["ATL_TOMCAT_PROTOCOL=${TomcatProtocol}", TomcatProtocol: !Ref TomcatProtocol] - !Sub ["ATL_TOMCAT_PROXYPORT=${TomcatProxyPort}", TomcatProxyPort: !If [DoSSL, 443, 80]] - !Sub ["ATL_TOMCAT_REDIRECTPORT=${TomcatRedirectPort}", TomcatRedirectPort: !Ref TomcatRedirectPort] - !Sub ["ATL_TOMCAT_SCHEME=${TomcatScheme}", TomcatScheme: !If [DoSSL, https, http]] - !Sub ["ATL_TOMCAT_SECURE=${TomcatSecure}", TomcatSecure: !If [DoSSL, true, false]] - !Sub ["ATL_DEPLOYMENT_REPOSITORY=${DeployRepository}", DeployRepository: !Ref "DeploymentAutomationRepository"] - !Sub ["ATL_DEPLOYMENT_REPOSITORY_BRANCH=${DeployRepositoryBranch}", DeployRepositoryBranch: !Ref "DeploymentAutomationBranch"] - !Sub ["ATL_DEPLOYMENT_REPOSITORY_PLAYBOOK=${DeployRepositoryPlaybook}", DeployRepositoryPlaybook: !Ref "DeploymentAutomationPlaybook"] - !Sub ["ATL_DEPLOYMENT_REPOSITORY_KEYNAME=${DeployRepositoryKeyName}", DeployRepositoryKeyName: !Ref "DeploymentAutomationKeyName"] - !Sub ["ATL_DEPLOYMENT_REPOSITORY_CUSTOM_PARAMS='${DeployRepositoryCustomParams}'", DeployRepositoryCustomParams: !Ref "DeploymentAutomationCustomParams"] - !Sub ["ATL_AWS_ENABLE_CLOUDWATCH=${EnableCW}", EnableCW: !If [EnableCloudWatch, true, false]] - !Sub ["ATL_AWS_ENABLE_CLOUDWATCH_LOGS=${EnableCWLogs}", EnableCWLogs: !If [EnableCloudWatchLogs, true, false]] /opt/atlassian/bin/clone_deployment_repo: content: !Sub | #!/bin/bash key_location=/root/.ssh/deployment_repo_key key_name="${DeploymentAutomationKeyName}" ssm_pin=/${AWS::StackName}/pinned-ansible-sha yum install -y git awscli jq if [[ ! -z "$key_name" ]]; then # Ensure awscli is up to date key_val=$(aws --region=${AWS::Region} ssm get-parameters --names "$key_name" --with-decryption | jq --raw-output '.Parameters[0].Value') echo -e "$key_val" > $key_location chmod 600 $key_location export GIT_SSH_COMMAND="ssh -o IdentitiesOnly=yes -o StrictHostKeyChecking=no -i $key_location" else export GIT_SSH_COMMAND="ssh -o IdentitiesOnly=yes -o StrictHostKeyChecking=no" fi ### Ansible repo pinning ### pinned_commit_id=$(aws --region=${AWS::Region} ssm get-parameters --names "$ssm_pin" | jq --raw-output '.Parameters[0].Value') git clone "${DeploymentAutomationRepository}" -b "${DeploymentAutomationBranch}" /opt/atlassian/dc-deployments-automation/ cd /opt/atlassian/dc-deployments-automation/ if [[ "$pinned_commit_id" == "latest" || -z "$pinned_commit_id" ]]; then head_id=$(git rev-parse HEAD) echo "SSM param [$ssm_pin] has been set to 'latest' - Using the HEAD SHA [$head_id] to build cluster [${AWS::StackName}]" echo "Updating SSM param [$ssm_pin] with current HEAD SHA: [$head_id]" aws --region=${AWS::Region} ssm put-parameter --name "$ssm_pin" --value "$head_id" --overwrite --type String else echo "Ansible repo has been pinned, checking out commit: [$pinned_commit_id]" git checkout -b "pinned-ansible-sha-$pinned_commit_id" "$pinned_commit_id" fi mode: "000750" owner: root group: root commands: 070_create_atl_dir: test: "test ! -d /opt/atlassian/" command: mkdir -p /opt/atlassian ignoreErrors: false 071_install_packages: command: yum install -y git python-virtualenv ignoreErrors: true 072_clone_atl_scripts: test: "test ! -d /opt/atlassian/dc-deployments-automation/" command: /opt/atlassian/bin/clone_deployment_repo ignoreErrors: true 080_run_atl_init_node: command: !Sub | cd /opt/atlassian/dc-deployments-automation/ && ./bin/install-ansible && ./bin/ansible-with-atl-env inv/aws_node_local ${DeploymentAutomationPlaybook} /var/log/ansible-bootstrap.log ignoreErrors: true Properties: AssociatePublicIpAddress: false BlockDeviceMappings: - DeviceName: /dev/xvda Ebs: VolumeSize: !Ref ClusterNodeVolumeSize - DeviceName: /dev/xvdf NoDevice: true KeyName: !If - KeyProvided - !Ref KeyPairName - Ref: AWS::NoValue IamInstanceProfile: !Ref ConfluenceClusterNodeInstanceProfile ImageId: !FindInMap - AWSRegionArch2AMI - !Ref AWS::Region - !FindInMap - AWSInstanceType2Arch - !Ref ClusterNodeInstanceType - Arch InstanceType: !Ref ClusterNodeInstanceType SecurityGroups: [!Ref SecurityGroup] UserData: Fn::Base64: !Join - "" - - "#!/bin/bash -xe\n" - "yum update -y aws-cfn-bootstrap\n" - !Sub ["/opt/aws/bin/cfn-init -v --stack ${StackName}", StackName: !Ref "AWS::StackName"] - !Sub [" --resource ClusterNodeLaunchConfig --region ${Region}\n", Region: !Ref "AWS::Region"] - !Sub ["/opt/aws/bin/cfn-signal -e $? --stack ${StackName}", StackName: !Ref "AWS::StackName"] - !Sub [" --resource ClusterNodeGroup --region ${Region}", Region: !Ref "AWS::Region"] ClusterNodeScaleUpPolicy: Type: AWS::AutoScaling::ScalingPolicy Properties: AdjustmentType: ChangeInCapacity AutoScalingGroupName: !Ref ClusterNodeGroup Cooldown: '600' ScalingAdjustment: 1 ClusterNodeScaleDownPolicy: Type: AWS::AutoScaling::ScalingPolicy Properties: AdjustmentType: ChangeInCapacity AutoScalingGroupName: !Ref ClusterNodeGroup Cooldown: '600' ScalingAdjustment: -1 CPUAlarmHigh: Type: AWS::CloudWatch::Alarm Properties: AlarmDescription: Scale up if CPU > 60% for 5 minutes MetricName: CPUUtilization Namespace: AWS/EC2 Statistic: Average Period: 60 EvaluationPeriods: 5 Threshold: 60 AlarmActions: [!Ref ClusterNodeScaleUpPolicy] Dimensions: - Name: AutoScalingGroupName Value: !Ref ClusterNodeGroup ComparisonOperator: GreaterThanThreshold CPUAlarmLow: Type: AWS::CloudWatch::Alarm Properties: AlarmDescription: Scale down if CPU < 40% for 30 minutes MetricName: CPUUtilization Namespace: AWS/EC2 Statistic: Average Period: 60 EvaluationPeriods: 30 Threshold: 40 AlarmActions: [!Ref ClusterNodeScaleDownPolicy] Dimensions: - Name: AutoScalingGroupName Value: !Ref ClusterNodeGroup ComparisonOperator: LessThanThreshold # Synchrony node config SynchronyClusterNodeGroup: Type: AWS::AutoScaling::AutoScalingGroup Condition: UseSynchronyAutoScalingGroup Properties: DesiredCapacity: !Ref SynchronyClusterNodeMin LaunchConfigurationName: !Ref SynchronyClusterNodeLaunchConfig MaxSize: !Ref SynchronyClusterNodeMax MinSize: !Ref SynchronyClusterNodeMin TargetGroupARNs: [!Ref SynchronyTargetGroup] VPCZoneIdentifier: !Split - "," - Fn::ImportValue: !Sub "${ExportPrefix}PriNets" Tags: - Key: Name Value: !Sub ["${StackName} Synchrony Node", StackName: !Ref 'AWS::StackName'] PropagateAtLaunch: true - Key: synchrony_service Value: !Ref AWS::StackName PropagateAtLaunch: true - Key: environment Value: Production PropagateAtLaunch: true SynchronyClusterNodeLaunchConfig: Type: AWS::AutoScaling::LaunchConfiguration Condition: UseSynchronyAutoScalingGroup DependsOn: - EFSMountAz1 - EFSMountAz2 - AnsibleRepoPinSHA Metadata: AWS::CloudFormation::Init: config: files: /etc/atl: mode: "000640" owner: root group: root content: !Join - "\n" - - "ATL_APP_DATA_MOUNT_ENABLED=false" - "ATL_CONFLUENCE_DATA_CENTER=true" - "ATL_JDBC_DB_NAME=confluence" - "ATL_ENABLED_PRODUCTS=Synchrony" - "ATL_ENABLED_SHARED_HOMES=" - "ATL_HAZELCAST_NETWORK_AWS_TAG_KEY=synchrony_service" - "ATL_JDBC_DRIVER=org.postgresql.Driver" - "ATL_JDBC_USER=atlconfluence" - "ATL_NGINX_ENABLED=false" - "ATL_POSTGRES_ENABLED=false" - "ATL_RELEASE_S3_BUCKET=atlassian-software" - "ATL_RELEASE_S3_PATH=releases/confluence" - "ATL_SSL_SELF_CERT_ENABLED=false" - "ATL_SYNCHRONY_STACK_SPACE=-Xss2048k" - "ATL_SYNCHRONY_WAITING_CONFIG_TIME=20" - !Sub ["ATL_EFS_ID=${ElasticFileSystem}", ElasticFileSystem: !Ref "ElasticFileSystem"] - !Sub ["ATL_PRODUCT_VERSION=${ConfluenceVersion}", ConfluenceVersion: !Ref ConfluenceVersion] - !If [DoSSL, "ATL_SSL_PROXY=true", !Ref "AWS::NoValue"] - !Sub ["ATL_AWS_STACK_NAME=${StackName}", StackName: !Ref "AWS::StackName"] - !Sub ["ATL_CATALINA_OPTS=\"${CatalinaOpts} ${MailOpts}\"", { CatalinaOpts: !Ref CatalinaOpts, MailOpts: !If [DisableMail, '-Datlassian.mail.senddisabled=true -Datlassian.mail.fetchdisabled=true -Datlassian.mail.popdisabled=true -Dconfluence.disable.mailpolling=true', ''] }] - !Sub ["ATL_DB_ENGINE=${DBEngine}", DBEngine: !If [DBEngineAurora, aurora_postgres, !If [DBEnginePostgres, rds_postgres, '']]] - !Sub ["ATL_DB_HOST=${DBEndpointAddress}", DBEndpointAddress: !GetAtt DB.Outputs.RDSEndPointAddress] - !Sub ["ATL_DB_PORT=${DBEndpointPort}", DBEndpointPort: !GetAtt DB.Outputs.RDSEndPointPort] - !Sub ["ATL_DB_PASSWORD='${DBMasterUserPassword}'", DBMasterUserPassword: !Ref DBMasterUserPassword] - !Sub ["ATL_HAZELCAST_NETWORK_AWS_IAM_REGION=${HazelcastAWSRegion}", HazelcastAWSRegion: !Ref "AWS::Region"] - !Sub ["ATL_HAZELCAST_NETWORK_AWS_IAM_ROLE=${ConfluenceClusterNodeRole}", ConfluenceClusterNodeRole: !Ref ConfluenceClusterNodeRole] - !Sub ["ATL_HAZELCAST_NETWORK_AWS_TAG_VALUE=${HazelcastAWSTagValue}", HazelcastAWSTagValue: !Ref "AWS::StackName"] - !Sub ["ATL_HOSTEDZONE=${HostedZone}", HostedZone: !Ref HostedZone] - !Sub ["ATL_JDBC_PASSWORD='${DBPassword}'", DBPassword: !Ref DBPassword] - !Sub ["ATL_JVM_HEAP=${AtlJvmHeap}", AtlJvmHeap: !If [OverrideHeap, !Ref 'JvmHeapOverride', !FindInMap [AWSInstanceType2Arch, !Ref ClusterNodeInstanceType, Jvmheap]]] - !Sub ["ATL_PROXY_NAME=${AtlProxyName}", AtlProxyName: !If [UseCustomDnsName, !Ref CustomDnsName, !If [UseHostedZone, !Ref LoadBalancerCname, !GetAtt LoadBalancer.DNSName]]] - !Sub ["ATL_SYNCHRONY_MEMORY=-Xmx${AtlJvmHeapSynchrony}", AtlJvmHeapSynchrony: !If [OverrideHeapSynchrony, !Ref 'JvmHeapOverrideSynchrony', '2g']] - !Sub ["ATL_SYNCHRONY_SERVICE_URL=${Protocol}://${LoadBalancerName}/synchrony", {Protocol: !If [DoSSL, "https", "http"], LoadBalancerName: !If [UseCustomDnsName, !Ref CustomDnsName, !If [UseHostedZone, !Ref LoadBalancerCname, !If [UseCustomDnsName, !Ref CustomDnsName, !GetAtt LoadBalancer.DNSName]]]}] - !Sub ["ATL_DEPLOYMENT_REPOSITORY=${DeployRepository}", DeployRepository: !Ref "DeploymentAutomationRepository"] - !Sub ["ATL_DEPLOYMENT_REPOSITORY_BRANCH=${DeployRepositoryBranch}", DeployRepositoryBranch: !Ref "DeploymentAutomationBranch"] - !Sub ["ATL_DEPLOYMENT_REPOSITORY_PLAYBOOK=${DeployRepositoryPlaybook}", DeployRepositoryPlaybook: !Ref "DeploymentAutomationPlaybook"] - !Sub ["ATL_DEPLOYMENT_REPOSITORY_KEYNAME=${DeployRepositoryKeyName}", DeployRepositoryKeyName: !Ref "DeploymentAutomationKeyName"] - !Sub ["ATL_DEPLOYMENT_REPOSITORY_CUSTOM_PARAMS='${DeployRepositoryCustomParams}'", DeployRepositoryCustomParams: !Ref "DeploymentAutomationCustomParams"] - !Sub ["ATL_AWS_ENABLE_CLOUDWATCH=${EnableCW}", EnableCW: !If [EnableCloudWatch, true, false]] - !Sub ["ATL_AWS_ENABLE_CLOUDWATCH_LOGS=${EnableCWLogs}", EnableCWLogs: !If [EnableCloudWatchLogs, true, false]] /opt/atlassian/bin/clone_deployment_repo: content: !Sub | #!/bin/bash key_location=/root/.ssh/deployment_repo_key key_name="${DeploymentAutomationKeyName}" ssm_pin=/${AWS::StackName}/pinned-ansible-sha yum install -y git awscli jq if [[ ! -z "$key_name" ]]; then # Ensure awscli is up to date key_val=$(aws --region=${AWS::Region} ssm get-parameters --names "$key_name" --with-decryption | jq --raw-output '.Parameters[0].Value') echo -e "$key_val" > $key_location chmod 600 $key_location export GIT_SSH_COMMAND="ssh -o IdentitiesOnly=yes -o StrictHostKeyChecking=no -i $key_location" else export GIT_SSH_COMMAND="ssh -o IdentitiesOnly=yes -o StrictHostKeyChecking=no" fi ### Ansible repo pinning ### pinned_commit_id=$(aws --region=${AWS::Region} ssm get-parameters --names "$ssm_pin" | jq --raw-output '.Parameters[0].Value') git clone "${DeploymentAutomationRepository}" -b "${DeploymentAutomationBranch}" /opt/atlassian/dc-deployments-automation/ cd /opt/atlassian/dc-deployments-automation/ if [[ "$pinned_commit_id" == "latest" || -z "$pinned_commit_id" ]]; then head_id=$(git rev-parse HEAD) echo "SSM param [$ssm_pin] has been set to 'latest' - Using the HEAD SHA [$head_id] to build cluster [${AWS::StackName}]" echo "Updating SSM param [$ssm_pin] with current HEAD SHA: [$head_id]" aws --region=${AWS::Region} ssm put-parameter --name "$ssm_pin" --value "$head_id" --overwrite --type String else echo "Ansible repo has been pinned, checking out commit: [$pinned_commit_id]" git checkout -b "pinned-ansible-sha-$pinned_commit_id" "$pinned_commit_id" fi mode: "000750" owner: root group: root commands: 070_create_atl_dir: test: "test ! -d /opt/atlassian/" command: mkdir -p /opt/atlassian ignoreErrors: false 071_install_packages: command: yum install -y git python-virtualenv ignoreErrors: true 072_clone_atl_scripts: test: "test ! -d /opt/atlassian/dc-deployments-automation/" command: /opt/atlassian/bin/clone_deployment_repo ignoreErrors: true 080_run_atl_init_node: command: cd /opt/atlassian/dc-deployments-automation/ && ./bin/install-ansible && ./bin/ansible-with-atl-env inv/aws_node_local aws_confluence_synchrony_node.yml /var/log/ansible-bootstrap.log ignoreErrors: true Properties: AssociatePublicIpAddress: false BlockDeviceMappings: - DeviceName: /dev/xvdf NoDevice: true KeyName: !If - KeyProvided - !Ref KeyPairName - Ref: AWS::NoValue IamInstanceProfile: !Ref ConfluenceClusterNodeInstanceProfile ImageId: !FindInMap - AWSRegionArch2AMI - !Ref AWS::Region - !FindInMap - AWSInstanceType2Arch - !Ref SynchronyNodeInstanceType - Arch InstanceType: !Ref SynchronyNodeInstanceType SecurityGroups: [!Ref SecurityGroup] UserData: Fn::Base64: !Join - "" - - "#!/bin/bash -xe\n" - "yum update -y aws-cfn-bootstrap\n" - !Sub ["/opt/aws/bin/cfn-init -v --stack ${StackName}", StackName: !Ref "AWS::StackName"] - !Sub [" --resource SynchronyClusterNodeLaunchConfig --region ${Region}\n", Region: !Ref "AWS::Region"] - !Sub ["/opt/aws/bin/cfn-signal -e $? --stack ${StackName}", StackName: !Ref "AWS::StackName"] - !Sub [" --resource SynchronyClusterNodeGroup --region ${Region}", Region: !Ref "AWS::Region"] SynchronyClusterNodeScaleUpPolicy: Type: "AWS::AutoScaling::ScalingPolicy" Condition: UseSynchronyAutoScalingGroup Properties: AdjustmentType: ChangeInCapacity AutoScalingGroupName: !Ref SynchronyClusterNodeGroup Cooldown: '600' ScalingAdjustment: 1 SynchronyClusterNodeScaleDownPolicy: Type: AWS::AutoScaling::ScalingPolicy Condition: UseSynchronyAutoScalingGroup Properties: AdjustmentType: ChangeInCapacity AutoScalingGroupName: !Ref SynchronyClusterNodeGroup Cooldown: '600' ScalingAdjustment: -1 SynchronyCPUAlarmHigh: Type: AWS::CloudWatch::Alarm Condition: UseSynchronyAutoScalingGroup Properties: AlarmDescription: Scale up if CPU > 60% for 5 minutes MetricName: CPUUtilization Namespace: AWS/EC2 Statistic: Average Period: 60 EvaluationPeriods: 5 Threshold: 60 AlarmActions: [!Ref SynchronyClusterNodeScaleUpPolicy] Dimensions: - Name: AutoScalingGroupName Value: !Ref SynchronyClusterNodeGroup ComparisonOperator: GreaterThanThreshold SynchronyCPUAlarmLow: Type: AWS::CloudWatch::Alarm Condition: UseSynchronyAutoScalingGroup Properties: AlarmDescription: Scale down if CPU < 40% for 30 minutes MetricName: CPUUtilization Namespace: AWS/EC2 Statistic: Average Period: 60 EvaluationPeriods: 30 Threshold: 40 AlarmActions: [!Ref SynchronyClusterNodeScaleDownPolicy] Dimensions: - Name: AutoScalingGroupName Value: !Ref SynchronyClusterNodeGroup ComparisonOperator: LessThanThreshold # Elastic file system ElasticFileSystem: Type: AWS::EFS::FileSystem Properties: BackupPolicy: Status: ENABLED FileSystemTags: - Key: Name Value: !Join [' ', [!Ref 'AWS::StackName', 'cluster shared-files']] - Key: Application Value: !Ref AWS::StackId # NOTE: The leading COMMIT/TIMESTAMP are used to locate the position to update; see scripts/update-tags.py - Key: "atl:quickstart:commit-id" Value: "COMMIT: 897142a7630be8e7b723d3d530a482dce454f607" - Key: "atl:quickstart:timestamp" Value: "TIMESTAMP: 2022-04-14T15:46:09Z" EFSMountAz1: Type: AWS::EFS::MountTarget Properties: FileSystemId: !Ref ElasticFileSystem SecurityGroups: [!Ref SecurityGroup] SubnetId: !Select - 0 - !Split - "," - Fn::ImportValue: !Sub "${ExportPrefix}PriNets" EFSMountAz2: Type: AWS::EFS::MountTarget Properties: FileSystemId: !Ref ElasticFileSystem SecurityGroups: [!Ref SecurityGroup] SubnetId: !Select - 1 - !Split - "," - Fn::ImportValue: !Sub "${ExportPrefix}PriNets" EFSCname: Type: AWS::Route53::RecordSet Condition: UseHostedZone Properties: HostedZoneName: !Ref HostedZone Comment: Route53 cname for the efs Name: !If [ UseHostedZone, !Join ['.', [!Ref 'AWS::StackName', 'efs', !Ref 'HostedZone']], ''] Type: CNAME TTL: 900 ResourceRecords: - !Join ['.', [!Ref ElasticFileSystem, 'efs', !Ref 'AWS::Region', 'amazonaws.com.']] # Database DB: Type: AWS::CloudFormation::Stack Properties: TemplateURL: !Sub - https://${QSS3BucketName}.${QSS3Region}.amazonaws.com/${QSS3KeyPrefix}submodules/quickstart-atlassian-services/templates/quickstart-database-for-atlassian-services.yaml - QSS3Region: !If ["GovCloudCondition", "s3-us-gov-west-1", "s3"] Parameters: DatabaseImplementation: !Ref DBEngine DBAllocatedStorage: !Ref DBStorage DBAutoMinorVersionUpgrade: "true" DBBackupRetentionPeriod: "1" DBEngineVersion: !Ref DBEngineVersion DBInstanceClass: !Ref DBInstanceClass DBIops: !Ref DBIops DBMasterUserPassword: !Ref DBMasterUserPassword DBMultiAZ: !Ref DBMultiAZ DBSecurityGroup: !Ref SecurityGroup DBStorageEncrypted: !Ref DBStorageEncrypted DBStorageType: !Ref DBStorageType ExportPrefix: !Ref ExportPrefix QSS3BucketName: !Ref QSS3BucketName QSS3KeyPrefix: !Ref QSS3KeyPrefix DBCname: Condition: UseHostedZone Type: AWS::Route53::RecordSet Properties: HostedZoneName: !Ref HostedZone Comment: Route53 cname for the RDS Name: !Join ['.', [!Ref 'AWS::StackName', 'db', !Ref 'HostedZone']] Type: CNAME TTL: 900 ResourceRecords: - !GetAtt DB.Outputs.RDSEndPointAddress # Loadbalancer LoadBalancer: Type: AWS::ElasticLoadBalancingV2::LoadBalancer Properties: LoadBalancerAttributes: - Key: idle_timeout.timeout_seconds Value: '300' Scheme: !If [UsePublicIp, 'internet-facing', 'internal'] SecurityGroups: [!Ref SecurityGroup] Subnets: !Split - "," - Fn::ImportValue: !Sub "${ExportPrefix}PubNets" Tags: - Key: Name Value: !Sub ["${StackName}-LoadBalancer", StackName: !Ref 'AWS::StackName'] - Key: Cluster Value: !Ref AWS::StackName # NOTE: The leading COMMIT/TIMESTAMP are used to locate the position to update; see scripts/update-tags.py - Key: "atl:quickstart:commit-id" Value: "COMMIT: 897142a7630be8e7b723d3d530a482dce454f607" - Key: "atl:quickstart:timestamp" Value: "TIMESTAMP: 2022-04-14T15:46:09Z" LoadBalancerHTTPListener: Type: AWS::ElasticLoadBalancingV2::Listener Properties: DefaultActions: - !If - DoSSL - Type: redirect RedirectConfig: Protocol: HTTPS Port: '443' Host: '#{host}' Path: '/#{path}' Query: '#{query}' StatusCode: HTTP_301 - Type: forward TargetGroupArn: !Ref MainTargetGroup LoadBalancerArn: !Ref LoadBalancer Port: 80 Protocol: HTTP LoadBalancerHTTPSListener: Condition: DoSSL Type: AWS::ElasticLoadBalancingV2::Listener Properties: Certificates: - CertificateArn: !Ref SSLCertificateARN DefaultActions: - Type: forward TargetGroupArn: !Ref MainTargetGroup LoadBalancerArn: !Ref LoadBalancer Port: 443 Protocol: HTTPS SynchronyListenerRule: Type: AWS::ElasticLoadBalancingV2::ListenerRule Condition: UseSynchronyAutoScalingGroup Properties: Actions: - Type: forward TargetGroupArn: !Ref SynchronyTargetGroup Conditions: - Field: path-pattern Values: - '/synchrony/*' ListenerArn: !If [DoSSL, !Ref LoadBalancerHTTPSListener, !Ref LoadBalancerHTTPListener] Priority: 1 LoadBalancerCname: Condition: UseHostedZone Type: AWS::Route53::RecordSet Properties: HostedZoneName: !Ref HostedZone Comment: Route53 cname for the ALB Name: !Join ['.', [!Ref "AWS::StackName", !Ref 'HostedZone']] Type: CNAME TTL: 900 ResourceRecords: - !GetAtt LoadBalancer.DNSName MainTargetGroup: Type: AWS::ElasticLoadBalancingV2::TargetGroup Properties: Port: !Ref TomcatDefaultConnectorPort Protocol: HTTP VpcId: Fn::ImportValue: !Sub "${ExportPrefix}VPCID" HealthCheckIntervalSeconds: 20 HealthCheckTimeoutSeconds: 10 HealthyThresholdCount: 2 Matcher: HttpCode: '200' HealthCheckPath: !If [UseContextPath, !Join ['', [!Ref 'TomcatContextPath', '/status']], '/status'] HealthCheckPort: !Ref TomcatDefaultConnectorPort HealthCheckProtocol: HTTP TargetGroupAttributes: - Key: stickiness.enabled Value: 'true' - Key: stickiness.type Value: lb_cookie Tags: - Key: Name Value: MainTargetGroup - Key: Cluster Value: !Ref AWS::StackName # NOTE: The leading COMMIT/TIMESTAMP are used to locate the position to update; see scripts/update-tags.py - Key: "atl:quickstart:commit-id" Value: "COMMIT: 897142a7630be8e7b723d3d530a482dce454f607" - Key: "atl:quickstart:timestamp" Value: "TIMESTAMP: 2022-04-14T15:46:09Z" DependsOn: - LoadBalancer SynchronyTargetGroup: Type: AWS::ElasticLoadBalancingV2::TargetGroup Condition: UseSynchronyAutoScalingGroup Properties: Port: 8091 Protocol: HTTP VpcId: Fn::ImportValue: !Sub "${ExportPrefix}VPCID" HealthCheckIntervalSeconds: 20 HealthCheckTimeoutSeconds: 10 HealthyThresholdCount: 2 Matcher: HttpCode: '200' HealthCheckPath: /synchrony/heartbeat HealthCheckPort: '8091' HealthCheckProtocol: HTTP TargetGroupAttributes: - Key: stickiness.enabled Value: 'true' - Key: stickiness.type Value: lb_cookie Tags: - Key: Name Value: SynchronyTargetGroup - Key: synchrony_service Value: !Ref AWS::StackName DependsOn: - LoadBalancer SecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Security group allowing SSH and HTTP/HTTPS access SecurityGroupIngress: - IpProtocol: tcp FromPort: 22 ToPort: 22 CidrIp: !Ref CidrBlock - IpProtocol: tcp FromPort: 80 ToPort: 80 CidrIp: !Ref CidrBlock - IpProtocol: tcp FromPort: 443 ToPort: 443 CidrIp: !Ref CidrBlock - IpProtocol: tcp FromPort: 25500 ToPort: 25500 CidrIp: !Ref CidrBlock - IpProtocol: tcp FromPort: 5801 ToPort: 5801 CidrIp: !Ref CidrBlock - IpProtocol: tcp FromPort: 8091 ToPort: 8091 CidrIp: !Ref CidrBlock - !If - UseBastionHost - IpProtocol: tcp FromPort: 22 ToPort: 22 CidrIp: !Sub - "${BastionIp}/32" - BastionIp: Fn::ImportValue: !Sub '${ExportPrefix}BastionPrivIp' - Ref: AWS::NoValue - IpProtocol: tcp FromPort: 80 ToPort: 80 CidrIp: !Sub - "${NAT1IP}/32" - NAT1IP: Fn::ImportValue: !Sub '${ExportPrefix}NAT1EIP' - IpProtocol: tcp FromPort: 80 ToPort: 80 CidrIp: !Sub - "${NAT2IP}/32" - NAT2IP: Fn::ImportValue: !Sub '${ExportPrefix}NAT2EIP' - IpProtocol: tcp FromPort: 443 ToPort: 443 CidrIp: !Sub - "${NAT1IP}/32" - NAT1IP: Fn::ImportValue: !Sub '${ExportPrefix}NAT1EIP' - IpProtocol: tcp FromPort: 443 ToPort: 443 CidrIp: !Sub - "${NAT2IP}/32" - NAT2IP: Fn::ImportValue: !Sub '${ExportPrefix}NAT2EIP' Tags: - Key: Name Value: !Join [' ', [!Ref "AWS::StackName", 'sg']] # NOTE: The leading COMMIT/TIMESTAMP are used to locate the position to update; see scripts/update-tags.py - Key: "atl:quickstart:commit-id" Value: "COMMIT: 897142a7630be8e7b723d3d530a482dce454f607" - Key: "atl:quickstart:timestamp" Value: "TIMESTAMP: 2022-04-14T15:46:09Z" VpcId: Fn::ImportValue: !Sub "${ExportPrefix}VPCID" SecurityGroupIngress: Type: AWS::EC2::SecurityGroupIngress Properties: GroupId: !Ref SecurityGroup IpProtocol: '-1' FromPort: -1 ToPort: -1 SourceSecurityGroupId: !Ref SecurityGroup EncryptionKey: Condition: UseDatabaseEncryption DeletionPolicy: Retain UpdateReplacePolicy: Retain Type: AWS::KMS::Key Properties: KeyPolicy: Version: 2012-10-17 Id: !Sub "${AWS::StackName}" Statement: - Effect: Allow Principal: AWS: - !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:root" Action: - kms:CreateAlias - kms:CreateGrant - kms:CreateKey - kms:DeleteAlias - kms:DeleteImportedKeyMaterial - kms:DescribeKey - kms:DisableKey - kms:DisableKeyRotation - kms:EnableKey - kms:EnableKeyRotation - kms:GetKeyPolicy - kms:GetKeyRotationStatus - kms:GetParametersForImport - kms:GetPublicKey - kms:PutKeyPolicy Resource: '*' EnableKeyRotation: true Tags: - Key: Name Value: !Sub ["${StackName} Encryption Key", {StackName: !Ref 'AWS::StackName'}] # NOTE: The leading COMMIT/TIMESTAMP are used to locate the position to update; see scripts/update-tags.py - Key: "atl:quickstart:commit-id" Value: "COMMIT: 897142a7630be8e7b723d3d530a482dce454f607" - Key: "atl:quickstart:timestamp" Value: "TIMESTAMP: 2022-04-14T15:46:09Z" EncryptionKeyAlias: Condition: UseDatabaseEncryption Type: AWS::KMS::Alias Properties: AliasName: !Sub "alias/${AWS::StackName}" TargetKeyId: !Ref EncryptionKey AnsibleRepoPinSHA: Type: AWS::SSM::Parameter Properties: Description: "The dc-deployments-automation commit SHA that all nodes in the cluster will use" Name: !Sub "/${AWS::StackName}/pinned-ansible-sha" Type: String AllowedPattern: '^(latest)|([0-9a-f]{5,40})$' Value: "latest" # Optional: CloudWatch dashboard to be created when CloudWatch is enabled CloudWatchDashboard: DependsOn: - DB Condition: EnableCloudWatch Type: AWS::CloudFormation::Stack Properties: TemplateURL: !Sub - https://${QSS3BucketName}.${QSS3Region}.amazonaws.com/${QSS3KeyPrefix}submodules/quickstart-atlassian-services/templates/quickstart-cloudwatch-dashboard.yaml - QSS3Region: !If ["GovCloudCondition", "s3-us-gov-west-1", "s3"] Parameters: ProductStackName: !Sub "${AWS::StackName}" ProductFamilyName: "confluence" AsgToMonitor: !Ref ClusterNodeGroup Outputs: ServiceURL: Description: The URL to access this Atlassian service Value: !If - UseCustomDnsName - !Sub - "${HTTP}://${CustomDNSName}${ContextPath}" - HTTP: !If [DoSSL, 'https', 'http'] CustomDNSName: !Ref CustomDnsName ContextPath: !Ref TomcatContextPath - !If - UseHostedZone - !Sub - "${HTTP}://${LBCName}${ContextPath}" - HTTP: !If [DoSSL, 'https', 'http'] LBCName: !Ref LoadBalancerCname ContextPath: !Ref TomcatContextPath - !Sub - "${HTTP}://${LoadBalancerDNSName}${ContextPath}" - HTTP: !If [DoSSL, 'https', 'http'] LoadBalancerDNSName: !GetAtt LoadBalancer.DNSName ContextPath: !Ref TomcatContextPath LoadBalancerURL: Description: The Load Balancer URL Value: !Sub - "${HTTP}://${LoadBalancerDNSName}" - HTTP: !If [DoSSL, 'https', 'http'] LoadBalancerDNSName: !GetAtt LoadBalancer.DNSName SGname: Description: The name of the SecurityGroup Value: !Ref SecurityGroup Export: { Name: !Join ['', [!Ref 'AWS::StackName', '-SGname']] } DBEndpointAddress: Description: The Database Connection String Value: !GetAtt DB.Outputs.RDSEndPointAddress DBEncryptionKey: Condition: UseDatabaseEncryption Description: The alias of the encryption key created for RDS Value: !Ref EncryptionKeyAlias EFSCname: Description: The cname of the EFS Value: !If - UseHostedZone - !Ref EFSCname - !Ref ElasticFileSystem Export: { Name: !Join ['', [!Ref 'AWS::StackName', '-EFSCname']] } ConfluenceTargetGroupARN: Description: The name of the load balancer of Confluence cluster nodes Value: !Ref MainTargetGroup ClusterNodeGroup: Description: The name of the auto scaling group of Confluence cluster nodes Value: !Ref ClusterNodeGroup SynchronyClusterNodeGroup: Description: The name of the auto scaling group of Synchrony cluster nodes Value: !If - UseSynchronyAutoScalingGroup - !Ref SynchronyClusterNodeGroup - 'local' CloudWatchDashboardURL: Description: CloudWatch monitoring dashboard URL Value: !GetAtt CloudWatchDashboard.Outputs.Dashboard Condition: EnableCloudWatch