AWSTemplateFormatVersion: 2010-09-09 Description: >- This template deploys WordPress serverless. **WARNING** You will be billed for the AWS resources used if you create a stack from this template. Metadata: LICENSE: Apache License Version 2.0 cfn-lint: config: ignore_checks: # Check for QSID - E9008 AWS::CloudFormation::Interface: ParameterGroups: - Label: default: Database configuration Parameters: - DBName - DBUsername - DBPassword - DBMaxCapacity - DBMinCapacity - DBBackupRetentionPeriod - DBPreferredBackupWindow - Label: default: Container configuration Parameters: - ContainerImage - ContainerMemory - ContainerCpu - ContainerMaxCount - ContainerMinCount - ContainerDesiredCount - ALBAccessCIDR - Label: default: FileSystem configuration Parameters: - EFSPerformanceMode - EFSThroughputMode - EFSProvisionedThroughputInMibps - Label: default: DNS and SSL Configuration Parameters: - DomainName - HostedZoneID - CertificateArn - Label: default: Web Application Firewall Configuration Parameters: - ActivateWordPressRule - ActivateSQLInjectionRule - Label: default: Network configuration Parameters: - VPCID - PrivateSubnet1AID - PrivateSubnet2AID - PrivateSubnet3AID - PublicSubnet1ID - PublicSubnet2ID - PublicSubnet3ID - Label: default: Quickstart configuration Parameters: - QSS3BucketName - QSS3KeyPrefix - QSS3BucketRegion ParameterLabels: QSS3BucketName: default: Quickstart S3 bucket name QSS3KeyPrefix: default: Quickstart S3 key prefix QSS3BucketRegion: default: Quickstart S3 bucket region ALBAccessCIDR: default: ALB access CIDR ContainerCpu: default: Container cpu ContainerDesiredCount: default: Container desired count ContainerImage: default: Container image ContainerMaxCount: default: Container max count ContainerMemory: default: Container memory ContainerMinCount: default: Container min count DBBackupRetentionPeriod: default: DB backup retention period DBMaxCapacity: default: DB max capacity DBMinCapacity: default: DB min capacity DBName: default: DB name DBPreferredBackupWindow: default: DB preferred backup window DBUsername: default: DB username DBPassword: default: DB password PrivateSubnet1AID: default: Private subnet 1 Id PrivateSubnet2AID: default: Private subnet 2 Id PrivateSubnet3AID: default: Private subnet 3 Id PublicSubnet1ID: default: Public subnet 1 Id PublicSubnet2ID: default: Public subnet 2 Id PublicSubnet3ID: default: Public subnet 3 Id EFSProvisionedThroughputInMibps: default: EFS provisioned throughput in mibps EFSPerformanceMode: default: EFS performance mode EFSThroughputMode: default: EFS throughput mode VPCID: default: VPC Id ActivateWordPressRule: default: Activate AWS managed wordPress protection ActivateSQLInjectionRule: default: Activate SQL injection protection Parameters: QSS3BucketName: Type: String Default: aws-quickstart Description: >- Alphanumeric String which identifies the S3 bucket name for the Quick Start assets. It's the bucket to store the copy of the Quick Start assets if you decided to customize or extend them for your own use. AllowedPattern: '^[0-9a-zA-Z]+([0-9a-zA-Z-]*[0-9a-zA-Z])*$' ConstraintDescription: >- S3 bucket name can include numbers, lowercase letters, uppercase letters, and hyphens (-). It cannot start or end with a hyphen (-). QSS3KeyPrefix: Type: String Default: quickstart-sudo-consultants-serverless-wordpress/ Description: >- Alphanumeric String which identifies the S3 key prefix used to simulate a folder for your copy of the Quick Start assets if you decided to customize or extend them for your own use. AllowedPattern: '^[0-9a-zA-Z-/._]*$' ConstraintDescription: >- S3 key prefix can include numbers, lowercase letters, uppercase letters, hyphens (-), and forward slash (/). QSS3BucketRegion: Type: String Default: us-east-1 Description: >- The AWS Region where the Quick Start S3 bucket (QSS3BucketName) is hosted. When using your own bucket, you must specify this value. EFSProvisionedThroughputInMibps: Type: Number Default: 0 Description: The throughput, measured in MiB/s, that you want to provision for a file system that you're creating. Valid values are 1-1024. Required if ThroughputMode is set to provisioned. MinValue: 0 MaxValue: 1024 EFSPerformanceMode: Type: String Default: generalPurpose Description: The performance mode of the file system. AllowedValues: - generalPurpose - maxIO EFSThroughputMode: Type: String Default: bursting Description: Specifies the throughput mode for the file system, either bursting or provisioned. AllowedValues: - bursting - provisioned DBName: Type: String Default: wordpressDB Description: The name of your database. If you don't provide a name, then Amazon RDS won't create a database in this DB cluster. AllowedPattern: '[a-zA-Z][a-zA-Z0-9]*' MaxLength: '64' MinLength: '5' DBUsername: NoEcho: 'true' Description: Username for MySQL database access Type: String MinLength: '1' MaxLength: '16' AllowedPattern: '[a-zA-Z][a-zA-Z0-9]*' ConstraintDescription: must begin with a letter and contain only alphanumeric characters. DBPassword: NoEcho: 'true' Description: Password MySQL database access Type: String MinLength: '8' MaxLength: '41' AllowedPattern: '[a-zA-Z0-9]*' ConstraintDescription: must contain only alphanumeric characters. DBBackupRetentionPeriod: Type: Number Default: '1' Description: The number of days for which automated backups are retained. ConstraintDescription: Database backup retention period must be between 1 and 35 days. MaxValue: '35' MinValue: '1' DBMaxCapacity: Type: Number Default: '2' Description: The maximum capacity for an Aurora DB cluster in serverless DB engine mode. AllowedValues: ['1', '2', '4', '8', '16', '32', '64', '128', '256'] DBMinCapacity: Type: Number Default: '1' Description: The minimum capacity for an Aurora DB cluster in serverless DB engine mode. AllowedValues: ['1', '2', '4', '8', '16', '32', '64', '128', '256'] DBPreferredBackupWindow: Type: String Default: '' Description: (Optional) The daily time range during which automated backups are created. AllowedPattern: '^(|([0-1][0-9]|2[0-3]):[0-5][0-9]-([0-1][0-9]|2[0-3]):[0-5][0-9])$' ConstraintDescription: 'Preferred backup window must be left blank or in the form of HH:MM-HH:MM' ContainerCpu: Type: String Default: '256' Description: The number of cpu units used by the task. AllowedValues: - '256' - '512' - '1024' - '2048' - '4096' ContainerMemory: Type: String Default: 0.5GB Description: The amount (in GiB) of memory used by the task. AllowedValues: - '0.5GB' - '1GB' - '2GB' - '3GB' - '4GB' - '5GB' - '6GB' - '7GB' - '8GB' - '16GB' - '30GB' # 512 (0.5 GB), 1024 (1 GB), 2048 (2 GB) - Available cpu values: 256 (.25 vCPU) # 1024 (1 GB), 2048 (2 GB), 3072 (3 GB), 4096 (4 GB) - Available cpu values: 512 (.5 vCPU) # 2048 (2 GB), 3072 (3 GB), 4096 (4 GB), 5120 (5 GB), 6144 (6 GB), 7168 (7 GB), 8192 (8 GB) - Available cpu values: 1024 (1 vCPU) # Between 4096 (4 GB) and 16384 (16 GB) in increments of 1024 (1 GB) - Available cpu values: 2048 (2 vCPU) # Between 8192 (8 GB) and 30720 (30 GB) in increments of 1024 (1 GB) - Available cpu values: 4096 (4 vCPU) ContainerDesiredCount: Type: Number Default: '2' Description: Desired number of WordPress containers. ContainerImage: Type: String Default: 'docker.io/wordpress:latest' Description: The image used to start a container. By default uses Wordpress official docker image. ContainerMaxCount: Type: Number Default: '2' Description: Maximum number of WordPress containers in the Auto Scaling group. ContainerMinCount: Type: Number Default: '1' Description: Minimum number of WordPress containers in the Auto Scaling group. DomainName: Description: >- (Optional) Domain name for the web site. It must be an existing, publicly resolvable domain. Type: String Default: '' ConstraintDescription: Must be a valid domain name. CertificateArn: Description: (Optional) The ARN of the SSL certificate to use for the load balancer. Type: String Default: '' HostedZoneID: Description: >- (Optional) Route 53 Hosted Zone ID of the domain name. If left blank route 53 will not be configured and DNS must be setup manually. If you specify this, you must also specify a Domain name. Type: String Default: '' MaxLength: '32' ActivateWordPressRule: Type: String Description: Activate AWS Managed WordPress WAF Rule, protects against common Wordpress attacks. Default: 'true' AllowedValues: - 'true' - 'false' ActivateSQLInjectionRule: Type: String Description: Activate AWS Managed SQL Injection WAF Rule, protects against common SQL Injection attacks. Default: 'true' AllowedValues: - 'true' - 'false' ALBAccessCIDR: Type: String Description: >- Allowed CIDR block for external web access to the Application Load Balancer (x.x.x.x/x) AllowedPattern: >- ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))$ ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/x VPCID: Type: 'AWS::EC2::VPC::Id' Description: 'ID of the VPC (e.g., vpc-0343606e).' PublicSubnet1ID: Type: 'AWS::EC2::Subnet::Id' Description: Subnet Id for public subnet 1 located in Availability Zone 1 AllowedPattern: '^subnet-[a-zA-Z0-9]*$' ConstraintDescription: Invalid subnet id PublicSubnet2ID: Type: 'AWS::EC2::Subnet::Id' Description: Subnet Id for public subnet 2 located in Availability Zone 2 AllowedPattern: '^subnet-[a-zA-Z0-9]*$' ConstraintDescription: Invalid subnet id PublicSubnet3ID: Type: String Description: Subnet Id for public subnet 3 located in Availability Zone 3 Default: '' PrivateSubnet1AID: Type: 'AWS::EC2::Subnet::Id' Description: Subnet Id for private subnet 1 located in Availability Zone 1 AllowedPattern: '^subnet-[a-zA-Z0-9]*$' ConstraintDescription: Invalid subnet id PrivateSubnet2AID: Type: 'AWS::EC2::Subnet::Id' Description: Subnet Id for private subnet 2 located in Availability Zone 2 AllowedPattern: '^subnet-[a-zA-Z0-9]*$' ConstraintDescription: Invalid subnet id PrivateSubnet3AID: Type: String Description: Subnet Id for private subnet 3 located in Availability Zone 3 Default: '' Conditions: UsingDefaultBucket: !Equals - !Ref QSS3BucketName - aws-quickstart EnableWAF: !Or - !Equals - !Ref ActivateWordPressRule - 'true' - !Equals - !Ref ActivateSQLInjectionRule - 'true' AddDNSRecord: !And - !Not - !Equals - !Ref DomainName - '' - !Not - !Equals - !Ref HostedZoneID - '' Resources: SecurityGroupsStack: Type: 'AWS::CloudFormation::Stack' Properties: TemplateURL: !Sub - >- https://${S3Bucket}.s3.${S3Region}.${AWS::URLSuffix}/${QSS3KeyPrefix}templates/securitygroups.template.yaml - S3Region: !If - UsingDefaultBucket - !Ref 'AWS::Region' - !Ref QSS3BucketRegion S3Bucket: !If - UsingDefaultBucket - !Sub '${QSS3BucketName}-${AWS::Region}' - !Ref QSS3BucketName Parameters: VPCID: !Ref VPCID ALBAccessCIDR: !Ref ALBAccessCIDR FileSystemStack: Type: 'AWS::CloudFormation::Stack' Properties: TemplateURL: !Sub - >- https://${S3Bucket}.s3.${S3Region}.${AWS::URLSuffix}/${QSS3KeyPrefix}templates/filesystem.template.yaml - S3Region: !If - UsingDefaultBucket - !Ref 'AWS::Region' - !Ref QSS3BucketRegion S3Bucket: !If - UsingDefaultBucket - !Sub '${QSS3BucketName}-${AWS::Region}' - !Ref QSS3BucketName Parameters: PrivateSubnet1AID: !Ref PrivateSubnet1AID PrivateSubnet2AID: !Ref PrivateSubnet2AID PrivateSubnet3AID: !Ref PrivateSubnet3AID EFSPerformanceMode: !Ref EFSPerformanceMode EFSProvisionedThroughputInMibps: !Ref EFSProvisionedThroughputInMibps EFSThroughputMode: !Ref EFSThroughputMode FileSystemSecurityGroupId: !GetAtt SecurityGroupsStack.Outputs.FileSystemSecurityGroupId DatabaseStack: Type: 'AWS::CloudFormation::Stack' Properties: TemplateURL: !Sub - >- https://${S3Bucket}.s3.${S3Region}.${AWS::URLSuffix}/${QSS3KeyPrefix}templates/database.template.yaml - S3Region: !If - UsingDefaultBucket - !Ref 'AWS::Region' - !Ref QSS3BucketRegion S3Bucket: !If - UsingDefaultBucket - !Sub '${QSS3BucketName}-${AWS::Region}' - !Ref QSS3BucketName Parameters: PrivateSubnet1AID: !Ref PrivateSubnet1AID PrivateSubnet2AID: !Ref PrivateSubnet2AID PrivateSubnet3AID: !Ref PrivateSubnet3AID DBBackupRetentionPeriod: !Ref DBBackupRetentionPeriod DBPreferredBackupWindow: !Ref DBPreferredBackupWindow DBName: !Ref DBName DBUsername: !Ref DBUsername DBPassword: !Ref DBPassword DBMaxCapacity: !Ref DBMaxCapacity DBMinCapacity: !Ref DBMinCapacity DBSecurityGroupId: !GetAtt SecurityGroupsStack.Outputs.DBSecurityGroupId ContainerStack: Type: 'AWS::CloudFormation::Stack' Properties: TemplateURL: !Sub - >- https://${S3Bucket}.s3.${S3Region}.${AWS::URLSuffix}/${QSS3KeyPrefix}templates/container.template.yaml - S3Region: !If - UsingDefaultBucket - !Ref 'AWS::Region' - !Ref QSS3BucketRegion S3Bucket: !If - UsingDefaultBucket - !Sub '${QSS3BucketName}-${AWS::Region}' - !Ref QSS3BucketName Parameters: PublicSubnet1ID: !Ref PublicSubnet1ID PublicSubnet2ID: !Ref PublicSubnet2ID PublicSubnet3ID: !Ref PublicSubnet3ID PrivateSubnet1AID: !Ref PrivateSubnet1AID PrivateSubnet2AID: !Ref PrivateSubnet2AID PrivateSubnet3AID: !Ref PrivateSubnet3AID DBUsername: !Ref DBUsername DBPassword: !Ref DBPassword DBName: !Ref DBName VPCID: !Ref VPCID DomainName: !Ref DomainName CertificateArn: !Ref CertificateArn HostedZoneID: !Ref HostedZoneID ContainerMinCount: !Ref ContainerMinCount ContainerMaxCount: !Ref ContainerMaxCount ContainerDesiredCount: !Ref ContainerDesiredCount ContainerCpu: !Ref ContainerCpu ContainerMemory: !Ref ContainerMemory ContainerImage: !Ref ContainerImage FileSystemId: !GetAtt FileSystemStack.Outputs.FileSystemId ContainerSecurityGroupId: !GetAtt SecurityGroupsStack.Outputs.ContainerSecurityGroupId LoadBalancerSecurityGroupId: !GetAtt SecurityGroupsStack.Outputs.LoadBalancerSecurityGroupId DBEndpoint: !GetAtt DatabaseStack.Outputs.DBEndpoint WAFStack: Condition: EnableWAF Type: 'AWS::CloudFormation::Stack' Properties: TemplateURL: !Sub - >- https://${S3Bucket}.s3.${S3Region}.${AWS::URLSuffix}/${QSS3KeyPrefix}templates/waf.template.yaml - S3Region: !If - UsingDefaultBucket - !Ref 'AWS::Region' - !Ref QSS3BucketRegion S3Bucket: !If - UsingDefaultBucket - !Sub '${QSS3BucketName}-${AWS::Region}' - !Ref QSS3BucketName Parameters: ActivateWordPressRule: !Ref ActivateWordPressRule ActivateSQLInjectionRule: !Ref ActivateSQLInjectionRule ResourceArn: !GetAtt ContainerStack.Outputs.ApplicationLoadBalancerArn Outputs: ApplicationURL: Condition: AddDNSRecord Description: The URL of the Application. Value: !GetAtt ContainerStack.Outputs.ApplicationURL ApplicationLoadBalancerDNSName: Description: The URL of the ELB. Point your domain to it by using a CNAME/ALIAS record. Value: !GetAtt ContainerStack.Outputs.ApplicationLoadBalancerDNSName ApplicationLoadBalancerArn: Description: The Amazon Resource Name (ARN) of the application load balancer. Value: !GetAtt ContainerStack.Outputs.ApplicationLoadBalancerArn DBPasswordSecret: Description: The Amazon Resource Name (ARN) of the DBPassword SSM secret. Value: !GetAtt ContainerStack.Outputs.DBPasswordSecret Cluster: Description: The name of your ECS cluster. Value: !GetAtt ContainerStack.Outputs.Cluster TaskDefinition: Description: The Amazon Resource Name (ARN) of the ECS task definition. Value: !GetAtt ContainerStack.Outputs.TaskDefinition DBEndpoint: Description: The connection endpoint of your database. Value: !GetAtt DatabaseStack.Outputs.DBEndpoint DBName: Description: The name of your database. Value: !GetAtt DatabaseStack.Outputs.DBName FileSystemId: Description: The ID of the EFS file system. Value: !GetAtt FileSystemStack.Outputs.FileSystemId