{"id":987,"date":"2021-03-24T01:26:33","date_gmt":"2021-03-24T00:26:33","guid":{"rendered":"https:\/\/nguenkam.com\/blog\/?p=987"},"modified":"2021-03-24T01:38:41","modified_gmt":"2021-03-24T00:38:41","slug":"pipeline-for-angular-ci-cd-with-gitlab-docker-and-ansible","status":"publish","type":"post","link":"https:\/\/nguenkam.com\/blog\/index.php\/2021\/03\/24\/pipeline-for-angular-ci-cd-with-gitlab-docker-and-ansible\/","title":{"rendered":"pipeline for Angular (CI\/CD)  with Gitlab , Docker and Ansible"},"content":{"rendered":"\n<p>How to automate, build &amp; deployment to your AWS ec2 instance?<\/p>\n\n\n\n<p>The goal of this tutorial is to give a high-level introduction of GitLab CI\/CD that helps people get started in 30 minutes without having to read all of GitLab\u2018s documentation.<\/p>\n\n\n\n<p>We will take an angular project as an example and guide you step by step to help you automate the process of the build and deployment of our application.To reach out our goal, we will be using :<\/p>\n\n\n\n<ul><li>Gitlab<\/li><li>Docker<\/li><li>Ansible<\/li><li>A host server (for example,Amazon Linux 2 AMI , kubernets,  AWS cloud, etc &#8230; )<\/li><\/ul>\n\n\n\n<blockquote class=\"wp-block-quote\"><p><em>Ansible is an automating tool, with it you can automate anything<\/em><\/p><p><em>Infrastructure, Application-deployment, networks, Containers, Security-and-compliance and cloud.<\/em><\/p><\/blockquote>\n\n\n\n<p><em>For our case, we our going to use Ansible to automate the application-deployment<\/em><\/p>\n\n\n\n<p><\/p>\n\n\n\n<h4><span class=\"has-inline-color has-vivid-cyan-blue-color\">Why the choice of Gitlab  ?<\/span><\/h4>\n\n\n\n<p>With Gitlab we can build a complete CI\/CD pipeline solution with one tool. It\u2019s fast, and it\u2019s open source.<\/p>\n\n\n\n<p>&nbsp;In the same place, we can create tickets, merge requests, write code and setup CI\/CD tools without another application.<\/p>\n\n\n\n<p>It is easy, simple to use and performs the best comparing to the other CI\/CD tools, such as Jenkins, CircleCI and TeamCity&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized\"><img loading=\"lazy\" src=\"https:\/\/miro.medium.com\/max\/1152\/1*eeogafBoBI5mOpLkPLLT_g.png\" alt=\"\" width=\"494\" height=\"444\"\/><\/figure>\n\n\n\n<h4><span class=\"has-inline-color has-vivid-cyan-blue-color\">Scenario<\/span><\/h4>\n\n\n\n<p id=\"d00e\">In this article we gonna be following this scenario:<\/p>\n\n\n\n<ul><li>Create our angular App and push it to Gitlab<\/li><li>Configure our Gitalb CI\/CD<\/li><li>Implement build stage<\/li><li>Implement packaging stage<\/li><li>Implement deploy stage<\/li><li>See the result<\/li><\/ul>\n\n\n\n<p>So, we have to get <a href=\"https:\/\/git-scm.com\/downloads\">Git<\/a> installed , <a href=\"https:\/\/nodejs.org\/en\/\">node<\/a> installed and a host server.<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h5>Create our Angular app<\/h5>\n\n\n\n<pre class=\"wp-block-code\"><code>ng new angular-app<\/code><\/pre>\n\n\n\n<p>Next we are going to make a new repository in Gitlab that we call \u201cDevops\u201d.<\/p>\n\n\n\n<p>You should then see a screen like this. Follow the instructions in the push existing folder section so we can push our project to our Gitlab repository.<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized\"><img loading=\"lazy\" src=\"https:\/\/miro.medium.com\/max\/927\/1*mndwldoX2JBUeviwoy8swQ.png\" alt=\"\" width=\"614\" height=\"320\"\/><\/figure>\n\n\n\n<p>If everything set correctly, you should see a project in your Gitlab repository.<br>We are ready now to configure our Gitlab CI\/CD.<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h5>Configure our Gitlab CI\/CD<\/h5>\n\n\n\n<p>The first step here, is to install&nbsp;<strong>Gitlab Runner on our host server<\/strong><\/p>\n\n\n\n<p>Gitlab CI\/CD uses<span class=\"has-inline-color has-vivid-cyan-blue-color\"> Runners <\/span>to execute pipelines, that means, without it, we can\u2019t go further.<\/p>\n\n\n\n<p>You can have your own runners directly on your machine or server.<\/p>\n\n\n\n<p>This <a href=\"https:\/\/docs.gitlab.com\/runner\/\">link<\/a> will help you install Gitlab runner. Check at first the<br><code><span class=\"has-inline-color has-vivid-red-color\">install Gitlab runner<\/span>&nbsp;<\/code>section then go to&nbsp;<code><span class=\"has-inline-color has-vivid-red-color\">register Gitlab runner&nbsp;<\/span><\/code>section.<br>these two sections will help you install Gitlab runner, then link it to your repository.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>If the Gitlab runner is set, we can dive now, into the interesting part.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><span class=\"has-inline-color has-vivid-red-color\"><strong>PS:<\/strong><\/span>  When you register a runner, you must choose an executor.<\/p>\n\n\n\n<p>An&nbsp;<a href=\"https:\/\/docs.gitlab.com\/runner\/executors\/README.html\"><strong>executor<\/strong><\/a>&nbsp;determines the environment each job runs in.<\/p>\n\n\n\n<p>For example:<\/p>\n\n\n\n<ul><li>If you want your CI\/CD job to run PowerShell commands, you might install GitLab Runner on a Windows server and then register a runner that uses the shell executor.<\/li><li>If you want your CI\/CD job to run commands in a custom Docker container, you might install GitLab Runner on a Linux server and register a runner that uses the Docker executor.<\/li><\/ul>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<p>To use GitLab CI\/CD, let us create a file called&nbsp;<code><strong>.gitlab-ci.yml<\/strong><\/code>&nbsp;at the root of our project and add the following&nbsp;<code>yaml<\/code>&nbsp;for now :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>stages:\n - build\n - package\n - deploy<\/code><\/pre>\n\n\n\n<p>This little&nbsp;<code>yaml<\/code>&nbsp;defines the&nbsp;<strong>stages&nbsp;<\/strong>of our&nbsp;<strong>Pipeline.&nbsp;<\/strong>A&nbsp;<strong>stage&nbsp;<\/strong>is basically a list of&nbsp;<strong>jobs&nbsp;<\/strong>(instructions) regrouped together. That means we are telling gitlab-ci to execute a specific list of&nbsp;<strong>jobs&nbsp;<\/strong>for each stage of the pipeline. Here is a detailed explication.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">A.) <strong>Build stage<\/strong>\n i. Install NPM Dependencies\n\nB.) <strong>package stage<\/strong>\n i. Run Dockerfile\n ii. push it in our container registry\n\nC.) <strong>Deploy stage<\/strong>\n i. create ssh keys\n ii. Run Ansible script<\/pre>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h4><span class=\"has-inline-color has-vivid-cyan-blue-color\">Implement build stage<\/span><\/h4>\n\n\n\n<p>For the build stage we are going to add this part to our&nbsp;<code>yaml<\/code>&nbsp;file .<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>stages:\n - build\n - package\n - deploy\n\nbuild:\n  stage: build\n  image: node:latest\n  only:\n    - master\n  script:\n    - npm install -g @angular\/cli@9.1.0\n    - npm install\n    - ng build \n  artifacts:\n    paths:\n      - dist\/\n    expire_in: 2 hours\n  cache:\n    paths:\n      - node_modules\/<\/code><\/pre>\n\n\n\n<p>Let\u2019s explain the new part we have added.<\/p>\n\n\n\n<p id=\"7f27\"><code><span class=\"has-inline-color has-vivid-purple-color\">build<\/span><\/code>: it\u2019s the name of our<strong>&nbsp;job<br><\/strong><span class=\"has-inline-color has-vivid-purple-color\"><code>stage:build<\/code>&nbsp;:<\/span> means in the build stage we are going to execute this job<code><br><\/code><span class=\"has-inline-color has-vivid-purple-color\"><code>only<\/code>&nbsp;:<\/span> the only tag, specifies the branches on which this job will be executed. For our case, we just specified the master branch, but you can specify more than one branch.<br><span class=\"has-inline-color has-vivid-purple-color\"><code>image<\/code>&nbsp;:<\/span> we are going to use a node image, so we can execute our npm scripts<br><span class=\"has-inline-color has-vivid-purple-color\"><code>script<\/code>&nbsp;:<\/span> the script part is designed to install the project dependencies and generate the dist folder, with the&nbsp;<code>ng build<\/code>&nbsp;command, which we are going to use later for the packaging part.<br><span class=\"has-inline-color has-vivid-purple-color\"><code>artifacts &amp; cache<\/code>&nbsp;:<\/span> Gitlab provides two ways of sharing files across jobs, which are artificats &amp; cache.<\/p>\n\n\n\n<ul><li><strong>For the artifact part<\/strong>, we have specified that the dist folder generated by the&nbsp;<code>ng build<\/code>&nbsp;command, will be shared across the other jobs<\/li><li><strong>The cache part<\/strong>, helps the&nbsp;<code>build-prod-app<\/code>&nbsp;job to retrieve the<br><code>node modules<\/code>&nbsp;folder so it won\u2019t do the build every time from scratch. This will help us gain some time.<\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<h4><span class=\"has-inline-color has-vivid-cyan-blue-color\">Implement Packaging stage<\/span><\/h4>\n\n\n\n<p><strong>First<\/strong>, for this part, we have to create at the root of our project a&nbsp;<code>Dockerfile<\/code>&nbsp;, with no extension, just a file called&nbsp;<code>Dockerfile<\/code>&nbsp;and let\u2019s put in it this little code<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>FROM nginx:latest\nCOPY dist\/angular-app\/ \/usr\/share\/nginx\/html\nCOPY nginx.conf \/etc\/nginx\/nginx.conf<\/code><\/pre>\n\n\n\n<p>let\u2019s now dive into some explanations<\/p>\n\n\n\n<h5><strong>STEP 1\/3 : FROM Nginx:latest<\/strong><\/h5>\n\n\n\n<p>In this step, we are telling our&nbsp;<code>Dockerfile<\/code>&nbsp;to use an&nbsp;<code>nginx:latest<\/code>&nbsp;image.<\/p>\n\n\n\n<p>Nginx is a web server, it will help us display our application on the browser.<\/p>\n\n\n\n<h5><strong>STEP 2\/3 : COPY dist\/angular-app\/ \/usr\/share\/nginx\/html<\/strong><\/h5>\n\n\n\n<p>Here we just copied the&nbsp;<code><strong>angular-app<\/strong><\/code>&nbsp;folder, which is located in the&nbsp;<code><strong>dist<\/strong><\/code>&nbsp;folder, generated previously by the&nbsp;<code>ng build<\/code>&nbsp;command into the&nbsp;<code>html nginx's<\/code>&nbsp;folder.<\/p>\n\n\n\n<p>If we haven\u2019t specified our dist folder in the <span class=\"has-inline-color has-vivid-red-color\">artifacts<\/span> previously, the&nbsp;<code>package<\/code>&nbsp;job won\u2019t see it and we won\u2019t be able to execute this step successfully.<\/p>\n\n\n\n<h5><strong>STEP 3\/3 : COPY nginx.conf \/etc\/nginx\/nginx.conf<\/strong><\/h5>\n\n\n\n<p>This step is prettier much the same as the previous one, we are copying the&nbsp;<code><strong>nginx.conf<\/strong><\/code>&nbsp;file into the&nbsp;<code><strong>\/etc\/nginx\/nginx.conf<\/strong><\/code>&nbsp;.<br>For this step to be a success, we have to create the&nbsp;<code>nginx.conf<\/code>&nbsp;file at the root of our project and paste this code.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>worker_processes  1;\nevents {\nworker_connections  1024;\n}\nhttp {\nserver {\nlisten 80;\nserver_name  localhost;\nroot   \/usr\/share\/nginx\/html;\nindex  index.html;\ninclude \/etc\/nginx\/mime.types;\ngzip on;\ngzip_min_length 1000;\ngzip_proxied expired no-cache no-store private auth;\ngzip_types text\/plain text\/css application\/json application\/javascript application\/x-javascript text\/xml application\/xml application\/xml+rss text\/javascript;\nlocation \/ {\ntry_files $uri $uri\/ \/index.html;\n}\n}\n}<\/code><\/pre>\n\n\n\n<p id=\"248b\">In this file, we have configured Nginx to :<\/p>\n\n\n\n<ul><li>listen on port 80&nbsp;<code>listen 80<\/code><\/li><li>look for our application content in&nbsp;<code>usr\/share\/nginx\/html<\/code>&nbsp;folder<\/li><li>look for all the rooters in our project (&nbsp;<code>location \/<\/code>&nbsp;)<\/li><\/ul>\n\n\n\n<p>Don\u00b4t worried, &nbsp;if you don\u2019t understand some things in this file, it\u2019s just a model to follow. You don\u2019t need really to know everything about it.<\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<p>We have finished now with the&nbsp;<code>Dockerfile<\/code>&nbsp;, we will now add some changements to our&nbsp;<code>gitlab-ci<\/code>&nbsp;file. Here is the update.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker-build:\n# Official docker image.\n image: docker:stable\n only :\n  - master\n stage: package\n services:\n  - docker:dind\n before_script:\n  - echo $CI_BUILD_TOKEN | docker login -u \"$CI_REGISTRY_USER\" \n    --password-stdin $CI_REGISTRY\n script:\n  - IMAGE_NAME=\"$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_NAME\"\n  - docker build --pull -t \"$IMAGE_NAME\" -f Dockerfile .\n  - docker push \"$IMAGE_NAME\"<\/code><\/pre>\n\n\n\n<p>Let\u2019s see what\u2019s new here and explain it .<\/p>\n\n\n\n<p><span class=\"has-inline-color has-vivid-purple-color\"><code>services<\/code>&nbsp;:<\/span> In this part, we are going to use a service which is&nbsp;<code>docker:dind<\/code>&nbsp;(dind: stand for docker in docker). This service will help us, build our&nbsp;<code>Dockerfile<\/code>&nbsp;created previously and pushed it to the&nbsp;<code>container Registry<\/code><\/p>\n\n\n\n<p><span class=\"has-inline-color has-vivid-purple-color\"><code>before_script<\/code>&nbsp;:<\/span> It\u2019s clear from it\u2019s name, we are going to execute some script before the&nbsp;<code><strong>script<\/strong><\/code>&nbsp;tag. The role of this&nbsp;<code><strong>before_script<\/strong><\/code>&nbsp;is to login to the container registry, so we can able,later, to push our built image to it.<br>Here is where you can find the&nbsp;<code>container registry<\/code><\/p>\n\n\n\n<figure class=\"wp-block-image is-resized\"><img loading=\"lazy\" src=\"https:\/\/miro.medium.com\/max\/333\/1*y_vXyG7YqAZDo6k34va_vQ.png\" alt=\"\" width=\"259\" height=\"354\"\/><\/figure>\n\n\n\n<p><code><span class=\"has-inline-color has-vivid-purple-color\">Script:<\/span><\/code>&nbsp;in this part we have done three things:<\/p>\n\n\n\n<ul><li><strong>First<\/strong>, we have declared a name for our image(you can put whatever you want)<\/li><li><strong>Second<\/strong>, we built our&nbsp;<code>Dockerfile<\/code>&nbsp;which is located at the root directory of our project. The&nbsp;<code>.<\/code>at the end, means the root directory<\/li><li><strong>Third<\/strong>, we pushed our image, in the container registry.<\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<h4><span class=\"has-inline-color has-vivid-cyan-blue-color\">Implement the deploy stage<\/span><\/h4>\n\n\n\n<p id=\"3ef8\">Now our goal is to:<\/p>\n\n\n\n<ul><li>Add and configure Ansible into our project<\/li><li>Install some dependencies to our host machine<\/li><li>Configure our gitlab-ci, so we can be able to deploy our app<\/li><\/ul>\n\n\n\n<h5>Add &amp; configure Ansible<\/h5>\n\n\n\n<p>just go to this<a href=\"https:\/\/nguenkam.com\/nextcloud-13.0.4\/index.php\/s\/kBWjkwBJ4237e2b\"> link<\/a> <a href=\"https:\/\/drive.google.com\/drive\/folders\/1GNhAegc-k2QycEwHUKpZDMj2glhFwxLh?usp=sharing\"><strong>\u00a0<\/strong><\/a>and click on download all. After downloading the folder extract it and put it in the root directory of our project, and let\u2019s dive into explaining the content of this folder .<\/p>\n\n\n\n<p>So basically the Ansible folder, has this hierarchy<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" src=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/03\/image-13.png\" alt=\"\" class=\"wp-image-995\" width=\"512\" height=\"398\" srcset=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/03\/image-13.png 791w, https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/03\/image-13-300x233.png 300w, https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/03\/image-13-768x596.png 768w\" sizes=\"(max-width: 512px) 100vw, 512px\" \/><\/figure>\n\n\n\n<p>we have just to modify little stuff and we will be ready to go.<\/p>\n\n\n\n<h5><strong>STEP 1: Config hosts.yml<\/strong><\/h5>\n\n\n\n<p id=\"33c7\">Open&nbsp;<code>hosts.yml<\/code>&nbsp;and :<\/p>\n\n\n\n<ul><li>Change the \u201dput-the-host-server-user\u201d in the\u00a0<code><strong>ansible_user<\/strong>\u00a0<\/code>section by the user of your host server, for me, it\u2019s \u201cec2- user\u201d.<br>(If you don\u2019t know the user, type \u201cwhoami\u201d in the terminal of your host server)<\/li><li>put in \u201d<strong>put-the-ip-of-your-host-server<\/strong>\u201d in the\u00a0<code>prod<\/code>\u00a0section the IP of your production host server, and put the IP of your development host server in the\u00a0<code>dev<\/code>\u00a0section. If you have just one host machine, you can put for now, the same IP for both sections, but it\u2019s a good practice to have two hosts, one for production and one for development.<\/li><\/ul>\n\n\n\n<h5>STEP 2: Config group_vars\/all.yml<\/h5>\n\n\n\n<p>In this file just change \u201c<strong>put-the-host-server-user<\/strong>\u201d with the user of your host server, like the step above.<\/p>\n\n\n\n<h5><strong>STEP 3: Config host_vars\/dev.yml &amp; host_vars\/prod.yml<\/strong><\/h5>\n\n\n\n<p>In this two files all we have to do is to specify the host_name for our both environments. For example, for the\u00a0<code>dev.yml\u00a0<\/code>we put \u201cdev.example.com\u201d and for the\u00a0<code>prod.yml\u00a0<\/code>we put \u201cexample.com\u201d.<br>If you don\u2019t have a host_name, you can just put the IP of your host server in both files.<\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<h5>Install some dependencies to our host machine<\/h5>\n\n\n\n<p><a href=\"https:\/\/mohamedwaelbenismail.medium.com\/angular-application-ci-cd-with-gitlab-docker-and-ansible-2c627c839185#\"><strong><em>NOTE<\/em><\/strong><\/a><em>:  we are using \u201c<\/em><strong>Amazon Linux 2 AMI\u201d\u00a0<\/strong><em>as a host, the commands that we are going to type may be specific only to this machine, so please check the equivalent of these following commands in the OS of your host server.<\/em><\/p>\n\n\n\n<p>We are going to add these 3 dependencies:<\/p>\n\n\n\n<ul><li>Python 3<\/li><li>docker<\/li><li>docker-compose<\/li><\/ul>\n\n\n\n<p>With these dependencies, we will be able to execute the script of\u00a0<strong>tasks\/main.yml,\u00a0<\/strong>which it\u2019s role is to run a docker container on our host machine<\/p>\n\n\n\n<p><strong>Python<\/strong>\u00a0is a popular programming language often used to write scripts for operating systems. It\u2019s versatile enough for use in web development and app design.<\/p>\n\n\n\n<h5><span class=\"has-inline-color has-vivid-purple-color\">Install Python 3<\/span><\/h5>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo yum install python3\n\n\/\/With Ubuntu 18.4 , it will be sudo apt install python3<\/code><\/pre>\n\n\n\n<p>After the installation, check the version of python 3, that you have just installed by typing\u00a0<code><strong>python3 --version<\/strong><\/code><\/p>\n\n\n\n<h5><span class=\"has-inline-color has-vivid-purple-color\">Install Docker<\/span><\/h5>\n\n\n\n<pre class=\"wp-block-code\"><code>pip3 install docker<\/code><\/pre>\n\n\n\n<h5><strong><span class=\"has-inline-color has-vivid-purple-color\">Install docker-compose<\/span><\/strong><\/h5>\n\n\n\n<pre class=\"wp-block-code\"><code>pip3 install docker-compose<\/code><\/pre>\n\n\n\n<p><\/p>\n\n\n\n<h5><strong>Configure the deploy stage<\/strong><\/h5>\n\n\n\n<p>First thing here, in order for Ansible to be able to ssh to our machine, we have to provide the ssh_key for him.<br>For that , get back into Gitlab, go to \u201csettings > CI\/CD\u201d and choose \u201cVariables\u201d, then click on add a variable.<br>In the\u00a0<code>key<\/code>\u00a0part put \u201cSSH_PRIVATE_KEY<strong>\u201d\u00a0<\/strong>and for the\u00a0<code>value\u00a0<\/code>past the content of your<strong> .pem<\/strong> certificate file used to connect to your ec2. We should have something like this .<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized\"><img loading=\"lazy\" src=\"https:\/\/miro.medium.com\/max\/1374\/1*RuYWJpBhg2C7NxCWFC5wtg.png\" alt=\"\" width=\"495\" height=\"373\"\/><\/figure>\n\n\n\n<p>Now , Let\u2019s go back to our\u00a0<strong><code>gitlab-ci.yml<\/code>\u00a0<\/strong>file and add at its end these few lines .<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ansible-deploy:   \r\n  stage: deploy\r\n  image: mullnerz\/ansible-playbook:2.9.1\r\n  only : \r\n    - master    \r\n  before_script: \r\n  #generate ssh key   \r\n    - mkdir -p ~\/.ssh     \r\n    - echo -e \"$SSH_PRIVATE_KEY\" > ~\/.ssh\/id_rsa     \r\n    - chmod 600 ~\/.ssh\/id_rsa     \r\n    - '&#91;&#91; -f \/.dockerenv ]] &amp;&amp; echo -e \"Host *\\n\\tStrictHostKeyChecking no\\n\\n\" > ~\/.ssh\/config'   \r\n    - export IMAGE_NAME=\"$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_NAME\"\r\n    - export DEPLOY_TARGET=prod\r\n    - cd ansible\r\n  script:\r\n    - chmod -v 700 $(pwd)      \r\n    - ansible-playbook --key-file ~\/.ssh\/id_rsa  playbook.yml<\/code><\/pre>\n\n\n\n<p>Let\u2019s see what\u2019s new here and explain it .<\/p>\n\n\n\n<p id=\"1b84\">In the&nbsp;<code>before_script<\/code>&nbsp;part we have done three main things :<\/p>\n\n\n\n<ul><li>Created an \u201cssh\u201d folder, and have put inside it the \u201cid_rsa\u201d file, which has the \u201cssh_private_key\u201d of our machine<\/li><li>Exported the name of our docker image so Ansible can use it later<\/li><li>Specified the deploy_target as \u201cprod\u201d, that means we are going to use our production host server<\/li><\/ul>\n\n\n\n<p id=\"6a4c\">For the&nbsp;<code>script<\/code>&nbsp;part :<\/p>\n\n\n\n<ul><li>Changed the permission of the Ansible directory, (pwd : stands for<br>\u201cpath of the working directory\u201d)<\/li><li>Run the Ansible-playbook command with our ssh file as a parameter<\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>Done !<\/strong><\/p>\n\n\n\n<p>All, we have to do now is to push our work, and see the result.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>git add .\r\ngit commit -m \"test\"\r\ngit push origin master<\/code><\/pre>\n\n\n\n<p>Once the push is done, we should be able to see our pipeline starting.<\/p>\n\n\n\n<p id=\"1514\">Once the pipeline is finished, you will be able to see an angular-app on your host server <\/p>\n\n\n\n<figure class=\"wp-block-image is-resized\"><img loading=\"lazy\" src=\"https:\/\/miro.medium.com\/max\/1360\/1*N-mbrkYOlMojJZ3WLzZ9bg.png\" alt=\"\" width=\"519\" height=\"264\"\/><\/figure>\n\n\n\n<h5>Reference:<\/h5>\n\n\n\n<p><a href=\"https:\/\/mohamedwaelbenismail.medium.com\/angular-application-ci-cd-with-gitlab-docker-and-ansible-2c627c839185\">https:\/\/mohamedwaelbenismail.medium.com\/<\/a><\/p>\n\n\n\n<p><a href=\"https:\/\/blog.eleven-labs.com\/fr\/introduction-gitlab-ci\/\">https:\/\/blog.eleven-labs.com\/fr\/introduction-gitlab-ci\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>How to automate, build &amp; deployment to your AWS ec2 instance? The goal of this tutorial is to give a high-level introduction of GitLab CI\/CD that helps people get started in 30 minutes without having to read all of GitLab\u2018s documentation. We will take an angular project as an example and guide you step by [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":992,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[37,32,145,169],"tags":[214,259,203,262,264,241,261,260],"_links":{"self":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts\/987"}],"collection":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/comments?post=987"}],"version-history":[{"count":11,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts\/987\/revisions"}],"predecessor-version":[{"id":1000,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts\/987\/revisions\/1000"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/media\/992"}],"wp:attachment":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/media?parent=987"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/categories?post=987"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/tags?post=987"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}