<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Prabhat Singh</title>
    <description>The latest articles on Forem by Prabhat Singh (@prabhatsingh014).</description>
    <link>https://forem.com/prabhatsingh014</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F883865%2Fc81bab61-01c6-4253-9fcc-acbf7b8456d8.jpeg</url>
      <title>Forem: Prabhat Singh</title>
      <link>https://forem.com/prabhatsingh014</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/prabhatsingh014"/>
    <language>en</language>
    <item>
      <title>Use keypair (.pem) to connect to Amazon EC2 Instance with PuTTy</title>
      <dc:creator>Prabhat Singh</dc:creator>
      <pubDate>Sun, 17 Jul 2022 13:23:10 +0000</pubDate>
      <link>https://forem.com/prabhatsingh014/use-keypair-pem-to-connect-to-amazon-ec2-instance-with-putty-b3f</link>
      <guid>https://forem.com/prabhatsingh014/use-keypair-pem-to-connect-to-amazon-ec2-instance-with-putty-b3f</guid>
      <description>&lt;h2&gt;
  
  
  Good Day Everyone
&lt;/h2&gt;

&lt;p&gt;Hope you all are doing well.&lt;/p&gt;

&lt;p&gt;With this post, I'd like to share my learning on how to connect to your AWS EC2 instance using Windows SSH Client i.e. "Putty".&lt;br&gt;
Though, there are several articles describing the steps, I'd like to share mine what I experienced during the task. &lt;/p&gt;

&lt;p&gt;This experience arose from the exercise that I was about to execute for installing gitlab-runner rpm on AWS EC2 instance running with AWS AMI.&lt;br&gt;
During the creation of the EC2 instance, I generated the keypair with the .pem extension whhich is to be used with Open SSH. There is already an option to generate the keypair with .ppk extension which is compatible to use with Putty. However, I chose the default option i.e. .pem&lt;/p&gt;

&lt;p&gt;Once the EC2 instance came up, I tried connecting to EC2 instance using SSH client i.e. Putty installed on my Windows machine. However, when I configured the SSH connection in Putty with the key (.pem) download from AWS, it didn't work and prompted me to use a key with .ppk extension.&lt;/p&gt;

&lt;p&gt;I didn't want to generate another keypair for my EC2 instance, hence I looked through the process to use the same .pem keypair to connect to the EC2 instance, which involved generating .ppk keypair using PuTTygen.&lt;/p&gt;

&lt;p&gt;Below are steps executed in the exercise.&lt;/p&gt;
&lt;h2&gt;
  
  
  Steps Involved
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Setup AWS EC2 instance with a public IP address and keypair (.pem)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For setting up the EC2 instance, following inputs were provided during the creation. I chose AWS AMI for the machine.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Name: example-vm
Application and OS Image: Amazon Linux
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Rikpfsdt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aqjcuvqct413l5ra1je4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Rikpfsdt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aqjcuvqct413l5ra1je4.png" alt="vm-name" width="880" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Instance type was set to t2.micro as it is available for free to use with free tier account.&lt;br&gt;
Also, to connect the EC2 instance using external SSH client, I created a new keypair as I didn't have any to use from.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Instance Type: t2.micro (which is available for free in free tier account)
Key pair (login): Click on "create a new key pair"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3sW3U5GR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6vtz1tbhdcdgbwbm4lkm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3sW3U5GR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6vtz1tbhdcdgbwbm4lkm.png" alt="instance-type" width="880" height="404"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;During the keypair creation, following inputs were provided. Keypair type was set to RSA and private key file format was set to .pem which are default choice. However, one can change these based on the requirement.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Key pair name: example-vm-keypair
Key pair type: RSA
Private key file format: .pem
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qekgVYgd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/62z6hrokmo3rmfq4vt47.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qekgVYgd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/62z6hrokmo3rmfq4vt47.png" alt="key-pair" width="747" height="783"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I made use of the default network settings ensuring that the EC2 instance is also assigned a public IP address to access it from the external machine.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Network Settings
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sRs29mWh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q0jnn6kejf15i0qdqyop.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sRs29mWh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q0jnn6kejf15i0qdqyop.png" alt="network-settings" width="880" height="408"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Once all the settings of EC2 instance are finalized, click on Launch Instance. You can check the status by navigating to EC2 --&amp;gt; Instances&lt;br&gt;
Once the EC2 instance is UP and running, it will be shown as below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Instances
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oly6ALFB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/irxu0d7wmvqqlldoe1tf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oly6ALFB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/irxu0d7wmvqqlldoe1tf.png" alt="instances" width="880" height="202"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install PuTTy and PuTTYgen&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If Putty is not installed on your Windows machine, you can refer the &lt;a href="https://www.putty.org/"&gt;link&lt;/a&gt; to download the executable.&lt;br&gt;
Once the Putty is installed, you'll also notice that there is another utility installed with the name "PuTTygen".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--giAU9JFO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zz15dt2hivabzmchiywi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--giAU9JFO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zz15dt2hivabzmchiywi.png" alt="puttygen1" width="436" height="732"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Configure PuTTYgen&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At this point, if you try to access the EC2 instance using PuTTy with keypair (.pem) generated earlier, you wouldn't be able to do that because PuTTy requires keypair with .ppk extension. Hence, it would show an error while loading the private key. For this purpose, we're going to generate the .ppk keypair with the help of .pem keypair.&lt;/p&gt;

