<?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>DEV Community: Juell</title>
    <description>The latest articles on DEV Community by Juell (@udujoel).</description>
    <link>https://dev.to/udujoel</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%2F488189%2F1cfa16c7-7e9e-4538-8d74-f3fbb3d36000.png</url>
      <title>DEV Community: Juell</title>
      <link>https://dev.to/udujoel</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/udujoel"/>
    <language>en</language>
    <item>
      <title>Docker: An easier way around</title>
      <dc:creator>Juell</dc:creator>
      <pubDate>Thu, 05 Nov 2020 09:40:54 +0000</pubDate>
      <link>https://dev.to/udujoel/docker-an-easier-way-around-251p</link>
      <guid>https://dev.to/udujoel/docker-an-easier-way-around-251p</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fbthrc0lorny0ib5f9fuh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fbthrc0lorny0ib5f9fuh.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Containers &amp;amp; Softwares
&lt;/h2&gt;

&lt;p&gt;Containers are all about Software!&lt;br&gt;
Traditionally we use the following process to run software:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Find the software, usually a standalone web site.&lt;/li&gt;
&lt;li&gt;  Download the software, usually a zip file or some sort of installer.&lt;/li&gt;
&lt;li&gt;  Then we install the software, often extracting a zip file or running an installer.&lt;/li&gt;
&lt;li&gt;  Then we run the installed software.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can learn a lot about containers by relating them to the process above. Here's what it looks like to run software with containers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Find the software, on Docker Hub.&lt;/li&gt;
&lt;li&gt;  Download the software with docker pull, comes down as an &lt;strong&gt;image&lt;/strong&gt; which is much like a zip file or msi installer. An image is an application packaging format.&lt;/li&gt;
&lt;li&gt;  Instead of installing the software, we create a container. So, a &lt;strong&gt;container&lt;/strong&gt;--a stopped container--is like installed software. Docker unpacks the image onto the computer, creating a container. Note: if you just want to create a container, you can use docker create.&lt;/li&gt;
&lt;li&gt;  Then we run the container which is exactly like running an exe. It's the same thing under the covers!!!&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We often use docker run to orchestrate all of these steps with one command, how convenient!&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;em&gt;docker exec&lt;/em&gt;&lt;/strong&gt; can be thought of as running another copy of our installed software, like when we launch an executable twice. For example, two copies of Microsoft Word. Or with MongoDB, we might run two mongo clients. After a container is created and running, we can use docker exec to run multiple applications, or multiple copies of the same app, inside the container.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Why Docker?
&lt;/h1&gt;

&lt;p&gt;With traditional softwares, we are faced with many challenges, such as:&lt;/p&gt;

&lt;h2&gt;
  
  
  Software Discovery
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Problems:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Where to get software?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;App stores&lt;/li&gt;
&lt;li&gt;Package Managers&lt;/li&gt;
&lt;li&gt;Standalone Websites&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Software Stats and Metadata&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Trust and Security&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Download Availability&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Payment &amp;amp; Licensing&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;h3&gt;
  
  
  Solution:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;Where:&lt;/em&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With Docker, we have just one place to go to get our software: Dockerhub.com. Here you can find any popular software repository that holds images you can download and use.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;Stats and Metadata:&lt;/em&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Dockerhub provides download stats and data on how many people likes a software. Softwares have documentation and other instructions on use. There is provision for comments too from images users.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;Trust and security:&lt;/em&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Dockerhub has what's called Official Images that Docker Inc certifies. On the Tags page of these images you can find the result of security scans on these images, showing discovered vulnerabilities, if any.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;Download Availability:&lt;/em&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;DockerHub can be relied upon to provide access to our software images for download. No need to search the whole internet for a simple software.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;Payment and Licensing:&lt;/em&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;DockerStore is a new way of accessing and paying for commercial images.&lt;/p&gt;




&lt;h2&gt;
  
  
  Software Installation:
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Problem:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Is it compatible? Is it cross-platform?&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;What format is it?&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;How to install?&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;What did it install?&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Updates/uninstall&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Solution:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;Compatibility:&lt;/em&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With Docker you no longer need to worry if software is cross-platform as you can run Linux containers on windows and vice-versa.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Format&lt;/em&gt;&lt;/strong&gt;:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is all taken care of in the Image for you. You can decide to peek into how the image was built by visiting Dockerhub page and inspecting the Dockerfile.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;Installation:&lt;/em&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No more lengthy instructions on how to install a software. Just Docker Run.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;What was installed:&lt;/em&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The publicly available Dockerfile can be access to find out what exactly was installed in a container.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;Updates/Uninstall&lt;/em&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Docker remove command is used to uninstall software. As for updates, you can easily pull down an updated image. Images are tagged, making its update and versioning consistent and easier to understand and follow. &lt;/p&gt;

&lt;p&gt;All other problems such as documentation, where its installed, starting service, stopping application, licensing, installing dependencies, and security, are equally taken care of by docker. Docker run starts all needed dependencies and performs all needed configs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Breaking Changes
&lt;/h2&gt;

&lt;p&gt;This used to be a huge one. An application update, operating system patch or upgrade of a shared library meant an end to a properly function software in the past. No more. Docker solves this as well.&lt;/p&gt;

&lt;h1&gt;
  
  
  Installation
&lt;/h1&gt;

&lt;p&gt;Docker’s installation is very straightforward.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Visit: &lt;a href="https://docs.docker.com/get-docker/" rel="noopener noreferrer"&gt;https://docs.docker.com/get-docker/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  Click on your host type, Mac, Windows or Linux&lt;/li&gt;
&lt;li&gt;  Follow the simple installation instruction to get started.&lt;/li&gt;
&lt;li&gt;  On Ubuntu, the installation can be as simple as running:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Sudo apt &lt;span class="nb"&gt;install &lt;/span&gt;docker.io
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make sure your machine has support for &lt;strong&gt;virtualization&lt;/strong&gt;. If you’re running a windows machine, ensure it has &lt;strong&gt;Hyper-V&lt;/strong&gt; as this is the technology Docker leverages to function. You might have to turn-on the support in the machine’s BIOS.&lt;/p&gt;

&lt;h1&gt;
  
  
  Working with Docker
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Common commands
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Docker Command&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;After installation, use the   following to check the success of the process:&lt;/td&gt;
&lt;td&gt;Docker version     Or     Docker info&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;To start a container&lt;/td&gt;
&lt;td&gt;Docker start &amp;lt; container-identifier&amp;gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;To view all running containers   in docker, you use the Process Status command:&lt;/td&gt;
&lt;td&gt;Docker ps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;To view all containers running   or not:&lt;/td&gt;
&lt;td&gt;Docker ps -a&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;To view all images, use:&lt;/td&gt;
&lt;td&gt;Docker images&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;To run a container, you use:&lt;/td&gt;
&lt;td&gt;Docker run &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;To start a container&lt;/td&gt;
&lt;td&gt;Docker start &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;To stop a running container:&lt;/td&gt;
&lt;td&gt;Docker stop &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;To uninstall a container:&lt;/td&gt;
&lt;td&gt;Docker rm &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;To remove an image:&lt;/td&gt;
&lt;td&gt;Docker rmi &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;To run another instance of an   image:&lt;/td&gt;
&lt;td&gt;Docker exec &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;To create a container&lt;/td&gt;
&lt;td&gt;Docker create &amp;lt; container-identifier&amp;gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;To search for an image&lt;/td&gt;
&lt;td&gt;Docker search &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;To find all details about a   container or image&lt;/td&gt;
&lt;td&gt;Docker inspect &lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Docker Demystification
&lt;/h2&gt;

&lt;p&gt;Enter the following docker command into your terminal&lt;/p&gt;

&lt;p&gt;docker run msoap/ascii-art cowsay 'Hello'&lt;/p&gt;

