<?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: Anderson</title>
    <description>The latest articles on DEV Community by Anderson (@mandax).</description>
    <link>https://dev.to/mandax</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%2F91020%2F45a8477d-6ade-4937-a566-4c3c36aa4225.jpeg</url>
      <title>DEV Community: Anderson</title>
      <link>https://dev.to/mandax</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mandax"/>
    <language>en</language>
    <item>
      <title>Static Blog: Using Hugo, S3 and deploying with Gitlab pipeline</title>
      <dc:creator>Anderson</dc:creator>
      <pubDate>Sun, 26 May 2019 14:43:07 +0000</pubDate>
      <link>https://dev.to/mandax/static-blog-using-hugo-s3-and-deploying-with-gitlab-pipeline-5pc</link>
      <guid>https://dev.to/mandax/static-blog-using-hugo-s3-and-deploying-with-gitlab-pipeline-5pc</guid>
      <description>&lt;p&gt;&lt;sup&gt;Picture by: &lt;a href="https://unsplash.com/@dsmacinnes" rel="noopener noreferrer"&gt;@dsmacinnes&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;If you want to blog post by pushing a new commit, this article was made for you, here I'll try to explain how I deployed &lt;a href="http://www.mandax.com.br" rel="noopener noreferrer"&gt;my blog&lt;/a&gt; and we'll use Aws, Gitlab and Hugo. The same concept can be applied using Circle CI, Heroku, Azure, Zeit, Github, Bitbucket, Jenkins and more. You can also skip the Hugo part if you already have a static content to deploy.&lt;/p&gt;

&lt;h1&gt;
  
  
  Requirements
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Hugo&lt;/li&gt;
&lt;li&gt;git&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Required skills
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;git&lt;/li&gt;
&lt;li&gt;markdown (to write the posts)&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  The problem
&lt;/h1&gt;

&lt;p&gt;Since I started to work with development I always had friends and coworkers encouraging me to start writing and one of the reasons that I've never started it was the process of building a blog, choosing or making a layout, and everything around this universe.&lt;/p&gt;

&lt;p&gt;I know that today we have great communities like dev.to to write, but to be honest, I wanted someplace to keep all my things together, not just code, but design, 3d, animations, and maybe  my personal thoughts also, I wanted that the process of writing could be seamlessly incorporated on my activities as a developer and a static generated website to be deployed everywhere with cheap costs and no magic involved.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F71knhh9cw8lumlhu040m.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F71knhh9cw8lumlhu040m.gif" alt="magic" width="245" height="165"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  The Solution
&lt;/h1&gt;

&lt;p&gt;The first point of this solution is to use Git to deploy a new post without using any heavy &lt;em&gt;Text Editor&lt;/em&gt;, just markdown. To do that I would need to make a continuous delivery pipeline triggered by a new commit.&lt;/p&gt;

&lt;p&gt;Then, &lt;a href="https://gohugo.io/" rel="noopener noreferrer"&gt;Hugo&lt;/a&gt;!&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fwww.mandax.com.br%2Fimages%2Fpost1_hugo.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fwww.mandax.com.br%2Fimages%2Fpost1_hugo.jpg" alt="go hugo logo" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Go Hugo
&lt;/h1&gt;
&lt;h2&gt;
  
  
  Install
&lt;/h2&gt;

&lt;p&gt;As I'm using macOS, I installed Hugo using brew, but you can install it on any platform, just check it &lt;a href="https://gohugo.io/getting-started/installing" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;brew install hugo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Creating a new site
&lt;/h2&gt;

&lt;p&gt;To create a new website you need to run this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;hugo new site [your-site-name]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Theme
&lt;/h2&gt;

&lt;p&gt;Now we need to choose and install a theme for our website. The theme that I chose is &lt;strong&gt;&lt;em&gt;Manis&lt;/em&gt;&lt;/strong&gt; developed by &lt;strong&gt;Yurizal Susanto&lt;/strong&gt;, a really minimalist, clean and beautiful theme and of course, I did my own modifications on it. You can check the &lt;a href="https://themes.gohugo.io/" rel="noopener noreferrer"&gt;available themes here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To install a theme you just need to clone its repository as a submodule on your Hugo project:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://github.com/yursan9/manis-hugo-theme themes/manis
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Hugo has a configuration file called &lt;code&gt;config.toml&lt;/code&gt;, this file contains the configuration of our website and the theme can have some specific configurations too, like colors, icons and pretty much anything that the developer of the theme put in there. This makes Hugo flexible and you can have themes really unique for a lot of different purposes.&lt;/p&gt;

&lt;p&gt;To see what configurations our recently downloaded theme have, we can find it inside the theme folder on a folder called &lt;code&gt;exampleSite&lt;/code&gt;, as the name says it’s an example website built with the theme and you can copy it’s &lt;code&gt;config.toml&lt;/code&gt; and use it on your project by overwriting your default &lt;code&gt;config.toml&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Running
&lt;/h2&gt;

