continuous delivery with puppet and artifactory - jenkins

I have Jenkins, Artifactory and 3 environments (development, test and production).
When a developer commits something from the development-environment it's compiled and tested in the test-environment. And the builds and artifacts of it are stored in Artifactory.
Now I wanna go the next step and with the help of puppet manage the environments and deploy the artifacts from Artifactory to the production-environment.
But I need some hints to start:
Where is the best place to install puppet? On the same server as artifactory as they work togehter? Puppet configures the environments as well.. so not sure if there is something that has to be consider.
Are there any configurations I need to keep in mind before or during the installation of puppet? Especially in context with artifactory and jenkins.
Thanks for any hint/ help.

Disclaimer: This is just how I do it :)
I don't see any benefit to putting Artifactory on the same server as Puppet Master, and that seems like a bad idea.
In Artifactory I have a virutal repository that includes only our product artifacts that I care about. I have a separate generic web server that hosts various things puppet nodes and sometimes people in our company need to download. That server is also a forward proxy to the virtual repo in artifactory.
The local web server syncs to an external aws server nightly. Internally, nodes that need to download bits get them from our local server. Externally, they download from the cloud server (really an auto-scaling cluster).
This makes it fairly straightforward to write puppet manifests/custom types that can download, md5, and install artifacts on nodes. Even slicker for Linux would be to build packages, but I don't currently.
I also use Foreman as a Puppet ENC. Versions of software are configured as Foreman parameters on a global, group, and, if need-be, node level. To deploy a new version of of an application war, someone just logs into Foreman, sets the parameter, and waits for Puppet to do its job (or logs into the node and forces a Puppet run if they need to).
Hope that gives you some ideas.

To start with, your first decision needs to be whether you want to run puppet in master-agent (client/server) mode, or in "masterless" mode. The getting started documentation over at puppetlabs.com is solid and it is worth a following the tutorials.
Regardless of your decision, you will need to install puppet on every server that runs puppet - the same binary runs master, agent, apply, etc.
Puppet 101 masterless example assuming redhat-ish OS:
# Install puppet
sudo yum install puppet -y
# Create basic manifest
echo "notify {'hello world':}" > hello.pp
# Run masterless scenario:
sudo puppet apply hello.pp
Expected result:
notice: hello world
notice: /Stage[main]//Notify[hello world]/message: defined 'message' as 'hello world'
notice: Finished catalog run in 0.03 seconds

Related

Deploy web app via Jenkins

I have recently started to mess about with Jenkins and am unsure how to deploy my web app to a basic server. I've gotten into the Pipeline (https://jenkins.io/doc/book/pipeline/) and it seems like a fantastic way to work.
Where I'm a bit stuck is in two spots:
Once my repo is in my workspace within Jenkins, how do I prep it so I am only deploying the files necessary for the application? For example, I don't need my src/ directory or my Vagrantfile when I'm deploying things.
How do I deploy my app to the server? I see examples all over the place, but I am getting a bit lost since there seems to be so many ways to do this. I'm assuming scp or something like that...?
To build off of #2, is there a way to deploy web apps as transactions (in one shot) rather than file-by-file?
Please let me know if I can provide any information for potential answers!
I can't speak to your specific use case but a common way to do this is the build-and-deploy model, where you will have 2 Jenkins jobs. The "build" job will check out from source, run build commands such as maven or make, and lastly will "archive" the build artifacts. The latter is an option under the 'post-build actions' tab at the bottom.
In the "deploy" job, you will grab the artifacts of your choice. You can fetch a single file, all of them, and everything in between. This requires use of the 'Copy Artifact' plug-in and it allows you to copy files generated by other jobs. Now you can run your usual deploy script in the 'Execute Command' box. Most command line paradigms are supported out of the box such as setting environment variables.
The instructions above assume that you want to run your application off of a host that you've provisioned as a Jenkins slave.
Use artifacts as mentioned by Paul Back, or a 3rd party artifactory server as in video
This is always tricky and error-prone. Why not spin up a fresh server with new release (humanly verified once)
Jenkins & Ansible is the answer here. This is how I deploy to production, since I am in no need to use anything like Docker (too many issues with particular app) so have to run the app natively. Quick example would be
You monitor a specific branch in gitlab / github or whatever else and then call a webhook on push / merge etc on that branch, at this point you deal with anything you need to do by running a playbook on the jenkins job that monitors that branch (jenkins).
in my case jenkins and ansible run on the same server. Jenkins runs the ansible playbook that does whatever I need to do.
for example with ansible, I copy certain files that need to be there, run configs / change filenames etc. setup nginx, run composer,
you get the point.

CI/CD with Jenkins and Vagrant