&lt;p&gt;If you’re running this for the first time, this will:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Download the software Image of Ascii-art from the msoap repository in Dockerhub.&lt;/li&gt;
&lt;li&gt; When this process is done, it’ll extract the files it just downloaded,&lt;/li&gt;
&lt;li&gt;Docker will the create a container and start up the application&lt;/li&gt;
&lt;li&gt;The ‘cowsay’ argument of the Ascii-art app takes a string input that it will display. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Attaching the &lt;strong&gt;&lt;em&gt;“-rm&lt;/em&gt;&lt;/strong&gt;” tag after the &lt;strong&gt;&lt;em&gt;run&lt;/em&gt;&lt;/strong&gt;, removes the container whenever it is done running.&lt;/p&gt;

&lt;p&gt;Run the following to test:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run --rm -it wernight/funbox asciiquarium
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;To close the animation/container press &lt;strong&gt;&lt;em&gt;Ctrl + C.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Inverted Learning
&lt;/h2&gt;

&lt;p&gt;Execute this in your terminal:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Docker run -p 80:80 nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The -p flag specifies the port Docker should forward from the container it’ll launch to which port in your host machine.&lt;/p&gt;

&lt;p&gt;This command pulls down Nginx server in layers. Since this comes in a compressed form to save bandwidth, docker then extracts them to save time in subsequent runs. Finally, docker starts the Nginx server and does the port forwarding.&lt;/p&gt;

&lt;p&gt;A simple process like installation and configuration of Nginx server can take a considerable length of time, and require some level of expertise. With Docker, all you have to do is run a line of command and the process is set up. This is called Inverted Learning.&lt;/p&gt;

&lt;p&gt;With Inverted learning one does not need to understand a technology to use it. With the Nginx example above, with just one line of code, you can have Nginx up and running, even without knowing how to set it up traditionally.&lt;/p&gt;

&lt;p&gt;This enables people to preview/use software and decide if they want to invest the time to learn it, saving wasted time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Images, and containers
&lt;/h2&gt;

&lt;p&gt;In a Windows parlance, an image can be likened to a downloaded software in say, .zip format. By extracting this software, we can access the ‘.msi’ or ‘.exe’ we can use to install our software. The same with docker. To download a software we use:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Docker pull &amp;lt;image-name:tag&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This downloads the file to our machine. If we do not specify a tag in our image identifier, the ‘latest’ tag is automatically used. I.e. .&lt;/p&gt;

&lt;p&gt;When we execute:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Docker run &amp;lt;image-name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;docker looks for the specified image locally first, and on locating it, it’ll extract it, create a container and run the app image inside it.&lt;/p&gt;

&lt;p&gt;A container is essentially a running instance of an image, the same way a running application is an instance of its installer file. Traditionally, we can’t install an application without its installer. In docker, when we execute the run command with an image name, docker first searches locally in our machine for the image, if not found, it proceeds to search Dockerhub. If the image is found, it’ll download, extract, install and run the image.&lt;/p&gt;

&lt;p&gt;Just as we can close a running application, we can also terminate a running container with:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Docker stop &amp;lt;container-name&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This doesn’t remove the container but merely stops its execution. To confirm this, you can use the command:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Docker ps -a
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This shows you all your docker equivalent of installed applications, both running and terminated, with their running status specified.&lt;/p&gt;

&lt;p&gt;If you want to ‘uninstall’ a container, you can use:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Docker rm &amp;lt;container-identifier&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The container identifier can be the ID or name. The full ID doesn’t need to be supplied, just enough to uniquely identify the container is enough. The output of this command is an echo of the affected container(s). To remove all containers, consider using:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Docker rm $(docker ps -aq)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This echoes out all the affected container IDs. The additional &lt;strong&gt;&lt;em&gt;-q&lt;/em&gt;&lt;/strong&gt; flag ensures only the container IDs are supplied to the &lt;strong&gt;&lt;em&gt;rm&lt;/em&gt;&lt;/strong&gt; command.&lt;/p&gt;

&lt;p&gt;Just as uninstalling a software in Windows doesn’t delete its downloaded installer, so also does removing a container doesn’t remove its image. To view all pulled images use:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Docker images -a
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;To remove the image, you use:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Docker rmi &amp;lt;image-identifier&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The identifier can be the image ID or the repository name. Running this command spits out a lot of outputs. This is because an image is often layered and while removing them, each layer must be deleted for the images to go.&lt;/p&gt;

&lt;h1&gt;
  
  
  Isolation
&lt;/h1&gt;

&lt;p&gt;Containers take isolation to a whole new level, and understandably so.&lt;/p&gt;