&lt;p&gt;Open PuTTygen and click on Load an existing private key file. Click on Load and browse to the keypair file with .pem extension&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PLVB4GQE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gvondqnb0v3cnh7vfx56.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PLVB4GQE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gvondqnb0v3cnh7vfx56.png" alt="puttygen2" width="632" height="576"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;As soon as you select the .pem file, it gets loaded into PuTTygen.&lt;/p&gt;

&lt;p&gt;Click on Save private key and select "yes" when prompted to save the file without passphrase. Save the file to a safe location on your machine.&lt;br&gt;
This is keypair generated with .ppk extension which can further be used to configure PuTTy session to connect EC2 instance.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vSZywpUA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/85wzzydp8dkn8ty4zxaa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vSZywpUA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/85wzzydp8dkn8ty4zxaa.png" alt="puttygen3" width="632" height="577"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Configure PuTTy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is time to configure PuTTy to be able to connect to EC2 instance using the private keypair with .ppk extension you just generated.&lt;/p&gt;

&lt;p&gt;Open the AWS console and navigate to the running instance. Click on the instance.&lt;br&gt;
Copy either Public IPv4 address or Public IPv4 DNS Name.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0wMpE4I0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3wu4bc3zp74fo8lxd66d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0wMpE4I0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3wu4bc3zp74fo8lxd66d.png" alt="instance-details" width="880" height="408"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Open PuTTy on your Windows machine and configure new session for EC2 instance.&lt;br&gt;
For this purpose, enter the public IPv4 address or public IPv4 DNS name in the Host Name field. By default, port is already set to 22 and connection type set to SSH.&lt;br&gt;
If not, please do so.&lt;br&gt;
To save the session, enter a name in the Saved Sessions field.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Host Name (or IP Address): Public IPv4 Address or Public IPv4 DNS Name
Port: 22
Connection Type: SSH
Saved Session: example-vm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--O3jVWRHH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v2zkrd9pxqvr5d1exy7r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--O3jVWRHH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v2zkrd9pxqvr5d1exy7r.png" alt="puttysession1" width="600" height="538"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Navigate to Connection --&amp;gt; SSH --&amp;gt; Auth --&amp;gt; Private key file for authentication --&amp;gt; Browse and select the keypair file with .ppk extension&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Private key file for authentication: example-vm-keypair.ppk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IhDyqs8P--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ci4uqx7pbympy9w5fc42.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IhDyqs8P--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ci4uqx7pbympy9w5fc42.png" alt="puttysession2" width="598" height="542"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Navigate to Session and click Save to save the newly created session. Click on Open.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--h0u0wgYI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kas0idqqx8mc1w2r6xwa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--h0u0wgYI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kas0idqqx8mc1w2r6xwa.png" alt="puttysession3" width="596" height="537"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;A new PuTTy window opens up and asks for your confirmation to save the key in PuTTy cache. Click Yes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6il6VTOB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/npfdzfha8ijraduinl7w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6il6VTOB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/npfdzfha8ijraduinl7w.png" alt="puttysession4" width="817" height="522"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;It will ask the username. Once entered, you are logged into the AWS EC2 machine without entering any password.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;login as: ec2-user
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--F1MUWEmJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x0zk13awlt2oj5gjog1c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--F1MUWEmJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x0zk13awlt2oj5gjog1c.png" alt="puttysession5" width="822" height="517"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;That is all Folks for now. I'll keep sharing my learnings. If my posts sound interesting to you, following are the places, where I can be reached.&lt;/p&gt;

