<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Andres</title>
    <description>The latest articles on Forem by Andres (@andresfmoya).</description>
    <link>https://forem.com/andresfmoya</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%2F378417%2Fdbf5576e-b39f-42a6-ac47-70766d49a544.png</url>
      <title>Forem: Andres</title>
      <link>https://forem.com/andresfmoya</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/andresfmoya"/>
    <language>en</language>
    <item>
      <title>Install Jenkins using Docker Compose</title>
      <dc:creator>Andres</dc:creator>
      <pubDate>Tue, 05 May 2020 14:14:05 +0000</pubDate>
      <link>https://forem.com/andresfmoya/install-jenkins-using-docker-compose-4cab</link>
      <guid>https://forem.com/andresfmoya/install-jenkins-using-docker-compose-4cab</guid>
      <description>&lt;h2&gt;
  
  
  What is Jenkins?
&lt;/h2&gt;

&lt;p&gt;Jenkins is an open source automation tool written in Java with plugins built for Continuous Integration purpose. It is used to build and test your software projects continuously making it easier for developers to integrate changes to the project, and making it easier for users to obtain a fresh build. It also allows you to continuously deliver your software by integrating with a large number of testing and deployment technologies.&lt;/p&gt;

&lt;h2&gt;
  
  
  And Docker Compose?
&lt;/h2&gt;

&lt;p&gt;Docker is a platform for running applications in an isolated environment called a "container" (or Docker container). Docker Compose is a tool for defining and running Docker applications. With Compose, you use a YAML file to configure your application’s services. Then, with a single command, you create and start all the services from your configuration. It lets you take advantage of the benefits of Docker while abstracting the complexity of your stack.&lt;/p&gt;

&lt;p&gt;Installing Jenkins directly in your OS can be tricky and expensive in terms of time and resources. You need to have Java installed in your local machine and at least 10 GB of drive space. On the other hand, using docker compose is really straightforward and offers a lot of advantages.&lt;/p&gt;

&lt;p&gt;We're going through the steps to install Jenkins using Docker-Compose. &lt;/p&gt;




&lt;h4&gt;
  
  
  Install Docker Compose
&lt;/h4&gt;

&lt;p&gt;Docker Desktop for Mac and Docker Toolbox already include Compose along with other Docker apps, so Mac users do not need to install Compose separately. Docker install instructions for these are here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.docker.com/compose/install/" rel="noopener noreferrer"&gt;Install Docker Compose&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can verify the version of docker compose using:&lt;/p&gt;

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

&amp;gt; docker-compose --version
docker-compose version 1.25.4, build 8d51620a


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

&lt;/div&gt;




&lt;h4&gt;
  
  
  Create docker-compose configuration
&lt;/h4&gt;

&lt;p&gt;Inside your working directory create the docker-compose.yml file:&lt;/p&gt;

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

/jenkins-config

touch docker-compose.yml


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

&lt;/div&gt;

&lt;p&gt;Then copy the following configuration:&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;/jenkins-config/docker-compose.yml&lt;/span&gt;

&lt;span class="na"&gt;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;3.7'&lt;/span&gt;
&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;jenkins&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;jenkins/jenkins:lts&lt;/span&gt;
    &lt;span class="na"&gt;privileged&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="na"&gt;user&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;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;8081:8080&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;50000:50000&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;jenkins&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;~/jenkins:/var/jenkins_home&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/var/run/docker.sock:/var/run/docker.sock&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/usr/local/bin/docker:/usr/local/bin/docker&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;You need to ensure the directory &lt;code&gt;~/jenkins&lt;/code&gt; exists:&lt;/p&gt;

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

mkdir ~/jenkins


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

&lt;/div&gt;

&lt;p&gt;This volume will be used to persist all your data: configurations, plugins, pipelines, passwords, etc.&lt;/p&gt;

&lt;p&gt;The remaining two volumes allow you to use docker inside the Jenkins server (Yes, you can create docker containers inside a docker container).&lt;/p&gt;

&lt;h4&gt;
  
  
  Run Docker Compose
&lt;/h4&gt;

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

/jenkins-config

&amp;gt; docker-compose up -d


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

&lt;/div&gt;

&lt;p&gt;Jenkins is running in &lt;code&gt;localhost:8081&lt;/code&gt;.&lt;/p&gt;

&lt;h5&gt;
  
  
  Firs Log in
&lt;/h5&gt;

&lt;p&gt;View the generated administrator password to log in the first time.&lt;/p&gt;

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

❯ docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword


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

&lt;/div&gt;




&lt;p&gt;Now, you're ready to install plugins and start creating pipelines. If you want to stop the Jenkins container you can do it with &lt;code&gt;docker-compose down&lt;/code&gt;. When you restart it all your configuration, users, plugins previously installed will persist there. &lt;/p&gt;

&lt;h5&gt;
  
  
  Upgrading Versions
&lt;/h5&gt;

