Skip to content

Commit 380f43f

Browse files
First Commit
0 parents  commit 380f43f

File tree

77 files changed

+8903
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

77 files changed

+8903
-0
lines changed

Diff for: .gitignore

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
*.js
2+
!jest.config.js
3+
*.d.ts
4+
node_modules
5+
6+
# CDK asset staging directory
7+
.cdk.staging
8+
cdk.out

Diff for: .npmignore

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
*.ts
2+
!*.d.ts
3+
4+
# CDK asset staging directory
5+
.cdk.staging
6+
cdk.out

Diff for: CODE_OF_CONDUCT.md

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
## Code of Conduct
2+
This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct).
3+
For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact
4+
[email protected] with any additional questions or comments.

Diff for: CONTRIBUTING.md

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# Contributing Guidelines
2+
3+
Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional
4+
documentation, we greatly value feedback and contributions from our community.
5+
6+
Please read through this document before submitting any issues or pull requests to ensure we have all the necessary
7+
information to effectively respond to your bug report or contribution.
8+
9+
10+
## Reporting Bugs/Feature Requests
11+
12+
We welcome you to use the GitHub issue tracker to report bugs or suggest features.
13+
14+
When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already
15+
reported the issue. Please try to include as much information as you can. Details like these are incredibly useful:
16+
17+
* A reproducible test case or series of steps
18+
* The version of our code being used
19+
* Any modifications you've made relevant to the bug
20+
* Anything unusual about your environment or deployment
21+
22+
23+
## Contributing via Pull Requests
24+
Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that:
25+
26+
1. You are working against the latest source on the *develop* branch.
27+
2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already.
28+
3. You open an issue to discuss any significant work - we would hate for your time to be wasted.
29+
30+
To send us a pull request, please:
31+
32+
1. Fork the repository.
33+
2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change.
34+
3. Ensure local tests pass.
35+
4. Commit to your fork using clear commit messages.
36+
5. Send us a pull request, answering any default questions in the pull request interface.
37+
6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation.
38+
39+
GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and
40+
[creating a pull request](https://help.github.com/articles/creating-a-pull-request/).
41+
42+
43+
## Finding contributions to work on
44+
Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 'help wanted' issues is a great place to start.
45+
46+
47+
## Code of Conduct
48+
This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct).
49+
For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact
50+
[email protected] with any additional questions or comments.
51+
52+
53+
## Security issue notifications
54+
If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue.
55+
56+
57+
## Licensing
58+
59+
See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution.

Diff for: LICENSE

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
MIT No Attribution
2+
3+
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy of
6+
this software and associated documentation files (the "Software"), to deal in
7+
the Software without restriction, including without limitation the rights to
8+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9+
the Software, and to permit persons to whom the Software is furnished to do so.
10+
11+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
12+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
13+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
14+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
15+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
16+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Diff for: README.md

