Skip to main content

Angular AWS Deployment

Introduction

Deploying Angular applications to the cloud is a crucial skill for modern web developers. Amazon Web Services (AWS) offers a robust, scalable infrastructure that's perfect for hosting Angular applications. This guide will walk you through the process of deploying your Angular app to AWS, using several services to create a production-ready environment with high availability, global content delivery, and automated deployments.

By the end of this tutorial, you'll understand how to:

  • Deploy an Angular app to AWS S3
  • Set up content delivery with CloudFront
  • Configure custom domains with Route 53
  • Implement CI/CD pipelines for automated deployments

Prerequisites

Before we begin, make sure you have:

  • An Angular application ready for deployment
  • Node.js and npm installed
  • AWS account with access credentials
  • AWS CLI installed and configured
  • Basic understanding of Angular and AWS concepts

Deploying Angular to AWS S3

Amazon S3 (Simple Storage Service) is perfect for hosting static websites like Angular applications.

Step 1: Build Your Angular Application

First, we need to create a production build of our Angular application:

bash
ng build --configuration production

This command compiles your Angular application into static files in the dist/ folder.

Step 2: Create an S3 Bucket

  1. Log in to the AWS Management Console
  2. Navigate to S3 and create a new bucket:
bash
aws s3 mb s3://your-angular-app-bucket-name
  1. Enable static website hosting for your bucket through the AWS console or with:
bash
aws s3 website s3://your-angular-app-bucket-name --index-document index.html --error-document index.html

Step 3: Configure Bucket Permissions

Create a bucket policy to make your content publicly accessible:

json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::your-angular-app-bucket-name/*"
}
]
}

Apply this policy to your bucket:

bash
aws s3api put-bucket-policy --bucket your-angular-app-bucket-name --policy file://bucket-policy.json

Step 4: Upload Your Application

Upload your compiled Angular app to the S3 bucket:

bash
aws s3 sync dist/your-angular-app-name s3://your-angular-app-bucket-name

At this point, your application is accessible via the S3 website endpoint, which looks like: http://your-angular-app-bucket-name.s3-website-us-east-1.amazonaws.com

Setting Up CloudFront Distribution

AWS CloudFront is a Content Delivery Network (CDN) that distributes your content globally for faster loading times.

Step 1: Create a CloudFront Distribution

  1. Go to the CloudFront service in the AWS Console
  2. Create a new distribution with these settings:
    • Origin Domain: Your S3 bucket website endpoint
    • Default root object: index.html
    • Viewer protocol policy: Redirect HTTP to HTTPS
    • Cache policy: Managed-CachingOptimized

Here's how you might do this with AWS CLI:

bash
aws cloudfront create-distribution \
--origin-domain-name your-angular-app-bucket-name.s3-website-us-east-1.amazonaws.com \
--default-root-object index.html \
--origins Id=S3Origin,DomainName=your-angular-app-bucket-name.s3-website-us-east-1.amazonaws.com

Step 2: Handle Angular Routing with CloudFront

Angular's client-side routing requires special handling. Create an error response to redirect 404s to index.html:

  1. Go to the Error Pages section in your CloudFront distribution
  2. Add a custom error response:
    • HTTP Error Code: 403
    • Response Page Path: /index.html
    • HTTP Response Code: 200

Configuring a Custom Domain with Route 53

To use your own domain name instead of the CloudFront URL:

Step 1: Register or Use an Existing Domain

If you don't have a domain, you can register one through Route 53 or another registrar.

Step 2: Create a Hosted Zone

bash
aws route53 create-hosted-zone --name yourdomain.com --caller-reference $(date +%s)

Step 3: Create an SSL Certificate

Using AWS Certificate Manager (ACM):

bash
aws acm request-certificate --domain-name yourdomain.com --validation-method DNS --subject-alternative-names www.yourdomain.com

Step 4: Update CloudFront Distribution

Add your custom domain and certificate to your CloudFront distribution:

bash
aws cloudfront update-distribution --id YOUR_DISTRIBUTION_ID --aliases Quantity=2,Items=[yourdomain.com,www.yourdomain.com] --viewer-certificate CertificateSource=acm,ACMCertificateArn=YOUR_CERTIFICATE_ARN,SSLSupportMethod=sni-only

Step 5: Create Route 53 Records

Create A records pointing to your CloudFront distribution:

bash
aws route53 change-resource-record-sets --hosted-zone-id YOUR_HOSTED_ZONE_ID --change-batch '{
"Changes": [
{
"Action": "CREATE",
"ResourceRecordSet": {
"Name": "yourdomain.com",
"Type": "A",
"AliasTarget": {
"HostedZoneId": "Z2FDTNDATAQYW2",
"DNSName": "YOUR_CLOUDFRONT_DOMAIN",
"EvaluateTargetHealth": false
}
}
}
]
}'

Setting Up CI/CD Pipeline for Automated Deployments

Let's automate the deployment process using AWS CodePipeline:

Step 1: Create an IAM Role

Create a role with permissions to access S3, CloudFront, and other necessary services.

Step 2: Create a CodeBuild Project

  1. Create a buildspec.yml file in your Angular project:
yaml
version: 0.2

phases:
install:
runtime-versions:
nodejs: 18
commands:
- npm install -g @angular/cli
- npm install
build:
commands:
- echo "Building Angular project..."
- ng build --configuration production
post_build:
commands:
- echo "Deploying to S3..."
- aws s3 sync ./dist/your-angular-app-name s3://your-angular-app-bucket-name --delete
- aws cloudfront create-invalidation --distribution-id YOUR_DISTRIBUTION_ID --paths "/*"

artifacts:
base-directory: './dist/your-angular-app-name'
files:
- '**/*'
  1. Set up a CodeBuild project in the AWS console:
    • Source: Your GitHub/BitBucket repository
    • Environment: Use the buildspec.yml from your repository
    • Service role: Use the IAM role created earlier

