Skip to content

Commit

Permalink
Release v2.3.1
Browse files Browse the repository at this point in the history
  • Loading branch information
echo-bravo-yahoo committed Jan 21, 2019
2 parents 8df360b + f5792ef commit 5862d7a
Show file tree
Hide file tree
Showing 46 changed files with 1,461 additions and 317 deletions.
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,23 @@ This creates a cloudfront distribution in front of the S3 bucket serving the sit
If you chose `UseRoute53Nameservers=true`, after the deployment finishes, go to the Route53 console, find the nameservers for the hosted zone created by the deployment, and add those as the nameservers for your domain name through your registrar. The specifics of this process will vary by registrar.

If you chose `UseRoute53Nameservers=false`, instead point your nameservers at the cloudfront distribution's URL.

### Add custom content and brand the Developer Portal
See [Customization section](#customization)

### Add an approval workflow to register new users
See [Components section](#cognito-user-pool-confirmation-strategy-lambdacognito-user-pools-confirmation-strategy)

## Updating to a new version
The Developer Portal follows the semantic versioning scheme (major.minor.patch). Changes to the minor or patch version are backwards compatible so you should feel safe to get the latest version.

### To update a SAM deployment:
1. Get the latest version from GitHub (Clone/Pull/Download).
2. When deploying follow the same steps as previous and use the same values for the parameters. The only difference is passing in a new value for "-StaticAssetRebuildToken". You can use any string for this as long as it is different than previously used. If you followed the instructions above and it is the first time you're updating, you can use any non-empty string (default value is "").

### To update a SAR deployment
1. When deploying follow the same steps as previous and use the same values for the parameters. The only difference is passing in a new value for "-StaticAssetRebuildToken". You can use any string for this as long as it is different than previously used (default value is "defaultRebuildToken").

## Components

![Alt text](/images/highLevelDiagram.png?raw=true)
Expand Down
6 changes: 6 additions & 0 deletions README_SAR.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ The Serverless Developer Portal is an application that you use for developer eng
1. Choose the name of the stack (aws-serverless-repository-api-gateway-dev-portal is the default stack name).
1. Open the Outputs section. The URL for the developer portal is specified in the WebSiteURL property.

#### Updating to a new version
The Developer Portal follows the semantic versioning scheme (major.minor.patch). Changes to the minor or patch version are backwards compatible so you should feel safe to get the latest version.

To update:
1. When deploying follow the same steps as previous and use the same values for the parameters. The only difference is passing in a new value for "-StaticAssetRebuildToken". You can use any string for this as long as it is different than previously used (default value is "defaultRebuildToken").

#### Next steps
1. Publish an API on it for your customer to look at. Learn how to do that [here](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-developer-portal.html#apigateway-developer-portal-publish).
1. Customize, own, and brand the portal. Learn how to do that [here](https://github.com/awslabs/aws-api-gateway-developer-portal#customization).
Expand Down
228 changes: 208 additions & 20 deletions cloudformation/template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,16 @@ Parameters:
Description: The name for your Cognito Identity Pool.
Default: "DevPortalUserPool"

CognitoDomainNameOrPrefix:
Type: String
Description: The Domain Name (or Prefix) at which your Cognito Hosted UI is located. Omitting this value opts out of the Cognito Hosted UI.
Default: ''

# CognitoDomainAcmCertArn:
# Type: String
# Description: Doesn't yet do anything. Oh well.
# Default: ''

CustomDomainName:
Type: String
Description: Optionally provide a custom domain name associated with an ACM cert to create a developer portal at that domain name (provide with the format foo.bar.net). Leave blank to create a developer portal without a custom domain name. Standing up a developer portal stack with a custom domain name will take significantly longer than without.
Expand All @@ -87,7 +97,52 @@ Conditions:
UseCustomDomainName: !And [!Not [!Equals [!Ref CustomDomainName, '']], !Not [!Equals [!Ref CustomDomainNameAcmCertArn, '']]]
# the second clause is a copy of the UseCustomDomainName condition
# re-using it doesn't seem possible?
UseRoute53: !And [!Equals [!Ref UseRoute53Nameservers, 'true'], !And [!Not [!Equals [!Ref CustomDomainName, '']], !Not [!Equals [!Ref CustomDomainNameAcmCertArn, '']]]]
NoCustomDomainName: !Not [ !Condition UseCustomDomainName ]
UseRoute53: !And [!Equals [!Ref UseRoute53Nameservers, 'true'], !Condition UseCustomDomainName]
UseCognitoHostedUI: !Not [!Equals [!Ref CognitoDomainNameOrPrefix, '']]

Mappings:
# this information comes from these locations, and will need to be kept manually up to date:
# https://docs.aws.amazon.com/general/latest/gr/rande.html#s3_website_region_endpoints
# https://docs.aws.amazon.com/govcloud-us/latest/ug-west/using-govcloud-endpoints.html
# http://docs.amazonaws.cn/en_us/general/latest/gr/rande.html#cnnorth_region
RegionSpecificConfig:
us-east-2:
s3Url: '.s3-website.us-east-2.amazonaws.com'
us-east-1:
s3Url: '.s3-website-us-east-1.amazonaws.com'
us-west-1:
s3Url: '.s3-website-us-west-1.amazonaws.com'
us-west-2:
s3Url: '.s3-website-us-west-2.amazonaws.com'
ap-south-1:
s3Url: '.s3-website.ap-south-1.amazonaws.com'
ap-northeast-3:
s3Url: '.s3-website.ap-northeast-3.amazonaws.com'
ap-northeast-2:
s3Url: '.s3-website.ap-northeast-2.amazonaws.com'
ap-southeast-1:
s3Url: '.s3-website-ap-southeast-1.amazonaws.com'
ap-southeast-2:
s3Url: '.s3-website-ap-southeast-2.amazonaws.com'
ap-northeast-1:
s3Url: '.s3-website-ap-northeast-1.amazonaws.com'
ca-central-1:
s3Url: '.s3-website.ca-central-1.amazonaws.com'
cn-northwest-1:
s3Url: '.s3-website.cn-northwest-1.amazonaws.com.cn'
eu-central-1:
s3Url: '.s3-website.eu-central-1.amazonaws.com'
eu-west-1:
s3Url: '.s3-website-eu-west-1.amazonaws.com'
eu-west-2:
s3Url: '.s3-website.eu-west-2.amazonaws.com'
eu-west-3:
s3Url: '.s3-website.eu-west-3.amazonaws.com'
sa-east-1:
s3Url: '.s3-website-sa-east-1.amazonaws.com'
us-gov-west-1:
s3Url: '.s3-website-us-gov-west-1.amazonaws.com'

Mappings:
# this information comes from these locations, and will need to be kept manually up to date:
Expand Down Expand Up @@ -380,16 +435,7 @@ Resources:
BucketName: !Ref DevPortalSiteS3BucketName
WebsiteConfiguration:
IndexDocument: index.html
ErrorDocument: error.html
RoutingRules:
- RoutingRuleCondition:
HttpErrorCodeReturnedEquals: 403
RedirectRule:
HostName: !If
- UseCustomDomainName
- !Ref CustomDomainName
- !Join ['', [!Ref DevPortalSiteS3BucketName, !FindInMap ['RegionSpecificConfig', !Ref 'AWS::Region', 's3Url']]]
ReplaceKeyPrefixWith: '#!/'
ErrorDocument: index.html

ArtifactsS3Bucket:
Type: AWS::S3::Bucket
Expand Down Expand Up @@ -579,8 +625,7 @@ Resources:
- !Ref ArtifactsS3BucketName
- '/*'
- Effect: Allow
Action:
# scope this down
Action: # scope this down
- apigateway:*
Resource: '*'

Expand Down Expand Up @@ -801,7 +846,9 @@ Resources:
PreSignUp: !GetAtt CognitoUserPoolsConfirmationStrategyFunction.Arn
Policies:
PasswordPolicy:
MinimumLength: 8
MinimumLength: 12
RequireLowercase: true
RequireNumbers: true
Schema:
- AttributeDataType: String
Name: email
Expand All @@ -815,6 +862,123 @@ Resources:
GenerateSecret: false
RefreshTokenValidity: 30

# Cognito User Pool Custom Resource config
CognitoUserPoolClientSettingsBackingFnRole:
Type: 'AWS::IAM::Role'
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
-
Effect: Allow
Action: 'sts:AssumeRole'
Principal:
Service: lambda.amazonaws.com
Policies:
- PolicyName: WriteCloudWatchLogs
PolicyDocument:
Version: '2012-10-17'
Statement:
-
Effect: Allow
Action:
- 'logs:CreateLogGroup'
- 'logs:CreateLogStream'
- 'logs:PutLogEvents'
Resource: 'arn:aws:logs:*:*:*'
- PolicyName: UpdateUserPoolClient
PolicyDocument:
Version: '2012-10-17'
Statement:
-
Effect: Allow
Action: 'cognito-idp:UpdateUserPoolClient'
Resource: 'arn:aws:cognito-idp:*:*:userpool/*'

CognitoUserPoolClientSettingsBackingFn:
Type: AWS::Serverless::Function
Properties:
Runtime: nodejs8.10
MemorySize: 128
Timeout: 300
CodeUri: ../lambdas/cfn-cognito-user-pools-client-settings
Handler: index.handler
Role: !GetAtt CognitoUserPoolClientSettingsBackingFnRole.Arn

CognitoUserPoolClientSettings:
Type: AWS::CloudFormation::CustomResource
Condition: UseCognitoHostedUI
Properties:
Timeout: 360
ServiceToken: !GetAtt CognitoUserPoolClientSettingsBackingFn.Arn
UserPoolId: !Ref CognitoUserPool
UserPoolClientId: !Ref CognitoUserPoolClient
SupportedIdentityProviders: [ "COGNITO" ] # should (eventually) allow people to add values
CallbackURL: !Join ['', [ 'https://', !If [ UseCustomDomainName, !Ref CustomDomainName, !GetAtt DefaultCloudfrontDistribution.DomainName ], '/login' ]]
LogoutURL: !Join ['', [ 'https://', !If [ UseCustomDomainName, !Ref CustomDomainName, !GetAtt DefaultCloudfrontDistribution.DomainName ], '/logout' ]]
AllowedOAuthFlowsUserPoolClient: true
AllowedOAuthFlows: [ "implicit" ]
AllowedOAuthScopes: [ "openid" ]

CognitoUserPoolDomainBackingFnRole:
Type: 'AWS::IAM::Role'
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
-
Effect: Allow
Action: 'sts:AssumeRole'
Principal:
Service: lambda.amazonaws.com
Policies:
- PolicyName: WriteCloudWatchLogs
PolicyDocument:
Version: '2012-10-17'
Statement:
-
Effect: Allow
Action:
- 'logs:CreateLogGroup'
- 'logs:CreateLogStream'
- 'logs:PutLogEvents'
Resource: 'arn:aws:logs:*:*:*'
- PolicyName: ManageUserPoolDomain
PolicyDocument:
Version: '2012-10-17'
Statement:
-
Effect: Allow
Action: 'cognito-idp:CreateUserPoolDomain'
Resource: 'arn:aws:cognito-idp:*:*:userpool/*'
-
Effect: Allow
Action: 'cognito-idp:DeleteUserPoolDomain'
Resource: 'arn:aws:cognito-idp:*:*:userpool/*'
-
Effect: Allow
Action: 'cognito-idp:DescribeUserPoolDomain'
Resource: '*'

CognitoUserPoolDomainBackingFn:
Type: AWS::Serverless::Function
Properties:
Runtime: nodejs8.10
MemorySize: 128
Timeout: 300
CodeUri: ../lambdas/cfn-cognito-user-pools-domain
Handler: index.handler
Role: !GetAtt CognitoUserPoolDomainBackingFnRole.Arn

CognitoUserPoolDomain:
Type: AWS::CloudFormation::CustomResource
Condition: UseCognitoHostedUI
Properties:
Timeout: 360
ServiceToken: !GetAtt CognitoUserPoolDomainBackingFn.Arn
UserPoolId: !Ref CognitoUserPool
Domain: !Ref CognitoDomainNameOrPrefix

CognitoIdentityPool:
Type: AWS::Cognito::IdentityPool
Properties:
Expand Down Expand Up @@ -916,6 +1080,7 @@ Resources:
IdentityPoolId: !Ref CognitoIdentityPool
UserPoolId: !Ref CognitoUserPool
UserPoolClientId: !Ref CognitoUserPoolClient
UserPoolDomain: !If [ UseCognitoHostedUI, !GetAtt CognitoUserPoolDomain.FullUrl, '' ]
MarketplaceSuffix: !Ref MarketplaceSubscriptionTopicProductCode
RebuildToken: !Ref StaticAssetRebuildToken
RebuildMode: !Ref StaticAssetRebuildMode
Expand Down Expand Up @@ -945,6 +1110,24 @@ Resources:
AcmCertificateArn: !Ref CustomDomainNameAcmCertArn
SslSupportMethod: 'sni-only'

DefaultCloudfrontDistribution:
Type: AWS::CloudFront::Distribution
Condition: NoCustomDomainName
Properties:
DistributionConfig:
DefaultCacheBehavior:
ForwardedValues:
QueryString: true
TargetOriginId: 'dev-portal-site-s3-bucket'
ViewerProtocolPolicy: redirect-to-https
DefaultRootObject: index.html
Enabled: true
Origins:
- DomainName: !Join ['', [!Ref DevPortalSiteS3BucketName, !FindInMap ['RegionSpecificConfig', !Ref 'AWS::Region', 's3Url']]]
Id: 'dev-portal-site-s3-bucket'
CustomOriginConfig:
OriginProtocolPolicy: 'http-only'

CustomDomainDistributionAccessIdentity:
Type: AWS::CloudFront::CloudFrontOriginAccessIdentity
Condition: UseCustomDomainName
Expand Down Expand Up @@ -979,9 +1162,14 @@ Resources:

Outputs:
WebsiteURL:
Value: !Join
- ''
- - 'http://'
- !Ref DevPortalSiteS3BucketName
- !FindInMap ['RegionSpecificConfig', !Ref 'AWS::Region', 's3Url']
Description: URL for website hosted on S3
Value: !Join ['', [ 'https://', !GetAtt DefaultCloudfrontDistribution.DomainName ]]
Description: URL for website hosted on S3

DEPRECATED_S3WebsiteURL:
Value: !Join [ '', [ 'http://', !Ref DevPortalSiteS3BucketName, !FindInMap ['RegionSpecificConfig', !Ref 'AWS::Region', 's3Url'] ]]
Description: URL for website

CustomWebsiteURL:
Condition: UseCustomDomainName
Value: !Ref CustomDomainName
Description: Custom URL for website hosted on S3, served through CloudFront
32 changes: 23 additions & 9 deletions dev-portal/README.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,42 @@
## Development guide

### Getting Started
1. Create a private S3 bucket for putting zipped lambda functions and zipped templates in. Note the bucket name for the next step.
1. Navigate to the `/dev-portal/` folder, and run `npm install`

2. Create a `deployer.config.js` file inside `/dev-portal/` with the following structure:
2. Create a private S3 bucket for putting zipped lambda functions and zipped templates in. Note the bucket name for the next step. (This can be the same one you used during in the initial deployment)

3. Create a `deployer.config.js` file inside `/dev-portal/` with the structure below. We recommend using the same values you used during the initial deployment.
```js
// replace your-lambda-artifacts-bucket-name with the name of the bucket you created in step 1
// then, replace 'custom-prefix-' in siteAssetsBucket and apiAssetsBucket with your name / your org name / some unique identifier
// the resulting bucket names need to be globally unique

module.exports = {
// required; bucket must be pre-made
buildAssetsBucket: `YOUR_LAMBDA_ARTIFACTS_BUCKET_NAME`,

// required; created by stack
stackName: `dev-portal`,
buildAssetsBucket: `your-lambda-artifacts-bucket-name`,
siteAssetsBucket: `custom-prefix-dev-portal-static-assets`,
apiAssetsBucket: `custom-prefix-dev-portal-artifacts`
siteAssetsBucket: `CUSTOM_PREFIX-dev-portal-static-assets`,
apiAssetsBucket: `CUSTOM_PREFIX-dev-portal-artifacts`,

// optional values (uncomment and change values if you want to use them)

// Change the name of the customer's table. Useful for multiple stacks. Defaults to `DevPortalCustomers`
// customersTableName: `DevPortalCustomers`,

// Turns on cognito hosted sign in / sign up UI; Defaults to `` (blank string)
// cognitoDomainName: `auth-url`,

// Set this to overwrite-content if you want to reset your custom content back to the defaults. Defaults to ``
// staticAssetRebuildMode: `overwrite-content` // ONLY SET
}
```
4. Run `npm run release`. This will build the static assets, deploy them, and generate the `dev-portal/public/config.js` file needed for local development. Take note of the bucket names you use

3. Run `npm run release`. This will build the static assets, deploy them, and generate the `dev-portal/public/config.js` file needed for local development. Take note of the bucket names you use

4. Run `npm run start` to start the local development server at `localhost:3000`.
5. Run `npm run start` to start the local development server at `localhost:3000`.

5. Make changes locally, test them at `localhost:3000`, and, when satisfied, run `npm run release` to build and upload the changes to your cloud dev portal.
6. Make changes locally, test them at `localhost:3000`, and, when satisfied, run `npm run release` to build and upload the changes to your cloud dev portal.

### npm Scripts

Expand Down
Binary file not shown.
Binary file not shown.
Loading

0 comments on commit 5862d7a

Please sign in to comment.