AWSTemplateFormatVersion: "2010-09-09"
Metadata:
  License: Apache-2.0
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          default: "Database"
        Parameters:
          - DBName
          - DBUser
          - DBPassword
          - DBRootPassword
      - Label:
          default: "Instance connection"
        Parameters:
          - InstanceType
          - KeyName
          - SSHLocation
Description:
  "AWS CloudFormation Sample Template WordPress_Single_Instance: WordPress
  is web software you can use to create a beautiful website or blog. This template
  installs WordPress with a local MySQL database for storage. It demonstrates using
  the AWS CloudFormation bootstrap scripts to deploy WordPress. **WARNING** This template
  creates an Amazon EC2 instance. You will be billed for the AWS resources used if
  you create a stack from this template."
Parameters:
  DBName:
    AllowedPattern: "[a-zA-Z][a-zA-Z0-9]*"
    ConstraintDescription:
      must begin with a letter and contain only alphanumeric
      characters.
    Default: wordpressdb
    Description: The WordPress database name
    MaxLength: "64"
    MinLength: "1"
    Type: String
  DBPassword:
    AllowedPattern: "[a-zA-Z0-9]+"
    ConstraintDescription: must contain only alphanumeric characters.
    Description: The WordPress database admin account password
    MaxLength: "41"
    MinLength: "8"
    NoEcho: "true"
    Type: String
  DBRootPassword:
    AllowedPattern: "[a-zA-Z0-9]+"
    ConstraintDescription: must contain only alphanumeric characters.
    Description: MySQL root password
    MaxLength: "41"
    MinLength: "8"
    NoEcho: "true"
    Type: String
  DBUser:
    AllowedPattern: "[a-zA-Z][a-zA-Z0-9]*"
    ConstraintDescription:
      must begin with a letter and contain only alphanumeric
      characters.
    Description: The WordPress database admin account username
    MaxLength: "16"
    MinLength: "1"
    Type: String
  InstanceType:
    AllowedValues:
      - t2.nano
      - t2.micro
      - t2.small
      - t2.medium
      - t2.large
      - m3.medium
      - m3.large
      - m3.xlarge
      - m3.2xlarge
      - m4.large
      - m4.xlarge
      - m4.2xlarge
      - m4.4xlarge
      - m4.10xlarge
      - c3.large
    ConstraintDescription: must be a valid EC2 instance type.
    Default: t2.nano
    Description: WebServer EC2 instance type
    Type: String
  KeyName:
    ConstraintDescription: must be the name of an existing EC2 KeyPair.
    Description: Name of an existing EC2 KeyPair to enable SSH access to the instances
    Type: AWS::EC2::KeyPair::KeyName
  SSHLocation:
    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.
    Default: 0.0.0.0/0
    Description: The IP address range that can be used to SSH to the EC2 instances
    MaxLength: "18"
    MinLength: "9"
    Type: String
Mappings:
  AWSInstanceType2Arch:
    c3.2xlarge:
      Arch: HVM64
    c3.4xlarge:
      Arch: HVM64
    c3.8xlarge:
      Arch: HVM64
    c3.large:
      Arch: HVM64
    c3.xlarge:
      Arch: HVM64
    c4.2xlarge:
      Arch: HVM64
    c4.4xlarge:
      Arch: HVM64
    c4.8xlarge:
      Arch: HVM64
    c4.large:
      Arch: HVM64
    c4.xlarge:
      Arch: HVM64
    cc2.8xlarge:
      Arch: HVM64
    cr1.8xlarge:
      Arch: HVM64
    d2.2xlarge:
      Arch: HVM64
    d2.4xlarge:
      Arch: HVM64
    d2.8xlarge:
      Arch: HVM64
    d2.xlarge:
      Arch: HVM64
    g2.2xlarge:
      Arch: HVMG2
    g2.8xlarge:
      Arch: HVMG2
    hi1.4xlarge:
      Arch: HVM64
    hs1.8xlarge:
      Arch: HVM64
    i2.2xlarge:
      Arch: HVM64
    i2.4xlarge:
      Arch: HVM64
    i2.8xlarge:
      Arch: HVM64
    i2.xlarge:
      Arch: HVM64
    m3.2xlarge:
      Arch: HVM64
    m3.large:
      Arch: HVM64
    m3.medium:
      Arch: HVM64
    m3.xlarge:
      Arch: HVM64
    m4.10xlarge:
      Arch: HVM64
    m4.2xlarge:
      Arch: HVM64
    m4.4xlarge:
      Arch: HVM64
    m4.large:
      Arch: HVM64
    m4.xlarge:
      Arch: HVM64
    r3.2xlarge:
      Arch: HVM64
    r3.4xlarge:
      Arch: HVM64
    r3.8xlarge:
      Arch: HVM64
    r3.large:
      Arch: HVM64
    r3.xlarge:
      Arch: HVM64
    t2.large:
      Arch: HVM64
    t2.medium:
      Arch: HVM64
    t2.micro:
      Arch: HVM64
    t2.nano:
      Arch: HVM64
    t2.small:
      Arch: HVM64
  AWSRegionArch2AMI:
    ap-northeast-1:
      HVM64: ami-383c1956
      HVMG2: ami-08e5c166
    ap-northeast-2:
      HVM64: ami-249b554a
      HVMG2: NOT_SUPPORTED
    ap-southeast-1:
      HVM64: ami-c9b572aa
      HVMG2: ami-5a15d239
    ap-southeast-2:
      HVM64: ami-48d38c2b
      HVMG2: ami-0c1a446f
    cn-north-1:
      HVM64: ami-43a36a2e
      HVMG2: NOT_SUPPORTED
    eu-central-1:
      HVM64: ami-bc5b48d0
      HVMG2: ami-ba1a09d6
    eu-west-1:
      HVM64: ami-bff32ccc
      HVMG2: ami-83fd23f0
    sa-east-1:
      HVM64: ami-6817af04
      HVMG2: NOT_SUPPORTED
    us-east-1:
      HVM64: ami-60b6c60a
      HVMG2: ami-e998ea83
    us-west-1:
      HVM64: ami-d5ea86b5
      HVMG2: ami-943956f4
    us-west-2:
      HVM64: ami-f0091d91
      HVMG2: ami-315f4850