&lt;p&gt;Like, Share, Follow, Comment.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;a href="https://www.linkedin.com/in/prabhatsingh/"&gt;LinkedIn&lt;/a&gt;&lt;/th&gt;
&lt;th&gt;&lt;a href="https://dev.to/prabhatsingh014"&gt;Dev&lt;/a&gt;&lt;/th&gt;
&lt;th&gt;&lt;a href="https://medium.com/@prabhatsingh014"&gt;Medium&lt;/a&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

</description>
      <category>aws</category>
      <category>ec2</category>
      <category>ssh</category>
      <category>putty</category>
    </item>
    <item>
      <title>Password management using ansible-vault</title>
      <dc:creator>Prabhat Singh</dc:creator>
      <pubDate>Sun, 03 Jul 2022 09:19:36 +0000</pubDate>
      <link>https://forem.com/prabhatsingh014/password-management-using-ansible-vault-2dbi</link>
      <guid>https://forem.com/prabhatsingh014/password-management-using-ansible-vault-2dbi</guid>
      <description>&lt;p&gt;Good Day Everyone!&lt;/p&gt;

&lt;p&gt;Here is another post out of my learning these days on using ansible-vault. &lt;/p&gt;

&lt;p&gt;I have been doing KodeKloud performance based tasks for a while and one of the tasks involved creating users and groups using ansible playbook. Passwords for the users have to be managed using ansible-vault.&lt;/p&gt;

&lt;p&gt;I have not used ansible-vault earlier, so it's definitely a fun learning.&lt;/p&gt;

&lt;h2&gt;
  
  
  Task
&lt;/h2&gt;

&lt;p&gt;Create an ansible playbook to perform the following task.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create users and groups given in the file users.yml
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# cat /home/centos/users.yml
admins:
  - rob
  - tim
developers:
  - mark
  - john
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;p&gt;For users in "&lt;em&gt;admins&lt;/em&gt;" group, home directory should be created in the "&lt;em&gt;/home/&lt;/em&gt;" directory.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For users in "&lt;em&gt;developers&lt;/em&gt;" group, home directory should be set to "&lt;em&gt;/var/www&lt;/em&gt;". Also it should not create any home directory with username in "&lt;em&gt;/var/www/&lt;/em&gt;".&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Password of users of admins group should be set to "&lt;em&gt;adminpassword&lt;/em&gt;".&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Password of users of developers group should be set to "&lt;em&gt;developerpassword&lt;/em&gt;".&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To encrypt the password, make use of ansible-vault secret file which is located at "&lt;em&gt;/home/centos/vault/password.txt&lt;/em&gt;".&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Solution
&lt;/h2&gt;