&lt;p&gt;To run the project locally, just type:&lt;/p&gt;

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

&lt;/div&gt;
&lt;h1&gt;
  
  
  AWS - S3
&lt;/h1&gt;
&lt;h2&gt;
  
  
  Quick explanation
&lt;/h2&gt;

&lt;p&gt;S3 Bucket works as a storage, as it is like a container to store your files of any kind, and luckily &lt;code&gt;aws&lt;/code&gt; has a feature to serve your bucket as a website. So, by having some &lt;code&gt;index.html&lt;/code&gt; inside it you will be able to see it online and also, if you have a domain you can use &lt;em&gt;Route 53&lt;/em&gt; to point it to your bucket, &lt;a href="https://docs.aws.amazon.com/AmazonS3/latest/dev/website-hosting-custom-domain-walkthrough.html" rel="noopener noreferrer"&gt;check the documentation here&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Creating a bucket
&lt;/h2&gt;

&lt;p&gt;To create a bucket we just need to access the &lt;a href="https://console.aws.amazon.com/s3" rel="noopener noreferrer"&gt;Aws console&lt;/a&gt; and find the &lt;em&gt;S3&lt;/em&gt; service section, once inside the page hit the blue button &lt;em&gt;Create Bucket&lt;/em&gt;. A modal will appear so you can configure your bucket but, for this purpose, we don’t need to make any specific configuration yet, just name the bucket and we are good to go.&lt;/p&gt;

