As a developer, you start with a Cloud Assembly blueprint that contains only minimal WordPress components, such as having only one application server.

Cloud Assembly is an infrastructure-as-code tool. You drag components to the design canvas to get started. Then, you complete the details using the code editor to the right of the canvas.

Prerequisites

Be familiar with your infrastructure. The examples shown here use the infrastructure values from the first part of the use case, but you would substitute your own.

Procedure

  1. Go to Blueprints, and click New.
  2. Name the blueprint Wordpress-BP.
  3. Select the WordPress project, and click Create.
  4. From the components on the left of the blueprint design page, drag two cloud agnostic machines onto the canvas.

    The machines serve as WordPress application server (WebTier) and MySQL database server (DBTier).

  5. On the right, edit the machine YAML code to add names, images, flavors, and constraint tags:
    resources:
      DBTier:    
        type: Cloud.Machine    
        properties:      
            name: mysql      
            image: 'ubuntu-16'      
            flavor: 'small'      
            constraints:        
                -   tag: env:dev
      WebTier:
        type: Cloud.Machine    
        properties:     
            name: wordpress      
            image: 'ubuntu-16'      
            flavor: 'small'      
            constraints:        
                - tag: env:dev
    
  6. Drag a cloud agnostic network to the canvas, and edit its code:
     WP-Network-Private:
        type: Cloud.Network
        properties:
            name: WP-Network-Private
            networkType: existing
            constraints:
                - tag: 'type:isolated-net'
                - tag: 'env:dev'
  7. Connect the machines to the network:

    Click and hold where the line touches the network block, drag to a machine block, and release.

    Two machines and one network

    In the editor, notice that the network code gets added to the two machines:

    resources:
      DBTier:    
        type: Cloud.Machine    
        properties:      
            name: mysql      
            image: 'ubuntu-16'      
            flavor: 'small'      
            constraints:        
                -   tag: env:dev
            networks:
                - name: '${WP-Network-Private.name}'
      WebTier:
        type: Cloud.Machine    
        properties:     
            name: wordpress      
            image: 'ubuntu-16'      
            flavor: 'small'      
            constraints:        
                - tag: env:dev
            networks:
                - name: '${WP-Network-Private.name}'
      

  8. Add user input prompting.

    In some places, the use case infrastructure was set up for multiple options. For example:

    • Cloud zone environments for development, test, and production

    • Flavor mappings for small, medium, and large machines

    • Storage disk speeds for general and fast usage

    You might set a specific option directly in the blueprint, but a better approach is to let the user select the option at blueprint deployment time. Prompting for user input lets you create one blueprint that can be deployed many ways, instead of having many hard-coded blueprints.

    1. Create an inputs section in the code so that users can select machine size and target environment at deployment time. Define the selectable values:
      inputs:
        env:
          type: string
          enum:
            - 'env:dev'
            - 'env:prod'
            - 'env:test'
          default: 'env:dev'
          title: Environment
          description: Target Environment
        size:
          type: string
          enum:
            - small
            - medium
            - large
          description: Size of Nodes
          title: Tier Machine Size
      
    2. In the resources section of the code, add ${input.input-name} code to prompt for the user selection:
      resources:
        DBTier:    
          type: Cloud.Machine    
          properties:      
              name: mysql      
              image: 'ubuntu-16'      
              flavor: '${input.size}'      
              constraints:        
                  -   tag: '${input.env}'
              networks:
                  - name: '${WP-Network-Private.name}'
        WebTier:
          type: Cloud.Machine    
          properties:     
              name: wordpress      
              image: 'ubuntu-16'      
              flavor: '${input.size}'      
              constraints:        
                  - tag: '${input.env}'
              networks:
                  - name: '${WP-Network-Private.name}'
        WP-Network-Private:
          type: Cloud.Network
          properties:
              name: WP-Network-Private
              networkType: existing
              constraints:
                  - tag: 'type:isolated-net'
                  - tag: '${input.env}'
  9. Finally, enhance the WebTier and DBTier code using the following examples. The WP-Network-Private code does not need additional changes.

    Note that the enhancements include login access to the database server, a database disk, and deployment-time cloudConfig initialization scripts.

    Component

    Example

    DBTier Resource

      DBTier:
        type: Cloud.Machine
        metadata:
          layoutPosition:
            - 0
            - 0
        properties:
          name: mysql
          image: ubuntu-16
          flavor: '${input.size}'
          constraints:
            - tag: '${input.env}'
          networks:
            - name: '${WP-Network-Private.name}'
              assignPublicIpAddress: true
          remoteAccess:
            authentication: usernamePassword
            username: '${input.username}'
            password: '${input.userpassword}'
          cloudConfig: |
            #cloud-config
            repo_update: true
            repo_upgrade: all
    
            packages:
             - mysql-server
    
            runcmd:
             - sed -e '/bind-address/ s/^#*/#/' -i /etc/mysql/mysql.conf.d/mysqld.cnf
             - service mysql restart
             - mysql -e "GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'mysqlpassword';"
             - mysql -e "FLUSH PRIVILEGES;"
          attachedDisks: []
    

    Additional DBTier Inputs

      username:
        type: string
        minLength: 4
        maxLength: 20
        pattern: '[a-z]+'
        title: Database Username
        description: Database Username
      userpassword:
        type: string
        pattern: '[a-z0-9A-Z@#$]+'
        encrypted: true
        title: Database Password
        description: Database Password
      databaseDiskSize:
        type: number
        default: 4
        maximum: 10
        title: MySQL Data Disk Size
        description: Database Disk Size
    

    WebTier Resource

      WebTier:
        type: Cloud.Machine
        metadata:
          layoutPosition:
            - 0
            - 1
        properties:
          name: wordpress
          flavor: '${input.size}'
          image: ubuntu-16
          constraints:
            - tag: '${input.env}'
          networks:
            - name: '${WP-Network-Private.name}'
              assignPublicIpAddress: true
          cloudConfig: |
            #cloud-config
            repo_update: true
            repo_upgrade: all
    
            packages:
             - apache2
             - php
             - php-mysql
             - libapache2-mod-php
             - php-mcrypt
             - mysql-client
    
            runcmd:
             - mkdir -p /var/www/html/mywordpresssite && cd /var/www/html && wget https://wordpress.org/latest.tar.gz && tar -xzf /var/www/html/latest.tar.gz -C /var/www/html/mywordpresssite --strip-components 1
             - i=0; while [ $i -le 5 ]; do mysql --connect-timeout=3 -h ${DBTier.networks[0].address} -u root -pmysqlpassword -e "SHOW STATUS;" && break || sleep 15; i=$((i+1)); done
             - mysql -u root -pmysqlpassword -h ${DBTier.networks[0].address} -e "create database wordpress_blog;"
             - mv /var/www/html/mywordpresssite/wp-config-sample.php /var/www/html/mywordpresssite/wp-config.php
             - sed -i -e s/"define('DB_NAME', 'database_name_here');"/"define('DB_NAME', 'wordpress_blog');"/ /var/www/html/mywordpresssite/wp-config.php && sed -i -e s/"define('DB_USER', 'username_here');"/"define('DB_USER', 'root');"/ /var/www/html/mywordpresssite/wp-config.php && sed -i -e s/"define('DB_PASSWORD', 'password_here');"/"define('DB_PASSWORD', 'mysqlpassword');"/ /var/www/html/mywordpresssite/wp-config.php && sed -i -e s/"define('DB_HOST', 'localhost');"/"define('DB_HOST', '${DBTier.networks[0].address}');"/ /var/www/html/mywordpresssite/wp-config.php
             - service apache2 reload