&lt;p&gt;In order to complete the task, we'll need to look and complete the task from the last to first.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Passwords for the users are supposed to be encrypted with the ansible-vault. Therefore, we need to make sure that the ansible.cfg file is configured with the vault password file.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Password for ansible-vault must be kept at a safe location. I'm showing it for the sake of the exercise.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[centos@localhost vault]$ pwd
/home/centos/vault
[centos@localhost vault]$ cat password.txt 
redhat
[centos@localhost vault]$ grep vault_password_file /etc/ansible/ansible.cfg 
vault_password_file = /home/centos/vault/password.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;There are two strings given in the tasks points 4 &amp;amp; 5 which are required to be encrypted with ansible-vault and those encrypted password would then be used during the user creation process.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For this purpose, we will use ansible-vault command to encrypt the string. We will also name the encrypted string for admins user password to a variable called "admin_pwd" and for developers user password to a variable called "developer_pwd".&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Important thing to ensure here is that the variable name must not contain the hyphen "-". Otherwise, the password won't work for the user. This is from my experience while attempting the task.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[centos@localhost ~]$ ansible-vault encrypt_string 'adminpassword' --name 'admin_pwd'
admin_pwd: !vault |
          $ANSIBLE_VAULT;1.1;AES256
          30323636346564376638376364386335646463626662646535633863663265383563383238363236
          3863623764366533313162346335653736323438656331370a373263643733623766373264613530
          37333537663761383232313564343131663438303966386336663733633332343030633866613737
          3139373661623137650a303936363562383335613437653365323737373430363831633164366334
          3336
Encryption successful
[centos@localhost ~]$ ansible-vault encrypt_string 'developerpassword' --name 'developer_pwd'
developer_pwd: !vault |
          $ANSIBLE_VAULT;1.1;AES256
          61656230636461653861356530346230386461646436636533366665346264366666623264383130
          3539343339626664383731363665306238386434306435620a653139353735366330336466346635
          39623832663063373738306238343433396661373566653232383236613662343437313832326562
          3166616232663137380a343133353439396261323939323365313339663464393266373437303335
          36323633306333386435616639653730396266616334643536643936623465383131
Encryption successful
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;As mentioned in the task point 3, users under developer group must have their home directory set to "/var/www". Let's ensure that directory is created into the system and appropriate permissions are applied to the directory.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[centos@localhost var]$ pwd
/var
[centos@localhost var]$ ls -ld www
drwxrwxrwx. 2 root root 27 Jul  2 17:53 www
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Observe the permissions on the directory &lt;a href="http://www"&gt;www&lt;/a&gt;. If it's not set, then use below command to update the permissions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[centos@localhost var]$ sudo chmod 777 www
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Now that we have configured the vault_password_file, created the variables containing password for the users under admins and developers group and created the home directory for developers users, let us start working on creating the playbook to create the groups and users
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[centos@localhost ~]$ cat playbook.yml 
---
- hosts: localhost
  vars_files: /home/centos/users.yml
  vars:
    admin_pwd: !vault |
          $ANSIBLE_VAULT;1.1;AES256
          30323636346564376638376364386335646463626662646535633863663265383563383238363236
          3863623764366533313162346335653736323438656331370a373263643733623766373264613530
          37333537663761383232313564343131663438303966386336663733633332343030633866613737
          3139373661623137650a303936363562383335613437653365323737373430363831633164366334
          3336
    developer_pwd: !vault |
          $ANSIBLE_VAULT;1.1;AES256
          61656230636461653861356530346230386461646436636533366665346264366666623264383130
          3539343339626664383731363665306238386434306435620a653139353735366330336466346635
          39623832663063373738306238343433396661373566653232383236613662343437313832326562
          3166616232663137380a343133353439396261323939323365313339663464393266373437303335
          36323633306333386435616639653730396266616334643536643936623465383131
  tasks:
  - name: create group
    group:
      name: "{{ item }}"
      state: present
    loop:
      - admins
      - developers
  - name: create admins users
    user:
      name: "{{ item }}"
      create_home: yes
      groups: admins, wheel
      append: yes
      password: "{{ admin_pwd | string | password_hash('sha512') }}"
    loop: "{{ admins }}"
  - name: create developers users
    user:
      name: "{{ item }}"
      create_home: yes
      home: /var/www
      groups: developers
      append: yes
      password: "{{ developer_pwd | string | password_hash('sha512') }}"
    loop: "{{ developers }}"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;vars_files is pointing to the file users.yml which contains the groups and users information.&lt;/li&gt;
