Skip to content

Commit 536ca37

Browse files
committed
Merge branch 'main' into rjuliano/amplify-integ-test-backend
2 parents 7aad6ba + f961f16 commit 536ca37

File tree

102 files changed

+2513
-73
lines changed

Some content is hidden

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

102 files changed

+2513
-73
lines changed

.flake8

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[flake8]
2+
exclude = cdk.out
3+
extend-ignore = E203, W503
4+
max-line-length = 100

.isort.cfg

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[settings]
2+
ensure_newline_before_comments = True
3+
force_grid_wrap = 0
4+
include_trailing_comma = True
5+
line_length = 100
6+
multi_line_output = 3
7+
use_parentheses = True
8+
skip = cdk.out

requirements.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
aws_cdk.aws_apigateway
2+
aws_cdk.aws_cloudfront
3+
aws_cdk.aws_cloudfront_origins
24
aws_cdk.aws_cloudtrail
35
aws_cdk.aws_cloudwatch
46
aws_cdk.aws_codebuild
@@ -10,6 +12,7 @@ aws_cdk.aws_iot
1012
aws_cdk.aws_kinesis
1113
aws_cdk.aws_kinesisfirehose
1214
aws_cdk.aws_kms
15+
aws_cdk.aws_lambda_python
1316
aws_cdk.aws_logs
1417
aws_cdk.aws_pinpoint
1518
aws_cdk.aws_s3
@@ -18,3 +21,4 @@ aws_cdk.core
1821
black
1922
boto3
2023
isort
24+
flake8

src/build_infrastructure/android/amplify_custom_resources/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@
33
from .device_farm_project import DeviceFarmProject
44
from .device_farm_device_pool import DeviceFarmDevicePool
55
from .pull_request_builder import PullRequestBuilder
6+
from .maven_release_publisher import MavenPublisher
67
sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), "."))
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
2+
from aws_cdk import core
3+
from aws_cdk.aws_codebuild import (
4+
BuildEnvironment,
5+
BuildSpec,
6+
ComputeType,
7+
EventAction,
8+
FilterGroup,
9+
LinuxBuildImage,
10+
Project,
11+
Source
12+
)
13+
14+
class MavenPublisher(Project):
15+
BUILD_IMAGE = LinuxBuildImage.AMAZON_LINUX_2_3
16+
def __init__(self, scope: core.Construct, id: str, *,
17+
project_name: str,
18+
github_owner,
19+
github_repo,
20+
buildspec_path,
21+
environment_variables = {},
22+
base_branch: str = "main",
23+
release_branch: str = "bump_version"):
24+
25+
build_environment = BuildEnvironment(build_image=self.BUILD_IMAGE, privileged = True, compute_type = ComputeType.LARGE)
26+
27+
trigger_on_pr_merged = FilterGroup.in_event_of(EventAction.PULL_REQUEST_MERGED).and_base_branch_is(base_branch).and_branch_is(release_branch).and_commit_message_is("release:.*")
28+
29+
super().__init__(scope, id,
30+
project_name = project_name,
31+
environment_variables = environment_variables,
32+
build_spec=BuildSpec.from_source_filename(buildspec_path),
33+
badge = True,
34+
source = Source.git_hub(owner = github_owner,
35+
report_build_status = True,
36+
repo = github_repo,
37+
webhook = True,
38+
webhook_filters = [trigger_on_pr_merged]),
39+
environment = build_environment)

src/build_infrastructure/android/app.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
from stacks.build_pipeline_stack import AmplifyAndroidCodePipeline
1010
from stacks.account_bootstrap_stack import AccountBootstrap
11+
from stacks.maven_release_stack import MavenReleaseStack
1112

1213
app = core.App()
1314
TARGET_REGION = app.node.try_get_context("region")
@@ -18,11 +19,15 @@
1819
github_owner=app.node.try_get_context("github_owner")
1920
branch=app.node.try_get_context("branch")
2021
config_source_bucket = app.node.try_get_context("config_source_bucket")
21-
print(f"AWS Account={TARGET_ACCOUNT} Region={TARGET_REGION}")
22+
release_pr_branch = app.node.try_get_context("release_pr_branch")
2223
log_level=app.node.try_get_context("log_level")
2324

