Application deployment is a multi-step process that can even include touching multiple machines or systems. In this blog post we’ll look at how we can use Puppet Bolt to deploy a node application. The application is a simple todo application created by scotch.io that is composed of a node application and a mongodb database. We’ll deploy the application and database on separate servers to show how this can be handled with Puppet Bolt.
We’ll create three (3) Bolt plans that will each be used for a different part of the automation. At a high level we want to install the mongodb database on our database virtual machine and then install our node application on the app virtual machine.
Plan Overview
- todoapp : The todoapp plan will be the overarching plan that actually handles the orchestration of the application deployment.
- db : The db plan installs the mongodb database on the database server virtual machine.
- app : The app plan installs node, npm, git and other prerequisites on the application server virtual machine.
Forge modules
The deployment plan uses the following Puppet Forge modules to deploy the application stack.
- puppet/mongodb
- puppet/nodejs
- camptocamp/systemd
- puppetlabs/vcsrepo
- puppet/firewalld
Initialize the Bolt project
Ensure that the latest version of Puppet Bolt is installed before getting started.
Puppet Bolt utilizes Project directories as launching points for running Bolt operations. Create a directory for our Puppet Bolt project name nodeproject.
mkdir nodeproject
Change the working directory to nodeproject directory
cd nodeproject
Now that we have a directory for hosting our Bolt project, we need to initialize the project.
bolt project init --modules puppet-mongodb,puppet-nodejs,camptocamp-systemd,puppetlabs-vcsrepo,puppet-firewalld
The command should generate output similar to that shown below if it ran successfully.
Installing project modules
→ Resolving module dependencies, this may take a moment
→ Writing Puppetfile at
/system/path/nodeproject/Puppetfile
→ Syncing modules from
/system/path/nodeproject/Puppetfile to
/system/path/nodeproject/modules
→ Generating type references
Successfully synced modules from /system/path/nodeproject/Puppetfile to /system/path/nodeproject/modules
Successfully created Bolt project at /system/path/nodeproject
Create the Bolt YAML plan
In order to utilize plans in Bolt, we need to create a directory named plans.
mkdir plans
Now that we have our plans directory created we’ll plan out what we want to accomplish as part of our plan.
The first thing we’ll do is create the todoapp plan that will call the app and db plans. The name of the sub or nested plans are app and db which are referenced in our plan by the name of the bolt project and the plan (bolt_project::bolt_plan). The plan accepts two parameters ( app, db ) that specify the IP address or FQDN of the virtual machines used for the application and database.
--------
parameters:
app:
type: TargetSpec
db:
type: TargetSpec
steps:
- plan: nodeproject::db
description: "Deploy todo node application mongodb database"
parameters:
db_targets: $db
- plan: nodeproject::app
description: "Deploy todo node application"
parameters:
app_targets: $app
db_targets: $db
Now that we’ve got the todoapp plan in place we need to create the db plan to install the mongodb database. Create another plan in the plans directory named db.yaml.
Steps
- Configure mongodb yum repository
- Install mongodb
- Create firewalld rule for mongodb (port 27017)
--------
parameters:
db_targets:
type: TargetSpec
steps:
- name: installmongo
targets: $db_targets
resources:
- class: mongodb::globals
parameters:
version: 4.2.0
manage_package_repo: true
server_package_name: mongodb-org-server
bind_ip: [0.0.0.0]
- class: mongodb::server
parameters:
port: 27017
- name: configurefirewall
targets: $db_targets
resources:
- class: firewalld
- firewalld_zone: 'public'
parameters:
ensure: present
purge_ports: true
- firewalld_port: 'node db'
parameters:
ensure: present
port: 27017
protocol: tcp
Finally, we’re ready to create the app plan to deploy the node application. Deploying the node application requires a number of steps to actually get the application running. The plan accepts the IP address or DNS name of the application virtual machine and the database virtual machine as parameters.
- Install the git package
- Create a firewalld rule for the node application (port 8080)
- Clone the node-todo git repository
- Install node and npm
- Install the node-todo application packages (npm install)
- Write the database configuration file
- Create a systemd unit file for the node application
- Reload the systemd daemon to recognize the unit file changes
- Start the todo-app service
--------
parameters:
app_targets:
type: TargetSpec
db_targets:
type: String
steps:
- name: installprerequisites
description: "install app prerequisite software"
targets: $app_targets
resources:
- package: git
parameters:
ensure: present
- name: configurefirewall
targets: $app_targets
resources:
- class: firewalld
- firewalld_zone: 'public'
parameters:
ensure: present
purge_ports: true
- firewalld_port: 'node app'
parameters:
ensure: present
port: 8080
protocol: 'tcp'
- name: installtodoapp
targets: $app_targets
resources:
- vcsrepo: '/opt/node-todo'
parameters:
ensure: present
provider: git
source: '[https://github.com/scotch-io/node-todo.git'](https://github.com/scotch-io/node-todo.git')
trust_server_cert: true
- class: nodejs
- nodejs::npm: 'app'
parameters:
ensure: present
target: /opt/node-todo
use_package_json: true
- file: '/opt/node-todo/config/database.js'
parameters:
ensure: present
content: >
module.exports = {
remoteUrl : "mongodb://$db_targets:27017/uwO3mypu",
localUrl: "mongodb://$db_targets:27017/meanstacktutorials"
};
- file: '/etc/systemd/system/todo-app.service'
parameters:
ensure: present
content: >
[Unit]
Description=Todo node application
Documentation=[https://github.com/scotch-io/node-todo](https://github.com/scotch-io/node-todo)
After=network.target
[Service]
Type=simple
WorkingDirectory=/opt/node-todo
ExecStart=/usr/bin/npm start
Restart=on-failure
[Install]
WantedBy=multi-user.target
notify: Class[systemd::systemctl::daemon_reload]
- class: systemd::systemctl::daemon_reload
- service: 'todo-app'
parameters:
ensure: running
subscribe: File[/etc/systemd/system/todo-app.service]
Now that we’ve created our plans we can ensure that it’s recognized by Bolt by running the following command.
bolt plan show
If the plan registers properly the output should include the following entries.
- nodeproject::todoapp
- nodeproject::app
- nodeproject::db
aggregate::count
aggregate::nodes
aggregate::targets
canary
facts
facts::external
facts::info
nodeproject::app
nodeproject::db
nodeproject::todoapp
puppet_agent::run
puppetdb_fact
reboot
secure_env_vars
terraform::apply
terraform::destroy
secure_env_vars
terraform::apply
terraform::destroy
With the plans registered we are now ready to run the todoapp plan by running the bolt plan run nodeproject::todoapp command. The plan.
bolt plan run nodeproject::todoapp app=10.0.0.41 db=10.0.0.42
If the plan ran successfully it should have generated output similar to that displayed below.
Starting: plan nodeproject::todoapp
Starting: plan nodeproject::db
Starting: install puppet and gather facts on 10.0.0.42
Finished: install puppet and gather facts with 0 failures in 74.59 sec
Starting: apply catalog on 10.0.0.42
Finished: apply catalog with 0 failures in 35.91 sec
Starting: install puppet and gather facts on 10.0.0.42
Finished: install puppet and gather facts with 0 failures in 8.03 sec
Starting: apply catalog on 10.0.0.42
Finished: apply catalog with 0 failures in 19.44 sec
Finished: plan nodeproject::db in 2 min, 18 sec
Starting: plan nodeproject::app
Starting: install puppet and gather facts on 10.0.0.41
Finished: install puppet and gather facts with 0 failures in 74.78 sec
Starting: apply catalog on 10.0.0.41
Finished: apply catalog with 0 failures in 25.49 sec
Starting: install puppet and gather facts on 10.0.0.41
Finished: install puppet and gather facts with 0 failures in 7.59 sec
Starting: apply catalog on 10.0.0.41
Finished: apply catalog with 0 failures in 18.23 sec
Starting: install puppet and gather facts on 10.0.0.41
Finished: install puppet and gather facts with 0 failures in 8.9 sec
Starting: apply catalog on 10.0.0.41
Finished: apply catalog with 0 failures in 65.48 sec
Finished: plan nodeproject::app in 3 min, 21 sec
Finished: plan nodeproject::todoapp in 5 min, 40 sec
Plan completed successfully with no result
Once the command completes successfully we can check that everything worked by opening entering the IP address or FQDN of the Bolt target in a web browser. The site should show the following message.
We have now successfully deployed a node application using Puppet Bolt. The automation can be made more elaborate such as interacting with a load balancer, performing database prep operations or more.
Top comments (0)