<?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: Karol Filipczuk</title>
    <description>The latest articles on DEV Community by Karol Filipczuk (@filip5114).</description>
    <link>https://dev.to/filip5114</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%2F816705%2F3fd70536-c5e7-46ae-a7ef-35826def17b6.JPG</url>
      <title>DEV Community: Karol Filipczuk</title>
      <link>https://dev.to/filip5114</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/filip5114"/>
    <language>en</language>
    <item>
      <title>GitLab CI Pipeline. Run Script via SSH to Remote Server</title>
      <dc:creator>Karol Filipczuk</dc:creator>
      <pubDate>Wed, 16 Feb 2022 23:37:24 +0000</pubDate>
      <link>https://dev.to/aws-builders/gitlab-ci-pipeline-run-script-via-ssh-to-remote-server-49l0</link>
      <guid>https://dev.to/aws-builders/gitlab-ci-pipeline-run-script-via-ssh-to-remote-server-49l0</guid>
      <description>&lt;p&gt;When you think about deploying to remote server, SSH is first network protocol which comes to your mind. Adding on top GitLab CI/CD will let you take advantage of automation. To use GitLab CI/CD pipeline together with SSH connections it is necessary to firstly configure GitLab and I would like to show you how to configure it and run simple script.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisite
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;GitLab account&lt;/li&gt;
&lt;li&gt;Remote server (I’m using Azure’s Linux VM)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Agenda
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Create new GitLab project&lt;/li&gt;
&lt;li&gt;Create and add SSH keys&lt;/li&gt;
&lt;li&gt;Create and run GitLab CI/CD pipeline&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Create new GitLab project
&lt;/h2&gt;

&lt;p&gt;As a first step we will create GitLab project.&lt;br&gt;&lt;br&gt;
Login into GitLab and navigate to &lt;code&gt;New project -&amp;gt; Create from template -&amp;gt; Pages/Plain HTML -&amp;gt; Use template&lt;/code&gt;. Give it a project name and hit &lt;code&gt;Create project&lt;/code&gt;. This will create a simple plain html project.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxpb76im6yriibtatbfvv.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%2Fuploads%2Farticles%2Fxpb76im6yriibtatbfvv.png" alt="Pages/Plain HTML project"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The template created README.md file, initial &lt;code&gt;.gitlab-ci.yml&lt;/code&gt; and public directory with &lt;code&gt;index.html&lt;/code&gt; and &lt;code&gt;style.css&lt;/code&gt; files.&lt;/p&gt;
&lt;h2&gt;
  
  
  Create and add SSH keys
&lt;/h2&gt;

&lt;p&gt;We already have an example project, now we need to create SSH keys. They will be used to connect to our remote server. Each time GitLab CI/CD pipeline is running, it is using GitLab Runner.&lt;/p&gt;

&lt;p&gt;GitLab Runner is an application which task is to run jobs in GitLab CI/CD pipeline. GitLab Runner can be installed by yourself on your infrastructure or you can leverage Shared Runners maintained by GitLab. You have 400 minutes per month for free from GitLab. We will use Shared Runner, since they are rady to use out-of-the-box and there is no configuration needed for our example. We need to setup SSH keys in a way that job run by Shared Runner will be able to access our remote server over SSH connection.&lt;/p&gt;
&lt;h4&gt;
  
  
  Create SSH key
&lt;/h4&gt;

&lt;p&gt;You can create new SSH key in any environment, even your local environment. When you create new SSH key, you will receive two keys: private and public. It is important that GitLab have private key and your remote server has public key. That is why it doesn’t matter where you create keys, it only matters to share them accordingly with GitLab and remote server.&lt;/p&gt;

&lt;p&gt;I have linux virtual machine on Azure and will use it for the purpose of this post. I’ll create new ssh key using the VM. GitLab recommendation is to create SSH key type ED25519, which is more secure than RSA. To create new key run &lt;code&gt;ssh-keygen -t ed25519 -C "GitLab SSH key"&lt;/code&gt;. Text after &lt;code&gt;-C&lt;/code&gt; option is a comment and you can change it.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnf28yg1k59tqydujohsg.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%2Fuploads%2Farticles%2Fnf28yg1k59tqydujohsg.png" alt="Create SSH key ed25519"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The key will be created in default directory which for linux is &lt;code&gt;/home/&amp;lt;user&amp;gt;/.ssh&lt;/code&gt;. Do not specify passphrase, otherwise it will be cumbersome for GitLab CI/CD pipeline. You should have two new files in &lt;code&gt;.ssh&lt;/code&gt; directory:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;id_ed25519&lt;/code&gt; — private key&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;id_ed25519.pub&lt;/code&gt; — public key&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  Add private key as GitLab Variable
&lt;/h4&gt;

