Pages

Developing a highly scalable blog from scratch - Part III


Removing tedious tasks from our process. Starting a CI/CD pipeline.

Hey people, I'm thrilled to continue this series of articles, I've been getting good feedback, and I hope you keep asking, this way I can try to help you more.

Let's have a quick review of what I did previously:

  • Hosted a static index.html on S3 and made it public readable; Part I
  • Added a better interface using Vue.js; Part II


Ok, I did execute the same task twice, which means I need to automatize it. I'm talking about uploading the static files to the S3 bucket and to configure them to be publicly accessible, and now we also have the Vue.js build step. As I told you, I'm lazy. I don't want to execute the same tasks over and over again. I'll introduce the AWS CodeBuild and AWS CodePipeline.


We saw that Vue.js generates the required static files when we execute the build command:

yarn build
But we have some dependencies to be able to run this command as such:
  • NodeJS
  • Yarn
  • Vue.JS

With this in mind, let's explore the provided build tool on AWS. AWS CodeBuild allows us to run a multistep build process on ephemeral build machines. To start the configuration, you need to access your AWS console and search for the CodeBuild service. 


Now we can start configuring our build process:

  1. Click on the Create build project button, just on the right side of your screen;
  2. Provide a name for the project: blog-build ;
  3. Select the Source: In my case, I'm using CodeCommit to manage the source code, so it will be the Source for this build and the search for the branch that will be used to run the build; 

  4. Select the Environment: I'll use the Ubuntu Linux as recommended by AWS. You can get more information about which image you should use at Docker images for CodeBuild


  5. Still, in the Environment section, we will need to create or to select an existing IAM role to have the required privileges to execute this build process. I created a new IAM role since I didn't have any created before;

  6. I will use a Buildspec YAML file, so we can also versioning the build process and steps using the source control, I'll give more information about it next;

  7. Select No artifacts, in the artifacts section (we will handle the artifacts using the buildspec.yml configuration file)
  8. Now, the last item, Logs, I recommend you to select the optional CloudWatch logs option, with this you will be able to see and to search your build logs on CloudWatch.
  9. Click on Create build project.

Ok, at this moment, I have a potential build project for the blog system. Let's continue and create the pipeline, which will take care of build, generating the artifacts and deploy them to the S3 bucket.


On the AWS console left panel, you have the CodePipeline option, this is an exciting managed service from AWS. The AWS CodePipeline allows you to run multiple builds, create artifacts, and deploy them to various targets.

Let's get to it

  1. Click on the CodePipeline on the left panel;
  2. Click on the Create pipeline button, just on the right side of your screen;
  3. Provide a name for the pipeline project: blog-pipeline, the IAM Role will be automatically populated for you. This role will be created with all the required privileges to execute all the steps of the pipeline; 

  4. Select the Source: I know, it's an overlap with the build configuration, I've started from the build, but you can start from the pipeline; 

  5. For the build, select AWS CodeBuild and search for the building project we created before, or, if you started from the pipeline, now you should click on the Create project button, it will open a popup where you can make the same configurations we did on the CodeBuild steps;

  6. The last step is the deployment step, in this section, we will select Amazon S3 bucket as the provider, and we will search for the S3 bucket that we are using to publish our application. Small tip, select the Extract file before deploy option because all the artifacts (the Dist folder of or blog build) are zipped into a single Artifact.zip file;

  7. One last modification before we finish this pipeline configuration. Remember that every time we upload a file to the S3 bucket, we need to change its permissions to make it public readable? Here it is no different, but we can select an advanced option on the Deployment step to set the canned ACL for the uploaded files to be public-read, making them available for everyone; 

  8. Now review it and click on Create Pipeline;


Pretty cool, isn't it?


This means that now we have a fully configured pipeline that will be automatically triggered by any commits on the master branch, it will build our application and it will deploy it by uploading the artifacts into our S3 bucket.


We have one last thing to do yet. We need to create our buildspec.yml file. This is the one I've created.

version: 0.2
phases:
  install:
    runtime-versions:
      nodejs: 12
    commands:
      - echo Entered the install phase...
      - curl -o- -L https://yarnpkg.com/install.sh | bash
  pre_build:
    commands:
      - echo Entered the pre_build phase...
      - yarn global add @vue/cli
      - yarn install
  build:
    commands:
      - echo Entered the build phase...
      - yarn run build
artifacts:
  files:
    - '**/*'
    base-directory: dist

Let's look into every part of this file, and understand how it works, you can get more information from AWS here.


There are basically three root properties:

  • version: which defines the release of the spec file from AWS point of view. (at the moment I wrote this, the 0.2 is the latest released version)
  • phases: which is defined by four stages that we can use to run commands. The steps are installpre_buildbuild, and post_build in order of execution.
  • artifacts: this property holds the configuration that will be used to zip the output files and upload it to the build artifact S3 output bucket.


The build spec file has more properties that I'm not using, but it is interesting to check it out on the documentation AWS BuildSpec syntax.

Ok, we have dependencies to build our blog, node, yarn, and vue.js. First, as the AWS documentation states, we can specify our runtime on the buildspec.yml file, and we do it on the Install stage.

  install:
    runtime-versions:
      nodejs: 12
    commands:
      - echo Entered the install phase...
      - curl -o- -L https://yarnpkg.com/install.sh | bash

Nodejs is a dependency, but it is provided by the image that we selected on the build configuration. On the commands section, we finish installing the latest required application, Yarn using the curl command to download and install it. I've chosen to use this method of installation because it's not restricted by the Linux distribution you are running on the build agent.

curl -o- -L https://yarnpkg.com/install.sh | bash

On the Pre-Build stage, we will install Vue.JS and all the dependencies of our project.


  pre_build:
    commands:
      - echo Entered the pre_build phase...
      - yarn global add @vue/cli
      - yarn install

At this moment, we have all the dependencies to successfully build our application satisfied. Node, Yarn, and Vue.JS are installed, as well as all dependencies specified on our application's package.json file.


The next stage is the Build stage, which in our case is pretty simple, all we need to do is to run the build command.


  build:
    commands:
      - echo Entered the build phase...
      - yarn run build


The last stage, post_build, is not used because we don't have any other actions to do after running the build command.


The artifacts section defines how the build process will pack our output.


artifacts:
  files:
    - '**/*'
    base-directory: dist

The files property accepts a list of locations that will be included in the artifact zip file. I'm using '**/*', which means any recursive file found will be included in the output. The filter will be applied to the `base-directory` specified, dist. This configuration means that all the files and folders under the dist folder will be included in the generated artifact.


Our first test, let's commit and push this buildspec.yml file, it should trigger the whole pipeline and deploy the generated static files from the build process.


Some snapshots from this execution of the pipeline:





----------------------------
Related articles:

Loé Lobo

No comments:

Post a Comment