Archive · DevOps

Jenkins: Build an Angular UI and Deploy It to S3 in Every Region

One build, then a parallel deploy to regional buckets with region-specific API URLs.

1 min read

  • Jenkins 2.479 LTS
  • Angular 19
  • Amazon S3
  • CloudFront

A config.json.template holds placeholders:

{ "apiUrl": "${API_URL}", "region": "${REGION}" }

Jenkinsfile:

pipeline {
  agent { label 'node22' }
  stages {
    stage('Build') {
      steps {
        sh 'npm ci && npx ng build --configuration production'
        stash name: 'dist', includes: 'dist/**'
      }
    }
    stage('Deploy') {
      matrix {
        axes { axis { name 'REGION'; values 'ap-south-1', 'eu-west-1', 'us-east-1' } }
        stages {
          stage('Publish') {
            steps {
              unstash 'dist'
              withAWS(role: 'ui-deployer', roleAccount: '111122223333', region: "${REGION}") {
                script {
                  def urls = [ 'ap-south-1': 'https://api-in.example.com',
                               'eu-west-1': 'https://api-eu.example.com',
                               'us-east-1': 'https://api-us.example.com' ]
                  env.API_URL = urls[REGION]
                }
                sh """
                  envsubst < config.json.template > dist/browser/config.json
                  aws s3 sync dist/browser s3://acme-ui-$REGION --delete --exclude config.json
                  aws s3 cp dist/browser/config.json s3://acme-ui-$REGION/config.json --cache-control no-cache
                """
              }
            }
          }
        }
      }
    }
  }
}

Add aws cloudfront create-invalidation --paths "/index.html" "/config.json" per region. Use a role with s3:PutObject on those buckets only, and ask for approval before the production regions.