I wanted to build a Jenkins server which would run test of my puppet code on Vagrant. The issue I found is that the we run our server as VMs already, either in vmWare or AWS and Vagrant will not work as another virtualisation.
Does anyone have an idea how can I create a test platform for my puppet code. What I want to test the deployment of manifest on the nodes them self i.e. If I deploy a class web server or make changes to it I would like to check if it affects/breaks deployment of other classes.
The idea would be to iterate over all the classes/roles and see if the deployments are passing. I would like to make it automatic and independent of our engineers. At the moment we are running manual test with vagrant up however there are too many roles to do that by hand.
Any ideas how can I tackle this?
You can use either Docker or AWS provider for Vagrant.
In case of AWS provider you need to set-up RSync to get your environment into newly launched instance.
If your Vagrant scripts are robust, you can use the same script for both local deployment on your workstation and AWS/Docker deployment on CI server.
There are drawbacks to doing these techniques, in case of Docker you are limited to the same kernel that Jenkins server is running, in case of AWS you will incur additional costs. However, for AWS your don't need to allocate as much resources for your Jenkins server, so you might even save money this way because you will be using paying for extra VMs only when you are running you tests. Just make sure you will shut them down after you done.
Is there any special reason why you want to use vagrant? I'm not sure if you are setting up your production environment with vagrant or not.
In case you are not bound to vagrant, I would recommend you to think about using a docker image to prepare a lightweight environment to run your setups and verifications in.
When doing your tests, spin up a container from your image that contains your puppet distribution and run your setups/tests inside. If you have special kernel requirements, use a separate jenkins slave/agent machine rather than executing jobs on the jenkins master.
If you are not sure how to get started using jenkins with docker, have a look into the examples section of the Jenkins Documentation. The provided examples are showing the declarative pipeline syntax thats still a bit new. Also consider the collapsed Toggle Scripted Pipeline Sections which show the groovy pipeline scripts that are alot more forgiving for jenkins pipeline beginners.
Those should be quite good pointers to get started with running+testing your puppet scripts inside docker. For building and using a docker image there should be more than enough tutorials out there.
Let me know if this was a hint in the right direction or if I mistinterpreted your question.

Deploying code on multiple server with Jenkins

I'm new to Jenkins, and I like to know if it is possible to have one Jenkins server to deploy / update code on multiple web servers.
Currently, I have two web servers, which are using python Fabric for deployment.
Any good tutorials, will be greatly welcomed.
One solution could be to declare your web servers as slave nodes.
First thing, give jenkins credentials to your servers (login/password or ssh login+private key or certificate. This can be configured in the "Manage credentials" menu
Then configure the slave nodes. Read the doc
Then, create a multi-configuration job. First you have to install the matrix-project plugin. This will allow you to send the same deployment intructions to both your servers at once
Since you are already using Fabic for deployment, I would suggest installing Fabric on the Jenkins master and have Jenkins kick off the Fabric commands to deploy to the remote servers. You could set up the hostnames or IPs of the remote servers as parameters to the build and just have shell commands that iterate over them and run the Fabric commands. You can take this a step further and have the same job deploy to dev/test/prod just by using a different set of hosts.
I would not make the webservers slave nodes. Reserve slave nodes for build jobs. For example, if you need to build a windows application, you will need a windows Jenkins slave. IF you have a problem with installing Fabric on your Jenkins master, you could create a slave node that is responsible for running Fabric deploys and force anything that runs a fabric command to use that slave. I feel like this is overly complex but if you have a ton of builds on your master, you might want to go this route.

Chef Cookbook for Jenkins Amazon EC2 Plugin Configuration

I want to use Amazon EC2 plugin for setting up autoscaled Slaves.
We aim to script everything using Chef and so far I haven't found anything for this Jenkins plugin. I want to write a cookbook of my own but am wondering what is the best way to do it?
Generally management of the build machine would be done through the EC2 plugin itself, it already installs the Jenkins remote jar for you, so all you need to do beyond that is make sure Java is installed.
There are two methods to use Amazon EC2 plugin and Chef together:
Run Chef to do provisioning on each slave launch or build start
Build pre-baked slave images using Chef and something like Packer and provide them to Jenkins Amazon EC2 plugin
Cons of the first approach:
May take a lot of time depending on what software you are installing with Chef. So it would give a latency for build start and extra bill for machine time.
You can't always get the same build environment you have last time. May lead to heisenbugs and hard troubleshooting.
The second approach is known as Immutable Server. It has its cons too:
Gives you an extra bill for AMI storage.
Less flexible — you can't just fix some version numbers or add requirements for some new software and start a new Jenkins build. You have to rebuild your slave images first. And if you need even slightly different environments you have to build and keep several pre-baked images.
I myself use the second approach right now. You could check source code here. Specifically, configuration of Amazon EC2 plugin with Chef is done here.

Is there a stable plugin for Jenkins for running builds on VMs?

Travis CI has a really nice feature, builds are run within VirtualBox VMs. Each time a build is started, the box is refreshed from a snapshot and the code copied on to it. Any problems with the build cannot affect the host, and you can use any OS to run your builds on.
This would be really good, for example, compiling and testing code on a guest OS that matches your production env. Also, you can keep your host free of any installation dependencies you might need (e.g. a database server) and run ITs without worrying about things like port conflicts.
Does such a thing exist for Jenkins?
Check out the Vagrant Plugin https://wiki.jenkins-ci.org/display/JENKINS/Vagrant-plugin
This plugin allows booting of Vagrant virtual machines, provisioning them and also executing scripts inside of them
You can run Jenkins in a Master Slave Setup. Your Master instance manages all the jobs but lets all the slaves do the actual work. These Slaves can be VMs or physical machines. Go To Manage Jenkins -> Manage Nodes -> New Node to add Nodes to your Jenkins Setup.
There is the vSphere Cloud Plugin and the Scripted Cloud Plugin that can be used for this purpose.

Resources