<repo_name>kevinmcmahon/bikeracks<file_sep>/aws/lib/StaticWebsiteStack.ts
import cdk = require('@aws-cdk/core');
import {
  CloudFrontWebDistribution,
  CloudFrontWebDistributionProps,
  OriginAccessIdentity,
} from '@aws-cdk/aws-cloudfront'
import { Bucket } from '@aws-cdk/aws-s3';
import { BucketDeployment, Source } from '@aws-cdk/aws-s3-deployment';
import * as semver from 'semver';

export class StaticWebsiteStack extends cdk.Stack {
  constructor(scope: cdk.App, id: string, staticWebsiteConfig: IStaticWebsiteProps) {
    super(scope, id, undefined);

    const resourcePrefix = staticWebsiteConfig.resourcePrefix;
    const deploymentVersion = semver.inc(staticWebsiteConfig.deploymentVersion, 'patch') || '1.0.0';
    const originPath = deploymentVersion.replace(/\./g, '_');

    const sourceBucket = new Bucket(this, `S3BucketForWebsite`, {
      websiteIndexDocument: staticWebsiteConfig.indexDocument || 'index.html',
      bucketName: `${resourcePrefix}-website`,
    });

    new BucketDeployment(this, 'DeployWebsite', {
      sources: [Source.asset(staticWebsiteConfig.websiteDistPath)],
      destinationBucket: sourceBucket,
      destinationKeyPrefix: originPath,
    });

    const oai = new OriginAccessIdentity(this, `CloudFrontOIA`,{
      comment: `OAI for ${resourcePrefix} website.`
    });
    sourceBucket.grantRead(oai);
    
    let cloudFrontDistProps: CloudFrontWebDistributionProps;

    if (staticWebsiteConfig.certificateArn) {
      cloudFrontDistProps = {
        originConfigs: [
          {
            s3OriginSource: {
              s3BucketSource: sourceBucket,
              originAccessIdentity: oai
            },
            behaviors: [ {isDefaultBehavior: true}],
            originPath: `/${originPath}`,
          }
        ],
        aliasConfiguration: {
          acmCertRef: staticWebsiteConfig.certificateArn,
          names: staticWebsiteConfig.domainNames || []
        }
      };
    } else {
      cloudFrontDistProps = {
        originConfigs: [
          {
            s3OriginSource: { s3BucketSource: sourceBucket },
            behaviors: [ {isDefaultBehavior: true}],
            originPath: `/${originPath}`,
          }
        ]
      };
    }

    new CloudFrontWebDistribution(this, `${resourcePrefix}-cloudfront`, cloudFrontDistProps);
  }
}

export interface IStaticWebsiteProps {
  websiteDistPath: string;
  deploymentVersion: string
  certificateArn?: string;
  domainNames?: Array<string>;
  resourcePrefix: string;
  indexDocument?: string;
}
<file_sep>/src/routes.js
import Vue from 'vue';
import Router from 'vue-router';
import RackDetail from '@/components/RackDetail';
import Search from '@/components/Search';
import Racks from '@/components/Racks';

Vue.use(Router);

export default new Router({
  mode: 'history',
  routes: [
    {
      path: '/',
      name: 'home',
      component: Search
    },
    {
      path: '/bikeracks',
      name: 'bikeracks',
      component: Racks
    },
    {
      path: '/bikeracks/:id',
      name: 'bikerackdetail',
      component: RackDetail
    }
  ]
});
<file_sep>/aws/lib/BikeRacksStaticWebsiteStack.ts
import cdk = require('@aws-cdk/core');
import { StaticWebsiteStack, IStaticWebsiteProps } from './StaticWebsiteStack';
const config = require('../config-cdk-bikeracks.json');

export class BikeRacksStaticWebsiteStack extends StaticWebsiteStack {
  constructor(scope: cdk.App, id: string ) {
    const props: IStaticWebsiteProps = {
      websiteDistPath: '../dist',
      deploymentVersion: '1.0.0',
      certificateArn: config.certificateArn,
      domainNames: [config.domainNames],
      resourcePrefix: config.resourcePrefix,
      indexDocument: 'index.html',
    };

    super(scope, id, props);
  }
}
<file_sep>/src/services/api.js
import axios from 'axios';
export default axios.create({
  baseURL: 'https://bh4i9yrgt9.execute-api.us-west-2.amazonaws.com/Prod/',
  timeout: 5000,
  headers: {
    'Content-Type': 'application/json'
  }
});
<file_sep>/README.md
# Chicago Bike Rack Locator

## What is the purpose of this Chicago Bike Rack Locator?

Find bike racks? More specifically though a toy app to play around with some data the City of Chicago publishes and PostGIS extensions for PostgresDB.

## Project setup

```
yarn install
```

### Compiles and hot-reloads for development
```
yarn serve
```

### Compiles and minifies for production
```
yarn build
```

### Lints and fixes files
```
yarn lint
```

## AWS CDK Stack

This project includes an AWS CDK Stack that can be used to easily deploy the site to AWS. A sample settings file has been provided (`config-cdk-bikeracks.json.example`). The certificateArn is optional but should be provided if the site will leverage AWS provided SSL certificates.

```
{
    "certificateArn": "YOUR_CERTIFICATE_ARN_HERE",
    "domainNames": "exampledomain.com",
    "resourcePrefix": "example-prefix"
}
```

### CDK Useful Commands

 * `yarn run build`   compile typescript to js
 * `yarn run watch`   watch for changes and compile
 * `cdk deploy`      deploy this stack to your default AWS account/region
 * `cdk diff`        compare deployed stack with current state
 * `cdk synth`       emits the synthesized CloudFormation template


### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).
<file_sep>/aws/bin/aws.ts
#!/usr/bin/env node
import cdk = require('@aws-cdk/core');
import { BikeRacksStaticWebsiteStack } from '../lib/BikeRacksStaticWebsiteStack';

const app = new cdk.App();
new BikeRacksStaticWebsiteStack(app, 'BikeRacksStaticWebsiteStack');