&lt;li&gt;vars is pointing to the variables which were created using the ansible-vault command&lt;/li&gt;
&lt;li&gt;tasks list consists of the task first to create the groups given in the users.yml, then create the users using group and user modules of the ansible respectively.&lt;/li&gt;
&lt;li&gt;create_home=yes -&amp;gt; home directory is supposed to be created in the /home&lt;/li&gt;
&lt;li&gt;users in the admins group are also supposed to be sudo user, this is why groups: admins, wheels &amp;amp; append: yes have been added into the task. Similarly for users in the developers group, groups: developers&lt;/li&gt;
&lt;li&gt;password for users in the admins and developers should be set to admin_pwd and developer_pwd variables created during encrypt string step. Password strings are also required to be hashed so as not to expose during the playbook execution or otherwise.&lt;/li&gt;
&lt;li&gt;both user creation tasks consists of loop where values under the admins and developers list (array) are being used from users.yml&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Now it's time for playbook execution. Execute the ansible-playbook command to implement changes from playbook.yml
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[centos@localhost ~]$ ansible-playbook playbook.yml 

PLAY [localhost] *************************************************************************************************************

TASK [Gathering Facts] *******************************************************************************************************
ok: [localhost]

TASK [create group] **********************************************************************************************************
ok: [localhost] =&amp;gt; (item=admins)
ok: [localhost] =&amp;gt; (item=developers)

TASK [create admins users] ***************************************************************************************************
changed: [localhost] =&amp;gt; (item=rob)
changed: [localhost] =&amp;gt; (item=tim)

TASK [create developers users] ***********************************************************************************************
changed: [localhost] =&amp;gt; (item=mark)
changed: [localhost] =&amp;gt; (item=john)

PLAY RECAP *******************************************************************************************************************
localhost                  : ok=4    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[centos@localhost ~]$ 

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If you'd like to see the detailed output of the playbook execution, use "-vv" option with the ansible-playbook command.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;# ansible-playbook playbook.yml -vv&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.ansible.com/ansible/latest/collections/ansible/builtin/user_module.html"&gt;Ansible user module&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.ansible.com/ansible/latest/collections/ansible/builtin/group_module.html"&gt;Ansible group module&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.ansible.com/ansible/latest/user_guide/vault.html"&gt;Ansible vault&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html"&gt;Ansible variable&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ansible</category>
      <category>password</category>
      <category>secrets</category>
      <category>management</category>
    </item>
    <item>
      <title>GitLab CD Pipeline for Linux package management</title>
      <dc:creator>Prabhat Singh</dc:creator>
      <pubDate>Tue, 28 Jun 2022 08:43:32 +0000</pubDate>
      <link>https://forem.com/prabhatsingh014/gitlab-cd-pipeline-for-linux-package-management-51ob</link>
      <guid>https://forem.com/prabhatsingh014/gitlab-cd-pipeline-for-linux-package-management-51ob</guid>
      <description>&lt;p&gt;Good Day Everyone!&lt;/p&gt;

&lt;p&gt;Hope you’re all doing well.&lt;/p&gt;

&lt;p&gt;I’m writing this article to share my learnings while working on different projects involving multiple skills in Telecommunications and Information Technology domains.&lt;/p&gt;

&lt;p&gt;Recent project has enabled me with the skills such as GitLab, Ansible, Docker, and Shell script.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use case
&lt;/h2&gt;

&lt;p&gt;Package management on multiple Linux machines using GitLab pipeline&lt;/p&gt;

&lt;h2&gt;
  
  
  Tools
&lt;/h2&gt;

&lt;p&gt;Following DevOps tools were used in implementing the CD pipeline&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;GitLab — Version control, project repository, CD pipeline&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;GitLab-Runner — Trigger the pipeline stages&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Linux Machines — Centos VMs for controller node and target nodes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ansible — Implements changes on the target nodes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Shell Scripting — Execute playbooks, used in the pipeline stages&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Architecture
&lt;/h2&gt;