Step 3: Create a CodePipeline

Set up a pipeline that:

  1. Sources code from your repository
  2. Builds and tests using CodeBuild
  3. Deploys to S3 and invalidates CloudFront cache

Advanced Configuration

Handling Environment Variables

For different environments, create environment-specific configuration:

  1. Create environment files in your Angular project: environment.ts, environment.prod.ts, etc.
  2. Use them in your Angular application:
typescript
// environment.prod.ts
export const environment = {
production: true,
apiUrl: 'https://api.yourdomain.com/v1/'
};

// app.module.ts
import { environment } from '../environments/environment';

// Use environment.apiUrl where needed

Setting Up CORS

If your Angular app makes API calls, configure CORS in your API Gateway or backend service:

json
{
"AllowedHeaders": ["*"],
"AllowedMethods": ["GET", "POST", "PUT", "DELETE"],
"AllowedOrigins": ["https://yourdomain.com"]
}

Implementing CI/CD with GitHub Actions

As an alternative to AWS CodePipeline, you can use GitHub Actions:

yaml
name: Deploy to AWS

on:
push:
branches: [main]

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install dependencies
run: npm ci
- name: Build
run: npm run build
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1
- name: Deploy to S3
run: aws s3 sync ./dist/your-angular-app-name s3://your-angular-app-bucket-name --delete
- name: Invalidate CloudFront
run: aws cloudfront create-invalidation --distribution-id ${{ secrets.CLOUDFRONT_DISTRIBUTION_ID }} --paths "/*"

Real-World Example: Company Portfolio Website

Let's go through a real-world example of deploying a company portfolio Angular application to AWS.

The Application Structure

my-company-portfolio/
├── src/
│ ├── app/
│ │ ├── home/
│ │ ├── projects/
│ │ ├── contact/
│ │ └── app.component.ts
│ ├── assets/
│ └── environments/
│ ├── environment.ts
│ └── environment.prod.ts
├── angular.json
└── package.json

Deployment Process

  1. Build the application for production:
bash
ng build --configuration production
  1. Create an S3 bucket with a company-specific name:
bash
aws s3 mb s3://acme-company-portfolio
  1. Configure website hosting and permissions as shown earlier

  2. Create a CloudFront distribution pointing to your S3 bucket

  3. Set up your corporate domain in Route 53 (e.g., portfolio.acme-corp.com)

  4. Create a CI/CD pipeline that deploys when changes are pushed to the main branch

Considerations for this Real-World Scenario

  • SEO Optimization: Add server-side rendering with Angular Universal to improve SEO
  • Performance Monitoring: Integrate AWS CloudWatch for monitoring and alerts
  • Usage Analytics: Add Google Analytics or AWS Pinpoint to track user behavior
  • Secure Forms: For the contact form, integrate with AWS API Gateway and Lambda
  • Multiple Environments: Set up separate pipelines for staging and production

Common Issues and Solutions

Problem: Angular Routing 404 Errors

Solution: Configure CloudFront to redirect 404s to index.html as shown earlier.

Problem: Cached Content Not Updating

Solution: Add cache invalidation to your deployment script:

bash
aws cloudfront create-invalidation --distribution-id YOUR_DISTRIBUTION_ID --paths "/*"

Problem: Environment Variables Not Accessible

Solution: Make sure you're using Angular's environment.ts properly and building with the right configuration.

Summary

In this guide, we've covered how to deploy an Angular application to AWS using S3, CloudFront, Route 53, and automated CI/CD pipelines. This approach provides:

  • Scalable hosting through S3
  • Fast global content delivery via CloudFront
  • Custom domain management with Route 53
  • Automated deployments using CI/CD

By following these steps, you've created a production-ready environment for your Angular application that is fast, reliable, and easy to maintain.

Additional Resources

Exercises

  1. Deploy a simple Angular application to S3 and access it through the S3 website endpoint.
  2. Add CloudFront to your deployment and test the performance improvement.
  3. Set up a GitHub Actions workflow that automatically deploys your Angular app when you push changes.
  4. Configure multiple environments (dev, staging, prod) with different S3 buckets and CloudFront distributions.
  5. Implement server-side rendering with Angular Universal and deploy it to AWS Lambda and API Gateway.


If you spot any mistakes on this website, please let me know at feedback@compilenrun.com. I’d greatly appreciate your feedback! :)