You and your team develop an WordPress application with cloud agnostic compute resources for the MySQL server, the WordPress server, and other components that can be deployed to AWS, Azure, or vSphere-based clouds. This use case uses AWS and Azure cloud resources.

In this use case, you drag components to the design canvas and then modify the YAML specifications. The process iterates on the same blueprint, adding components, deploying, testing, and redeploying.

As you recall, you also created the infrastructure to support multiple entries in the following profiles and tags:

  • Cloud zone capability tags for zone:dev, zone:test, and zone:prod.

  • Flavor mappings for small, medium, and large size machines.

  • Network profile capability tags for zone:dev, zone:test, and zone: prod.

  • Storage profile tags for usage:general and usage:fast.

To make the deployment process more efficient, you add input values to the blueprint. The deploying users then selects the value at deployment time. You could modify the blueprint when you want to change flavor size or deployment zone, but the inputs are easier to manage in an intensely productive environment.

An example of the full YAML specification is available at the end of this article.

To get started with a blueprint, when you do not have a baseline blueprint-as-code that you can add to a new canvas, you add components, add details, and create relationships.

After you create a baseline, you can iteratively build out the blueprint. In this procedure, you first create a basic blueprint, and they enhance the blueprint until you have a complete multi-tier application that you can deploy to development, testing, and finally, a production environment.

Prerequisites

This blueprint use case uses the sample values that you configured in the infrastructure section. See WordPress Use Case: Create the Infrastructure.

Procedure

  1. On the Blueprints tab, create a new blueprint named Wordpress-BP.
  2. Select the WordPress project.
  3. On the blueprint design page, begin by creating some simple database, WordPress, and WordPress network resources.
    1. Drag two cloud Agnostic Machine component to the canvas to use as the MySQL and WordPress machines.

      Update the YAML in the right pane to match the example.

      resources:
        DBTier:    
          type: Cloud.Machine    
          properties:      
              name: mysql      
              image: 'ubuntu-16'      
              flavor: 'small'      
              constraints:        
                  -   tag: zone:dev
        WebTier:
          type: Cloud.Machine    
          properties:     
              name: wordpress      
              image: 'ubuntu-16'      
              flavor: 'small'      
              constraints:        
                  - tag: zone:dev
      
    2. Add a Cloud Agnostic Network to the canvas and update the YAML to match the example.
       WP-Network-Private:
          type: Cloud.Network
          properties:
              name: WP-Network-Private
              networkType: existing
              constraints:
                  - tag: 'type:isolated-net'
                  - tag: 'zone:dev'
    3. Connect the network to the two machines.


      Connecting networks updates the component YAML

      Notice that the networks are added to the machines in the YAML so that it resembles the example.

      resources:
        DBTier:    
          type: Cloud.Machine    
          properties:      
              name: mysql      
              image: 'ubuntu-16'      
              flavor: 'small'      
              constraints:        
                  -   tag: zone:dev
              networks:
                  - name: '${WP-Network-Private.name}'
        WebTier:
          type: Cloud.Machine    
          properties:     
              name: wordpress      
              image: 'ubuntu-16'      
              flavor: 'small'      
              constraints:        
                  - tag: zone:dev
              networks:
                  - name: '${WP-Network-Private.name}'
        WP-Network-Private:
          type: Cloud.Network
          properties:
              name: WP-Network-Private
              networkType: private
              constraints:
                  - tag: 'type:isolated-net'
                  - tag: 'zone:dev'
  4. Add input properties to the YAML so that deploying users can readily select flavor sizes and zones.
    1. Add the input property definitions.
      inputs:
      	size:
      		type: string
      		enum:
      			- small
      			- medium
      			- large
      		description: Select the size of the deployment. 
      		title: Node Size
      	zone:
      		type: string
      		enum:
      			- zone:dev
      			- zone:test
      			- zone:prod 
      		description: Select the development, testing, or production zone. 
      		title: Deployment Zone
    2. Update the resource properties with variable to populate the request based on what is selected at request time.

      The variable format is ${input.<inputName>}

      inputs:
        size:
          type: string
          enum:
            - small
            - medium
          description: Size of Nodes
          title: Node Size
        zone:
          type: string
          enum:
            - zone:dev
            - zone:test
            - zone:prod
          description: Select the development, testing, or production zone.
          title: Deployment Zone
      resources:
        DBTier:    
          type: Cloud.Machine    
          properties:      
              name: mysql      
              image: 'ubuntu-16'      
              flavor: '${input.size}'      
              constraints:        
                  -   tag: ${input.zone}
              networks:
                  - name: '${WP-Network-Private.name}'
        WebTier:
          type: Cloud.Machine    
          properties:     
              name: wordpress      
              image: 'ubuntu-16'      
              flavor: '${input.size}'      
              constraints:        
                  - tag: ${input.zone}
              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.size}'
  5. Update your blueprint with the full information required for a robust application.
    1. Update the DBTier and WebTier components. The WP-Network-Private resource section is complete.

    Update the resources component based on the example. Update the inputs section to support the resource section.

    The following examples include cloudConfig sections. The cloudConfig section accepts Cloud-Init scripts.

    Component

    Example

    DBTier Resource

    DBTier:
        type: Cloud.Machine
        properties:
          name: mysql
          flavor: '${input.size}'
          image: 'ubuntu-16'
          storage:
            disks:
              - capacityGb: '${input.databaseDiskSize}'
                name: DatabaseDisk
          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;"

    DBTier Inputs

    databaseDiskSize:
        type: number
        default: 4
        maximum: 10
        title: MySQL Data Disk Size
        description: Size of database disk
      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

    WebTier Resource

    WebTier:
        type: Cloud.Machine
        properties:
          name: wordpress
          flavor: '${input.size}'
          image: 'ubuntu-16'
          count: '${input.count}'
          networks:
            - name: '${WP-Network-Private.name}'
              assignPublicIpAddress: true
          storage:
            disks:
              - capacityGb: '${input.archiveDiskSize}'
                name: ArchiveDisk
          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 10 ]; 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

    WebTier Inputs

    count:
        type: integer
        default: 2
        maximum: 5
        minimum: 2
        title: Wordpress Cluster Size
        description: Wordpress Cluster Size (Number of nodes)
      archiveDiskSize:
        type: number
        default: 4
        maximum: 10
        title: Wordpress Archive Disk Size
        description: Size of Wordpress archive disk
  6. To test your application, deploy the blueprint.
    1. Click Deploy and Select Create a new deployment.
    2. Name the deployment WordPress for OurCo.
    3. Select the variables.

      Option

      Description

      Node Size

      small

      Deployment Zone

      zone:dev

  7. To verify that the blueprint deployed successfully, go to the Deployments tab.
    • If it fails, click the deployment and review the History tab messages to troubleshoot the provisioning process. Click the details icon to access the request details.

      Use the History tab to troubleshoot failed deployments

    • After you successfully deploy the application, you can locate the IP address for the deployed application on the Wordpress deployment Topology tab.

  8. In a browser, open the WordPress web site and verify that the application is working as intended.

    If the application needs more work, make your changes and deploy. In this iterative development stage, select Update an existing deployment when you deploy the blueprint. This option conserves resources by replacing the existing deployment rather than deploying a new instance.

  9. Now that you have a baseline deployment, you can version it.

    Versioning during the iterative development process allows you to save the blueprint as a snapshot. You can then revert to a working version if a change that you make causes the blueprint to fail.

    1. On the blueprint canvas page, click Version.
    2. On the Creating Version page, enter wp-1.1.
    3. Click Create.

    To review or revert to a version, on the canvas page header, click Version History.

  10. Now that you have a baseline deployment, you know that the application needs to run on larger machines. You update the WordPress blueprint to increase the size of the mysql and wordpress components.

    When you change the configuration of a blueprint by adding or removing CPUs or memory, this flavor change tears down the previous VMs and reprovisions them as new rather than updating them.

    1. To add memory and CPU select medium at deployment time.
    2. Deploy the blueprint as a new deployment and verify that the application is still working.

