Simple Angular CI/CD pipeline with GitLab & AWS

In this tutorial, I will show you how to set up a simple CI/CD pipeline that compiles code on GitLab and then deploys to AWS EC2 via AWS CodeDeploy. This tutorial assumes:

  1. You have a working EC2 Ubuntu instance set up with a web server such as Nginx or Apache running and configured. 
  2. You have an existing code repository hosting an Angular project on GitLab.

Technologies Used: 

  • Angular 7
  • Gitlab CI/CD
  • AWS S3
  • AWS CodeDeploy
  • AWS EC2 Ubuntu 18.04 LTS

I’ve made a start project that I will be referencing throughout this project on Github will all the files you need already built in. Check it out here!

Step 1 – Create an S3 to AWS CodeDeploy Pipeline

I really don’t like dropping links in tutorials like this, however, for the sake of not re-writing Amazon’s documentation, I will have to tell you to follow all instructions in the tutorial in the link below. Only once you finished the tutorial will you be able to continue with the rest of this tutorial. Once you’re done with Amazon’s tutorial, you will have a CD pipeline ready to go waiting for GitLab to send the code.

https://docs.aws.amazon.com/codepipeline/latest/userguide/tutorials-simple-s3.html

If you have successfully completed the above tutorial, any changes pushed to your S3 bucket will be deployed immediately to your EC2 instance. Then steps below will show you how to upload your production bundle to S3 from Gitlab to complete the CI/CD pipeline.

Step 2 – Create an appspec.yml 

Welcome back! The first thing we’ll have to do is create an appspec.yml file in the src/ folder of our project. The appspec.yml will tell AWS CodeDeploy to deploy your code in a specific file directory on the server – in our case, it’s the /var/www/ directory. 

version: 0.0
os: linux
files:
  - source: ./
    destination: /var/www/

Then we have to tell angular to include this file as an asset so it stays preserved during the production build. To do this, we edit the assets block in our angular.json file to include "src/appspec.yml":

