<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Jose Armesto&#39;s Blog</title>
    <link>https://blog.armesto.net/tags/jenkins-x/index.xml</link>
    <description>Recent content on Jose Armesto&#39;s Blog</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>es-es</language>
    <copyright>Powered by [Hugo](//gohugo.io). Theme by [PPOffice](https://github.com/ppoffice).</copyright>
    <atom:link href="https://blog.armesto.net/tags/jenkins-x/index.xml" rel="self" type="application/rss+xml" />
    
    <item>
      <title>Automatically versioning your Application on Jenkins X</title>
      <link>https://blog.armesto.net/automatically-versioning-your-application-on-jenkins-x/</link>
      <pubDate>Fri, 01 Feb 2019 23:47:55 +0000</pubDate>
      
      <guid>https://blog.armesto.net/automatically-versioning-your-application-on-jenkins-x/</guid>
      <description>&lt;p&gt;Having a good versioning strategy for our applications is key.
Specially in Jenkins X, which follows the &lt;a href=&#34;https://www.weave.works/blog/what-is-gitops-really&#34;&gt;GitOps flow&lt;/a&gt; to deploy our applications, specifying which version of our application will be used on each environment.&lt;/p&gt;

&lt;p&gt;But having to manually create tags or releases for our applications can be a tedious task. Jenkins X automatically takes care of versioning for us.
It uses a tool called &lt;a href=&#34;https://github.com/jenkins-x/jx-release-version&#34;&gt;jx-release-version&lt;/a&gt; to figure out which is the next version to be released.
In order to do that it checks what&amp;rsquo;s the current released version in the repository looking at the released Git tags. It can also read this version from your &lt;code&gt;pom.xml&lt;/code&gt; file, or your &lt;code&gt;Makefile&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If we use &lt;a href=&#34;https://semver.org/&#34;&gt;semver semantics&lt;/a&gt;, and versions are written in the format major.minor.patch, jx-release-version will tell you which is the next patch version.&lt;/p&gt;

&lt;p&gt;The cool thing is that you don&amp;rsquo;t need to use Jenkins X to use &lt;a href=&#34;https://github.com/jenkins-x/jx-release-version&#34;&gt;jx-release-version&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;Let&amp;rsquo;s go through some examples.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;h1 id=&#34;using-git-tags&#34;&gt;Using git tags&lt;/h1&gt;

&lt;p&gt;Using git tags is probably the easiest way to handle our application versions. We can create a new git tag for every new version that we want to release.&lt;/p&gt;

&lt;p&gt;If we try to use &lt;code&gt;jx-release-version&lt;/code&gt; on a Git repository that has no tags, it will return that the next version number to release is &lt;code&gt;0.0.1&lt;/code&gt;.
Next time we use &lt;code&gt;jx-release-version&lt;/code&gt;, it will increase our patch number.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-bash&#34;&gt;$ git --no-pager tag -l
$ # there are no tags just yet!
$ RELEASE_VERSION=`jx-release-version` &amp;amp;&amp;amp; git tag -fa v${RELEASE_VERSION} -m &#39;Release version ${RELEASE_VERSION}&#39;
$ git --no-pager tag -l
v0.0.1
$ RELEASE_VERSION=`jx-release-version` &amp;amp;&amp;amp; git tag -fa v${RELEASE_VERSION} -m &#39;Release version ${RELEASE_VERSION}&#39;
$ git --no-pager tag -l
  v0.0.1
  v0.0.2
&lt;/code&gt;&lt;/pre&gt;

&lt;h1 id=&#34;using-maven-pom-file&#34;&gt;Using maven pom file&lt;/h1&gt;

&lt;p&gt;If you are using a &lt;code&gt;pom.xml&lt;/code&gt; file that also tracks your current application version, you still can use &lt;code&gt;jx-release-version&lt;/code&gt;.
It will try to sync the git tags in your Git repository with the version that you specify in the &lt;code&gt;pom.xml&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Your release process needs to look something like this&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-bash&#34;&gt;# First we call the `jx-release-version` binary that will return the next version number to be released.
# Every time we call the binary it will try to figure out the next version number. Normally it&#39;s not a good idea to call it more than once.
RELEASE_VERSION=`jx-release-version`
echo &amp;quot;New release version ${RELEASE_VERSION}

# We update our current pom.xml file with this new version number.
mvn versions:set -DnewVersion=${RELEASE_VERSION}

# Changes to the pom.xml file need to be committed to our repository.
git commit -a -m &#39;release ${RELEASE_VERSION}&#39;

# The git commit containing both our application changes and the change to the pom.xml file will be tagged using the same version number.
git tag -fa v${RELEASE_VERSION} -m &#39;Release version ${RELEASE_VERSION}&#39;

# Push the commit and tag to the remote repository.
git push origin v${RELEASE_VERSION}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If we start a new git repository that has no tags, the &lt;code&gt;jx-release-version&lt;/code&gt; will use the version in our &lt;code&gt;pom.xml&lt;/code&gt; file.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-xml&#34;&gt;&amp;lt;project xmlns=&amp;quot;http://maven.apache.org/POM/4.0.0&amp;quot; xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot; xsi:schemaLocation=&amp;quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd&amp;quot;&amp;gt;
    &amp;lt;modelVersion&amp;gt;4.0.0&amp;lt;/modelVersion&amp;gt;

    &amp;lt;groupId&amp;gt;io.example&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;example&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;1.0-0-SNAPSHOT&amp;lt;/version&amp;gt;
    &amp;lt;packaging&amp;gt;pom&amp;lt;/packaging&amp;gt;
&amp;lt;/project&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The release version for &lt;code&gt;1.0.0-SNAPSHOT&lt;/code&gt; is &lt;code&gt;1.0.0&lt;/code&gt;, so &lt;code&gt;jx-release-version&lt;/code&gt; will return &lt;code&gt;1.0.0&lt;/code&gt; as the next version number to use.
Similarly, if our &lt;code&gt;pom.xml&lt;/code&gt; file had &lt;code&gt;&amp;lt;version&amp;gt;0.0-23-SNAPSHOT&amp;lt;/version&amp;gt;&lt;/code&gt; in it, &lt;code&gt;jx-release-version&lt;/code&gt; would return &lt;code&gt;0.0.23&lt;/code&gt; as the next version number to use.&lt;/p&gt;

&lt;h1 id=&#34;using-a-makefile&#34;&gt;Using a Makefile&lt;/h1&gt;

&lt;p&gt;Let&amp;rsquo;s say we have this Makefile that tracks the current version of our application&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-bash&#34;&gt;# This is the current version of your application
VERSION := 2.0.3-SNAPSHOT

# Use jx-release-version to calculate next version
RELEASE_VERSION := $(shell jx-release-version)

build:
	# The git commit containing our application changes will be tagged.
	git tag -fa v${RELEASE_VERSION} -m &#39;Release version ${RELEASE_VERSION}&#39;

	# Push the tag to the remote repository.
	git push origin v${RELEASE_VERSION}

&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The current version of our application is &lt;code&gt;2.0.3-SNAPSHOT&lt;/code&gt;.
That means that the &lt;code&gt;jx-release-version&lt;/code&gt; will return &lt;code&gt;2.0.3&lt;/code&gt; as the next version number to use.&lt;/p&gt;

&lt;h1 id=&#34;releasing-a-new-major-minor-version&#34;&gt;Releasing a new major/minor version&lt;/h1&gt;

&lt;p&gt;Sometimes we don&amp;rsquo;t want to just release a new patch version (like going from &lt;code&gt;1.0.5&lt;/code&gt; to &lt;code&gt;1.0.6&lt;/code&gt;). Instead, we want to release &lt;code&gt;1.1.0&lt;/code&gt;, or even &lt;code&gt;2.0.0&lt;/code&gt;.
We have said earlier that jx-release-version calculates the next version number based on the current Git tag, or current specified version on &lt;code&gt;pom.xml&lt;/code&gt;/&lt;code&gt;Makefile&lt;/code&gt;.
So if we need to release a new major/minor version, we just have to release a new Git tag or update the &lt;code&gt;pom.xml&lt;/code&gt;/&lt;code&gt;Makefile&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For example, if the current version is &lt;code&gt;0.0.2&lt;/code&gt; and we want to release &lt;code&gt;0.1.0&lt;/code&gt;, we first create a git tag for that and let &lt;code&gt;jx-release-version&lt;/code&gt; do it&amp;rsquo;s thing afterwards.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-bash&#34;&gt;# Manually create new tag for the version that we want
git tag -fa v0.1.0 -m &amp;quot;Release version 0.1.0&amp;quot;
# Use jx-release version normally
$ RELEASE_VERSION=`jx-release-version` &amp;amp;&amp;amp; git tag -fa v${RELEASE_VERSION} -m &#39;Release version ${RELEASE_VERSION}&#39;
$ git --no-pager tag -l
v0.0.1
v0.0.2
v0.1.0
v0.1.1
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As said in the &lt;a href=&#34;https://github.com/jenkins-x/jx-release-version&#34;&gt;project&amp;rsquo;s README&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If your project is new or has no existing git tags then running &lt;code&gt;jx-release-version&lt;/code&gt; will return a default version of &lt;code&gt;0.0.1&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;If your latest git tag is &lt;code&gt;1.2.3&lt;/code&gt; and you Makefile or pom.xml is &lt;code&gt;1.2.0-SNAPSHOT&lt;/code&gt; then &lt;code&gt;jx-release-version&lt;/code&gt; will return &lt;code&gt;1.2.4&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;If your latest git tag is &lt;code&gt;1.2.3&lt;/code&gt; and your Makefile or pom.xml is &lt;code&gt;2.0.0&lt;/code&gt; then &lt;code&gt;jx-release-version&lt;/code&gt; will return &lt;code&gt;2.0.0&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
    </item>
    
    <item>
      <title>Jenkins X Environments</title>
      <link>https://blog.armesto.net/jenkins-x-environments/</link>
      <pubDate>Wed, 05 Dec 2018 23:47:55 +0000</pubDate>
      
      <guid>https://blog.armesto.net/jenkins-x-environments/</guid>
      <description>&lt;p&gt;This year Jenkins X has been announced. If you haven&amp;rsquo;t heard, Jenkins X is a tool that lets you automate the whole delivery process of your software to a Kubernetes cluster.
One key aspect of Jenkins X is that the deployment of applications is implemented following the &lt;a href=&#34;https://www.weave.works/blog/what-is-gitops-really&#34;&gt;GitOps flow&lt;/a&gt;.
In this approach every environment is represented by a Git repository. In this post we&amp;rsquo;ll see how Jenkins X environments work.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;h2 id=&#34;environments&#34;&gt;Environments&lt;/h2&gt;

&lt;p&gt;An installation of Jenkins X consists of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;code&gt;Development Environment&lt;/code&gt; which is a kubernetes namespace running tools like Jenkins, Nexus, etc. Each different team within an organization is meant to have its own development environment so that they can be as independent from each other as possible.&lt;/li&gt;
&lt;li&gt;Other &lt;code&gt;Permanent Environments&lt;/code&gt; which are kubernetes namespaces where our applications will be deployed into. By default &lt;code&gt;Staging&lt;/code&gt; and &lt;code&gt;Production&lt;/code&gt; are created. Each team can have as many Permanent Environments as they wish and call them whatever they like.&lt;/li&gt;
&lt;li&gt;Optional &lt;code&gt;Preview Environments&lt;/code&gt;, which are kubernetes namespaces where our applications will be deployed, just like Permanent Environments, but these are created on a PR basis, before you even merge your PR changes into master.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Under the covers this is implemented creating a custom Kubernetes resource &lt;code&gt;jenkins.io/v1/Environment&lt;/code&gt;.
Assuming that each team has a Kubernetes namespace assigned, each team will normally have a Development Environment and several different Permanent Environments.
Each of these environments is represented by a &lt;code&gt;jenkins.io/v1/Environment&lt;/code&gt; object on the namespace assigned to that team.&lt;/p&gt;

&lt;p&gt;Teams are also represented by a &lt;code&gt;jenkins.io/v1/Team&lt;/code&gt; object, but we will cover that on a different post.&lt;/p&gt;

&lt;p&gt;These &lt;code&gt;Environment&lt;/code&gt; objects contain configuration about which Git repository is associated with it, and which git branch to use.&lt;/p&gt;

&lt;p&gt;There could be one namespace which is where all apps run across all teams - though from a kubernetes RBAC perspective, if you are working in microservices teams, it&amp;rsquo;s better for each team to manage their own microservices in their own production environment and use service linking between teams.&lt;/p&gt;

&lt;h3 id=&#34;development-environment&#34;&gt;Development Environment&lt;/h3&gt;

&lt;p&gt;A &lt;code&gt;jenkins.io/v1/Environment&lt;/code&gt; object created on the team’s namespace, which &lt;code&gt;spec.Kind&lt;/code&gt; field is &lt;code&gt;Dev&lt;/code&gt;.
This environment is not linked to a Github repository, we will never promote changes here.
It’s just a Kubernetes namespace used to run applications while developing, thanks to &lt;a href=&#34;https://github.com/GoogleContainerTools/skaffold&#34;&gt;skaffold&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In the dev environment Jenkins X installs a number of core applications they believe are required at a minimum to start folks off with CI/CD on Kubernetes. They come with configuration that wires these services together meaning everything works together straight away.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Jenkins — provides both Continuous Integration and Continuous Delivery automation.&lt;/li&gt;
&lt;li&gt;Nexus — acts as a dependency cache for applications to dramatically improve build times.&lt;/li&gt;
&lt;li&gt;Docker registry — an in cluster Docker registry where the pipelines push application images.&lt;/li&gt;
&lt;li&gt;Chartmuseum — a registry for publishing Helm charts.&lt;/li&gt;
&lt;li&gt;Monocular — a UI used for discovering and running Helm charts.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&#34;permanent-environments&#34;&gt;Permanent Environments&lt;/h3&gt;

&lt;p&gt;These environments are where the applications will ran. By default &lt;code&gt;Staging&lt;/code&gt; and &lt;code&gt;Production&lt;/code&gt; are created, but more environments can be created. &lt;code&gt;Staging&lt;/code&gt; has the Auto promote strategy and &lt;code&gt;Production&lt;/code&gt; the Manual promote strategy. We&amp;rsquo;ll see what that means in a minute.&lt;/p&gt;

&lt;p&gt;These environment are linked to&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A GitHub repository containing a Helm chart that defines which application charts are to be installed on the environment, which versions of them and any environment specific configuration and additional resources (e.g. Secrets or operational applications like Prometheus etc).&lt;/li&gt;
&lt;li&gt;A Kubernetes namespace where the Helm chart from the repository will be installed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When you want to deploy to an environment, a Pull Request must be made to that environment’s repository.
We can manually create the PR to deploy an application to an environment, or we can use this handy &lt;code&gt;jx&lt;/code&gt; command&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;jx promote --app myapp --version 1.2.3 --env production
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Typically we specify the environment while promoting to environments with the Manual promote strategy, like the &lt;code&gt;Production&lt;/code&gt; environment.
Instead of specifying the environment, we can create a Pull Request in all the environments having the Auto promote strategy using this &lt;code&gt;jx&lt;/code&gt; command&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;jx promote -b --all-auto --timeout 1h --version \$(cat ../../VERSION) --no-wait
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Changing the &lt;code&gt;Production&lt;/code&gt; environment&amp;rsquo;s promote strategy from Manual to Auto you can do Continuous Deployment.&lt;/p&gt;

&lt;p&gt;When these PRs are merged into the environment&amp;rsquo;s git repository, the environment pipeline runs, which then applies the Helm chart living on that repo to the environment&amp;rsquo;s Kubernetes namespace.&lt;/p&gt;

&lt;h3 id=&#34;preview-environments&#34;&gt;Preview Environments&lt;/h3&gt;

&lt;p&gt;Preview Environments are similar to Permanent Environments in that they are defined in a source code Git repository using Helm charts.
The main difference is that Preview Environments are configured inside the application repository in the ./chart/preview folder.
Also they are not permanent but created when a Pull Request is made to an application&amp;rsquo;s git repository, and then deleted some time after (manually or via automatic garbage collection).&lt;/p&gt;

&lt;p&gt;When the Preview Environment is up and running Jenkins X will comment on your Pull Request with a link so in one click your team members can try out the preview.&lt;/p&gt;

&lt;p&gt;You can create a preview environments using&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;jx preview
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This will create the &lt;code&gt;Environment&lt;/code&gt; and &lt;code&gt;Namespace&lt;/code&gt; objects for this environment.
It will also build the application creating a new Docker image that will be deployed to the preview environment using the preview chart defined in the ./chart/preview folder.&lt;/p&gt;

&lt;h2 id=&#34;managing-environments&#34;&gt;Managing environments&lt;/h2&gt;

&lt;p&gt;You can create new environments using jx&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;jx create env --name prod --label Production --namespace my-prod
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Some interesting options are&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;label: The Environment label which is a descriptive string like &lt;code&gt;Production&lt;/code&gt; or &lt;code&gt;Staging&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;prefix: Environment repo prefix, your Git repo will be of the form &lt;code&gt;environment-$prefix-$envName&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;promotion: The promotion strategy, Auto or Manual.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can then list all existing environments&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;jx get environments
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Or edit an existing environment (-b for no interactive)&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;jx edit env -b --name prod --label Production --no-gitops --namespace my-prod
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Or finally delete it&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;jx delete environment prod
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&#34;deployment-flow&#34;&gt;Deployment Flow&lt;/h2&gt;

&lt;p&gt;In the workflow that Jenkins X proposes, we will have a repository for each application that we want to deploy.
But also we will have a repository for each environment where you want to deploy these applications.
The repositories for the different environments describe all the applications that must be running on them.&lt;/p&gt;

&lt;p&gt;So while developing your application, the usual flow would be&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a Pull Request on the application repository: this will execute the application CI pipeline to build and test the application.&lt;/li&gt;
&lt;li&gt;Once the Pull Request on the application repository is merged, the application pipeline will release this newly built version to a Docker Registry and promote it to the environments with the Auto promote strategy using a &lt;code&gt;jx&lt;/code&gt; command.&lt;/li&gt;
&lt;li&gt;If we want to deploy to production or any environment with the Manual promotion strategy, we need to execute the &lt;code&gt;jx&lt;/code&gt; command targeting the desired environment.&lt;/li&gt;
&lt;/ul&gt;</description>
    </item>
    
  </channel>
</rss>