Tutorial: Deploy to a Service Fabric cluster
This tutorial covers several possible ways of setting up your Jenkins environment as well as different ways to deploy your application to a Service Fabric cluster after it has been built. Follow these general steps to successfully configure Jenkins, pull changes from GitHub, build your application, and deploy it to your cluster:
- Ensure that you install the Prerequisites.
- Then follow the steps in one of these sections to set up Jenkins:
- After you've set up Jenkins, follow the steps in Create and configure a Jenkins job to set up GitHub to trigger Jenkins when changes are made to your application and to configure your Jenkins job pipeline through the build step to pull the changes from GitHub and build your application.
- Finally, configure the Jenkins job post-build step to deploy your application to your Service Fabric cluster. There are two ways to configure Jenkins to deploy your application to a cluster:
- For development and test environments, use Configure deployment using cluster management endpoint. This method is the simplest deployment method to set up.
- For production environments, use Configure deployment using Azure credentials. Microsoft recommends this method for production environments because with Azure credentials you can limit the access that a Jenkins job has to your Azure resources.
Prerequisites
- Make sure Git is installed locally. You can install the appropriate Git version from the Git downloads page based on your operating system. If you're new to Git, learn more about it from the Git documentation.
- This article uses the Service Fabric Getting Started Sample on GitHub: https://github.com/Azure-Samples/service-fabric-java-getting-started for the application to build and deploy. You can fork this repository to follow along, or, with some modification to the instructions, use your own GitHub project.
Install Service Fabric plug-in in an existing Jenkins environment
If you're adding the Service Fabric plug-in to an existing Jenkins environment, you need to do the following steps:
- Service Fabric CLI (sfctl). Install the CLI at the system level rather than at the user level, so Jenkins can run CLI commands.
- To deploy Java applications, install both Gradle and Open JDK 8.0.
- To deploy .NET Core 2.0 applications, install the .NET Core 2.0 SDK.
After you've installed the prerequisites needed for your environment, you can search for the Azure Service Fabric plug-in in Jenkins marketplace and install it.
After you've installed the plug-in, skip ahead to Create and configure a Jenkins job.
Set up Jenkins inside a Service Fabric cluster
You can set up Jenkins either inside or outside a Service Fabric cluster. The following sections show how to set it up inside a cluster while using an Azure storage account to save the state of the container instance.
Ensure that you have a Service Fabric Linux cluster with Docker installed. Service Fabric clusters running in Azure already have Docker installed. If you're running the cluster locally (OneBox dev environment), check if Docker is installed on your machine with the
docker info
command. If it is not installed, install it by using the following commands:sudo apt-get install wget wget -qO- https://get.docker.io/ | sh
Note
Make sure that the 8081 port is specified as a custom endpoint on the cluster. If you are using a local cluster, make sure that port 8081 is open on the host machine and that it has a public-facing IP address.
Clone the application, by using the following commands:
git clone https://github.com/suhuruli/jenkins-container-application.git cd jenkins-container-application
Persist the state of the Jenkins container in a file-share:
Create an Azure storage account in the same region as your cluster with a name such as
sfjenkinsstorage1
.Create a File Share under the storage Account with a name such as
sfjenkins
.Click on Connect for the file-share and note the values it displays under Connecting from Linux, the value should look similar to the one below:
sudo mount -t cifs //sfjenkinsstorage1.file.core.windows.net/sfjenkins [mount point] -o vers=3.0,username=<username>,password=<storage-key>,dir_mode=0777,file_mode=0777
Note
To mount cifs shares, you need to have the cifs-utils package installed in the cluster nodes.
Update the placeholder values in the
setupentrypoint.sh
script with the azure-storage details from step 2.vi JenkinsSF/JenkinsOnSF/Code/setupentrypoint.sh
- Replace
[REMOTE_FILE_SHARE_LOCATION]
with the value//sfjenkinsstorage1.file.core.windows.net/sfjenkins
from the output of the connect in step 2 above. - Replace
[FILE_SHARE_CONNECT_OPTIONS_STRING]
with the valuevers=3.0,username=<username>,password=<storage-key>,dir_mode=0777,file_mode=0777
from step 2 above.
- Replace
Secure Cluster Only:
To configure the deployment of applications on a secure cluster from Jenkins, the cluster certificate must be accessible within the Jenkins container. In the ApplicationManifest.xml file, under the ContainerHostPolicies tag add this certificate reference and update the thumbprint value with that of the cluster certificate.
<CertificateRef Name="MyCert" X509FindValue="[Thumbprint]"/>
Additionally, add the following lines under the ApplicationManifest (root) tag in the ApplicationManifest.xml file and update the thumbprint value with that of the cluster certificate.
<Certificates> <SecretsCertificate X509FindType="FindByThumbprint" X509FindValue="[Thumbprint]" /> </Certificates>
Connect to the cluster and install the container application.
Secure Cluster
sfctl cluster select --endpoint https://PublicIPorFQDN:19080 --pem [Pem] --no-verify # cluster connect command bash Scripts/install.sh
The preceding command takes the certificate in PEM format. If your certificate is in PFX format, you can use the following command to convert it. If your PFX file isn't password protected, specify the passin parameter as
-passin pass:
.openssl pkcs12 -in cert.pfx -out cert.pem -nodes -passin pass:<password>
Unsecure Cluster
sfctl cluster select --endpoint http://PublicIPorFQDN:19080 # cluster connect command bash Scripts/install.sh
This installs a Jenkins container on the cluster, and can be monitored by using the Service Fabric Explorer.
Note
It may take a couple of minutes for the Jenkins image to be downloaded on the cluster.
From your browser, go to
http://PublicIPorFQDN:8081
. It provides the path of the initial admin password required to sign in.Look at the Service Fabric Explorer to determine on which node the Jenkins container is running. Secure Shell (SSH) sign in to this node.
ssh user@PublicIPorFQDN -p [port]
Get the container instance ID by using
docker ps -a
.Secure Shell (SSH) sign in to the container and paste the path you were shown on the Jenkins portal. For example, if in the portal it shows the path
PATH_TO_INITIAL_ADMIN_PASSWORD
, run the following commands:docker exec -t -i [first-four-digits-of-container-ID] /bin/bash # This takes you inside Docker shell
cat PATH_TO_INITIAL_ADMIN_PASSWORD # This displays the password value
On the Jenkins Getting Started page, choose the Select plug-in to install option, select the None checkbox, and click install.
Create a user or select to continue as an admin.
After you've set up Jenkins, skip ahead to Create and configure a Jenkins job.
Set up Jenkins outside a Service Fabric cluster
You can set up Jenkins either inside or outside of a Service Fabric cluster. The following sections show how to set it up outside a cluster.
Make sure that Docker is installed on your machine by running
docker info
in the terminal. The output indicates if the Docker service is running.If Docker is not installed, run the following commands:
sudo apt-get install wget wget -qO- https://get.docker.io/ | sh
Pull the Service Fabric Jenkins container image:
docker pull rapatchi/jenkins:latest
. This image comes with Service Fabric Jenkins plug-in pre-installed.Run the container image:
docker run -itd -p 8080:8080 rapatchi/jenkins:latest
Get the ID of the container image instance. You can list all the Docker containers with the command
docker ps –a
Sign in to the Jenkins portal with the following steps:
Sign in to a Jenkins shell from your host. Use the first four digits of the container ID. For example, if the container ID is
2d24a73b5964
, use2d24
.docker exec -it [first-four-digits-of-container-ID] /bin/bash
From the Jenkins shell, get the admin password for your container instance:
cat /var/jenkins_home/secrets/initialAdminPassword
To sign in to the Jenkins dashboard, open the following URL in a web browser:
http://<HOST-IP>:8080
. Use the password from the previous step to unlock Jenkins.(Optional.) After you sign in for the first time, you can create your own user account and use that for the following steps, or you can continue to use the administrator account. If you create a user, you need to continue with that user.
Set up GitHub to work with Jenkins by using the steps in Generating a new SSH key and adding it to the SSH agent.
Use the instructions provided by GitHub to generate the SSH key, and to add the SSH key to the GitHub account that is hosting the repository.
Run the commands mentioned in the preceding link in the Jenkins Docker shell (and not on your host).
To sign in to the Jenkins shell from your host, use the following command:
docker exec -t -i [first-four-digits-of-container-ID] /bin/bash
Make sure that the cluster or machine where the Jenkins container image is hosted has a public-facing IP address. This enables the Jenkins instance to receive notifications from GitHub.
After you've set up Jenkins, continue on to the next section, Create and configure a Jenkins job.
Create and configure a Jenkins job
The steps in this section show you how to configure a Jenkins job to respond to changes in a GitHub repo, fetch the changes, and build them. At the end of this section, you're directed to the final steps to configure the job to deploy your application based on whether you're deploying to a development/test environment or to a production environment.
On the Jenkins dashboard, click New Item.
Enter an item name (for example, MyJob). Select free-style project, and click OK.
The Job configuration page opens. (To get to the configuration from the Jenkins dashboard, click the job, and then click Configure).
On the General tab, check the box for GitHub project, and specify your GitHub project URL. This URL hosts the Service Fabric Java application that you want to integrate with the Jenkins continuous integration, continuous deployment (CI/CD) flow (for example,
https://github.com/{your-github-account}/service-fabric-java-getting-started
).On the Source Code Management tab, select Git. Specify the repository URL that hosts the Service Fabric Java application that you want to integrate with the Jenkins CI/CD flow (for example,
https://github.com/{your-github-account}/service-fabric-java-getting-started
). You can also specify which branch to build (for example,/master
).Configure your GitHub repository to talk to Jenkins:
On your GitHub repository page, go to Settings > Integrations and Services.
Select Add Service, type Jenkins, and select the Jenkins-GitHub plug-in.
Enter your Jenkins webhook URL (by default, it should be
http://<PublicIPorFQDN>:8081/github-webhook/
). Click add/update service.A test event is sent to your Jenkins instance. You should see a green check by the webhook in GitHub, and your project will build.
On the Build Triggers tab in Jenkins, select which build option you want. For this example, you want to trigger a build whenever a push to the repository happens, so select GitHub hook trigger for GITScm polling. (Previously, this option was called Build when a change is pushed to GitHub.)
On the Build tab, do one of the following depending on whether you're building a Java application or a .NET Core application:
For Java Applications: From the Add build step drop-down, select Invoke Gradle Script. Click Advanced. In the advanced menu, specify the path to Root build script for your application. It picks up build.gradle from the path specified and works accordingly. For the ActorCounter application, this is:
${WORKSPACE}/reliable-services-actor-sample/Actors/ActorCounter
.For .NET Core Applications: From the Add build step drop-down, select Execute Shell. In the command box that appears, the directory first needs to be changed to the path where the
build.sh
file is located. Once the directory has been changed, thebuild.sh
script can be run to build the application.cd /var/jenkins_home/workspace/[Job Name]/[Path to build.sh] ./build.sh
The following screenshot shows an example of the commands that are used to build the Counter Service sample with a Jenkins job name of
CounterServiceApplication
.
To configure Jenkins to deploy your app to a Service Fabric cluster in the post-build actions, you need the location of that cluster's certificate in your Jenkins container. Choose one of the following depending on whether your Jenkins container is running inside or outside of your cluster and note the location of the cluster certificate:
For Jenkins running inside your cluster: The path to the certificate can be found by echoing the value of the Certificates_JenkinsOnSF_Code_MyCert_PEM environment variable from within the container.
echo $Certificates_JenkinsOnSF_Code_MyCert_PEM
For Jenkins running outside your cluster: Follow these steps to copy the cluster certificate to your container:
Your certificate must be in PEM format. If you don't have a PEM file, you can create one from the certificate PFX file. If your PFX file is not password protected, run the following command from your host:
openssl pkcs12 -in clustercert.pfx -out clustercert.pem -nodes -passin pass:
If the PFX file is password protected, include the password in the
-passin
parameter. For example:openssl pkcs12 -in clustercert.pfx -out clustercert.pem -nodes -passin pass:<password>
To get the container ID for your Jenkins container, run
docker ps
from your host.Copy the PEM file to your container with the following Docker command:
docker cp clustercert.pem [first-four-digits-of-container-ID]:/var/jenkins_home
You're almost finished! Keep the Jenkins job open. The only remaining task is to configure the post-build steps to deploy your application to your Service Fabric cluster:
- To deploy to a development or test environment, follow the steps in Configure deployment using cluster management endpoint.
- To deploy to a production environment, follow the steps in Configure deployment using Azure credentials.
Configure deployment using cluster management endpoint
For development and test environments, you can use the cluster management endpoint to deploy your application. Configuring the post-build action with the cluster management endpoint to deploy your application requires the least amount of set-up. If you're deploying to a production environment, skip ahead to Configure deployment using Azure credentials to configure a Microsoft Entra service principal to use during deployment.
In the Jenkins job, click the Post-build Actions tab.
From the Post-Build Actions drop-down, select Deploy Service Fabric Project.
Under Service Fabric Cluster Configuration, select the Fill the Service Fabric Management Endpoint radio button.
For Management Host, enter the connection endpoint for your cluster; for example
{your-cluster}.eastus.cloudapp.azure.com
.For Client Key and Client Cert, enter the location of the PEM file in your Jenkins container; for example
/var/jenkins_home/clustercert.pem
. (You copied the location of the certificate the last step of Create and configure a Jenkins job.)Under Application Configuration, configure the Application Name, Application Type, and the (relative) Path to Application Manifest fields.
Click Verify Configuration. On successful verification, click Save. Your Jenkins job pipeline is now fully configured. Skip ahead to Next steps to test your deployment.
Configure deployment using Azure credentials
For production environments, configuring an Azure credential to deploy your application is strongly recommended. This section shows you how to configure a Microsoft Entra service principal to use to deploy your application in the post-build action. You can assign service principals to roles in your directory to limit the permissions of the Jenkins job.
For development and test environments, you can configure either Azure credentials or the cluster management endpoint to deploy your application. For details about how to configure a cluster management endpoint, see Configure deployment using cluster management endpoint.
To create a Microsoft Entra service principal and assign it permissions in your Azure subscription, follow the steps in Use the portal to create a Microsoft Entra application and service principal. Pay attention to the following:
- While following the steps in the topic, be sure to copy and save the following values: Application ID, Application key, Directory ID (Tenant ID), and Subscription ID. You need them to configure the Azure credentials in Jenkins.
- If you don't have the required permissions on your directory, you'll need to ask an administrator to either grant you the permissions or create the service principal for you, or you'll need to configure the management endpoint for your cluster in the Post-Build Actions for your job in Jenkins.
- In the Create a Microsoft Entra application section, you can enter any well-formed URL for the Sign-on URL.
- In the Assign application to a Role section, you can assign your application the Reader role on the resource group for your cluster.
Back in the Jenkins job, click the Post-build Actions tab.
From the Post-Build Actions drop-down, select Deploy Service Fabric Project.
Under Service Fabric Cluster Configuration, Click Select the Service Fabric Cluster. Click Add next to Azure Credentials. Click Jenkins to select the Jenkins Credentials Provider.
In the Jenkins Credentials Provider, select Microsoft Azure Service Principal from the Kind drop-down.
Use the values you saved when setting up your service principal in Step 1 to set the following fields:
- Client ID: Application ID
- Client Secret: Application key
- Tenant ID: Directory ID
- Subscription ID: Subscription ID
Enter a descriptive ID that you use to select the credential in Jenkins and a brief Description. Then click Verify Service Principal. If the verification succeeds, click Add.
Back under Service Fabric Cluster Configuration, make sure that your new credential is selected for Azure Credentials.
From the Resource Group drop-down, select the resource group of the cluster you want to deploy the application to.
From the Service Fabric drop-down, select the cluster that you want to deploy the application to.
For Client Key and Client Cert, enter the location of the PEM file in your Jenkins container. For example
/var/jenkins_home/clustercert.pem
.Under Application Configuration, configure the Application Name, Application Type, and the (relative) Path to Application Manifest fields.
Click Verify Configuration. On successful verification, click Save. Your Jenkins job pipeline is now fully configured. Continue on to Next steps to test your deployment.
Troubleshooting the Jenkins plug-in
If you encounter any bugs with the Jenkins plug-in, file an issue in the Jenkins JIRA for the specific component.
Ideas to try
GitHub and Jenkins are now configured. Consider making some sample change in the reliable-services-actor-sample/Actors/ActorCounter
project in your fork of the repository, https://github.com/Azure-Samples/service-fabric-java-getting-started. Push your changes to the remote master
branch (or any branch that you have configured to work with). This triggers the Jenkins job, MyJob
, that you configured. It fetches the changes from GitHub, builds them, and deploys the application to the cluster you specified in post-build actions.