How to Host a Static WebSite on S3?
In order to serve a static web site, we need a web server. AWS provides many different options to run a server but since we are Serverless Gurus, we are going to focus only on the serverless options available. S3 is an object storage service, which among other options, allows us to enable web site hosting on the bucket. This means that we don’t need to manage any server and that is exactly what we want.
If we are going to create a static website with vanilla HTML/CSS/JS we can just upload our files to S3. However, if we want to use one of the currently popular frameworks (Angular, React or Vue), then there is a build step required in between writing code and deploying to the bucket.
What is Continuous Integration (CI)?
CI is one of the most important stages in the software development release process. When using a distributed version control system like Git, every team member works on its own copy of the main source code. After the developer finishes working on the new feature or bug fix, those changes have to be merged into the main repository. Since source code is distributed, the risk of code conflicts and regressions is increased so we need to make sure that our code is tested well before it is integrated. On the other hand, we want this process to be done continuously as we are improving our application and therefore:
Continuous Integration (CI) is a development practice where developers’ working copies of the source code are integrated into a shared repository frequently, preferably several times a day.
What is Continuous Deployment (CD)?
Integrating source code into the main codebase is just a first step on the road to production. Continuous Deployment means that once the source code is integrated into the main repository it will be built and deployed to the environment. Continuous delivery is almost the same process except that it requires a manual approval step before production release.
Introducing AWS Developer Tools
Now that we know what CI/CD is, there is one important question that needs to be answered: how can we automate this process?
There are many tools created for this purpose like Jenkins, GitHub Actions, BitBucket pipelines… but today we are going to talk about AWS tools available and those tools will be serverless.
The software release process can be described as a series of steps taken from writing code until the application reaches the production stage. Our code flows through these steps. Every step tests or transforms the code shape until it becomes ready to use in the application. Therefore, we can describe this flow as code going through a pipeline.
AWS provides a service called CodePipeline which does exactly what we need. It connects various stages together and passes source code or artifacts between them.
If we look at the picture above, we will see an example of the standard pipeline with several stages (source, build, test… etc.). Every stage consists of one or more actions. One thing to note is that the number of stages is not fixed. This number highly depends on our requirements and can vary from project to project.
The example above presents a use case of CodePipeline for Continuous Deployment to the Staging environment and Continuous Delivery to the production environment (notice the manual approval step). This pipeline can be triggered by many different events.
We want to trigger our pipeline every time new source code is integrated (merged) into the development or master branch, then build and deploy the application to the test or production respectively. So how can we add our source code to the pipeline?
AWS CodeCommit is a fully-managed source control service that hosts secure Git-based repositories. We will use this service as our source stage in the pipeline. Note that even though we are using CodeCommit in this example — we don’t have to. We can trigger the pipeline from S3, GitHub, BitBucket, ECR as well as Lambda functions.
Now that we have our pipeline set with the source stage, we need to build our source and include that step into the pipeline. For that purpose, we will use the CodeBuild service. This is how our pipeline is going to look alike when we add the build step:
All this can be set using AWS console but what happens if we want to do it more than once, in other words, what if we want to use it on all our future projects? It is a very repetitive and error-prone process as we are going to configure the same things over and over again. In order to avoid this, we can create a CloudFormation template that allows us to deploy the same infrastructure for every project we start. Now let’s get our hands dirty.
What Will We Create?
- Test and Production S3 buckets with website hosting enabled
- Angular/Vue/React application using respected CLI
- CodeCommit repository
- CodeBuild projects with build specification for master and development branch
- CodePipelines for test and production
- Hello world lambda function that can be used as the backend
How Does it Work?
Our templates are located inside of resources folder in the repository.
repository.yml template will create CodeCommit repository. The repository name is taken from the Serverless Pro Dashboard parameters.
pipeline.yml and build.yml contains templates for CodePipeline and CodeBuild resource.
iam.yml and events.yml will create required roles and events to trigger pipeline when source code change happens on the master or development branch.
Frontend application will be auto-created based on the framework selection which is passed as a parameter to the bash script.
There are few prerequisites that we need to take care of before we start and those are:
- Clone ServerlessGuru templates repository
- Copy sls-frontend-with-cicd to your project folder
- Login to your Serverless Pro dashboard then create an app
- Go to the apps section, then click on your application name
- On the right side of the screen, click on the three dots, then click on settings. Click on your default profile and there you will see where you can add parameters.
- Create the following parameters:
- Update serverless.yml file app and org properties with your organization and application name
- run ./deploy.sh YOUR_REGION YOUR_AWS_PROFILE react|vue|angular from your terminal
Example: ./deploy us-east-1 default vue
What About the Backend?
There is an example hello world function inside of the functions folder. We can further expand this by creating more functions, or we can create more services that belong to this app with required functionalities.
Agile methods help developers move fast and iterate, but that comes with a price colloquially called “integration hell”. Modern software development is hard to imagine without setting up CI/CD pipelines to challenge this issue. In this article, we explained how to create a reusable serverless pipeline using AWS Developer Tools, Serverless framework, and IAC. No matter how big your team or project currently is, it will grow eventually. Setting up CI/CD is an essential foundation for any project. With AWS developer tools you can utilize serverless architecture and only care about release stages and your code without thinking about physical servers.