Front-End Web & Mobile

Deploy a VueJS app with the Amplify Console using AWS CloudFormation

This article was written by Simon Thulbourn, Solutions Architect, AWS.

Developers and Operations people love automation. It gives them the power to introduce repeatability into their applications. The provisioning of infrastructure components is no different. Being able to create and manage resources through the use of AWS CloudFormation is a powerful way to run and rerun the same code to create resources in AWS across accounts.

Today, the Amplify Console launched support for AWS CloudFormation resources to give developers the ability to have reliable and repeatable access to the Amplify Console service. The Amplify Console offers three new resources:

  • AWS::Amplify::App
  • AWS::Amplify::Branch
  • AWS::Amplify::Domain

For newcomers, AWS Amplify Console provides a Git-based workflow to enable developers to build, deploy and host web application, whether it’s  Angular, ReactJS, VueJS or something else. These web applications can then consume APIs based on GraphQL or Serverless technologies, enabling fullstack serverless applications on AWS.

Working with CloudFormation

As an example, you’ll deploy the Todo example app from VueJS using Amplify Console and the new CloudFormation resources.

deploy the Todo example app from VueJS

You’ll start by forking the Vue repository on GitHub to your account. You have to fork the repository since Amplify Console will want to add a webhook and clone the repository for future builds.

You’ll also create a new personal access token on GitHub since you’ll need one to embed in the CloudFormation. You can read more about creating personal access tokens on GitHub’s website. The token will need the “repo” OAuth scope.

Note: Personal access tokens should be treated as a secret.

You can deploy the Todo application using the CloudFormation template at the end of this blog post. This CloudFormation template will create an Amplify Console App, Branch & Domain with a TLS certificate and an IAM role. To deploy the CloudFormation template, you can either use the AWS Console or the AWS CLI. In this example, we’re using the AWS CLI:

aws cloudformation deploy \
  --template-file ./template.yaml \
  --capabilities CAPABILITY_IAM \
  --parameter-overrides \
      OAuthToken=<GITHUB PERSONAL ACCESS TOKEN> \
      Repository=https://github.com/sthulb/vue \
      Domain=example.com \
  --stack-name TodoApp

After deploying the CloudFormation template, you need to go into the Amplify Console and trigger a build. The CloudFormation template can provision the resources, but can’t trigger a build since it creates resources but cannot trigger actions.

Diving deeper Into the template

The CloudFormation template needs to be updated to add your forked GitHub URL, and the Oauth token created above, and a custom domain you own. The AmplifyApp resource is your project definition – it is a collection of all the branches (or the AmplifyBranch resource) in your repository. The BuildSpec describes the settings used to build and deploy the branches in your app. In this example, we are deploying an example Todo app, which consists of four files. The Todo app expects a vue.min.js file to be available at: https://a1b2c3.amplifyapp.com/dist/vue.min.js; as a part of the buildspec we made sure the vue.min.js was in the deployment artifact, but not in the right location. We used the CustomRules property to rewrite the URL, transforming the URL from https://a1b2c3.amplifyapp.com/vue.min.js to https://a1b2c3.amplifyapp.com/dist/vue.min.js.

The AmplifyDomain resource allows you to connect your domain (https://yourdomain.com) or a subdomain (https://foo.yourdomain.com) so end users can start visiting your site.

Template

AWSTemplateFormatVersion: 2010-09-09

Parameters:
  Repository:
    Type: String
    Description: GitHub Repository URL

  OauthToken:
    Type: String
    Description: GitHub Repository URL
    NoEcho: true

  Domain:
    Type: String
    Description: Domain name to host application

Resources:
  AmplifyRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - amplify.amazonaws.com
            Action:
              - sts:AssumeRole
      Policies:
        - PolicyName: Amplify
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action: "amplify:*"
                Resource: "*"

  AmplifyApp:
    Type: "AWS::Amplify::App"
    Properties:
      Name: TodoApp
      Repository: !Ref Repository
      Description: VueJS Todo example app
      OauthToken: !Ref OauthToken
      BuildSpec: |-
        version: 0.1
        frontend:
          phases:
            build:
              commands:
                - cp dist/vue.min.js examples/todomvc/
          artifacts:
            baseDirectory: examples/todomvc/
            files:
              - '*'
      CustomRules:
        - Source: /dist/vue.min.js
          Target: /vue.min.js
          Status: '200'
      Tags:
        - Key: Name
          Value: Todo
      IAMServiceRole: !GetAtt AmplifyRole.Arn

  AmplifyBranch:
    Type: AWS::Amplify::Branch
    Properties:
      BranchName: master
      AppId: !GetAtt AmplifyApp.AppId
      Description: Master Branch
      EnableAutoBuild: true
      Tags:
        - Key: Name
          Value: todo-master
        - Key: Branch
          Value: master

  AmplifyDomain:
    Type: AWS::Amplify::Domain
    Properties:
      DomainName: !Ref Domain
      AppId: !GetAtt AmplifyApp.AppId
      SubDomainSettings:
        - Prefix: master
          BranchName: !GetAtt AmplifyBranch.BranchName

Outputs:
  DefaultDomain:
    Value: !GetAtt AmplifyApp.DefaultDomain

  MasterBranchUrl:
    Value: !Join [ ".", [ !GetAtt AmplifyBranch.BranchName, !GetAtt AmplifyDomain.DomainName ]]

Conclusion

To start using Amplify Console’s CloudFormation resources, visit the CloudFormation documentation page.

Acknowledgements

All of the code in the VueJS repository is licensed under the MIT license and property of Evan You and contributors.