&lt;p&gt;To upgrade to latest versions just modify the tag of the image in your docker-compose yml file, for example:&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;/jenkins-config/docker-compose.yml&lt;/span&gt;

&lt;span class="na"&gt;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;3.7'&lt;/span&gt;
&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;jenkins&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;jenkins/jenkins:2.223.1&lt;/span&gt;
    &lt;span class="s"&gt;...&lt;/span&gt;


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

&lt;/div&gt;




&lt;p&gt;That's it! You can start using Jenkins to implement your CI/CD.&lt;/p&gt;

&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%2Fmy-blog-andmedev.s3.amazonaws.com%2FScreen%2BShot%2B2020-05-04%2Bat%2B10.59.05%2BPM.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%2Fmy-blog-andmedev.s3.amazonaws.com%2FScreen%2BShot%2B2020-05-04%2Bat%2B10.59.05%2BPM.png" alt="Pipeline"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>jenkins</category>
      <category>devops</category>
      <category>cicd</category>
      <category>docker</category>
    </item>
    <item>
      <title>Multiple Playbooks in Ansible</title>
      <dc:creator>Andres</dc:creator>
      <pubDate>Sun, 03 May 2020 15:34:38 +0000</pubDate>
      <link>https://forem.com/andresfmoya/multiple-playbooks-in-ansible-2pdc</link>
      <guid>https://forem.com/andresfmoya/multiple-playbooks-in-ansible-2pdc</guid>
      <description>&lt;p&gt;Ansible is a simple IT automation engine that automates cloud provisioning, configuration management, application deployment, intra-service orchestration, and many other IT needs.&lt;/p&gt;

&lt;p&gt;Ansible works by connecting to your nodes and pushing out small programs, called "Ansible modules" to them. These programs are written to be resource models of the desired state of the system. Ansible then executes these modules (over SSH by default), and removes them when finished.&lt;/p&gt;




&lt;h3&gt;
  
  
  TL;DR
&lt;/h3&gt;

&lt;p&gt;Ansible has the option to import multiple playbooks into a single one using the method: &lt;code&gt;import_playbook&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/playbooks/main.yml
---
- name: Playbook_1
    import_playbook: 00-playbook-1.yml
- name: Playbook_2
    import_playbook: 01-playbook-2.yml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;When you execute &lt;code&gt;ansible-playbook playbooks/main.yml&lt;/code&gt; Ansible will execute first the Playbook1, and then Playbook 2.&lt;/p&gt;

&lt;p&gt;We're going through an example to see it in action&lt;/p&gt;




&lt;p&gt;The first playbook executes a ping into your servers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/playbooks/00-ping.yml
---
- hosts: all
  tasks:
    - name: Ping All Servers
      action: ping
    - debug: msg="Success"
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The second playbook upgrades all your yum packages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/playbooks/01-upgrade.yml
---
- hosts: all
  tasks:
    - name: upgrade all packages
      become: yes
      yum:
        name: '*'
        state: latest
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The third playbook download a node binary distribution:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/playbooks/02-download-node.yml
---
- hosts: all
  tasks:
    - name: Download node binary distro
      shell: curl sL https://rpm.nodesource.com/setup_12.x | sudo bash -
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The fourth playbook install node:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/playbooks/03-install-node.yml
---
- hosts: all
  tasks:
    - name: Install Node
      become: yes
      yum:
        name: nodejs
        state: present
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The fifth playbook copy your app into the remote servers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/playbooks/04-provisioning.yml
---
- hosts: all
  tasks:
    - name: Copy app files
      copy:
        src: ~/documents/my-app-folder/
        dest: /home/ec2-user/my-app
        force: no
    - debug: msg="Success"
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And finally you need to install dependencies based on your package-json:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/playbooks/05-install-dependencies.yml
---
- hosts: all
  tasks:
    - name: Install packages based on package.json.
      npm:
        path: /home/ec2-user/my-app
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Once you have all your playbooks ready, if you want to execute all of them in the desired order you need to create a main playbook, and import all of them as follow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/playbooks/main.yml
---
- name: Ping
  import_playbook: 00-ping.yml

- name: Update
  import_playbook: 01-update.yml

- name: Download Node
  import_playbook: 02-download-node.yml

- name: Install Node
  import_playbook: 03-install-node.yml

- name: Provisioning
  import_playbook: 04-provisioning.yml

- name: Install Dependencies
  import_playbook: 05-install-dependencies.yml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That's it. You are ready to execute &lt;code&gt;ansible-playbook playbooks/main.yml&lt;/code&gt; and you'll upgrade all your packages, download and install node, provision all your selected servers, and install your dependencies.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>ansible</category>
      <category>cloud</category>
      <category>infrastructure</category>
    </item>
    <item>
      <title>Remote Back-End in Terraform</title>
      <dc:creator>Andres</dc:creator>
      <pubDate>Sun, 03 May 2020 02:47:07 +0000</pubDate>
      <link>https://forem.com/andresfmoya/remote-back-end-in-terraform-4dl1</link>
      <guid>https://forem.com/andresfmoya/remote-back-end-in-terraform-4dl1</guid>
      <description>&lt;p&gt;A "backend" in Terraform determines how the state is loaded and how an operation such as apply is executed.&lt;/p&gt;

