<?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: Nikolay Bunev</title>
    <description>The latest articles on DEV Community by Nikolay Bunev (@justnick).</description>
    <link>https://dev.to/justnick</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%2F607249%2Ff6994af8-5b15-462d-b80a-51d40a93c81f.jpg</url>
      <title>DEV Community: Nikolay Bunev</title>
      <link>https://dev.to/justnick</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/justnick"/>
    <language>en</language>
    <item>
      <title>When to use Customer Managed KMS CMKs?</title>
      <dc:creator>Nikolay Bunev</dc:creator>
      <pubDate>Sun, 02 May 2021 20:16:30 +0000</pubDate>
      <link>https://dev.to/aws-builders/when-to-use-customer-managed-kms-cmks-3hgl</link>
      <guid>https://dev.to/aws-builders/when-to-use-customer-managed-kms-cmks-3hgl</guid>
      <description>&lt;h2&gt;
  
  
  Encrypt everything
&lt;/h2&gt;

&lt;p&gt;Encryption has been available from quite a while, but the Snowden revelations about the Global surveillance program back in 2013 started an informal movement to encrypt everything.&lt;/p&gt;

&lt;p&gt;AWS CTO Werner Vogels has been vocal about it on nearly every re:invent or AWS Summit in the last couple of years, and he is notorious with his encrypted T-shirts:&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%2Fupload.wikimedia.org%2Fwikipedia%2Fcommons%2Ff%2Fff%2F2019_-_Centre_Stage_-_Day_2_VJR22256_%252849024993977%2529.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%2Fupload.wikimedia.org%2Fwikipedia%2Fcommons%2Ff%2Fff%2F2019_-_Centre_Stage_-_Day_2_VJR22256_%252849024993977%2529.jpg" title="Werner Vogels - Encrypt Everything, Web Summit 2019, CC BY 2.0, Wikipedia Commons" alt="Werner Vogels - Encrypt Everything, Web Summit 2019, CC BY 2.0, Wikipedia Commons"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is AWS Key Management System (KMS)?
&lt;/h2&gt;

&lt;p&gt;I'm not going to retell the &lt;a href="https://docs.aws.amazon.com/kms/latest/developerguide/overview.html" rel="noopener noreferrer"&gt;AWS KMS documentation&lt;/a&gt; but we need to define it, before we can get into the details on when to choose the different key options.&lt;/p&gt;

&lt;p&gt;So, in general, KMS is the AWS managed service that helps you to easily create and control the keys you use for cryptographic operations. &lt;br&gt;
It provides a highly available solution for key generation, storage, management, and auditing for you to encrypt your data and control who has access to both the data and the encryption keys. &lt;/p&gt;

&lt;h2&gt;
  
  
  What's the difference between AWS-managed and customer-managed Custom Master Keys?
&lt;/h2&gt;

&lt;p&gt;In general, there are two main types of KMS Customer Master Keys (CMKs)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AWS Managed Keys - they are created automatically for you within your AWS account, whenever you enable or start using encryption for another AWS service or resource like S3. If you create an s3 bucket and enable encryption for it, AWS will automatically create the SSE-S3 KMS key in the account in which that bucket was created. This key is unique for the AWS account and region in which it has been created. And it could be used only by the respective service for which it was created.&lt;/li&gt;
&lt;li&gt;Customer Managed Keys - they are created at your request and can configured to better suite your use case&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We will outline the key differences in the table below &lt;a href="https://docs.aws.amazon.com/whitepapers/latest/kms-best-practices/aws-managed-and-customer-managed-cmks.html" rel="noopener noreferrer"&gt;(based on the table in the official docs}&lt;/a&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;CMKs&lt;/th&gt;
&lt;th&gt;AWS-managed&lt;/th&gt;
&lt;th&gt;Customer-managed&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;who creates the key&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;AWS creates the key on user's behalf&lt;/td&gt;
&lt;td&gt;explicitly generated by the customer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;who rotates the key&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;automatically rotated by AWS every three years&lt;/td&gt;
&lt;td&gt;Rotated every year if the customer enables rotation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;who deletes the key&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;can't be deleted&lt;/td&gt;
&lt;td&gt;can be deleted by the customer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;what's the scope of the key&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;limited to the service for which it was created&lt;/td&gt;
&lt;td&gt;can be used by multiple services, based on it's resource policy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;who manages the resource policy and controls the access to the key&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;AWS-managed, there is a policy but it can't be changed by the customer&lt;/td&gt;
&lt;td&gt;Customer managed via KMS/IAM policy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;who can use the key&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Every user os service that has access to KMS granted by it's IAM policy&lt;/td&gt;
&lt;td&gt;Every user or service that has access to KMS granted by it's IAM policy, unless it's forbidden by the KMS policy&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  When should we use Customer Managed KMS CMKs?
&lt;/h2&gt;

