Skip to content

Template Heat for WordPress

Deploy

You can easily and quickly deploy a WordPress with an integrated MariaDB using a Heat template that we provide:

openstack stack create --template https://docs.infomaniak.cloud/tutorials/02.wordpress/wordpress.yml wordpress \
--parameter key='<YOUR_KEY>' \
--parameter EMAIL='<YOUR_EMAIL>' \
--parameter NDD='<YOUR_NDD>'

Warning

Remember to replace the variables <YOUR_KEY> by your key pair , <YOUR_EMAIL> by your email address and <YOUR_NDD> by your domain name !

After a few minutes, you can use the following command to display your WordPress informations:

$ openstack stack show wordpress

+-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------+
| Field                 | Value                                                                                                                                                 |
+-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------+
| id                    | 6a68797c-6c0f-4b6a-8b3d-0276a00c2974                                                                                                                  |
| stack_name            | Wordpress                                                                                                                                             |
| description           | wordpress Environment                                                                                                                                 |
| creation_time         | 2022-03-21T12:32:16Z                                                                                                                                  |
| updated_time          | None                                                                                                                                                  |
| stack_status          | CREATE_COMPLETE                                                                                                                                       |
| stack_status_reason   | Stack CREATE completed successfully                                                                                                                   |
| parameters            | EMAIL: coucou@email.com                                                                                                                               |
|                       | NDD: website.domain.com                                                                                                                               |
|                       | OS::project_id: 8fe2d1aa62774f0f96740505ec4b1dd6                                                                                                      |
|                       | OS::stack_id: 6a68797c-6c0f-4b6a-8b3d-0276a00c2974                                                                                                    |
|                       | OS::stack_name: Wordpress                                                                                                                             |
|                       | flavor: a2-ram4-disk50-perf1                                                                                                                          |
|                       | floating_network_id: ext-floating1                                                                                                                    |
|                       | image: Debian 11 bullseye                                                                                                                           |
|                       | key: Yubikey                                                                                                                                          |
|                       | network: wordpress-network                                                                                                                            |
|                       | subnet_id: wordpress-subnet                                                                                                                           |
|                       |                                                                                                                                                       |
| outputs               | - description: Database root password                                                                                                                 |
|                       |   output_key: traefik_url                                                                                                                             |
|                       |   output_value: AvjnxKvbaJjGMhYnBSi5k2xGaHUUlEZx                                                                                                      |
|                       | - description: Database wordpress password                                                                                                            |
|                       |   output_key: portainer_url                                                                                                                           |
|                       |   output_value: q6bp6lUnsqf7f1ChNftOt5V9Ro6fq529                                                                                                      |
|                       | - description: IP                                                                                                                                     |
|                       |   output_key: server_IP                                                                                                                               |
|                       |   output_value: /!\ Don't forget to redirect website.domain.com to 195.15.245.112                                                                     |
|                       |     !                                                                                                                                                 |
|                       |                                                                                                                                                       |
| links                 | - href: https://api.pub1.infomaniak.cloud/orchestration-api/v1/8fe2d1aa62774f0f96740505ec4b1dd6/stacks/Wordpress/6a68797c-6c0f-4b6a-8b3d-0276a00c2974 |
|                       |   rel: self                                                                                                                                           |
|                       |                                                                                                                                                       |
| deletion_time         | None                                                                                                                                                  |
| notification_topics   | []                                                                                                                                                    |
| capabilities          | []                                                                                                                                                    |
| disable_rollback      | True                                                                                                                                                  |
| timeout_mins          | None                                                                                                                                                  |
| stack_owner           | PCU-LDAPCXX                                                                                                                                           |
| parent                | None                                                                                                                                                  |
| stack_user_project_id | 336736ef0dcf4d3185a99b14c41f3f7b                                                                                                                      |
| tags                  | []                                                                                                                                                    |
|                       |                                                                                                                                                       |
+-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------+