Completed Basic Blueprint Code Example

inputs:
  env:
    type: string
    enum:
      - 'env:dev'
      - 'env:prod'
      - 'env:test'
    default: 'env:dev'
    title: Environment
    description: Target Environment
  size:
    type: string
    enum:
      - small
      - medium
      - large
    description: Size of Nodes
    title: Tier Machine Size
  username:
    type: string
    minLength: 4
    maxLength: 20
    pattern: '[a-z]+'
    title: Database Username
    description: Database Username
  userpassword:
    type: string
    pattern: '[a-z0-9A-Z@#$]+'
    encrypted: true
    title: Database Password
    description: Database Password
  databaseDiskSize:
    type: number
    default: 4
    maximum: 10
    title: MySQL Data Disk Size
    description: Database Disk Size
  archiveDiskSize:
    type: number
    default: 4
    maximum: 10
    title: Wordpress Archive Disk Size
    description: Archive Storage Disk Speed
resources:
  DBTier:
    type: Cloud.Machine
    metadata:
      layoutPosition:
        - 0
        - 0
    properties:
      name: mysql
      image: ubuntu-16
      flavor: '${input.size}'
      constraints:
        - tag: '${input.env}'
      networks:
        - name: '${WP-Network-Private.name}'
          assignPublicIpAddress: true
      remoteAccess:
        authentication: usernamePassword
        username: '${input.username}'
        password: '${input.userpassword}'
      cloudConfig: |
        #cloud-config
        repo_update: true
        repo_upgrade: all

        packages:
         - mysql-server

        runcmd:
         - sed -e '/bind-address/ s/^#*/#/' -i /etc/mysql/mysql.conf.d/mysqld.cnf
         - service mysql restart
         - mysql -e "GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'mysqlpassword';"
         - mysql -e "FLUSH PRIVILEGES;"
      attachedDisks: []
  WebTier:
    type: Cloud.Machine
    metadata:
      layoutPosition:
        - 0
        - 1
    properties:
      name: wordpress
      flavor: '${input.size}'
      image: ubuntu-16
      constraints:
        - tag: '${input.env}'
      networks:
        - name: '${WP-Network-Private.name}'
          assignPublicIpAddress: true
      cloudConfig: |
        #cloud-config
        repo_update: true
        repo_upgrade: all

        packages:
         - apache2
         - php
         - php-mysql
         - libapache2-mod-php
         - php-mcrypt
         - mysql-client

        runcmd:
         - mkdir -p /var/www/html/mywordpresssite && cd /var/www/html && wget https://wordpress.org/latest.tar.gz && tar -xzf /var/www/html/latest.tar.gz -C /var/www/html/mywordpresssite --strip-components 1
         - i=0; while [ $i -le 5 ]; do mysql --connect-timeout=3 -h ${DBTier.networks[0].address} -u root -pmysqlpassword -e "SHOW STATUS;" && break || sleep 15; i=$((i+1)); done
         - mysql -u root -pmysqlpassword -h ${DBTier.networks[0].address} -e "create database wordpress_blog;"
         - mv /var/www/html/mywordpresssite/wp-config-sample.php /var/www/html/mywordpresssite/wp-config.php
         - sed -i -e s/"define('DB_NAME', 'database_name_here');"/"define('DB_NAME', 'wordpress_blog');"/ /var/www/html/mywordpresssite/wp-config.php && sed -i -e s/"define('DB_USER', 'username_here');"/"define('DB_USER', 'root');"/ /var/www/html/mywordpresssite/wp-config.php && sed -i -e s/"define('DB_PASSWORD', 'password_here');"/"define('DB_PASSWORD', 'mysqlpassword');"/ /var/www/html/mywordpresssite/wp-config.php && sed -i -e s/"define('DB_HOST', 'localhost');"/"define('DB_HOST', '${DBTier.networks[0].address}');"/ /var/www/html/mywordpresssite/wp-config.php
         - service apache2 reload
  WP-Network-Private:
    type: Cloud.Network
    metadata:
      layoutPosition:
        - 1
        - 0
    properties:
      name: WP-Network-Private
      networkType: existing
      constraints:
        - tag: 'type:isolated-net'
        - tag: '${input.env}'

What to do next

Test the blueprint by deploying it.