&lt;p&gt;So, based on the key differences outlined in the table above when we should opt for Customer-managed KMS key instead of AWS Managed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;if you want to have more granular control and limit the access to certain services and their data which you want to encrypt (as by default AWS-Managed keys are granting access to everyone within the account who has the neccesary IAM permissions to access KMS)&lt;/li&gt;
&lt;li&gt;if you want to grant access to encrypted service or its data from another service or AWS account (as with AWS managed keys you don't have access to the KMS key resource policy)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  In practice
&lt;/h2&gt;

&lt;p&gt;A common use case from the day-to-day practice is to have an S3 bucket in one AWS account to which you want to grant access from another AWS account or to another service within your account. &lt;br&gt;
If you need to comply with a security standard or you just want to listen to Werner Vogels and "encrypt everything" your only option would be to create a customer-managed AWS KMS key with which you can encrypt the whole S3 bucket or just the objects in it.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>kms</category>
      <category>cmk</category>
      <category>encryption</category>
    </item>
    <item>
      <title>Hosting your Hugo blog on AWS</title>
      <dc:creator>Nikolay Bunev</dc:creator>
      <pubDate>Sat, 10 Apr 2021 15:06:57 +0000</pubDate>
      <link>https://dev.to/aws-builders/hosting-your-hugo-blog-on-aws-ga8</link>
      <guid>https://dev.to/aws-builders/hosting-your-hugo-blog-on-aws-ga8</guid>
      <description>&lt;h2&gt;
  
  
  How it started
&lt;/h2&gt;

&lt;p&gt;When I decided to resurrect my personal blog a couple of months back I was pretty sure that I want something fast and small that won't require time to maintain.&lt;br&gt;
This narrowed down my choices to the static site frameworks like &lt;a href="https://gohugo.io/" rel="noopener noreferrer"&gt;Hugo&lt;/a&gt; and &lt;a href="https://jekyllrb.com/" rel="noopener noreferrer"&gt;Jekyll&lt;/a&gt;. &lt;br&gt;
As the latter is built on Ruby, which I'm not a big fan of, Hugo took the crown.&lt;/p&gt;

&lt;p&gt;With that sorted out, I had another decision to make. What I should use to host it?&lt;/p&gt;

&lt;p&gt;Once you pick up Hugo, you &lt;a href="https://gohugo.io/hosting-and-deployment/" rel="noopener noreferrer"&gt;have a lot of options&lt;/a&gt; - Netlify, Github Pages, Gitlab, &lt;a href="https://aws.amazon.com/amplify/" rel="noopener noreferrer"&gt;AWS Amplify&lt;/a&gt;, S3, you can even host it on an VPS instance &lt;a href="https://aws.amazon.com/lightsail/" rel="noopener noreferrer"&gt;LightSail&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As already mentioned I was looking for low maintenance effort and if possible cost effective solution too. &lt;br&gt;
As my repositories were going to be in Github, my shortlist was:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Github Pages (potentially combined with Github Actions, as I wanted to try them from awhile)&lt;/li&gt;
&lt;li&gt;AWS Amplify (for the same reason above stated above - I was looking into it for quite some time)&lt;/li&gt;
&lt;li&gt;Custom solution around &lt;a href="https://docs.aws.amazon.com/AmazonS3/latest/userguide/WebsiteHosting.html" rel="noopener noreferrer"&gt;S3 static hosting&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As I'm using AWS for living in the last couple of years, I scratched the Github idea and did a quick Amplify test. &lt;a href="https://gohugo.io/hosting-and-deployment/hosting-on-aws-amplify/" rel="noopener noreferrer"&gt;Hugo docs on deploying to Amplify&lt;/a&gt; are a good start if you ar leaning down that path. &lt;br&gt;
There's also a nice &lt;a href="https://aws.amazon.com/blogs/devops/agile-website-delivery-with-hugo-and-aws-amplify/" rel="noopener noreferrer"&gt;AWS blog post combining Hugo with Cloud9 and Amplify&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;I played around with it, and it looks like a really nice service to build different websites or applications with support for a lot of frameworks, but as actually pointed out in Amplify documentation itself it's aiming to help frontend developers.&lt;br&gt;
And as I'm an infra guy, it was a bit more developer-centric for my taste.&lt;/p&gt;
&lt;h2&gt;
  
  
  How it looks like
&lt;/h2&gt;

&lt;p&gt;With that settled, my solution started to take more shape and in the end this is how it looks like:&lt;br&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%2F8t4xxop8ux86vs1iyk89.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%2F8t4xxop8ux86vs1iyk89.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I have two Github repositories - one holding the terraform code for the blog infrastructure, and another one for the actual blog content created with Hugo.&lt;br&gt;
Both repositories have webhooks that are starting two AWS CodeBuild projects upon push to the main branch - one applying the terraform code and another that's publishing the blog content to my public S3 bucket.&lt;/p&gt;

&lt;p&gt;The S3 bucket in question has an Amazon CloudFront distribution in front itself and an SSL certificate provisioned from AWS Certificate Manager (ACM). End users are resolving the website address via Route53, where we have a public hosted zone with a record for the CloudFront distribution.&lt;/p&gt;
&lt;h2&gt;
  
  
  Terraform it all
&lt;/h2&gt;

&lt;p&gt;As already pointed out all this is created as Infrastructure as Code (IaC) with &lt;a href="https://www.terraform.io/" rel="noopener noreferrer"&gt;terraform&lt;/a&gt;.&lt;br&gt;
I should mention that I took a shortcut here and instead of writing my own code to do the task I went up using &lt;a href="https://nicholasarmstrong.com/2020/05/https-static-site-hugo-terraform/" rel="noopener noreferrer"&gt;Nickolas Armstrong's&lt;/a&gt; code, with a few changes some additions from me. If you are starting from scratch his &lt;a href="(https://github.com/ndrarmstrong/hugo-terraform-aws)"&gt;repo&lt;/a&gt; is quite useful and could be used as is. &lt;br&gt;
However, I already had a state bucket with encryption and logging enabled, so I haven't used that part of the code.&lt;/p&gt;

&lt;p&gt;In addition, in his blog post he is doing the certificate validation and the Route53 record manually, so I wrote that piece on my own. &lt;br&gt;
My acm.tf looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ACM Certificate&lt;/span&gt;
&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_acm_certificate"&lt;/span&gt; &lt;span class="s2"&gt;"blog"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;provider&lt;/span&gt;          &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;us-east-1&lt;/span&gt;
  &lt;span class="nx"&gt;domain_name&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;blog_domain_name&lt;/span&gt;
  &lt;span class="nx"&gt;validation_method&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"DNS"&lt;/span&gt;

  &lt;span class="nx"&gt;lifecycle&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;create_before_destroy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_route53_record"&lt;/span&gt; &lt;span class="s2"&gt;"blog_cert"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;for_each&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;dvo&lt;/span&gt; &lt;span class="nx"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;aws_acm_certificate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;blog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;domain_validation_options&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dvo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;domain_name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;name&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;dvo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resource_record_name&lt;/span&gt;
    &lt;span class="nx"&gt;record&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;dvo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resource_record_value&lt;/span&gt;
    &lt;span class="nx"&gt;type&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;dvo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resource_record_type&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;allow_overwrite&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;            &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;each&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
  &lt;span class="nx"&gt;records&lt;/span&gt;         &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;each&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;record&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="nx"&gt;ttl&lt;/span&gt;             &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt;            &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;each&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;
  &lt;span class="nx"&gt;zone_id&lt;/span&gt;         &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;terraform_remote_state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bootstrap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;outputs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;route53_hosted_zone_id&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_acm_certificate_validation"&lt;/span&gt; &lt;span class="s2"&gt;"blog_cert"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;provider&lt;/span&gt;          &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;us-east-1&lt;/span&gt;
  &lt;span class="nx"&gt;certificate_arn&lt;/span&gt;         &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_acm_certificate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;blog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;arn&lt;/span&gt;
  &lt;span class="nx"&gt;validation_record_fqdns&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;record&lt;/span&gt; &lt;span class="nx"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;aws_route53_record&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;blog_cert&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;record&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fqdn&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I have also added this snippet to the cloudfront.tf file in order to create the Route53 record for the CloudFront distribution with terraform too:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;resource "aws_route53_record" "blog" {
  zone_id         = data.terraform_remote_state.bootstrap.outputs.route53_hosted_zone_id
  name    = var.blog_name
  type    = "A"

  alias {
    name                   = aws_cloudfront_distribution.site.domain_name
    zone_id                = aws_cloudfront_distribution.site.hosted_zone_id
    evaluate_target_health = false
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Let's deploy it automatically
&lt;/h2&gt;

&lt;p&gt;So far so good. &lt;br&gt;
If you have combined my blog post with the one from Nicholas you should have a running Hugo site by now.&lt;/p&gt;

&lt;p&gt;However, as visible in my solution diagram I wanted to have automatic blog posts creation once I push to my blog content repository.&lt;/p&gt;

&lt;p&gt;In order to do so, we mainly need three things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;create a &lt;a href="https://docs.aws.amazon.com/codebuild/latest/userguide/access-tokens.html" rel="noopener noreferrer"&gt;CodeBuild project with a Github source repository provider (this requires authentication to GitHub)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/codebuild/latest/userguide/github-webhook.html" rel="noopener noreferrer"&gt;A webhook to trigger the CodeBuild project automatically&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;provide a set of instructions to the the CodeBuild project (by defining a set of command in a &lt;a href="https://docs.aws.amazon.com/codebuild/latest/userguide/build-spec-ref.html" rel="noopener noreferrer"&gt;buildspec file&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;It should be noted that as pointed out in the &lt;a href="https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/codebuild_webhook" rel="noopener noreferrer"&gt;codebuild_webhook&lt;/a&gt; terraform resource documentation the webhook requires OAuth authorization from CodeBuild to Github, &lt;br&gt;
which could be done manually in the Console prior to the terraform deployment of the resource.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The terraform code snippet for the webhook looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_codebuild_webhook"&lt;/span&gt; &lt;span class="s2"&gt;"auto_update_blog"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;project_name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hugo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;codebuild_name&lt;/span&gt;

  &lt;span class="nx"&gt;filter_group&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;filter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;type&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"EVENT"&lt;/span&gt;
      &lt;span class="nx"&gt;pattern&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"PUSH"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;filter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;type&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"HEAD_REF"&lt;/span&gt;
      &lt;span class="nx"&gt;pattern&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"main"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;My buildspec.yml file has 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="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.2&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;parameter-store&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{}&lt;/span&gt;

&lt;span class="na"&gt;phases&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;install&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;commands&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 Install dependencies...&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;yum -y install git&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo Downloading Hugo ${HUGO_VERSION}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;wget -q https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_Linux-64bit.tar.gz&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo Extracting Hugo binary&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;tar -zxvf hugo_extended_${HUGO_VERSION}_Linux-64bit.tar.gz hugo&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mv hugo /usr/local/bin&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;rm -f hugo_extended_${HUGO_VERSION}_Linux-64bit.tar.gz&lt;/span&gt;
    &lt;span class="na"&gt;finally&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 Installation done&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;commands&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 Entering the build static content phase&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo Build started on `date`&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;cd $CODEBUILD_SRC_DIR&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;git submodule init&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;git submodule update --recursive&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/usr/local/bin/hugo&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ls -la public&lt;/span&gt;
    &lt;span class="na"&gt;finally&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 Building the static HTML files has finished&lt;/span&gt;
  &lt;span class="na"&gt;post_build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;commands&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 Entering the publish content phase&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/usr/local/bin/hugo deploy --maxDeletes -1 --invalidateCDN&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo Publishing has finished&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;files&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[]&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And voilla, the only thing that you need to do afterwards is to git add, git commit and git push - this is how this particular blog post ended up on the Internet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Additional links
&lt;/h2&gt;

&lt;p&gt;If you want to take a different approach, I would recommend the following blog posts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://nicholasarmstrong.com/2020/05/https-static-site-hugo-terraform/" rel="noopener noreferrer"&gt;Static hugo site with terraform&lt;/a&gt; by Nicholas Armstrong&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://bezdelev.com/hacking/hugo-aws-lambda-static-website-amazon-s3/" rel="noopener noreferrer"&gt;How to build a Hugo website with AWS Lambda&lt;/a&gt; by Ilya Bezdelev&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://neonmirrors.net/post/2020-05/cicd-for-hugo-on-aws/" rel="noopener noreferrer"&gt;Complete CI/CD for Hugo on AWS with Github Actions&lt;/a&gt; by Chip Zoller&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://lebureau.dev/deploying-ghost-3-0-to-aws-using-ec2-auto-scaling-rds-and-terraform-pt-1/" rel="noopener noreferrer"&gt;Deploying Ghost 3.0 t0 AWS with Auto Scaling, RDS and Terraform&lt;/a&gt; by my colleague and friend Florian Valéry&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>aws</category>
      <category>terraform</category>
      <category>hugo</category>
      <category>codebuild</category>
    </item>
  </channel>
</rss>
