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.

The code editor allows you to type, cut, and paste code directly. If you're uncomfortable editing code, you can select a resource in the canvas, click the code editor Properties tab, and enter values there. Values that you enter appear in the code as if you had typed them directly.

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:
                - network: '${resource["WP-Network-Private"].id}'
      WebTier:
        type: Cloud.Machine    
        properties:     
            name: wordpress      
            image: 'ubuntu-16'      
            flavor: 'small'      
            constraints:        
                - tag: env:dev
            networks:
                - network: '${resource["WP-Network-Private"].id}'
      
  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:
                  - network: '${resource["WP-Network-Private"].id}'
        WebTier:
          type: Cloud.Machine    
          properties:     
              name: wordpress      
              image: 'ubuntu-16'      
              flavor: '${input.size}'      
              constraints:        
                  - tag: '${input.env}'
              networks:
                  - network: '${resource["WP-Network-Private"].id}'
        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
    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
    
    DBTier Resource
      DBTier:
        type: Cloud.Machine
        properties:
          name: mysql
          image: ubuntu-16
          flavor: '${input.size}'
          constraints:
            - tag: '${input.env}'
          networks:
            - network: '${resource["WP-Network-Private"].id}'
              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 Resource
      WebTier:
        type: Cloud.Machine
        properties:
          name: wordpress
          flavor: '${input.size}'
          image: ubuntu-16
          constraints:
            - tag: '${input.env}'
          networks:
            - network: '${resource["WP-Network-Private"].id}'
              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
resources:
  DBTier:
    type: Cloud.Machine
    properties:
      name: mysql
      image: ubuntu-16
      flavor: '${input.size}'
      constraints:
        - tag: '${input.env}'
      networks:
        - network: '${resource["WP-Network-Private"].id}'
          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
    properties:
      name: wordpress
      flavor: '${input.size}'
      image: ubuntu-16
      constraints:
        - tag: '${input.env}'
      networks:
        - network: '${resource["WP-Network-Private"].id}'
          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
    properties:
      name: WP-Network-Private
      networkType: existing
      constraints:
        - tag: 'type:isolated-net'
        - tag: '${input.env}'

What to do next

Test the blueprint by checking the syntax and deploying it.