As written in the output, you have to redirect your domain name to the IP address of the instance. In this example, I need to create a DNS record for website.domain.com to 195.15.245.112.

Once the redirection is functional, you must connect to the instance to generate the SSL certificate with certbot :

ssh debian@195.15.245.112
sudo ./wordpress_ssl.sh

Your WordPress instance is online!

final.png

Heat Template

heat_template_version: rocky
description:  WordPress
parameters:
  image:
    type: string
    description: image use for wordpress
    default: Debian 11 bullseye
  key:
    type: string
    description: SSH key to connect to the servers
  flavor:
    type: string
    description: flavor used by wordpress
    default: a2-ram4-disk50-perf1
  network:
    type: string
    description: network used by wordpress
    default: wordpress-network
  subnet_id:
    type: string
    description: dedicated subnet for wordpress
    default: wordpress-subnet
  floating_network_id:
    type: string
    description: UUID of a Neutron external network
    default: ext-floating1
  EMAIL:
    type: string
    description: Email for Let's Encrypt
  NDD:
    type: string
    description: Domain for URL (example.com)

resources:
  wait_condition:
    type: OS::Heat::WaitCondition
    properties:
      handle: { get_resource: wait_handle }
      timeout: 600

  database_password:
    type: OS::Heat::RandomString
  database_root_password:
    type: OS::Heat::RandomString


  wait_handle:
    type: OS::Heat::WaitConditionHandle



  # security group
  wordpress_security_group:
    type: OS::Neutron::SecurityGroup
    properties:
      name: "wordpress_security_group"
      description: >
        Allows ICMP, SSH, HTTP & HTTPS default port
      rules:
         - { direction: ingress, protocol: icmp }
         - { direction: ingress, protocol: tcp, port_range_min: 22, port_range_max: 22 }
         - { direction: ingress, protocol: tcp, port_range_min: 80, port_range_max: 80 }
         - { direction: ingress, protocol: tcp, port_range_min: 443, port_range_max: 443 }

  # network resources
  wordpress_network:
    type: OS::Neutron::Net
    properties:
      name: { get_param: network }
      value_specs:
        mtu: 1500

  wordpress_subnet:
    type: OS::Neutron::Subnet
    properties:
      name: 'wordpress-subnet'
      network_id: { get_resource: wordpress_network }
      cidr: "10.11.3.0/24"
      dns_nameservers:
        - "84.16.67.69"
        - "84.16.67.70"
      ip_version: 4

  wordpress_router:
    type: OS::Neutron::Router
    properties:
      name:  'wordpress-router'
      external_gateway_info: { network: ext-floating1 }

  wordpress_router_subnet_interface:
    type: OS::Neutron::RouterInterface
    properties:
      router_id: { get_resource: wordpress_router }
      subnet: { get_resource: wordpress_subnet }

  wordpress_port:
    type: OS::Neutron::Port
    properties:
      network: { get_resource: wordpress_network }
      security_groups: [ { get_resource: wordpress_security_group } ]
      fixed_ips:
        - subnet_id: { get_resource: wordpress_subnet }

  wordpress_floating:
    type: OS::Neutron::FloatingIP
    properties:
      floating_network_id: { get_param: floating_network_id }
      port_id: { get_resource: wordpress_port }

  # instance
  server:
    type: OS::Nova::Server
    depends_on: [ wordpress_router]
    properties:
      flavor: { get_param: flavor }
      image: { get_param: image }
      key_name: {get_param: key}
      networks:
        - port: { get_resource: wordpress_port }
      user_data:
        str_replace:
          template: |
            #!/bin/bash -v
            # Apache
            apt update && apt upgrade -y
            apt-get install apache2  -y
            systemctl start apache2
            systemctl enable apache2
            # PHP
            apt-get install gnupg2 ca-certificates apt-transport-https software-properties-common -y
            echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" | tee /etc/apt/sources.list.d/php.list
            wget -qO - https://packages.sury.org/php/apt.gpg | apt-key add -
            apt-get update -y
            apt-get install php libapache2-mod-php php-pear php-cgi php-common php-mbstring php-zip php-net-socket php-gd php-xml-util php-php-gettext php-mysql php-bcmath unzip wget git -y
            # MariaDB
            apt-get install mariadb-server mariadb-client -y
            systemctl start mariadb
            systemctl enable mariadb
            sed -i s/127.0.0.1/0.0.0.0/ /etc/mysql/mariadb.conf.d/50-server.cnf
            systemctl restart mariadb.service
            mysqladmin -u root password $db_rootpassword
            cat << EOF | mysql -u root --password=$db_rootpassword
            CREATE DATABASE wordpress;
            GRANT ALL PRIVILEGES ON wordpress.* TO "wordpress"@"%"
            IDENTIFIED BY "$db_password";
            FLUSH PRIVILEGES;
            EXIT
            EOF
            # WordPress
            cd /var/www/html
            wget https://wordpress.org/latest.zip
            unzip latest.zip
            mv wordpress $NDD
            cd $NDD
            cp wp-config-sample.php wp-config.php
            sed -i s/database_name_here/wordpress/ wp-config.php
            sed -i s/username_here/wordpress/ wp-config.php
            sed -i s/password_here/$db_password/ wp-config.php
            chown -R www-data:www-data /var/www/html/$NDD
            tee -a /etc/apache2/sites-available/$NDD.conf << EOF
            <VirtualHost *:80>
                ServerAdmin $EMAIL
                ServerName $NDD

                RewriteEngine On
                RewriteCond %{HTTPS} off
                RewriteRule ^(.*)$ $NDD/$1 [L,R=301]
                RewriteCond %{SERVER_NAME} =$NDD
                RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
            </VirtualHost>

            <VirtualHost *:443>
                ServerAdmin $EMAIL
                DocumentRoot /var/www/html/$NDD

                ServerName $NDD

                <Directory /var/www/html/>
                    Options FollowSymLinks
                    AllowOverride All
                    Require all granted
                </Directory>

                ErrorLog ${APACHE_LOG_DIR}/error.log
                CustomLog ${APACHE_LOG_DIR}/access.log combined
            </VirtualHost>
            EOF
            a2ensite $NDD
            a2enmod rewrite
            systemctl restart apache2
            # CertBot
            apt-get install certbot python3-certbot-apache -y
            tee -a /home/debian/wordpress_ssl.sh << EOF
              certbot -n --apache --agree-tos --redirect --hsts --uir --staple-ocsp --email $EMAIL -d $NDD
              echo "@daily certbot renew --quiet &amp;&amp; systemctl reload apache2" >> /etc/cron.d/ssl
              systemctl restart cron
            EOF
            chmod +x /home/debian/wordpress_ssl.sh
            wc_notify --data-binary '{"status": "SUCCESS"}'
          params:
            wc_notify: { get_attr: ['wait_handle', 'curl_cli'] }
            $db_password: {get_attr: [database_password, value]}
            $db_rootpassword: {get_attr: [database_root_password, value]}
            $NDD: { get_param: NDD }
            $EMAIL: { get_param: EMAIL }


outputs:
  root_password:
    value:
      str_replace:
        template: PASSWORD
        params:
          PASSWORD: {get_attr: [database_root_password, value]}
    description: "Database root password"

  wordpress_password:
    value:
      str_replace:
        template: PASSWORD
        params:
          PASSWORD: {get_attr: [database_password, value]}
    description: "Database wordpress password"

  server_IP:
    value:
      str_replace:
        template: /!\ Don't forget to redirect NDD to IP !
        params:
          NDD: { get_param: NDD }
          IP: { get_attr: [wordpress_floating, floating_ip_address] }
    description: "IP"