+137
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
# AppSync MergedApi CI / CD
2+
An example pipeline for deploying a Merged API using AWS CDK and AWS CodePipeline
3+
4+
# Overview
5+
This project includes 3 source AppSync APIs with resolvers written in Typescript:
6+
7+
1. Reviews Service
8+
2. Books Service
9+
3. Authors Service
10+
11+
Also, it contains a Merged API which is able to integrate these 3 services into a single endpoint. This is known as the Book Reviews Merged API following the same example as the previous blog (https://aws.amazon.com/blogs/mobile/introducing-merged-apis-on-aws-appsync/).
12+
13+
14+
![mergedApi](https://github.com/ndejaco2/MergedApiCICD/assets/54116900/71e8d0fe-0b4a-4d27-bbfa-63cc9ff3593f)
15+
16+
* While this sample configures the stacks in the same repository for simplicity, each API has its own CodePipeline for deployment as these will be managed by separate teams. Each CodePipline has a beta stage, which is recommended for initial integration tests and staging, as well as a production stage.
17+
* For this sample, all APIs are deployed within the same AWS account.
18+
* Each source API stack includes a special SourceApiAssociation construct which handles configuring the association to the corresponding Merged API in the corresponding pipeline stage.
19+
* The construct includes a CustomResource backed by a Lambda function which will propagate changes to the corresponding Merged API whenever the source API stack is updated and verify that the merge is successful. If the merge operation fails, the CustomResource notifies Cloudformation of the failure causing a Rollback and the CodePipeline will halt.
20+
* Each source API stack includes unit testing using the AppSync EvaluateCode API and integration tests on both the source API and the Merged API after merge occurs.
21+
22+
23+
# Deployment Prerequisities
24+
25+
1. The sample requires that you have the [AWS CDK](https://docs.aws.amazon.com/cdk/v2/guide/getting_started.html) installed.
26+
2. The sample requires that you have Node 16+ and NPM
27+
3. The sample requires that you have an AWS account with credentials in order to deploy the sample.
28+
4. Cleanup of the sample requires the [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) to be installed.
29+
30+
# Deploying the Sample
31+
32+
1. Fork the repository on Github to create a repository that you own.
33+
34+
2. Clone the fork locally for your local development
35+
```
36+
git clone <your repository fork url>
37+
```
38+
39+
3. Add the forked repository name in `YOUR_REPOSITORY_NAME` in bin/bookReviewsMergedApi.ts to ensure that the pipeline receives notifications when you commit a change to your repository on Github.
40+
41+
4. Install dependencies and build the sample:
42+
```
43+
npm ci && npm run build && npx cdk synth
44+
```
45+
5. Create an [AWS Secrets Manager](https://aws.amazon.com/secrets-manager/) secret named "API-848-github-token" containing a fine-grained [Github personal access token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens/) as a plaintext secret. The token requires scopes to include repo and admin:repo_hook.
46+
47+
6. Deploy the AppSync SchemaBreakingChangeDetection stack. This stack is responsible for configuring the Cloudformation Hook which will perform breaking change detection of AppSync schema updates within Cloudformation.
48+
49+
```
50+
export AWS_DEFAULT_REGION='us-east-1'
51+
npx cdk deploy BreakingChangeDetection
52+
```
53+
54+
7. Deploy the BookReviews MergedApi [AWS CodePipeline](https://aws.amazon.com/codepipeline/) Stack. This stack is responsible for configuring the CodePipeline which will handle deploying changes to both the beta and production stage BookReviews Merged API. Note that initially the integration tests in this pipeline are not added initially because they have a dependency on the source APIs being associated.
55+
```
56+
npx cdk deploy BookReviewsMergedApiPipeline
57+
```
58+
8. Sign in to the AWS Management Console and open the [CodePipeline console](https://console.aws.amazon.com/codesuite/codepipeline/home). You should see the BookReviewsMergedApiPipeline resource with an ongoing pipeline execution. Wait for the execution to finish to ensure that the stacks have been deployed.
59+
60+
61+
9. Once the Merged API pipeline execution has completed, deploy the source API pipelined and wait for them to finish a pipeline execution to successfully deploy the beta and production stages.
62+
```
63+
npx cdk deploy AuthorsServicePipeline ReviewsServicePipeline BooksServicePipeline
64+
```
65+
66+
10. Now that all initial resources are deployed, we can enable the Merged API integration tests. Uncomment the code for adding the Merged API integration tests in lib/mergedApi/book-reviews-mergedapi-pipeline.ts as well as lib/sourceApis/authorsService/authors-service-pipeline-stack.ts, lib/sourceApis/booksService/books-service-pipeline-stack.ts, and lib/sourceApis/reviewsService/reviews-service-pipeline-stack.ts. Commit the code to your branch on Github and the changes will be picked up and automatically enable the integration testing step during the next pipeline execution.
67+
68+
```
69+
pipeline.addStage(new BookReviewsMergedApiStage(this, "BookReviewsMergedApiBetaStage", {
70+
env: {
71+
region: region
72+
},
73+
stageName: 'beta'
74+
}), {
75+
post: [
76+
new CodeBuildStep('Integ-Test-Beta-MergedApi', {
77+
env: {
78+
Stage: 'beta',
79+
AWS_REGION: this.region
80+
},
81+
commands: [
82+
"npm ci",
83+
"npm run build",
84+
"npm test integ-tests/mergedApi"
85+
],
86+
rolePolicyStatements: [
87+
integTestPolicyStatement,
88+
integTestListExportsPolicyStatement
89+
]
90+
})
91+
]
92+
});
93+
94+
pipeline.addStage(new BookReviewsMergedApiStage(this, "BookReviewsMergedApiProdStage", {
95+
env: {
96+
region: region
97+
},
98+
stageName: 'prod'
99+
}), {
100+
post: [
101+
new CodeBuildStep('Integ-Test-Prod-MergedApi', {
102+
env: {
103+
Stage: 'prod',
104+
AWS_REGION: this.region
105+
},
106+
commands: [
107+
"npm ci",
108+
"npm run build",
109+
"npm test integ-tests/mergedApi"
110+
],
111+
rolePolicyStatements: [
112+
integTestPolicyStatement,
113+
integTestListExportsPolicyStatement
114+
]
115+
})
116+
]
117+
});
118+
119+
```
120+
121+
# Cleanup
122+
123+
1. Clean up all the code pipeline stacks:
124+
125+
```
126+
npx cdk destroy --all
127+
```
128+
129+
2. Clean up the Source API stacks created by the code pipeline (Requires AWS CLI):
130+
```
131+
./scripts/cleanup-source-api-beta-and-prod-stages.sh
132+
```
133+
134+
3. Clean up the Merged API stacks created by the code pipeline (Requires AWS CLI):
135+
```
136+
./scripts/cleanup-merged-api-beta-and-prod-stages.sh
137+
```

Diff for: bin/bookReviewsMergedApi.ts

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#!/usr/bin/env node
2+
import * as cdk from 'aws-cdk-lib';
3+
import { BooksServicePipelineStack } from "../lib/sourceApis/booksService/books-service-pipeline-stack";
4+
import { BookReviewsMergedApiPipeline } from "../lib/mergedApi/book-reviews-mergedapi-pipeline";
5+
import { AuthorsServicePipelineStack } from "../lib/sourceApis/authorsService/authors-service-pipeline";
6+
import { ReviewsServicePipelineStack } from "../lib/sourceApis/reviewsService/reviews-service-pipeline";
7+
import { SchemaBreakingChangeDetectionStack } from '../lib/breakingChangeDetection/schema-breaking-change-detection-stack';
8+
9+
const app = new cdk.App();
10+
11+
const defaultRegion = 'us-east-1'
12+
export const YOUR_REPOSITORY_NAME = "sagarsinha7777/aws-appsync-merged-api-ci-cd-sample";
13+
new SchemaBreakingChangeDetectionStack(app, 'BreakingChangeDetection', {
14+
env: {
15+
region: defaultRegion
16+
}
17+
});
18+
19+
new BookReviewsMergedApiPipeline(app, 'BookReviewsMergedApiPipeline', {
20+
env: {
21+
region: defaultRegion
22+
}
23+
});
24+
25+
new AuthorsServicePipelineStack(app, 'AuthorsServicePipeline', {
26+
env: {
27+
region: defaultRegion
28+
}
29+
});
30+
31+
new ReviewsServicePipelineStack(app, 'ReviewsServicePipeline', {
32+
env: {
33+
region: defaultRegion
34+
},
35+
});
36+
37+
new BooksServicePipelineStack(app, 'BooksServicePipeline', {
38+
env: {
39+
region: defaultRegion
40+
},
41+
})

Diff for: build.mjs

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/* eslint-disable */
2+
import { build } from 'esbuild'
3+
import {glob} from 'glob'
4+
5+
for (const microServiceName of ['authorsService', 'booksService', 'reviewsService']) {
6+
// Build resolver code for authors service
7+
const files_agent = await glob(`lib/sourceApis/${microServiceName}/resolverCode/**/*.ts`)
8+
console.log(`Building ${files_agent.length} files from ${microServiceName}`)
9+
10+
await build({
11+
sourcesContent: false,
12+
format: 'esm',
13+
target: 'esnext',
14+
platform: 'node',
15+
external: ['@aws-appsync/utils'],
16+
outdir: `lib/sourceApis/${microServiceName}/resolverCode`,
17+
entryPoints: files_agent,
18+
bundle: true,
19+
})
20+
}

Diff for: cdk.json

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
{
2+
"app": "npx ts-node --prefer-ts-exts bin/bookReviewsMergedApi.ts",
3+
"watch": {
4+
"include": [
5+
"**"
6+
],
7+
"exclude": [
8+
"README.md",
9+
"cdk*.json",
10+
"**/*.d.ts",
11+
"**/*.js",
12+
"tsconfig.json",
13+
"package*.json",
14+
"yarn.lock",
15+
"node_modules",
16+
"test"
17+
]
18+
},
19+
"context": {
20+
"@aws-cdk/aws-lambda:recognizeLayerVersion": true,
21+
"@aws-cdk/core:checkSecretUsage": true,
22+
"@aws-cdk/core:target-partitions": [
23+
"aws",
24+
"aws-cn"
25+
],
26+
"@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true,
27+
"@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true,
28+
"@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true,
29+
"@aws-cdk/aws-iam:minimizePolicies": true,
30+
"@aws-cdk/core:validateSnapshotRemovalPolicy": true,
31+
"@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true,
32+
"@aws-cdk/aws-s3:createDefaultLoggingPolicy": true,
33+
"@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true,
34+
"@aws-cdk/aws-apigateway:disableCloudWatchRole": true,
35+
"@aws-cdk/core:enablePartitionLiterals": true,
36+
"@aws-cdk/aws-events:eventsTargetQueueSameAccount": true,
37+
"@aws-cdk/aws-iam:standardizedServicePrincipals": true,
38+
"@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": true,
39+
"@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": true,
40+
"@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true,
41+
"@aws-cdk/aws-route53-patters:useCertificate": true,
42+
"@aws-cdk/customresources:installLatestAwsSdkDefault": false,
43+
"@aws-cdk/aws-rds:databaseProxyUniqueResourceName": true,
44+
"@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": true,
45+
"@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId": true,
46+
"@aws-cdk/aws-ec2:launchTemplateDefaultUserData": true,
47+
"@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments": true,
48+
"@aws-cdk/aws-redshift:columnId": true,
49+
"@aws-cdk/aws-stepfunctions-tasks:enableEmrServicePolicyV2": true,
50+
"@aws-cdk/aws-ec2:restrictDefaultSecurityGroup": true,
51+
"@aws-cdk/aws-apigateway:requestValidatorUniqueId": true,
52+
"@aws-cdk/aws-kms:aliasNameRef": true,
53+
"@aws-cdk/core:includePrefixInUniqueNameGeneration": true
54+
}
55+
}

Diff for: jest.config.js

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
module.exports = {
2+
testEnvironment: 'node',
3+
roots: ['<rootDir>/test'],
4+
testMatch: ['**/*.test.ts'],
5+
transform: {
6+
'^.+\\.tsx?$': 'ts-jest'
7+
}
8+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import * as cdk from "aws-cdk-lib";
2+
import { Role, ServicePrincipal, PrincipalWithConditions } from "aws-cdk-lib/aws-iam";
3+
import { Construct } from "constructs";
4+
5+
export class SchemaBreakingChangeDetectionStack extends cdk.Stack {
6+
7+
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
8+
super(scope, id)
9+
10+
const executionRole = new Role(this, 'ActivationExecutionRole', {
11+
assumedBy: new PrincipalWithConditions(
12+
new ServicePrincipal( "hooks.cloudformation.amazonaws.com"), {
13+
StringEquals: { 'aws:SourceAccount': this.account },
14+
ArnLike: { 'aws:SourceArn': `arn:aws:cloudformation:${this.region}:${this.account}:type/hook/AwsCommunity-AppSync-BreakingChangeDetection/*`},
15+
})
16+
});
17+
18+
const type = new cdk.CfnTypeActivation(this, 'BreakingChangeDetectionHook', {
19+
executionRoleArn: executionRole.roleArn,
20+
typeName: "AwsCommunity::AppSync::BreakingChangeDetection",
21+
type: "HOOK",
22+
publisherId: "c830e97710da0c9954d80ba8df021e5439e7134b",
23+
})
24+
25+
new cdk.CfnHookTypeConfig(this, 'BreakingChangeDetectionConfig', {
26+
typeArn: type.attrArn,
27+
configuration: "{\"CloudFormationConfiguration\":{\"HookConfiguration\":{\"TargetStacks\":\"ALL\",\"FailureMode\":\"FAIL\",\"Properties\":{ \"ConsiderDangerousChangesBreaking\": false}}}}"
28+
})
29+
}
30+
}

0 commit comments

Comments
 (0)