...
"tsConfig": "src/tsconfig.app.json",
            "assets": [
              "src/favicon.ico",
              "src/assets",
              "src/manifest.json",
              "src/appspec.yml"
            ],
            "styles": [
...

Step 3 – Create .gitlab-ci.yml

Gitlab offers a continuous integration service if you add a

.gitlab-ci.yml

file to the root directory fo your code repository. I’ve provided a sample .gitlab-ci.yml file as seen in example Github project. Please be sure to update the group name and repository name for your own project. If you copy this code please be sure to use your own repository name.

image: node:10

stages:
  - build
  - deploy

build:
  stage: 'build'
  script:
    - apt update
    - apt-get install -y nodejs
    - npm install -y npm@6.11.0
    - nodejs -v
    - npm -v
    - ls -la -F
    - npm ci
    - npx ng build --prod
  cache:
    paths:
      - node_modules/
  artifacts:
    when: on_success
    name: '$CI_JOB_NAME-$CI_COMMIT_REF_NAME'
    paths:
      - dist/angular-gitlab-ci-cd-example/
  only:
    - dev
    - master

deploy:
  stage: 'deploy'
  environment:
    name: production
  script:
    - apt update
    - apt install -y software-properties-common
    - apt install -y python-dev
    - apt install -y python-pip
    - pip install awscli
    - aws configure set aws_access_key_id $AWS_ACCESS_KEY_ID
    - aws configure set aws_secret_access_key $AWS_SECRET_ACCESS_KEY
    - aws configure set region us-east-1
    - ls -la -F
    - mv dist/angular-gitlab-ci-cd-example/appspec.yml dist/
    - cd dist
    - ls -al -F
    - cd ..
    - aws deploy push --application-name angular-gitlab-ci-cd-example --s3-location $AWS_S3_LOCATION --ignore-hidden-files --source dist
  only:
    - master

If you commit to your master branch with this file in the root directory of your project, a CI pipeline will initiate with two steps outlined line-by-line below:

The Build Stage

1.Update the packages in the node:10 Docker container

- apt update

2. Install node & npm

- apt-get install -y nodejs
- npm install -y npm@6.11.0
- nodejs -v
- npm -v

3. Run npm install

- npm install

4. Build the production bundle of Angular using the local cli

- npx ng build --prod

6. Tell GitLab to cache your node_modules so that your project builds faster next time around

cache: 
    paths: 
      - node_modules/

7. This code block creates a build artifact that will be passed onto the next stage in the pipeline if all operations in the container run without error. In the case of Angular7, I’m passing the created dist/ directory to the next stage so that GitLab can send it to AWS to be deployed

  artifacts: 
    when: on_success    
    name: "$CI_JOB_NAME-$CI_COMMIT_REF_NAME"
    paths: 
      - dist/angular-gitlab-ci-cd-example/

8. This keyword tells GitLab only to run this stage when a commit is pushed to either the master and dev branches. You can customize any stage to run a specific set of branched or all branches if that’s what you need. 

  only:
    - dev
    - master

The Deploy Stage

1. Update the packages on the node:10 Docker image, install the python libraries needed for AWS CLI and then install the AWS CLI.

script: 
    - apt update
    - apt install -y software-properties-common
    - apt install -y python-dev  
    - apt install -y python-pip
    - pip install awscli

2. Navigate to your CI/CD settings in GitLab and add the following variables for your $AWS_ACCESS_KEY_ID and $AWS_SECRET_ACCESS_KEY from the CodeDeploy IAM User you created earlier from following the AWS tutorial in Step 1. You should also include the $AWS_S3_LOCATION as a CI/CD variable as well in the following format:

s3://your-bucket-name/your-bundle-name.zip

The <key> will be by the same name as the zip created from the build stage.

3. In this step, we are configuring the AWS CLI with the IAM Credentials of a user with the correct CodePipeline policies attached.

    - aws configure set aws_access_key_id $AWS_ACCESS_KEY_ID
    - aws configure set aws_secret_access_key $AWS_SECRET_ACCESS_KEY
    - aws configure set region us-east-1

4. Remember from step 1 how we made sure the appspec.yml was preserved in the dist/ production bundle? Well, now we have to move it out it to the same directory level as the dist/ folder so that it sits on the same level as the dist/ folder. We have to do this to make the appspec.yml visible to AWS. If we do not do this, the AWS CLI will throw an error stating that it cannot find the appspec.yml file in the next step.

- mv dist/angular-gitlab-ci-cd-example/appspec.yml dist/
- cd dist
- cd .. 

5. Use the AWS CLI to deploy the dist/ bundle to AWS S3

 - aws deploy push --application-name angular-gitlab-ci-cd-example --s3-location $AWS_S3_LOCATION --ignore-hidden-files --source dist
only:
    - master

You’re Done!

Once you push your code to the master branch, navigate to the CI/CD pipeline and watch your code being built. Once GitLab is done building the production bundle, it will send it to AWS S3, which in turn will be deployed onto your live server moments later. I would love to hear your feedback on how I can improve this simple pipeline. 

4 Simple Things To Make Your Personal Website More Aesthetic

The purpose of this article is to highlight some small adjustments you can make to your personal site that will make a huge difference in usability and aesthetics. You don’t need to be an expert web designer or developer to make these changes. I’ve written this article after reviewing 100+ personal websites across the web which were custom built, WordPress, Square Space, etc. sites

1. Standardize your typography

Creating a standard typography for your site will make it easier for your users to recognize if the text on the page represents links/anchor tags, paragraph text, annotations, titles, and navigation links. Setting a standard typography means that the font and style used for paragraphs should be the same on every page of your application. (i.e. All paragraph text will be of font size 16px in Helvetica-Neue font. All text contained within buttons will be uppercase size 14px font.). That being said, all text with the same meaning or function should have the same font and text style.

Here is a simple typography generated via
Type Scale

type-scale

The folks over at Material Design also have a detailed typography scale you can use for reference.

2. Color scheme

For those who want to create a more aesthetically pleasing experience while users navigate your site, it may be worth spending a few minutes to create a matching color scheme for your website. I use often coolors.co to generate color schemes for my website builds.

Screenshot from coolors.co:

coolorsco

After picking a color scheme make sure you’re consistently making sure all your elements of the same function have the same styles. (i.e. All button on your page are green with white text which. Once your user sees this button once they will recognize all other green blobs with white on the page as buttons.)

3. Set max content width

All content on the page should be kept within a certain max with. When is last time you were on a web page on your desktop and your eyes had to move from the left side of the screen all the way to the right side of the screen to read a paragraph?

max-content

All content should be focused in one section so that it’s easier for a user to read.

4. Favicon

For those of you building a personal brand, I think having a favicon on your site will make you look that much more official and serious. Not having a favicon on your web page may make your personal site look incomplete and give the impression that it’s still under construction.

no-favicon

5 Atom packages that will speed up your workflow

The purpose of this article is to share 5 Atom packages that I use constantly that have sped up my workflow. Let’s start!

atom-beautify

atom-beautify on atom packages

With atom-beautify you never have to worry making sure your code is perfectly indented throughout the entire page. By hitting a designated set of hotkeys this package will take you unformatted code and indent it perfectly as if you spend the next 15 minutes indenting it yourself. The creators of this project made beautifiers for all types of code formats and languages such as JS, ESLint, Nginx, Vue, and many more.

autoclose-html

autoclose-html on atom packages
As you can probably infer from the name of the of the package, autoclose-html will automatically insert the closing HTML tag after you close the opening tag.

emmet

emmet on atom packages

emmet has had the largest impact on speeding up my web development workflow. Generating HTML code blocks has never been easier with the set of hotkey shortcuts this package comes pre-packaged with. For those who use a front-end framework like Bootstrap4 are familiar with writing the following code:

Screen Shot 2018-10-08 at 1.49.39 PM

For some of us, this code becomes muscle memory at some point. However, with emmet we can simply write the following:

div.row>div.col*3

and hit tab on the keyboard and generate the same code above.

emmet hotkey cheat sheet

minimap

minimap on atom packages

minimap generates a map of all the code in your open document/script file where you can quickly navigate to any point in your open source file no time at all. This is a huge step up from using a combination Ctrl + F and memory to jump between lines of code.

platformio-ide-terminal

platformio-ide-terminal on atom packages

This package allows you to open up multiple terminal instances in Atom in your current working directly. This is very convenient since you don’t have to open up another application to access the terminal.

Productivity as a DIY project

Guest Author: Mario Villacres

As I was wrapping up my time at Fullstack Academy, the future seemed bright. I had an in-demand skill set in my arsenal and after three months of drilling algorithms and learning best practices in web development, landing a position as a web developer was all but guaranteed.

And although my time in the classroom was done, I continued to get my money’s worth from Fullstack. I was assigned a career counselor who would continue to help me in my efforts to break into the world of tech, whether it be mock interviews or salary negotiation tips.

In order to make it easier for her to keep track of where I stood in the interview process with a given company, she had set up an account on Asana for me to record my progress. After trying Asana for a week, however, I was not a fan. This was not my first project management tool — I’ve used both Trello and Todoist extensively — and Asana felt cluttered by comparison.

I shared my gripes with my career counselor, she said I could simply keep her in the loop via Slack. Through this minor experience, however, I came to realize how much time I had been wasting switching between multiple services, which totally defeats the purpose of “productivity” apps.

Seeking a single source of productivity

Rather than have all my projects and tasks splintered across multiple services, I decided to consolidate all my projects onto a single platform. The only issue was which one to use.

Trello’s kanban boards were great for large-scale projects, but left much to be desired for one-off tasks (e.g. “Buy milk today”). On the other hand, Todoist’s single stream of tasks made it difficult to visualize workflow. I sought out other services that might have been a better compromise, but each service I sought out came with its own off-putting limitations (oftentimes it was the price tag).

Seeking a single source of productivity

It seems silly in retrospect. Here I was in search of a web app that would fulfill my particular needs, forgetting for a moment that I had just spent the past 3 months developing the skills I would need to build it myself! And so began my quest to build my perfect web app.

The building of Dharana

I chose the name Dharana both in reference to Asana (as both words refer to concepts from the Eight Limbs of Yoga) and as a way to describe what would be the experience of using my app — the word dharana in Sanskrit has several related meanings, including “a collection of the mind” and “uninterrupted focus.”

Tools Used

I was delighted to find out that Todoist was built with several of the same tools I had learned at Fullstack, and so I began building my app with a similar structure, adding my own twists along the way. Ultimately, Dharana’s tech stack was the following:

  • React on the front end, as each task and kanban list could easily be thought of as components
  • Redux in order to allow tasks to appear under various filtered/queried views (one of my favorite features of Todoist)
  • Node and Express on the back end for their flexibility
  • PostgreSQL as the database as the data easily lent itself to a relational structure

New faces, new influences

Anybody that has been job hunting within the past few years will tell you that it is simply not enough to get your resume circulated to the right people, your reputation also needs to make the rounds.

It’s for this reason that I began attending meetups almost daily since leaving Fullstack. One particular meetup group that I became fond of was the React NYC meetup. Every two weeks, they bring in some of the best professionals in the tech industry to give a presentation on how their companies go about using React in their online offerings. Each time I attend a React NYC event, I walk away learning something new and feeling like I’ve better refined my understanding of contemporary best practices on the front end.

Whenever I learned something that I felt would improve the experience of Dharana, I would spend the time to refactor the project; I usually ended up extremely satisfied by the results. Slowly, I began approaching my building of Dharana less as an end goal, and more as an open-ended exploration.

What’s next for Dharana?

While the current culture in tech dictates that developers must monetize everything under the sun, I’m in no rush to make Dharana into a full-blown business.

I have no doubt that Dharana could be a tool that several people might find useful in their daily lives, but for now, I’m very much content with Dharana being something that’s just for me.

Link to Mario’s Original Post on Medium