Resources:
  WebServer:
    Type: AWS::EC2::Instance
    CreationPolicy:
      ResourceSignal:
        Timeout: PT15M
    Metadata:
      AWS::CloudFormation::Init:
        configSets:
          wordpress_install:
            - install_cfn
            - install_wordpress
            - configure_wordpress
        configure_wordpress:
          commands:
            01_set_mysql_root_password:
              command: !Sub |
                mysqladmin -u root password '${DBRootPassword}'
              test: !Sub |
                $(mysql ${DBName} -u root --password='${DBRootPassword}' >/dev/null 2>&1 </dev/null); (( $? != 0 ))
            02_create_database:
              command: !Sub |
                mysql -u root --password='${DBRootPassword}' < /tmp/setup.mysql
              test: !Sub |
                $(mysql ${DBName} -u root --password='${DBRootPassword}' >/dev/null 2>&1 </dev/null); (( $? !=0))
            03_configure_wordpress:
              command: /tmp/create-wp-config
              cwd: /var/www/html/wordpress
        install_cfn:
          files:
            /etc/cfn/cfn-hup.conf:
              content: !Sub |
                [main]
                stack= ${AWS::StackId}
                region=${AWS::Region}
              group: root
              mode: "000400"
              owner: root
            /etc/cfn/hooks.d/cfn-auto-reloader.conf:
              content: !Sub |
                [cfn-auto-reloader-hook]
                triggers=post.update
                path=Resources.WebServer.Metadata.AWS::CloudFormation::Init
                action=/opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource WebServer --configsets wordpress_install --url https://stackbuilder.amazonaws.com
              group: root
              mode: "000400"
              owner: root
          services:
            sysvinit:
              cfn-hup:
                enabled: true
                ensureRunning: true
                files:
                  - /etc/cfn/cfn-hup.conf
                  - /etc/cfn/hooks.d/cfn-auto-reloader.conf
        install_wordpress:
          files:
            /tmp/create-wp-config:
              content: !Sub |
                #!/bin/bash -xe
                cp /var/www/html/wordpress/wp-config-sample.php /var/www/html/wordpress/wp-config.php
                sed -i "s/'database_name_here'/'${DBName}'/g" wp-config.php
                sed -i "s/'username_here'/'${DBUser}'/g" wp-config.php
                sed -i "s/'password_here'/'${DBPassword}'/g" wp-config.php
              group: root
              mode: "000500"
              owner: root
            /tmp/setup.mysql:
              content: !Sub |
                CREATE DATABASE ${DBName};
                CREATE USER '${DBUser}'@'localhost' IDENTIFIED BY '${DBPassword}';
                GRANT ALL ON ${DBName}.* TO '${DBUser}'@'localhost';
                FLUSH PRIVILEGES;
              group: root
              mode: "000400"
              owner: root
            /var/www/noindex/index.html:
              content: |
                <!DOCTYPE html>
                <HTML><HEAD>
                      <TITLE>HTML Meta Tag</title>
                      <META HTTP-EQUIV= "refresh" CONTENT= "0; url = /wordpress" />
                   </HEAD><BODY>
                      <P>Redirect to <A HREF=/wordpress>WordPress</A>.</P>
                      <!-- By default, redirect to the installed WordPress -->
                   </BODY></HTML>
          packages:
            yum:
              httpd24: []
              mysql: []
              mysql-devel: []
              mysql-libs: []
              mysql-server: []
              php73: []
              php73-mysqlnd: []
          services:
            sysvinit:
              httpd:
                enabled: true
                ensureRunning: true
              mysqld:
                enabled: true
                ensureRunning: true
          sources:
            /var/www/html: http://wordpress.org/latest.tar.gz
    Properties:
      ImageId:
        !FindInMap [
          AWSRegionArch2AMI,
          !Ref "AWS::Region",
          !FindInMap [AWSInstanceType2Arch, !Ref InstanceType, Arch],
        ]
      InstanceType:
        Ref: InstanceType
      KeyName:
        Ref: KeyName
      SecurityGroups:
        - Ref: WebServerSecurityGroup
      UserData:
        Fn::Base64: !Sub |
          #!/bin/bash -xe
          yum update -y
          yum update -y aws-cfn-bootstrap
          /opt/aws/bin/cfn-init -v --stack ${AWS::StackId} --resource WebServer --configsets wordpress_install --region ${AWS::Region}
          /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackId} --resource WebServer --region ${AWS::Region}
  WebServerSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: "Enable HTTP access via port 80 locked down to the load balancer + SSH access"
      SecurityGroupIngress:
        - CidrIp: 0.0.0.0/0
          FromPort: "80"
          IpProtocol: tcp
          ToPort: "80"
        - CidrIp: !Ref SSHLocation
          FromPort: "22"
          IpProtocol: tcp
          ToPort: 22
Outputs:
  PublicIP:
    Description: EC2 public IP
    Value: !GetAtt WebServer.PublicIp
  WebsiteURL:
    Description: WordPress Website
    Value: !Sub "http://${WebServer.PublicDnsName}/wordpress"