&lt;p&gt;After creating our bucket we will need to set it as public readable, to do so we will need to click in the name of it and then in the &lt;em&gt;Permissions&lt;/em&gt; tab, find the &lt;em&gt;Bucket Policy&lt;/em&gt; link, add this &lt;em&gt;JSON&lt;/em&gt; there and don’t forget to replace &lt;code&gt;&amp;lt;your-bucket-name&amp;gt;&lt;/code&gt; with your bucket name:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"Version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"Statement"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"Sid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"PublicReadForGetBucketObjects"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"Principal"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"AWS"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"s3:GetObject"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:s3:::&amp;lt;your-bucket-name&amp;gt;/*"&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we need to tell aws to host our bucket as a website and to do so, we need to go to the Properties tab and activate a Static website hosting setting the default file to &lt;code&gt;index.html&lt;/code&gt;. &lt;br&gt;
Your bucket URL will be shown on the top of the block.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fwww.mandax.com.br%2Fimages%2Fpost1_bucket_host.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fwww.mandax.com.br%2Fimages%2Fpost1_bucket_host.jpg" alt="Gitlab pipeline" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Get your access key
&lt;/h2&gt;

&lt;p&gt;Before the next step, we need to create an access key which will be used by Gitlab to synchronize our website files to our s3 bucket and the easiest way to do that would just create a key based on our administrator user, but we will not do it, because… Safety first, right?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Ftpc1nbvzwk18buqr0vhr.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Ftpc1nbvzwk18buqr0vhr.gif" alt="safety first" width="480" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The safest and correct way to do this is to create a policy which will grant just enough access to sync files with our bucket.&lt;/p&gt;
&lt;h2&gt;
  
  
  Creating a policy
&lt;/h2&gt;

&lt;p&gt;Inside aws console, go to &lt;strong&gt;Services &amp;gt; IAM &amp;gt; Customer Managed Policies &amp;gt; Create Policy&lt;/strong&gt;, then click on the &lt;em&gt;JSON&lt;/em&gt; tab and paste this text, modifying &lt;code&gt;&amp;lt;your-bucket-name&amp;gt;&lt;/code&gt; with the name of your bucket of course.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"Version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"Statement"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"Sid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ListObjectsInBucket"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="s2"&gt;"s3:ListBucket"&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:s3:::&amp;lt;your-bucket-name&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"Sid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AllObjectActions"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"s3:*Object"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:s3:::&amp;lt;your-bucket-name&amp;gt;/*"&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will grant access to read all objects inside the bucket and allow all object actions which are necessary to synchronize files.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a user
&lt;/h2&gt;

&lt;p&gt;Now that we have a policy, we need to assign it to a new user created specifically to the Gitlab access, this way we can revoke the access without compromise our main user. &lt;/p&gt;

&lt;p&gt;On IAM page, add a new user with &lt;strong&gt;&lt;em&gt;Programmatic Access&lt;/em&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;em&gt;Attach existing policies directly&lt;/em&gt;&lt;/strong&gt;. A list with a search bar will be shown for you, on this search bar you will type our policy name and add it to the user. After that, you can skip the next step and an &lt;strong&gt;&lt;em&gt;Access Key ID&lt;/em&gt;&lt;/strong&gt; and a &lt;strong&gt;&lt;em&gt;Secret access key&lt;/em&gt;&lt;/strong&gt; will be generated. Save those keys on a temporary file.&lt;/p&gt;

&lt;h1&gt;
  
  
  Continuous delivery
&lt;/h1&gt;

&lt;p&gt;The idea here is to build your Hugo website and send it to your s3 bucket when a new commit would be pushed to Gitlab.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gitlab CI/CD
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Setting the aws access key&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Inside your repository on Gitlab go to &lt;strong&gt;Settings &amp;gt; CI/CD &amp;gt; Variables&lt;/strong&gt; and create two new variables:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fwww.mandax.com.br%2Fimages%2Fpost1_keys.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fwww.mandax.com.br%2Fimages%2Fpost1_keys.jpg" alt="Gitlab pipeline" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;AWS_ACCESS_KEY_ID&lt;/strong&gt; with the access key id as value&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AWS_SECRET_ACCESS_KEY&lt;/strong&gt; with the secret key as value.&lt;/li&gt;
&lt;li&gt;Save it&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you are asking why not to put these keys inside the project or the deployment script, it's just to not expose them on the code and committing sensitive data like this is not recommended, because depending on the structure of the project and the team that will access the repository, you can leak the key. On the worst case scenario, the project will be using the administrator key and it will grant full access for who's found the keys.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuring CI/CD
&lt;/h2&gt;

&lt;p&gt;Gitlab is smart, and it will look for instructions inside our repository that can trigger the pipeline automatically, this file’s name is &lt;code&gt;.gitlab-ci.yml&lt;/code&gt;. Let’s create this file and give it two simple instructions, one for build Hugo website and other to synchronize the built files on the s3 bucket.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;.gitlab-ci.yml&lt;/em&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="na"&gt;stages&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&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;cache&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;build&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;orus/hugo-builder:latest&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;build&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;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="s"&gt;git submodule sync --recursive&lt;/span&gt;
       &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;git submodule update --init --recursive&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;hugo&lt;/span&gt;

    &lt;span class="na"&gt;deploy&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;xueshanf/awscli:latest&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;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;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;aws s3 sync public s3://&amp;lt;your-bucket-name&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Quick explaination
&lt;/h3&gt;

&lt;p&gt;The first service &lt;code&gt;build&lt;/code&gt; will use the docker image &lt;code&gt;orus/hugo-builder:latest&lt;/code&gt; that contains a version of the Hugo that will be used to build our project. This service will be only triggered when some commit is pushed to the &lt;em&gt;master&lt;/em&gt; branch and before it will run a script that will clone the submodules inside the container. Remember that the Hugo theme is a submodule so if we just clone the repository, the submodule will not be present and the Hugo build will use the default theme or fail to build.&lt;/p&gt;

&lt;p&gt;The second service &lt;code&gt;deploy&lt;/code&gt; will synchronize the built files to our s3 bucket and don’t forget to replace the &lt;code&gt;&amp;lt;your-bucket-name&amp;gt;&lt;/code&gt; with your bucket’s name.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fwww.mandax.com.br%2Fimages%2Fpost1_pipeline.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fwww.mandax.com.br%2Fimages%2Fpost1_pipeline.jpg" alt="Gitlab pipeline" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  That’s it
&lt;/h1&gt;

&lt;p&gt;Now to deploy a new blog post, we just need to push it to the master branch and this concept can be applied on a bunch of different ways we can extrapolate it and add more steps to our pipeline, including unit tests and a lot of things.&lt;/p&gt;

&lt;p&gt;I think this can be a good solution for a development company to deploy static pages efficiently without any manual effort, just automatically and safe.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fx8w2u1ypuexrzmqzxwqm.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fx8w2u1ypuexrzmqzxwqm.gif" alt="Yeah, nice" width="480" height="464"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  References
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://gohugo.io/" rel="noopener noreferrer"&gt;Go Hugo&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://docs.gitlab.com/ee/ci/" rel="noopener noreferrer"&gt;Gitlab Ci docs&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://www.markdownguide.org/" rel="noopener noreferrer"&gt;Markdown Guide&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html" rel="noopener noreferrer"&gt;Aws IAM Policies Guide&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://docs.aws.amazon.com/AmazonS3/latest/dev/WebsiteHosting.html" rel="noopener noreferrer"&gt;Aws S3 web hosting&lt;/a&gt;  &lt;/p&gt;

&lt;h1&gt;
  
  
  Recommendations
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://docs.gitlab.com/ee/ci/pipelines.html" rel="noopener noreferrer"&gt;Gitlab pipeline docs&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://www.docker.com/resources/what-container" rel="noopener noreferrer"&gt;Docker&lt;/a&gt;&lt;/p&gt;

</description>
      <category>hugo</category>
      <category>aws</category>
      <category>gitlab</category>
      <category>pipeline</category>
    </item>
  </channel>
</rss>