&lt;p&gt;Below is a high level architecture of the setup&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tbUOM1qx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7c3gb9k9w6x7ckzsw3sz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tbUOM1qx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7c3gb9k9w6x7ckzsw3sz.png" alt="Architecture" width="720" height="190"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://gitlab.com"&gt;GitLab &lt;/a&gt;account where you can store your project and configure CD pipeline.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.gitlab.com/runner/install/"&gt;Gitlab-runner&lt;/a&gt; package downloaded and installed on the controller node, which is basically a Linux machine.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6Wox-jvP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/axfsxne247lin1tkxb5l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6Wox-jvP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/axfsxne247lin1tkxb5l.png" alt="Gitlab-runner" width="801" height="216"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Gitlab-runner for the project has been registered on the controller node. Navigate to &lt;strong&gt;GitLab → Project → Settings → CI/CD → Runners&lt;/strong&gt;. Scroll down to the steps where it shows the steps to register gitlab-runner on the controller node.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BWhuFBMQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cjcopff6fl07vc8p4usu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BWhuFBMQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cjcopff6fl07vc8p4usu.png" alt="register-process" width="484" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Register the runner on the controller node with the details mentioned above. For this exercise, shell executor for gitlab-runner is used to trigger the gitlab jobs on the target machines.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WcKmXJt6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kx4dsndxt83ppfmj8nw8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WcKmXJt6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kx4dsndxt83ppfmj8nw8.png" alt="register-runner" width="875" height="357"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html"&gt;Ansible&lt;/a&gt; installed on the controller node. For testing purpose, inventory file consists of the entry for the localhost
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;targetvm1 ansible_host=127.0.0.1 ansible_user=root
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XUmAN_et--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ks2y94y3q5pjasdr0gb4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XUmAN_et--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ks2y94y3q5pjasdr0gb4.png" alt="ansible" width="875" height="158"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.tecmint.com/ssh-passwordless-login-using-ssh-keygen-in-5-easy-steps/"&gt;SSH password-less connectivity&lt;/a&gt; established between the controller node (gitlab-runner user) and target nodes (any user)(linux machines)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--c9tdhmq7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qmd1n3v1yrndgh5049du.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--c9tdhmq7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qmd1n3v1yrndgh5049du.png" alt="ssh-connection" width="875" height="83"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://git-scm.com/download/linux"&gt;Git&lt;/a&gt; is installed on your local machine to clone, pull, &amp;amp; push the changes in your local repository&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bNCYVKka--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fn4ebrf1ug8tn7346v0t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bNCYVKka--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fn4ebrf1ug8tn7346v0t.png" alt="git" width="663" height="95"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementation
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Clone the project from the &lt;a href="https://github.com/prabhatsingh014/pkg-mgmt.git"&gt;Github&lt;/a&gt; on your local machine&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1PYACoop--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z7vybo8ljrc16yu20xvv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1PYACoop--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z7vybo8ljrc16yu20xvv.png" alt="github" width="875" height="313"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Change to the directory and edit the variables.yml and provide values against the parameters mentioned&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--17DNYBMt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6eumbrfayvzi5dq1rhh7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--17DNYBMt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6eumbrfayvzi5dq1rhh7.png" alt="variables" width="875" height="97"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Commit the changes to your local repository and push to the remote repository&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--W8iUyAXm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6ei6xdf9paq9yc7wsrcb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--W8iUyAXm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6ei6xdf9paq9yc7wsrcb.png" alt="commit-change" width="875" height="336"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8CSyDT07--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vxgwl01fangf0zndl5lp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8CSyDT07--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vxgwl01fangf0zndl5lp.png" alt="push-change" width="875" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;As soon as you push the changes, a pipeline will be triggered on GitLab. Navigate to &lt;strong&gt;GitLab → Project → CI/CD → Pipelines&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Stages include in the pipeline: prechecks, prebackup, activity, postbackup, postchecks.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--j8gZBsAz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8nnzbabke0qboib5bbpm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--j8gZBsAz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8nnzbabke0qboib5bbpm.png" alt="pipeline-stages" width="875" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gQ_yThyv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f83osiw32jhulb84otwe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gQ_yThyv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f83osiw32jhulb84otwe.png" alt="pipeline-status" width="875" height="71"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ansible playbooks can further be modified for different operating systems, system checks, system backup before and after the installation, upgrade, &amp;amp; removal of the packages.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>gitlab</category>
      <category>ansible</category>
      <category>pipeline</category>
    </item>
  </channel>
</rss>