&lt;p&gt;Copy content of private key and go back to GitLab project. Navigate to &lt;code&gt;Settings -&amp;gt; CI/CD -&amp;gt; Variables -&amp;gt; Expand -&amp;gt; Add Variable&lt;/code&gt;. GitLab’s variable is a key-value pair. Name key &lt;code&gt;SSH_PRIVATE_KEY&lt;/code&gt; and paste private key in value field. Click &lt;code&gt;Add Variable&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Add two more variables:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;SSH_USER&lt;/code&gt; — name of the user on the remote server&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;VM_IPADDRESS&lt;/code&gt; — IP address of remote server&lt;/li&gt;
&lt;/ul&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz2z9tviwpd7s890rvgt2.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%2Fuploads%2Farticles%2Fz2z9tviwpd7s890rvgt2.png" alt="Added variables"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Add public key to remote server
&lt;/h4&gt;

&lt;p&gt;Copy content of public key and go back to remote server. Login as the same user which you have specified in &lt;code&gt;SSH_USER&lt;/code&gt; GitLab’s variable. If you don’t have yet this user, it is time to create it.&lt;/p&gt;

&lt;p&gt;Navigate to &lt;code&gt;/home/&amp;lt;username&amp;gt;/.ssh&lt;/code&gt;. If directory &lt;code&gt;.ssh&lt;/code&gt; doesn’t exist, then create it. Paste the public key into &lt;code&gt;authorized_keys&lt;/code&gt; file. If you don’t have &lt;code&gt;authorized_keys&lt;/code&gt; file, create it. Here is screenshot from my VM (which I have deleted before posting, so they are useless now).&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdlo5n5znnpjbd6stff49.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%2Fuploads%2Farticles%2Fdlo5n5znnpjbd6stff49.png" alt="Authorized keys setup"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Create and run GitLab CI/CD pipeline
&lt;/h2&gt;

&lt;p&gt;It’s time to create GitLab CI/CD pipeline. We want to achieve two goals using SSH: log remote server’s hostname and create an example file in user’s home directory.&lt;/p&gt;

&lt;p&gt;The pipeline is defined in &lt;code&gt;.gitlab-ci.yml&lt;/code&gt; and we have two option to create/edit:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Directly in GitLab project in web browser, we can edit &lt;code&gt;.gitlab-ci.yml&lt;/code&gt; and commit changes&lt;/li&gt;
&lt;li&gt;Clone repository, edit &lt;code&gt;.gitlab-ci.yml&lt;/code&gt; in your favorite code editor, commit changes and push it to GitLab&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I will go with option number 2, it’s more proper way to handle &lt;code&gt;.gitlab-ci.yml&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You can clone repository using command &lt;code&gt;git clone &amp;lt;repo_address&amp;gt;&lt;/code&gt; and repo address you can find in GitLab repository by clicking &lt;code&gt;Clone&lt;/code&gt; button.&lt;br&gt;&lt;br&gt;
After cloning open already existing &lt;code&gt;.gitlab-ci.yml&lt;/code&gt; which was created as part of the Pages/Plain HTML template.&lt;/p&gt;

&lt;p&gt;Original .gitlab-ci.yml:&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;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;alpine:latest&lt;/span&gt;

&lt;span class="na"&gt;pages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;deploy&lt;/span&gt;
  &lt;span class="na"&gt;script&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 'Nothing to do...'&lt;/span&gt;
  &lt;span class="na"&gt;artifacts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;paths&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;public&lt;/span&gt;
  &lt;span class="na"&gt;only&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We need to add &lt;code&gt;before_script&lt;/code&gt; section and update &lt;code&gt;script&lt;/code&gt; section.&lt;/p&gt;

&lt;p&gt;Final .gitlab-ci.yml:&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;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;alpine:latest&lt;/span&gt;