&lt;p&gt;Let us step back and examine a running application. A running software is made up of the following layer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Application (with supporting runtimes and frameworks)&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OS Apps—cmd, powershell, etc&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The libraries (dependencies, etc.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Kernel, drivers&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Hardware&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When an image is pulled down, it contains the needed files in the User space. This is to ensure the application has access to all libraries, components and dependencies it’ll need. This is what makes the image large most times as it attempts to err on the part of being over careful. And well, sometimes you never know what else an application might be needing, so why not have it all.&lt;/p&gt;

&lt;p&gt;Since it’s the Kernel that has full access to the machine’s computing resources, the software makes all request through API calls to the Kernel. The Kernel is responsible for telling the running container all the processes, network or files that it can see. This isolation enable container to be more independent and to not compromise the host system. It’s basically the Kernel lying to containers in order to provide security to the host.&lt;/p&gt;

&lt;p&gt;All containers are processes with the same Process ID in a host system. Processes inside a container can only see and interact with processes within the same container.&lt;/p&gt;

&lt;h1&gt;
  
  
  Drive Mounting
&lt;/h1&gt;

&lt;p&gt;In docker, there are times when we need a container to interact with files in a host machine. This can be to process, access or output data. To achieve this, we use the Drive mounting feature of docker:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Docker run -v c:/users/folder_to_share:/data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This command mounts the c:/users/folder to the container’s /data folder thanks to the -v (volume) flag. This way we can specify some extra command that can perform the desired operation.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Docker run –rm -v c:/Users/folder:/data alpine ls /data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Mounting is the process of adding a reference to a host filesystem for permission to access some host files.&lt;/p&gt;

&lt;h1&gt;
  
  
  Docker Docs
&lt;/h1&gt;

&lt;p&gt;You can get the docker docs for local reference with:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Docker run -p 4000:4000 -d docs/docker.github.io
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The -d flag is for it to run in detached mode. When the process is done, you can access the full docker docs in your browser at &lt;a href="http://0.0.0.0:4000" rel="noopener noreferrer"&gt;http://0.0.0.0:4000&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thanks for your time!&lt;/p&gt;

</description>
      <category>docker</category>
      <category>software</category>
      <category>devops</category>
      <category>easy</category>
    </item>
    <item>
      <title>Vagrant-up with ease</title>
      <dc:creator>Juell</dc:creator>
      <pubDate>Fri, 23 Oct 2020 20:54:18 +0000</pubDate>
      <link>https://dev.to/udujoel/vagrant-up-with-ease-3ha0</link>
      <guid>https://dev.to/udujoel/vagrant-up-with-ease-3ha0</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fp2jozxsosstu1w1ype7r.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fp2jozxsosstu1w1ype7r.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What &amp;amp; why
&lt;/h3&gt;

&lt;p&gt;Vagrant is an &lt;strong&gt;open-source tool&lt;/strong&gt; that allows you to create, configure, and manage &lt;strong&gt;boxes&lt;/strong&gt; of virtual machines through an easy to use command interface. It is a tool for building complete development environments with a focus on automation and easy workflow.&lt;/p&gt;

&lt;p&gt;It is used in software development to ensure all team members are building with the same &lt;strong&gt;&lt;em&gt;configuration&lt;/em&gt;&lt;/strong&gt;. Not only does Vagrant make it possible to share environments, it also shares code as well. This allows the code from one developer to work on the system of another, making collaborative and cooperative development possible. With Vagrant, you can &lt;strong&gt;&lt;em&gt;create virtual machines on-the-fly&lt;/em&gt;&lt;/strong&gt; via a set of reusable configuration files. Developers can track environment configuration changes and share their environment so that others can spin up an identical environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Download the latest version of Vagrant from:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://www.vagrantup.com/downloads.html" rel="noopener noreferrer"&gt;https://www.vagrantup.com/downloads.html&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Download the latest version of VirtualBox:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://www.virtualbox.org/wiki/Downloads" rel="noopener noreferrer"&gt;https://www.virtualbox.org/wiki/Downloads&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Install and restart your PC. Confirm they are properly set up:&lt;/p&gt;

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

&lt;/div&gt;
&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;

&lt;p&gt;Run:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Vagrant init generic/alpine310

Vagrant up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h1&gt;
  
  
  Vagrant
&lt;/h1&gt;
&lt;h2&gt;
  
  
  Vagrant Boxes
&lt;/h2&gt;

&lt;p&gt;The basic unit in a Vagrant setup is called a “&lt;strong&gt;box&lt;/strong&gt;” or a “&lt;strong&gt;Vagrantbox&lt;/strong&gt;.” This is a complete, self-contained image of an operating system environment. It is a clone of a base operating system image. Using a clone speeds up the launching and provisioning process.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Adding a VagrantBox:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can add a box with the command:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vagrant box add ubuntu/trusty64
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This downloads the box and stores it locally in your machine.&lt;/p&gt;

&lt;p&gt;To see all your OS boxes, use:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Vagrant box list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;To make use of a box, you need to configure the Vagrantfile and point it to the box. Make sure you’re at the desired folder. Initialize vagrant with:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Vagrant init trusty64
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;A “&lt;strong&gt;&lt;em&gt;Vagrant&lt;/em&gt;&lt;/strong&gt;” file will be created in the directory. Open It with the command:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo nano vagrantfile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Once the Vagrantfile is open, locate and change the “config.vm.box” string from what it is to “&lt;strong&gt;&lt;em&gt;ubuntu/trusty64&lt;/em&gt;&lt;/strong&gt;”:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;config.vm.box = "ubuntu/trusty64"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;To remove a VagrantBox:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vagrant box remove ubuntu/trusty64 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  VagrantFile Demystification
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Vagrantfile&lt;/em&gt;&lt;/strong&gt; is the file that Vagrant uses to specify the configuration of the VagrantBox. It’s a Ruby Script but doesn’t require the knowledge of &lt;strong&gt;Ruby&lt;/strong&gt; to create or understand one. Note that &lt;em&gt;VagrantFile has no extension&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The primary function of the Vagrantfile is to describe the type of machine required for a project, and how to configure and provision these machines. Vagrantfiles are called so because the actual literal filename for the file is Vagrantfile.&lt;/p&gt;

&lt;p&gt;Here is a sample vagrant file (you can generate one by executing “&lt;em&gt;Vagrant Init &lt;/em&gt;”):&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;
&lt;span class="no"&gt;Vagrant&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;configure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;

 &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;box&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"trusty64"&lt;/span&gt;

 &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;box_check_update&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;

 &lt;span class="c1"&gt;# **NETWORK SETTING**&lt;/span&gt;

 &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;network&lt;/span&gt; &lt;span class="s2"&gt;"forwarded_port"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;guest: &lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;host: &lt;/span&gt;&lt;span class="mi"&gt;8080&lt;/span&gt;

 &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;network&lt;/span&gt; &lt;span class="s2"&gt;"forwarded_port"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;guest: &lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;host: &lt;/span&gt;&lt;span class="mi"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;host_ip: &lt;/span&gt;&lt;span class="s2"&gt;"127.0.0.1"&lt;/span&gt;

 &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;network&lt;/span&gt; &lt;span class="s2"&gt;"private_network"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;ip: &lt;/span&gt;&lt;span class="s2"&gt;"192.168.33.10"&lt;/span&gt;

 &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;network&lt;/span&gt; &lt;span class="s2"&gt;"public_network"&lt;/span&gt;

 &lt;span class="c1"&gt;# **SHARED FOLDER**&lt;/span&gt;

 &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;synced_folder&lt;/span&gt; &lt;span class="s2"&gt;"../data"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"/vagrant_data"&lt;/span&gt;

 &lt;span class="c1"&gt;# **PROVIDER-SPECIFIC CONFIGURATION**&lt;/span&gt;

 &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;provider&lt;/span&gt; &lt;span class="s2"&gt;"virtualbox"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;vb&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;

 &lt;span class="c1"&gt;#  # Display the VirtualBox GUI when booting the machine&lt;/span&gt;

  &lt;span class="n"&gt;vb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gui&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;

 &lt;span class="c1"&gt;# Customize the amount of memory on the VM:&lt;/span&gt;

  &lt;span class="n"&gt;vb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;memory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"1024"&lt;/span&gt;

  &lt;span class="k"&gt;end&lt;/span&gt;

 &lt;span class="c1"&gt;# **PROVISIONING**&lt;/span&gt;

 &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;provision&lt;/span&gt; &lt;span class="s2"&gt;"shell"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;inline: &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;-&lt;/span&gt;&lt;span class="no"&gt;SHELL&lt;/span&gt;&lt;span class="sh"&gt;

   apt-get update

   apt-get install -y apache2

&lt;/span&gt;&lt;span class="no"&gt;  SHELL&lt;/span&gt;

&lt;span class="k"&gt;end&lt;/span&gt;

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;“#” is used to comment out a line. These can be uncommented to apply
the implied setting.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Versioning&lt;/strong&gt;: Configuration versions are the mechanism by which Vagrant is able to remain backward compatible. It is specified by the &lt;em&gt;**Vagrant.configure(“&lt;/em&gt;&lt;em&gt;version_number&lt;/em&gt;&lt;em&gt;”)&lt;/em&gt;**&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Box:&lt;/strong&gt; A box can be used on any platform that Vagrant supports to bring up an identical working environment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shared folder&lt;/strong&gt;: Vagrant automatically synchronizes content that is in your project directory with a special directory in the guest  (virtual) system&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Networking&lt;/strong&gt;: Vagrant includes options to place your virtual machine on a network. This makes it more accessible. You can create a forwarded port for the guest system, define private networks, public networks, and other more advanced options.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Provisioning&lt;/strong&gt;: Provisioners in Vagrant allow you to automatically install software, alter configurations, and more on the machine as part of the &lt;strong&gt;&lt;em&gt;vagrant up&lt;/em&gt;&lt;/strong&gt; process. Some supported Provisioners includes Ansible and Shell script.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Vagrant Up
&lt;/h2&gt;

&lt;p&gt;After making any modification to a VagrantFile, it is advised you save and commit it to a Version Control system. To apply the changes made, execute this command:&lt;/p&gt;

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

&lt;/div&gt;

&lt;p&gt;subsequently, to apply any other change while the provisioned VM is running, use the command:&lt;/p&gt;

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

&lt;/div&gt;
&lt;h2&gt;
  
  
  Vagrant SSH
&lt;/h2&gt;

&lt;p&gt;After the vagrant up has successfully completed, you can connect to the created virtual machine by using an SSH connection, with:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vagrant ssh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This opens a secure shell connection to the new virtual machine. Your command prompt will change to “vagrant@trusty64” to indicate that you are logged into the virtual machine.&lt;/p&gt;

&lt;p&gt;Once you are done exploring the virtual machine, you can exit the session with &lt;strong&gt;CTRL-D&lt;/strong&gt;. The virtual machine will still be running in the background, but the SSH connection will be closed.&lt;/p&gt;

&lt;h1&gt;
  
  
  Vagrant on Azure
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;First visit &lt;a href="http://www.portal.azure.com" rel="noopener noreferrer"&gt;www.portal.azure.com&lt;/a&gt; and  &lt;strong&gt;&lt;em&gt;provision a VM&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;SSH into the VM&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Install Vagrant&lt;/strong&gt; on it with: &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;wget https://releases.hashicorp.com/vagrant/2.2.10/vagrant_2.2.10_x86_64.deb

sudo dpkg -i vagrant_2.2.10_x86_64.deb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Install the Vagrant-azure package&lt;/strong&gt; with:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vagrant plugin install vagrant-azure
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Add the Azure Dummy Box:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vagrant box add azure-dummy https://github.com/azure/vagrant-azure/raw/v2.0/dummy.box --provider azure
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Install Azure-cli&lt;/em&gt;&lt;/strong&gt; with:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Login to your Azure Account&lt;/strong&gt; with:&lt;/p&gt;

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

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Create Azure Service Principal&lt;/strong&gt; with:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;az ad sp create-for-rbac
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The output of “az ad sp create-for-rbac” should look like the following:&lt;/p&gt;

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

 "appId": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",

 "displayName": "some-display-name",

 "name": "http://azure-cli-2017-04-03-15-30-52",

 "password": "XXXXXXXXXXXXXXXXXXXX",

 "tenant": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"

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

&lt;/div&gt;

&lt;p&gt;The values tenant, &lt;strong&gt;appId&lt;/strong&gt; and password map to the configuration values &lt;strong&gt;azure.tenant_id&lt;/strong&gt;, &lt;strong&gt;azure.client_id&lt;/strong&gt; and &lt;strong&gt;azure.client_secret&lt;/strong&gt; in your Vagrant file or environment variables.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Create a Vagrantfile&lt;/em&gt;&lt;/strong&gt; and add this config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Vagrant&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;configure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'2'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;

 &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;box&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'azure-dummy'&lt;/span&gt;

 &lt;span class="c1"&gt;# use local ssh key to connect to remote vagrant box&lt;/span&gt;

 &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ssh&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;private_key_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dirname&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kp"&gt;__FILE__&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s1"&gt;'azure_private_key.id_rsa'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

 &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;provider&lt;/span&gt; &lt;span class="ss"&gt;:azure&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;azure&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;override&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;

 &lt;span class="c1"&gt;# each of the below values will default to use the env vars named as below if not specified explicitly&lt;/span&gt;

 &lt;span class="n"&gt;azure&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tenant_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;ENV&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'AZURE_TENANT_ID'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

 &lt;span class="n"&gt;azure&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;client_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;ENV&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'AZURE_CLIENT_ID'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

 &lt;span class="n"&gt;azure&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;client_secret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;ENV&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'AZURE_CLIENT_SECRET'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

 &lt;span class="n"&gt;azure&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscription_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;ENV&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'AZURE_SUBSCRIPTION_ID'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

 &lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;####### Provisioner #######&lt;/span&gt;

 &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;provision&lt;/span&gt; &lt;span class="s2"&gt;"ansible"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;ansible&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;

 &lt;span class="n"&gt;ansible&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;playbook&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"playbook.yml"&lt;/span&gt;

 &lt;span class="n"&gt;ansible&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;verbose&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;

 &lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since we specified Ansible as our provisioned, we need to install it on our host machine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;software-properties-common
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-add-repository ppa:ansible/ansible
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;ansible

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

&lt;/div&gt;



&lt;p&gt;Set up the ENV variables with:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export AZURE_CLIENT_ID=“***************************”
export AZURE_CLIENT_SECRET=“***********************”
export AZURE_TENANT_ID=“***************************”
export AZURE_SUBSCRIPTION_ID=“*********************”
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Generate your SSH key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh-keygen &lt;span class="nt"&gt;-t&lt;/span&gt; rsa  &lt;span class="nt"&gt;-f&lt;/span&gt; azure_private_key.id_rsa
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;Create a “playbook.yml”&lt;/em&gt;&lt;/strong&gt; that we’ll be using for provisioning:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;install nginx on a Azure VM instance&lt;/span&gt;
      &lt;span class="na"&gt;hosts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;all&lt;/span&gt;
      &lt;span class="na"&gt;become&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yes&lt;/span&gt;
      &lt;span class="na"&gt;become_method&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;sudo&lt;/span&gt;
      &lt;span class="na"&gt;gather_facts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yes&lt;/span&gt;
      &lt;span class="na"&gt;tasks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;install nginx&lt;/span&gt;            
          &lt;span class="na"&gt;apt&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx&lt;/span&gt;
            &lt;span class="na"&gt;update_cache&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yes&lt;/span&gt;
            &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;present&lt;/span&gt;

        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;stop nginx service&lt;/span&gt;
          &lt;span class="na"&gt;service&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx&lt;/span&gt;
            &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;stopped&lt;/span&gt;
          &lt;span class="na"&gt;register&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx_down&lt;/span&gt;


        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;delete the default html file&lt;/span&gt;
          &lt;span class="na"&gt;file&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/var/www/html/index.nginx-debian.html&lt;/span&gt;
            &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;absent&lt;/span&gt;


        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;copy new file from template folder&lt;/span&gt;
          &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./index.html&lt;/span&gt;
            &lt;span class="na"&gt;dest&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/var/www/html/index.html&lt;/span&gt;
            &lt;span class="na"&gt;owner&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;root&lt;/span&gt;
            &lt;span class="na"&gt;group&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;root&lt;/span&gt;


        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;restart nginx service&lt;/span&gt;
          &lt;span class="na"&gt;service&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx&lt;/span&gt;
            &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;restarted&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;Create a “templates” folder&lt;/em&gt;&lt;/strong&gt; and add an &lt;strong&gt;&lt;em&gt;index.html file.&lt;/em&gt;&lt;/strong&gt; Paste this inside:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Welcome to DevOps - Powered by Telios&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;35em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

                &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

                &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Tahoma&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Verdana&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Arial&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;sans-serif&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Welcome to Vagrant&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Powered By Telios&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;If you see this page, Our page is hosted on Nginx server on our VM with Vagrant.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;br&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Return back to the base folder you were with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ..
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now Run:&lt;/p&gt;

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

&lt;/div&gt;

&lt;p&gt;When the process is done, ssh into the provisioned VM with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;vagrant&lt;/span&gt; &lt;span class="n"&gt;ssh&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Access the localhost to check if our provisioning was successful. We can use &lt;strong&gt;curl&lt;/strong&gt; but lets use &lt;strong&gt;lynx&lt;/strong&gt; for a more formatted output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;lynx &lt;span class="nt"&gt;-y&lt;/span&gt;
lynx localhost
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we get the custom page then the process was a success.&lt;/p&gt;

&lt;h1&gt;
  
  
  Clean Up Vagrant
&lt;/h1&gt;

&lt;p&gt;Once you are done working on your guest system, you have a few options on how to end the session.&lt;/p&gt;

&lt;p&gt;To stop the machine and save its current state-run:&lt;/p&gt;

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

&lt;/div&gt;

&lt;p&gt;You can resume by running vagrant up again. This is much like putting the machine in sleep mode.&lt;/p&gt;

&lt;p&gt;To shut down the virtual machine use the command:&lt;/p&gt;

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

&lt;/div&gt;

&lt;p&gt;Again, &lt;strong&gt;vagrant up&lt;/strong&gt; will reboot the same virtual machine, and you can resume where you left off. This is much like shutting down a regular machine.&lt;/p&gt;

&lt;p&gt;To remove all traces of the virtual machine from your system type in the following:&lt;/p&gt;

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

&lt;/div&gt;

&lt;p&gt;Anything you have saved in the virtual machine will be removed. This frees up the system resources used by Vagrant. The next time you vagrant up, the machine will have to be re-imported and re-provisioned. This is much like formatting a hard drive on a system, then reloading a fresh image.&lt;/p&gt;

&lt;p&gt;Thanks for your time!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Questions??&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>vagrant</category>
      <category>devops</category>
      <category>easy</category>
      <category>azure</category>
    </item>
    <item>
      <title>Github Actions: From Scratch to Azure Deployment</title>
      <dc:creator>Juell</dc:creator>
      <pubDate>Wed, 21 Oct 2020 17:37:23 +0000</pubDate>
      <link>https://dev.to/udujoel/github-actions-from-scratch-to-azure-deployment-7fc</link>
      <guid>https://dev.to/udujoel/github-actions-from-scratch-to-azure-deployment-7fc</guid>
      <description>&lt;h1&gt;
  
  
  &lt;strong&gt;Github Actions Training&lt;/strong&gt;
&lt;/h1&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Introduction&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;GitHub&lt;/strong&gt; is a development platform that enables you to host and review code, manage projects, and build software alongside 50 million developers. It provides some important DevOps features that organizations of all sizes need for their software projects. Be it planning of features, fixing bugs, or collaborating on changes, GitHub is the place where developers gather to make things.&lt;/p&gt;

&lt;p&gt;In the October of 2018, Github was added to the Microsoft stack and has served to increase enterprise use of GitHub alongside other Microsoft's developer tools and services.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Github Actions&lt;/strong&gt; are a relatively new feature to Github. It enables you to build, test, package and deploy your code, right from your repository. It is a task automation system fully baked into GitHub. It came out of beta and reached general availability in November 2019. In any organization, Github Action can significantly scale down the amount of work and time required to build and maintain software projects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Github Flow&lt;/strong&gt;: is a workflow that simplifies the way changes are made to a software project. It is branch based. We start off with the Master. When there is need to add a feature, we branch off into a parallel feature branch to add the changes. This is not to disrupt the master. When done, we create a Pull Request for team members review. If approved, it is merged with the Master branch.&lt;/p&gt;

&lt;p&gt;Github Actions can massively improve an organization’s Github flow and SDLC.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Setting Up Github Action&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Github Actions are YAML files located at the “&lt;strong&gt;&lt;em&gt;.github/workflows&lt;/em&gt;&lt;/strong&gt;” of your Github repository, that describes actions or tasks to be taken on your code based off an event.&lt;/p&gt;

&lt;p&gt;There are two ways of setting up Github Actions in your repo, and we shall consider both:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;From the Actions Tab&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Manually Adding a &lt;strong&gt;.github/workflows&lt;/strong&gt; folder&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Method 1: Automatic Process&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;From the Actions Tab:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a new Github repo, or use an existing one without Github
Actions yet.&lt;/li&gt;
&lt;li&gt;Navigate to the &lt;strong&gt;Actions&lt;/strong&gt; tab.&lt;/li&gt;
&lt;li&gt;Locate the “&lt;strong&gt;&lt;em&gt;Simple Workflow&lt;/em&gt;&lt;/strong&gt;” Github Action and click on the
&lt;strong&gt;&lt;em&gt;Set up this workflow&lt;/em&gt;&lt;/strong&gt; button.&lt;/li&gt;
&lt;li&gt;This would open the Simple Workflow. Click on Commit.&lt;/li&gt;
&lt;li&gt;You now have this Github Action in your .github/workflows directory.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Example 1:&lt;/strong&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# This is a basic workflow to help you get started with Actions&lt;/span&gt;

&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;CI&lt;/span&gt;

&lt;span class="c1"&gt;# Controls when the action will run. Triggers the workflow on push or pull request&lt;/span&gt;
&lt;span class="c1"&gt;# events but only for the master branch&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;master&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;master&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;# A workflow run is made up of one or more jobs that can run sequentially or in parallel&lt;/span&gt;
&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;# This workflow contains a single job called "build"&lt;/span&gt;
  &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# The type of runner that the job will run on&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;

    &lt;span class="c1"&gt;# Steps represent a sequence of tasks that will be executed as part of the job&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="c1"&gt;# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;

      &lt;span class="c1"&gt;# Runs a single command using the runners shell&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run a one-line script&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;echo Hello, world!&lt;/span&gt;

      &lt;span class="c1"&gt;# Runs a set of commands using the runners shell&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run a multi-line script&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;echo Add other actions to build,&lt;/span&gt;
          &lt;span class="s"&gt;echo test, and deploy your project.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Field Dymystification&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The file is called an Action File. It is a YAML file that specifies the triggers, runners, steps and other details needed to run a job. Lets consider the terms you can find in the above Action file.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Name&lt;/strong&gt;: &lt;em&gt;Optional&lt;/em&gt; - The name of the workflow as it will appear in the Actions tab of the GitHub repository. It is a label.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;On&lt;/strong&gt;: Specifies the event that automatically triggers the workflow file. This example uses the &lt;strong&gt;&lt;em&gt;push&lt;/em&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;em&gt;pull_request&lt;/em&gt;&lt;/strong&gt; events on the &lt;strong&gt;&lt;em&gt;Master branch&lt;/em&gt;&lt;/strong&gt;, so that the jobs run every time someone pushes a change to that branch.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Jobs&lt;/em&gt;&lt;/strong&gt;: This Groups together all the jobs that run in the &lt;strong&gt;&lt;em&gt;CI&lt;/em&gt;&lt;/strong&gt; workflow file.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Runs-on&lt;/strong&gt;: Configures the job to run on a runner. A runner is a VM that has the Github Actions Application runner installed. Here an
&lt;strong&gt;&lt;em&gt;Ubuntu Linux&lt;/em&gt;&lt;/strong&gt; runner is specified. This means that the job will execute on a fresh virtual machine hosted by GitHub. A runner can be Github hosted or self hosted.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Steps&lt;/strong&gt;: Steps represent a sequence of tasks that will be executed sequentially as part of the job. Each line nested under this section is a separate action.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Uses&lt;/strong&gt;: The uses keyword tells the job to retrieve &lt;strong&gt;&lt;em&gt;v2&lt;/em&gt;&lt;/strong&gt; of the community action named &lt;strong&gt;&lt;em&gt;actions/checkout@v2&lt;/em&gt;&lt;/strong&gt;. This is an action that checks out your repository and downloads it to the runner, allowing you to run actions against your code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Run&lt;/strong&gt;: The &lt;strong&gt;&lt;em&gt;run&lt;/em&gt;&lt;/strong&gt; keyword tells the job to execute a command on the runner. In this case, it uses the runner’s shell to echo texts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A job contains steps with actions, run commands or api calls that is triggered when a workflow runs.&lt;/p&gt;

&lt;p&gt;Steps run actions or commands on the same runner, meaning they can share data.&lt;/p&gt;

&lt;p&gt;You can target any event and activity type on a repo with the syntax:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt; &lt;span class="na"&gt;On&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 
&lt;span class="s"&gt;&amp;lt;event_type&amp;gt;&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
   &lt;span class="na"&gt;Activity type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;activity1&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;activity2&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;…&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The full list of all activities can be found at developer.github.com/v3&lt;/p&gt;

&lt;p&gt;You can also schedule a workflow to run at a given UTC time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;On&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 
  &lt;span class="na"&gt;Schedule&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
   &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;cron&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;‘*/15 * * *’&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will trigger a run on the last commit on the default branch.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Method 2: Manual Process&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The manual way of adding a Github Action to Github is to add a &lt;strong&gt;‘.Github/workflow’&lt;/strong&gt; folder to your new or existing Github repo. Here you’ll create your Action Files.&lt;/p&gt;

&lt;p&gt;Github will automatically pick up these action files and run them when the specified even and activity occurs.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Example 2&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In the .github/workflows folder, create an action file. Name it ‘Greet.yml’. In the file enter the following.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# your-repo-name/.github/workflows/greet.yml&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Second Example&lt;/span&gt; 
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 
&lt;span class="na"&gt;Push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;master&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;                                                  
&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;                         
  &lt;span class="na"&gt;greet-job&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;                           
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Say hi&lt;/span&gt;                           
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;                           
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;                           
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Print a greeting&lt;/span&gt;                             
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;echo Hi from our first workflow!&lt;/span&gt;   

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Show ASCII greeting&lt;/span&gt;                             
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mscoutermarsh/ascii-art-action@master&lt;/span&gt;   
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;                               
          &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;HELLO!'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This workflow is triggered whenever there is a push event. Lets commit this file to the master and observe the run at the Action tab.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;CI&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;CI stands for Continuous Integration, and is the idea that as different members of the team work on code on different git branches, the code is merged to a single working branch which is then built and tested with automated workflows before merging to the production ready Master branch. This helps to constantly make sure everyone's code is working properly together and is well-tested.&lt;/p&gt;

&lt;p&gt;From the point of view of CI, the main goal of GitHub Actions and Workflows is to build and test our software every time something changes. This way we can spot bugs and correct things as soon as the errors come up.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;CI Demo: A NodeJS CI pipeline&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Create a &lt;strong&gt;&lt;em&gt;CI.yaml&lt;/em&gt;&lt;/strong&gt; file in your &lt;strong&gt;&lt;em&gt;.github/workflows&lt;/em&gt;&lt;/strong&gt; folder.&lt;/p&gt;

&lt;p&gt;Paste the following into it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Node Continuous Integration&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;Push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;master&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;

  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;master&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;


&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;test_pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v1&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;12&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm ci&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm test&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm run build`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Branch Protection&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Define branch protection rules to ensure builds pass before it can be merged to master.&lt;/p&gt;

&lt;p&gt;To set up branch protection:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to &lt;strong&gt;setting&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Click on &lt;strong&gt;branches&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Under &lt;strong&gt;Branch Protection Rules&lt;/strong&gt; click on &lt;strong&gt;Add Rule&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Check “&lt;strong&gt;&lt;em&gt;Require status checks to pass before merging&lt;/em&gt;&lt;/strong&gt;” and other
additional rules you want.&lt;/li&gt;
&lt;li&gt;Click on &lt;strong&gt;create&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now test your rule by intentionally breaking your code such that build fails.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;CD&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;CD stands for Continuous Deployment (or Delivery). Continuous Deployment takes things a step further and takes the automation to the deployment level. Where with the CI process, you automate the testing and the building, Continuous Deployment will automate the process of deploying the project to a desired environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;CICD Demo: A NodeJS CICD Pipeline&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Clone this repo for a Sample NodeJS app
[&lt;a href="https://github.com/udujoel/nodejs_sample.git"&gt;https://github.com/udujoel/nodejs_sample.git&lt;/a&gt; ]&lt;/li&gt;
&lt;li&gt;Create a &lt;strong&gt;&lt;em&gt;.github/workflows&lt;/em&gt;&lt;/strong&gt; folder&lt;/li&gt;
&lt;li&gt;Add a &lt;strong&gt;&lt;em&gt;cicd.yaml&lt;/em&gt;&lt;/strong&gt; file&lt;/li&gt;
&lt;li&gt;Copy the workflow details below into it and Commit.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# File: .github/workflows/cicd.yml&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;master&lt;/span&gt;

&lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;AZURE_WEBAPP_NAME&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;app_name_here&lt;/span&gt;   &lt;span class="c1"&gt;# set this to your application's name&lt;/span&gt;
  &lt;span class="na"&gt;AZURE_WEBAPP_PACKAGE_PATH&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;.'&lt;/span&gt;      
  &lt;span class="na"&gt;NODE_VERSION&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;10.x'&lt;/span&gt;                

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;build-and-deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build and Deploy&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@master&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Use Node.js ${{ env.NODE_VERSION }}&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v1&lt;/span&gt;
      &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ env.NODE_VERSION }}&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm install, build, and test&lt;/span&gt;
      &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
        &lt;span class="s"&gt;# Build and test the project, then&lt;/span&gt;
        &lt;span class="s"&gt;# deploy to Azure Web App.&lt;/span&gt;
        &lt;span class="s"&gt;npm install&lt;/span&gt;
        &lt;span class="s"&gt;npm run build --if-present&lt;/span&gt;
        &lt;span class="s"&gt;npm run test --if-present&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Deploy&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Azure&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;WebApp'&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;azure/webapps-deploy@v2&lt;/span&gt;
      &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 
        &lt;span class="na"&gt;app-name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ env.AZURE_WEBAPP_NAME }}&lt;/span&gt;
        &lt;span class="na"&gt;publish-profile&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}&lt;/span&gt;
        &lt;span class="na"&gt;package&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ env.AZURE_WEBAPP_PACKAGE_PATH }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Checking the Actions page, you’ll see our deploy is failing. We’ll fix that next. Now we need to understand how to setup Secrets and how to use it for Job authentication.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Secrets and Authentication&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;You can use encrypted secrets, variables and tokens in your workflow to protect your repo and store sensitive info.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can set them by visiting your Github repo settings tab,&lt;/li&gt;
&lt;li&gt;click on ‘&lt;strong&gt;&lt;em&gt;Secrets’&lt;/em&gt;&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click on ‘&lt;strong&gt;&lt;em&gt;New Secret&lt;/em&gt;&lt;/strong&gt;’ to add a new one.&lt;/li&gt;
&lt;li&gt;Set the name and value&lt;/li&gt;
&lt;li&gt;Click on ‘&lt;strong&gt;&lt;em&gt;add secret&lt;/em&gt;&lt;/strong&gt;’ to save the addition.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To make use of a added secret:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;Steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;With&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="na"&gt;Super_secret_input&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secret.SECRET_NAME }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To set these secrets as environment variable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;Steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="na"&gt;Super_secret_input&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secret.SECRET_NAME }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Now to fix our workflow:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Create an &lt;strong&gt;Azure App Service&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Download, open and copy the App service's &lt;strong&gt;Publish Profile.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Add a repo secret, with title "&lt;strong&gt;&lt;em&gt;AZURE_WEBAPP_PUBLISH_PROFILE&lt;/em&gt;&lt;/strong&gt;" and
paste the &lt;strong&gt;Publish Profile&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Update the &lt;strong&gt;&lt;em&gt;CICD.yaml&lt;/em&gt;&lt;/strong&gt; file in &lt;code&gt;.github/workflows&lt;/code&gt; with the App name.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Commit this file to trigger a CICD process. Open the Actions tab to observe the build and deploy.&lt;/p&gt;

&lt;p&gt;When done.&lt;/p&gt;

&lt;p&gt;View the changes on the site address: &lt;code&gt;[your-app-name].azurewebsites.net&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Thanks for your time!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>azure</category>
      <category>github</category>
      <category>actions</category>
      <category>workflows</category>
    </item>
    <item>
      <title>Ansible: Enders Game</title>
      <dc:creator>Juell</dc:creator>
      <pubDate>Tue, 20 Oct 2020 04:18:47 +0000</pubDate>
      <link>https://dev.to/udujoel/ansible-from-enders-game-to-ending-drift-ofj</link>
      <guid>https://dev.to/udujoel/ansible-from-enders-game-to-ending-drift-ofj</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tTNWSCJ3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/3qktjmh0jqp6difkyjav.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tTNWSCJ3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/3qktjmh0jqp6difkyjav.jpeg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Configuration Management&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The purpose of configuration management is to maintain systems in a desired state. It aims to eliminate configuration drift as much as possible. &lt;br&gt;
Configuration drift occurs when ad-hoc configuration changes and updates result in a mismatched development, test, and deployment environments. This can result in issues at deployment, security vulnerabilities, and risks when developing applications and services that need to meet strict regulatory compliance standards. &lt;br&gt;
Configuration management makes it possible to scale infrastructure without worrying about increasing staff or workload. It ensures consistency across all infrastructure, improves automation and mitigates human error.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Ansible&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Ansible is a very powerful and popular configuration management tool. Here are some quick facts that will interest you about Ansible:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The name “ansible” originally refers to a category of fictional technology capable of  faster-than-light communication. It can send and receive messages to and from a corresponding device over any distance or obstacle whatsoever with no delay.&lt;/li&gt;
&lt;li&gt;Its name is used in sci-fi movies (e.g Enders Game)and novels
(Ursula).&lt;/li&gt;
&lt;li&gt;In the Enders Game, the story depends on the ansible to centrally
control a huge, complex fleet of distant ships. This was what
inspired Ansible automation software founders to choose the term as
the name for their product.&lt;/li&gt;
&lt;li&gt;Developed by Michael DeHaan, the creator of Cobbler and Func.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Ansible is an &lt;strong&gt;&lt;em&gt;agentless&lt;/em&gt;&lt;/strong&gt; &lt;strong&gt;&lt;em&gt;push-based&lt;/em&gt;&lt;/strong&gt; configuration tool that&lt;br&gt;
functions by connecting via SSH to its managed nodes. It doesn’t need&lt;br&gt;
a special agent on the node and operates by pushing modules to the&lt;br&gt;
clients. The modules are then executed locally on the node, and the&lt;br&gt;
output is pushed back to the controller or host.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Drift&lt;/em&gt;&lt;/strong&gt; is the process of making changes on a host that makes it differ from the synced version.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;Nodes for Demo:&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Spin-up 3 Ubuntu Linux VMs on portal.azure.com&lt;/li&gt;
&lt;li&gt;Make user=&lt;em&gt;agent&lt;/em&gt;, password=&lt;em&gt;password@101&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Copy out the IP addresses of all 3 VMs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ssh into any one that would serve as our control node, and proceed as follows.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;Ansible Installation :&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Step 1&lt;/strong&gt;: Perform an update to the packages&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   sudo apt update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Step 2&lt;/strong&gt;: Install the software-properties-common package&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; sudo apt install software-properties-common
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Step 3&lt;/strong&gt;: Add ansible personal package archive&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt-add-repository ppa:ansible/ansible
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Step 4:&lt;/strong&gt; Install ansible&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; sudo apt install ansible
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;To test your installation, do:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ansible --version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;Ansible Ad-hoc Commands:&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;This is one of the simplest ways Ansible can be used to issue some commands on a server or a bunch of servers. Ad-hoc commands are not version controlled but represent a fast way to interact with the desired servers.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ansible -m ping localhost 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;-&lt;em&gt;m&lt;/em&gt; ==&amp;gt; module&lt;br&gt;
&lt;em&gt;Ping&lt;/em&gt; ==&amp;gt; module name&lt;br&gt;
&lt;em&gt;Localhost&lt;/em&gt; ==&amp;gt; target node&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ansible -m copy -a 'src=./file1.txt dest=~/file.txt' localhost 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;To see if some changes would be implemented, do a dry run. Add &lt;strong&gt;&lt;em&gt;‘--check’&lt;/em&gt;&lt;/strong&gt; to the command. To see the changes that would be implemented, add &lt;strong&gt;&lt;em&gt;‘--diff’. ‘&lt;/em&gt;&lt;/strong&gt; diff flag alone implements the changes after pointing them out to you.&lt;/p&gt;
&lt;h4&gt;
  
  
  Idempotency:
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;This is an IaC property that ensures a defined infrastructure&lt;br&gt;
deployment sets the target environment to the desired state, every&lt;br&gt;
time it is run, regardless of its starting state. The IaC provider&lt;br&gt;
will decide what needs to be stood-up, torn down or reconfigure to&lt;br&gt;
match your described target state.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Ansible Playbook
&lt;/h2&gt;

&lt;p&gt;The ansible playbook is a more readable, versionable way of executing tasks using ansible. In comparison with ad-hoc commands, playbooks are used in complex scenarios, and they offer increased flexibility and capability. Playbooks use YAML format, so there is not much syntax needed, but its indentation rules are strict.  Ansible playbooks tend to be more of a configuration language than a programming language.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Like its name, a playbook is a collection of plays. A play is a set of&lt;br&gt;
orchestration instructions.&lt;br&gt;
&lt;/p&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;    &lt;span class="s"&gt;---&lt;/span&gt;
      &lt;span class="s"&gt;#ansible -m copy -a “src=./file1.txt dest=~/file1.txt” localhost&lt;/span&gt;
    &lt;span class="s"&gt;- name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Play name&lt;/span&gt;
    &lt;span class="na"&gt;hosts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;localhost&lt;/span&gt;
      &lt;span class="s"&gt;tasks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Copy a file&lt;/span&gt;
        &lt;span class="na"&gt;copy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./file1.txt&lt;/span&gt;
          &lt;span class="na"&gt;dest&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;~/file1.txt&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;An ansible playbook starts with the 3 dashes.&lt;/li&gt;
&lt;li&gt;"#" indicates a comment line.&lt;/li&gt;
&lt;li&gt;The - name indicates a non-executed name that serves a descriptive
purpose.&lt;/li&gt;
&lt;li&gt;Hosts specifies the target node device, or groups.&lt;/li&gt;
&lt;li&gt;A task is made up of an action and its args.&lt;/li&gt;
&lt;li&gt;Under tasks you can specify your modules and its parameter.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;If the action you desire requires root/sudo, use the ‘&lt;strong&gt;&lt;em&gt;Become&lt;/em&gt;&lt;/strong&gt;’ keyword&lt;br&gt;
for privilege escalation.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Ansible Inventory
&lt;/h2&gt;

&lt;p&gt;Ansible uses the Inventory to identify its managed hosts. The default host file is at:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/etc/ansible/hosts 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Here you define your nodes, node alias, node groups and variables. Create a group with the ip addresses of the VMs you created. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[master]
host1 ansible_host=192.168.100.2 ansible_user=agent ansible_password=password@101
[agents]
node1 ansible_host=192.168.100.3 ansible_user=agent ansible_password=password@101
node2 ansible_host=192.168.100.4 ansible_user=agent ansible_password=password@101
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The ‘&lt;strong&gt;&lt;em&gt;ansible-inventory&lt;/em&gt;&lt;/strong&gt;’ command is used for working with the managed nodes. &lt;br&gt;
To see a full list of all our nodes type:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ansible-inventory --list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;For a more graphical layout use:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ansible-inventory --graph
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;@localhost&lt;/strong&gt; refers to the current/control node&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;@all&lt;/strong&gt; refers to all the nodes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;@group_name&lt;/strong&gt; targets all nodes under a group.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To simplify our host file, define all variables in the [all:vars] group:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[all:vars]
ansible_user=agent
ansible_password=password@101

[master]
host1 ansible_host=192.168.100.2 

[agents]
node1 ansible_host=192.168.100.3 
node2 ansible_host=192.168.100.4 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: Since Ansible is going to be making an SSH connection with a password to these machines, we need to install “sshpass”.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;sshpass &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let us try to test our hosts with the &lt;strong&gt;&lt;em&gt;ping&lt;/em&gt;&lt;/strong&gt; command:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ansible -m ping all
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Gives us an error. We need to modify some ansible configuration. &lt;/p&gt;

&lt;h2&gt;
  
  
  Ansible CFG
&lt;/h2&gt;

&lt;p&gt;The Ansible configuration file is exactly what you expect it to be. Its located at:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/etc/ansible/ansible.cfg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;We’ll need to open it and modify a setting. Open the file and uncomment:  &lt;code&gt;host_key_checking = false&lt;/code&gt;&lt;br&gt;
Or enter it. &lt;br&gt;
Now you can run your ping command:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ansible -m ping all
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Writing a Playbook
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Create a file:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;touch playbook.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Open it and add the following to it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;    &lt;span class="s"&gt;---&lt;/span&gt;
    &lt;span class="s"&gt;- name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;play one - install vim from custom inventory&lt;/span&gt;
      &lt;span class="s"&gt;hosts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;agents&lt;/span&gt;
      &lt;span class="s"&gt;become&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;
      &lt;span class="s"&gt;tasks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apt&lt;/span&gt; 
        &lt;span class="na"&gt;apt&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;vim&lt;/span&gt;
          &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;latest&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;zsh install&lt;/span&gt;
        &lt;span class="na"&gt;apt&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;zsh&lt;/span&gt;
          &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;latest&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;vagrant install&lt;/span&gt;
        &lt;span class="na"&gt;apt&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;vagrant&lt;/span&gt;
          &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;latest&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nodejs install&lt;/span&gt;
        &lt;span class="na"&gt;apt&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nodejs&lt;/span&gt;
          &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;latest&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;play two server config&lt;/span&gt;
      &lt;span class="na"&gt;become&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;
      &lt;span class="na"&gt;hosts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;master&lt;/span&gt;
      &lt;span class="na"&gt;tasks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ensure Nginx is at latest&lt;/span&gt;
          &lt;span class="na"&gt;apt&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx&lt;/span&gt;
            &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;latest&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;start server&lt;/span&gt;
          &lt;span class="na"&gt;service&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx&lt;/span&gt;
            &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;started&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Executing a Playbook
&lt;/h2&gt;

&lt;p&gt;To execute the play we just wrote, we use the ‘ansible-playbook’ command. Enter:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ansible-playbook playbook.yml -v
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The &lt;strong&gt;-v is for verbosity.&lt;/strong&gt; The more the v’s the more details that would be output.&lt;br&gt;
We can also execute a playbook from a custom inventory file.&lt;br&gt;
Create a custom inventory file. &lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;touch inventory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Add nodes to it.&lt;/p&gt;

&lt;p&gt;Ping test it with the following:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ansible -I inventory -m ping all
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Run a playbook off it with:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ansible-playbook -I inventory playbook.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Shut-down our VMs
&lt;/h1&gt;

&lt;p&gt;Now, as a final demo, let's shut down our VMs to avoid extra charges. Since we know ansible can do all sorts of things, let's use it for this demo. &lt;br&gt;
Can you write the YAML script for this? Try it out first. It's a simple one.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;    &lt;span class="s"&gt;---&lt;/span&gt;
    &lt;span class="s"&gt;- name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;shut down all my agent VMs&lt;/span&gt;
      &lt;span class="s"&gt;hosts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;all&lt;/span&gt;
      &lt;span class="s"&gt;become&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;
      &lt;span class="s"&gt;tasks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;run shutdown command&lt;/span&gt;
          &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;shutdown&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save and execute this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ansible-playbook shutdownVMs.yml -vv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;h1&gt;
  
  
  Ansible on Azure Cloudshell
&lt;/h1&gt;

&lt;p&gt;Azure Cloudshell has all we need to execute both Ansible Ad-hoc command and playbooks. We shall next create a VM with its underlying resources from the Azure Cloudshell.&lt;/p&gt;

&lt;p&gt;Visit &lt;a href="HTTP://portal.azure.com"&gt;HTTP://portal.azure.com&lt;/a&gt; and open the Cloudshell. Choose Bash and enter the following to open its embedded VS Code editor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;code &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;inside the editor, create a &lt;strong&gt;azvmplaybook.yml&lt;/strong&gt; and paste the following inside:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Create Azure VM&lt;/span&gt;
  &lt;span class="na"&gt;hosts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;localhost&lt;/span&gt;
  &lt;span class="na"&gt;connection&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;local&lt;/span&gt;
  &lt;span class="na"&gt;tasks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Create resource group&lt;/span&gt;
    &lt;span class="na"&gt;azure_rm_resourcegroup&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myResourceGroup&lt;/span&gt;
      &lt;span class="na"&gt;location&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;eastus&lt;/span&gt;


  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Create virtual network&lt;/span&gt;
    &lt;span class="na"&gt;azure_rm_virtualnetwork&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;resource_group&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myResourceGroup&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myVnet&lt;/span&gt;
      &lt;span class="na"&gt;address_prefixes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;10.0.0.0/16"&lt;/span&gt;


  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Add subnet&lt;/span&gt;
    &lt;span class="na"&gt;azure_rm_subnet&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;resource_group&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myResourceGroup&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mySubnet&lt;/span&gt;
      &lt;span class="na"&gt;address_prefix&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;10.0.1.0/24"&lt;/span&gt;
      &lt;span class="na"&gt;virtual_network&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myVnet&lt;/span&gt;


  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Create public IP address&lt;/span&gt;
    &lt;span class="na"&gt;azure_rm_publicipaddress&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;resource_group&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myResourceGroup&lt;/span&gt;
      &lt;span class="na"&gt;allocation_method&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Static&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myPublicIP&lt;/span&gt;
    &lt;span class="na"&gt;register&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;output_ip_address&lt;/span&gt;

  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Dump public IP for VM which will be created&lt;/span&gt;
    &lt;span class="na"&gt;debug&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;msg&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;The&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;public&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;IP&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;is&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;output_ip_address.state.ip_address&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}."&lt;/span&gt;


  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Create Network Security Group that allows SSH&lt;/span&gt;
    &lt;span class="na"&gt;azure_rm_securitygroup&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;resource_group&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myResourceGroup&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myNetworkSecurityGroup&lt;/span&gt;
      &lt;span class="na"&gt;rules&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;SSH&lt;/span&gt;
          &lt;span class="na"&gt;protocol&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Tcp&lt;/span&gt;
          &lt;span class="na"&gt;destination_port_range&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;22&lt;/span&gt;
          &lt;span class="na"&gt;access&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Allow&lt;/span&gt;
          &lt;span class="na"&gt;priority&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1001&lt;/span&gt;
          &lt;span class="na"&gt;direction&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Inbound&lt;/span&gt;


  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Create virtual network interface card&lt;/span&gt;
    &lt;span class="na"&gt;azure_rm_networkinterface&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;resource_group&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myResourceGroup&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myNIC&lt;/span&gt;
      &lt;span class="na"&gt;virtual_network&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myVnet&lt;/span&gt;
      &lt;span class="na"&gt;subnet&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mySubnet&lt;/span&gt;
      &lt;span class="na"&gt;public_ip_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myPublicIP&lt;/span&gt;
      &lt;span class="na"&gt;security_group&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myNetworkSecurityGroup&lt;/span&gt;


  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Create VM&lt;/span&gt;
    &lt;span class="na"&gt;azure_rm_virtualmachine&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;resource_group&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myResourceGroup&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myVM&lt;/span&gt;
      &lt;span class="na"&gt;vm_size&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Standard_DS1_v2&lt;/span&gt;
      &lt;span class="na"&gt;admin_username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;agent&lt;/span&gt;
      &lt;span class="na"&gt;admin_password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;password@101&lt;/span&gt;
      &lt;span class="na"&gt;network_interfaces&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myNIC&lt;/span&gt;
      &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;offer&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;UbuntuServer&lt;/span&gt;
        &lt;span class="na"&gt;publisher&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Canonical&lt;/span&gt;
        &lt;span class="na"&gt;sku&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;18.04-LTS'&lt;/span&gt;
        &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;latest&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;To set the ball rolling, execute this on the Cloudshell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ansible-playbook azvmplaybook.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wait for it...&lt;br&gt;
When it's done, go to your Resource Group to check it out. You can even SSH into your created VM. When done playing with it, we need to clean our tracks. Conveniently, simply deleting our resource group will take all the created resources with it. So let's do just that. Create a &lt;strong&gt;rmrgplaybook.yml&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;hosts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;localhost&lt;/span&gt;
  &lt;span class="na"&gt;tasks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deleting resource group&lt;/span&gt;
      &lt;span class="na"&gt;azure_rm_resourcegroup&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myResourceGroup&lt;/span&gt;
        &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;absent&lt;/span&gt;
        &lt;span class="na"&gt;force_delete_nonempty&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yes&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Here we set the &lt;strong&gt;force_delete_nonempty&lt;/strong&gt; flag to yes to enable it to delete all underlying resources. &lt;br&gt;
Now to put it in play:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ansible-playbook rmrgplaybook.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;&lt;a href="https://www.digitalocean.com/community/cheatsheets/how-to-use-ansible-cheat-sheet-guide"&gt;Thanks for your time!&lt;/a&gt;&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>ansible</category>
      <category>config</category>
      <category>automation</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