&lt;p&gt;By default, Terraform uses the "local" backend, which is the normal behavior of Terraform you're used to, but, if you're working in a team, or you don't want to keep sensitive information in your local disk, or you're working remotely, it's highly recommended to store this 'state' in the cloud, and we're going to see in this article how it can be done storing the backend in an S3 bucket.&lt;/p&gt;




&lt;h3&gt;
  
  
  TL;DR
&lt;/h3&gt;

&lt;p&gt;To configure your remote state in Terraform, you need two instances:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An s3 bucket where the terraform.state file is stored.&lt;/li&gt;
&lt;li&gt;A dynamo table with a lock id to prevent two or more users perform changes to the state at the same time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When you call &lt;code&gt;terraform plan&lt;/code&gt;, or &lt;code&gt;terraform apply&lt;/code&gt; it locks the access to the state using the Lock ID in the dynamo table and then uses the terraform.state file to apply the changes to your infrastructure. When the changes are done, the terraform.state file is updated and the table is unlocked to allow new operations.&lt;/p&gt;




&lt;h3&gt;
  
  
  Create S3 Bucket
&lt;/h3&gt;

&lt;p&gt;The code to create the S3 bucket is the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;provider "aws" {&lt;/span&gt;
  &lt;span class="s"&gt;region = "us-east-1"&lt;/span&gt;
  &lt;span class="s"&gt;version = "~&amp;gt;2.59"&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;

&lt;span class="s"&gt;resource "aws_s3_bucket" "enterprise_backend_state" {&lt;/span&gt;
  &lt;span class="s"&gt;bucket = "my-backend-bucket"&lt;/span&gt;

  &lt;span class="s"&gt;lifecycle {&lt;/span&gt;
    &lt;span class="s"&gt;prevent_destroy = &lt;/span&gt;&lt;span class="no"&gt;true&lt;/span&gt;
  &lt;span class="s"&gt;}&lt;/span&gt;

  &lt;span class="s"&gt;versioning {&lt;/span&gt;
    &lt;span class="s"&gt;enabled = &lt;/span&gt;&lt;span class="no"&gt;true&lt;/span&gt;
  &lt;span class="s"&gt;}&lt;/span&gt;

  &lt;span class="s"&gt;server_side_encryption_configuration {&lt;/span&gt;
    &lt;span class="s"&gt;rule {&lt;/span&gt;
      &lt;span class="s"&gt;apply_server_side_encryption_by_default {&lt;/span&gt;
        &lt;span class="s"&gt;sse_algorithm = "AES256"&lt;/span&gt;
      &lt;span class="s"&gt;}&lt;/span&gt;
    &lt;span class="s"&gt;}&lt;/span&gt;
  &lt;span class="s"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;






&lt;h3&gt;
  
  
  Create the Dynamo Table
&lt;/h3&gt;

&lt;p&gt;The code to create the dynamo table is the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;resource "aws_dynamodb_table" "enterprise_backend_state" {&lt;/span&gt;
  &lt;span class="s"&gt;hash_key = "LockID"&lt;/span&gt;
  &lt;span class="s"&gt;name = "backend-lock-table"&lt;/span&gt;
  &lt;span class="s"&gt;billing_mode = "PAY_PER_REQUEST"&lt;/span&gt;
  &lt;span class="s"&gt;attribute {&lt;/span&gt;
    &lt;span class="s"&gt;name = "LockID"&lt;/span&gt;
    &lt;span class="s"&gt;type = "S"&lt;/span&gt;
  &lt;span class="s"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;






&lt;p&gt;Once you have an s3 bucket and the dynamo table you're ready to tell Terraform to store the state in s3 bucket from now on:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;terraform {&lt;/span&gt;
  &lt;span class="s"&gt;backend "s3" {&lt;/span&gt;
    &lt;span class="s"&gt;bucket         = "my-backend-bucket"&lt;/span&gt;
    &lt;span class="s"&gt;key            = "dev/terraform.tfstate"&lt;/span&gt;
    &lt;span class="s"&gt;region         = "us-east-1"&lt;/span&gt;
    &lt;span class="s"&gt;dynamodb_table = "backend-lock-table"&lt;/span&gt;
    &lt;span class="s"&gt;encrypt        = &lt;/span&gt;&lt;span class="no"&gt;true&lt;/span&gt;
  &lt;span class="s"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That's it. You can do &lt;code&gt;terraform init&lt;/code&gt; to execute the configuration. You'll notice Terraform will no continue storing the state on your disk. You´re ready to start collaborating with your team on the same infrastructure. &lt;/p&gt;

</description>
      <category>devops</category>
      <category>infrastructure</category>
      <category>aws</category>
      <category>terraform</category>
    </item>
  </channel>
</rss>