Results

You created the blueprint basics that you deployed to your dev environment.

Basic Blueprint YAML Example

inputs:
  size:
    type: string
    enum:
      - small
      - medium
      - large
    description: Size of Nodes
    title: Node Size
  zone:
    type: string
    enum:
      - zone:dev
      - zone:test
      - zone:prod
    description: Select the development, testing, or production zone.
    title: Deployment Zone
		count:
    type: integer
    default: 2
    maximum: 5
    minimum: 2
    title: Wordpress Cluster Size
    description: Wordpress Cluster Size (Number of nodes)
  archiveDiskSize:
    type: number
    default: 4
    maximum: 10
    title: Wordpress Archive Disk Size
    description: Size of Wordpress archive disk
  databaseDiskSize:
    type: number
    default: 4
    maximum: 10
    title: MySQL Data Disk Size
    description: Size of database disk
  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
resources:
  DBTier:    
    type: Cloud.Machine    
    properties:      
        name: mysql      
        image: 'ubuntu-16'      
        flavor: '${input.size}'      
        constraints:        
          -   tag: ${input.zone}
       	storage:
        disks:
          - capacityGb: '${input.databaseDiskSize}'
            name: DatabaseDisk
      		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;"				
  WebTier:
    type: Cloud.Machine    
    properties:     
        name: wordpress      
        image: 'ubuntu-16'      
        flavor: '${input.size}'
								count: '${input.count}'      
        constraints:        
            - tag: ${input.zone}
       		networks:
        		- name: '${WP-Network-Private.name}'
          		assignPublicIpAddress: true
      		storage:
       		 disks:
          		- capacityGb: '${input.archiveDiskSize}'
            		name: ArchiveDisk
      		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 10 ]; 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
    properties:
        name: WP-Network-Private
        networkType: existing
        constraints:
            - tag: 'type:isolated-net'
            - tag: '${input.size}'

What to do next

Continue adding backup and load balancer components, and an application network. When it is working, you then deploy to testing and then to your production environment.