&lt;span class="na"&gt;pages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;deploy&lt;/span&gt;
  &lt;span class="na"&gt;before_script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;command&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;-v&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;ssh-agent&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;gt;/dev/null&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;(&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;apk&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;add&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;--update&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;openssh&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="s"&gt;eval $(ssh-agent -s)&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mkdir -p ~/.ssh&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;chmod 700 ~/.ssh&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ssh-keyscan $VM_IPADDRESS &amp;gt;&amp;gt; ~/.ssh/known_hosts&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;chmod 644 ~/.ssh/known_hosts&lt;/span&gt;
  &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ssh $SSH_USER@$VM_IPADDRESS "hostname &amp;amp;&amp;amp; echo 'Welcome!!!' &amp;gt; welcome.txt"&lt;/span&gt;
  &lt;span class="na"&gt;artifacts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;paths&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;public&lt;/span&gt;
  &lt;span class="na"&gt;only&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;.gitlab-ci.yml&lt;/code&gt; defines pipeline. It uses docker image &lt;code&gt;alpine:latest&lt;/code&gt; to run jobs defined in pipeline. We only have one job &lt;code&gt;pages&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The job run in &lt;code&gt;stage: deploy&lt;/code&gt;. We didn’t define any stages, but we have 5 default stages to use: &lt;code&gt;.pre, build, test, deploy, .post&lt;/code&gt;. It doesn't matter in our case, since our pipeline at the moment is simple and doesn’t require setting up stages.&lt;/p&gt;

&lt;p&gt;Then we have &lt;code&gt;before_script&lt;/code&gt; which is pretty self-explanatory and will run before &lt;code&gt;script&lt;/code&gt; command. Let’s explain script line by line:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;command -v ssh-agent &amp;gt; /dev/null || (apk add --update openssh)&lt;/code&gt; — checks if ssh-agent is already installed and if not, then install it&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;eval $(ssh-agent -v)&lt;/code&gt; — starts ssh-agent&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add —&lt;/code&gt; — adds ssh private key stored in variable &lt;code&gt;SSH_PRIAVTE_KEY&lt;/code&gt; to agent store&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;mkdir -p ~/.ssh&lt;/code&gt; and &lt;code&gt;chmod 700 ~/.ssh&lt;/code&gt; — creates &lt;code&gt;.ssh&lt;/code&gt; directory and assign correct permissions&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ssh-keyscan $VM_IPADDRESS &amp;gt;&amp;gt; ~/.ssh/known_hosts&lt;/code&gt; — checks public key on remotes server using IP address stored in &lt;code&gt;VM_IPADDRESS&lt;/code&gt; variable and add it to known hosts. It is protecting from men-in-the-middle attack and is necessary to work, otherwise the job will fail.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;chmod 644 ~/.ssh/known_hosts&lt;/code&gt; — assign correct permissions&lt;/li&gt;
&lt;li&gt;For more information refer to GitLab docs &lt;a href="https://docs.gitlab.com/ee/ci/ssh_keys/" rel="noopener noreferrer"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;script&lt;/code&gt; is where our actual code to execute is defined. We simply want to print hostname to job log and then create an example file on remote host.&lt;br&gt;&lt;br&gt;
&lt;code&gt;ssh $SSH_USER@$IP_ADDRESS "hostname &amp;amp;&amp;amp; echo 'Welcome!!!' &amp;gt; welcome.txt"&lt;/code&gt; will connect over SSH as user specified in &lt;code&gt;SSH_USER&lt;/code&gt; variable to remote server, then run command &lt;code&gt;hostname&lt;/code&gt; which will print hostname and echo &lt;code&gt;Welcome!!!&lt;/code&gt; to file &lt;code&gt;welcome.txt&lt;/code&gt; which will be created on remote server in &lt;code&gt;SSH_USER&lt;/code&gt; home directory.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;artifacts&lt;/code&gt; specify which artifacts to use in deployment. We are not using it in our example.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;only&lt;/code&gt; specify that the job should be only run if any change is pushed into &lt;code&gt;master&lt;/code&gt; branch in repository.&lt;/p&gt;

&lt;p&gt;After making changes, we need to commit them and push to repository.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw41azdl3ijt7x1uqnlbl.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%2Fuploads%2Farticles%2Fw41azdl3ijt7x1uqnlbl.png" alt="Add, commit and push changes to repository"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the change is pushed into master branch the GitLab CI/CD will be trigged. Navigate to &lt;code&gt;CI/CD -&amp;gt; Pipelines&lt;/code&gt; and you should see pipeline in status running.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkva9kngowpphndilrsde.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%2Fuploads%2Farticles%2Fkva9kngowpphndilrsde.png" alt="Running pipeline"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on it and the click on job &lt;code&gt;pages&lt;/code&gt; to see logs.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9fk5zcrmv6j20mk1i5ao.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%2Fuploads%2Farticles%2F9fk5zcrmv6j20mk1i5ao.png" alt="Pipeline's job logs"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Job should finish quickly, in my case it took 16 seconds. The last line shows that job was run successfully. Line 51 shows &lt;code&gt;script&lt;/code&gt; part from &lt;code&gt;.gitlab-ci.yml&lt;/code&gt; and in line 52 we can see remote server hostname which is exactly what we wanted to achieve. Check your remote server, you will find &lt;code&gt;welcome.txt&lt;/code&gt; there.&lt;/p&gt;

&lt;p&gt;That’s it! We have successfully created new GitLab project, setup SSH connection to remote server and created simple GitLab CI/CD pipeline to run script via SSH to the remote server.&lt;br&gt;&lt;br&gt;
Thanks for reading.&lt;/p&gt;

</description>
      <category>gitlab</category>
      <category>devops</category>
      <category>ssh</category>
      <category>aws</category>
    </item>
  </channel>
</rss>