25+
print(f"AWS Account={TARGET_ACCOUNT} Region={TARGET_REGION}")
26+
27+
# Account bootstrap stack
2428
account_bootstrap = AccountBootstrap(app, "AccountBootstrap", {}, env=TARGET_ENV)
2529

30+
# Unit and integration test stack
2631
code_pipeline_stack_props = {
2732
# If set, config files for tests will be copied from S3. Otherwise, it will attempt to retrieve using the Amplify CLI
2833
'config_source_bucket': account_bootstrap.config_source_bucket.bucket_name,
@@ -41,5 +46,18 @@
4146
description="CI Pipeline assets for amplify-android",
4247
env=TARGET_ENV)
4348

49+
# Maven publisher stack
50+
maven_publisher_stack_props = {
51+
'github_source': {
52+
'owner': github_owner,
53+
'repo': REPO,
54+
'base_branch': branch,
55+
'release_pr_branch': release_pr_branch
56+
},
57+
'codebuild_project_name_prefix': 'AmplifyAndroid'
58+
}
59+
60+
MavenReleaseStack(app, "MavenPublisher", maven_publisher_stack_props, description="Assets used for publishing amplify-android to maven.", env=TARGET_ENV)
61+
4462

4563
app.synth()
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
from aws_cdk import (
2+
core
3+
)
4+
5+
from amplify_custom_resources import MavenPublisher
6+
7+
class MavenReleaseStack(core.Stack):
8+
def __init__(self, scope: core.App, id: str, props, **kwargs) -> None:
9+
super().__init__(scope, id, **kwargs)
10+
11+
required_props = ['github_source']
12+
for prop in required_props:
13+
if prop not in props:
14+
raise RuntimeError(f"Parameter {prop} is required.")
15+
16+
codebuild_project_name_prefix = props['codebuild_project_name_prefix']
17+
18+
github_source = props['github_source']
19+
owner = github_source['owner']
20+
repo = github_source['repo']
21+
base_branch = github_source['base_branch']
22+
23+
24+
MavenPublisher(self, "ReleasePublisher", project_name=f"{codebuild_project_name_prefix}-ReleasePublisher",
25+
github_owner=owner,
26+
github_repo=repo,
27+
base_branch=base_branch,
28+
buildspec_path="scripts/maven-release-publisher.yml")
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
*.swp
2+
package-lock.json
3+
__pycache__
4+
.pytest_cache
5+
.env
6+
.venv
7+
*.egg-info
8+
9+
# CDK asset staging directory
10+
.cdk.staging
11+
cdk.out
12+
13+
# external lambda dependencies
14+
lambda_layers/external_dependencies/python/
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
2+
# NPM user credentials rotation infrastructure
3+
4+
This CDK app helps to automate the credentials rotation for a NPM user.
5+
The credentials that are configured for rotation include login password and access keys.
6+
7+
#### Configuring the app
8+
The `lambda_functions/secrets.json` configuration file should be populated with the
9+
information about **accessing** secret values from AWS Secrets Manager. **It must not be
10+
used to store the secret values themselves.**
11+
12+
```
13+
{
14+
"npm_login_username_secret": {
15+
"arn": "<npm_login_username_secret_arn>",
16+
"secret_key": "npm_login_username"
17+
},
18+
"npm_login_password_secret": {
19+
"arn": "<npm_login_password_secret_arn>",
20+
"secret_key": "npm_login_password",
21+
"alarm_subscriptions": ["[email protected]"]
22+
},
23+
"npm_otp_seed_secret": {
24+
"arn": "<npm_otp_seed_secret_arn>",
25+
"secret_key": "npm_otp_seed"
26+
},
27+
"npm_access_token_secrets": {
28+
"secrets": [
29+
{
30+
"arn": "<npm_access_token_codegen_arn>",
31+
"secret_key": "npm_access_token_codegen"
32+
},
33+
{
34+
"arn": "<npm_access_token_js_arn>",
35+
"secret_key": "npm_access_token_js"
36+
}
37+
],
38+
"alarm_subscriptions": ["[email protected]"]
39+
}
40+
}
41+
```
42+
Since, CDK does not support creating/populating the secrets, recommended best practice is
43+
to use the AWS CLI or Console to create the above secrets.
44+
For example, to create a secret to hold the npm username using CLI:
45+
```
46+
aws secretsmanager create-secret --name npm-username-secret --secret-string "{ \"npm_login_username\": \"my-npm-username\" }"
47+
```
48+
Paste the `ARN` returned from above operation under `npm_login_username_secret`.
49+
The `secret_key` (`npm_login_username` in this case) can also be customized.
50+
51+
Similarly, create the other secrets required in the configuration file:
52+
* `npm_login_username_secret`: stores the login username for the npm user. This secret is static and is not rotated.
53+
* `npm_login_password_secret`: stores the login password for the npm user. This secret is configured for rotation and accepts
54+
a list of emails to alert in case the rotation fails.
55+
* `npm_otp_seed_secret`: stores the OTP seed for the npm user. This is created when the NPM user enables 2-factor Authentication.
56+
This secret is static and is not rotated.
57+
* `npm_access_token_secrets`: stores the list of secrets that hold the access keys created by the npm user.
58+
This secret is configured for rotation and accepts a list of emails to alert in case the rotation fails.
59+
60+
#### Deploying the infrastructure
61+
The AWS credentials have to be set using following environment variables:
62+
1. `AWS_ACCESS_KEY_ID`
63+
2. `AWS_SECRET_ACCESS_KEY`
64+
3. `AWS_SESSION_TOKEN`
65+
4. `AWS_DEFAULT_REGION`: The region of deployment should be same as the region where the above secrets are created.
66+
67+
`python 3` and `pip3` should be installed.
68+
Run `pip3 install -r requirements.txt --upgrade` from the app root to fetch necessary modules for the app.
69+
70+
At this point you can now deploy the infrastructure using:
71+
```
72+
$ cdk deploy --all
73+
```
74+
or run any of the cdk commands listed below.
75+
76+
77+
#### Useful commands
78+
79+
* `cdk ls` list all stacks in the app
80+
* `cdk synth` emits the synthesized CloudFormation template
81+
* `cdk deploy` deploy this stack to your default AWS account/region
82+
* `cdk diff` compare deployed stack with current state
83+
* `cdk docs` open CDK documentation
84+
85+
86+
#### Stacks included in the app
87+
* `UserLoginPasswordRotatorStack`: Contains resources like a rotator lambda to rotate the `npm_login_password_secret`
88+
along with necessary permissions, alarms to monitor it.
89+
* `UserAccessTokensRotatorStack`: Contains resources like a rotator lambda to rotate the access keys specified under `npm_access_token_secrets`
90+
along with necessary permissions, alarms to monitor it.
91+
92+
To deploy a single stack, use `cdk deploy UserLoginPasswordRotatorStack`
93+
94+
------------------
95+
96+
[amplify.aws](https://amplify.aws)
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#!/usr/bin/env python3
2+
3+
from aws_cdk import core
4+
from stacks.user_login_password_rotator_stack import UserLoginPasswordRotatorStack
5+
from stacks.user_access_tokens_rotator_stack import UserAccessTokensRotatorStack
6+
7+
8+
app = core.App()
9+
10+
# Stack with necessary infrastructure to rotate npm login password secret
11+
UserLoginPasswordRotatorStack(app, "UserLoginPasswordRotatorStack")
12+
13+
# Stack with necessary infrastructure to rotate npm user's access tokens specified in `secrets_config.json`
14+
UserAccessTokensRotatorStack(app, "UserAccessTokensRotatorStack")
15+
16+
app.synth()

0 commit comments

Comments
 (0)