amplify-backend
amplify-backend copied to clipboard
add support for `cdk diff`
Environment information
System:
OS: macOS 14.5
CPU: (10) arm64 Apple M1 Pro
Memory: 159.56 MB / 32.00 GB
Shell: /opt/homebrew/bin/fish
Binaries:
Node: 20.15.0 - ~/.local/state/fnm_multishells/82389_1721400785562/bin/node
Yarn: undefined - undefined
npm: 10.8.1 - ~/.local/state/fnm_multishells/82389_1721400785562/bin/npm
pnpm: 9.4.0 - ~/.local/state/fnm_multishells/82389_1721400785562/bin/pnpm
NPM Packages:
@aws-amplify/backend: 1.0.4
@aws-amplify/backend-cli: 1.1.0
aws-amplify: 6.3.8
aws-cdk: 2.147.2
aws-cdk-lib: 2.147.2
typescript: 5.5.3
AWS environment variables:
AWS_PROFILE = josef
AWS_REGION = us-east-1
AWS_STS_REGIONAL_ENDPOINTS = regional
AWS_NODEJS_CONNECTION_REUSE_ENABLED = 1
AWS_SDK_LOAD_CONFIG = 1
No CDK environment variables
Description
After making changes to my personal sandbox and opening a PR to merge to main/production, it would help the review process to better understand resource changes that are being made beyond the backend code diff.
For example,
- team member A adds a new Function with access to Data
- team member A deploys changes to their sandbox
- team member A verifies changes and opens PR
- PR check runs and emits diff artifacts
- team member B reviews diff artifacts
- team member B approves PR and merges to main
this can be a part of check
npx ampx check --diff [--app-id <amplify-app-id>] [--branch <git-branch>]
or on its own
npx ampx diff [--app-id <amplify-app-id>] [--branch <git-branch>]
Currently diffs can be executed by recreating CDK commands
for branch
cdk diff \
--ci \
--app "tsx amplify/backend.ts" \
--output .amplify/artifacts/cdk.out \
--context amplify-backend-name=main \ # this is your git branch
--context amplify-backend-namespace=<amplify-app-id> \ # this is your Amplify app ID
--context amplify-backend-type=branch
for sandbox
cdk diff \
--ci \
--app "tsx amplify/backend.ts" \
--output .amplify/artifacts/cdk.out \
--context amplify-backend-name=josef \ # this is $(whoami)
--context amplify-backend-namespace=discord-interactions \ # this is package.json#name
--context amplify-backend-type=sandbox
Marking as feature request.
@josefaidt FYI, one thing I've noticed since I've been able to use diffs is that even straight after a deploy, there are always differences, even without code changes. So, there might be some idempotency issues in the underlying constructs.
For example
Bundling asset amplify-d1gtpvh7spqh9p-backendadminprod-branch-b36a66850a/AmplifyBranchLinker/CustomResourceLambda/Code/Stage...
packages/backend-admin/.amplify/artifacts/cdk.out/bundling-temp-4e05b95e2f7fb31244ad681a912c5072f35284c98910154ea00d840059decb36/index.js 1.2mb ⚠️
⚡ Done in 28ms
Bundling asset amplify-d1gtpvh7spqh9p-backendadminprod-branch-b36a66850a/auth/SecretFetcherResourceProviderLambda/Code/Stage...
packages/backend-admin/.amplify/artifacts/cdk.out/bundling-temp-bd4e411f9cbd7cab4accee678f878aaa537d6823982356dc2379b33a2a4baf53/index.js 305.9kb
⚡ Done in 10ms
[Warning at /amplify-xxx-backendadminprod-branch-xxx/data/amplifyData/GraphQLAPI] @predictions is deprecated. This functionality will be removed in the next major release.
[Warning at /amplify-xxx-backendadminprod-branch-xxx/data/amplifyData/GraphQLAPI] @manyToMany is deprecated. This functionality will be removed in the next major release.
[Warning at /amplify-xxxx-backendadminprod-branch-xxxx/data/amplifyData/GraphQLAPI] @searchable is deprecated. This functionality will be removed in the next major release.
Stack amplify-xxxx-backendadminprod-branch-xxxx
Resources
[~] AWS::CloudFormation::Stack auth.NestedStack/auth.NestedStackResource authxxxx
└─ [~] TemplateURL
└─ [~] .Fn::Join:
└─ @@ -13,6 +13,6 @@
[ ] {
[ ] "Fn::Sub": "cdk-xxxxassets-${AWS::AccountId}-${AWS::Region}"
[ ] },
[-] "/cb444fe90255ade753ff156ebc9b2f1bda331fc579c216def4fe5583b6cbd8de.json"
[+] "/d608b82054fdc22f26d2ebf0ad31f8da53a9de955eae838fc21965902c4a2b64.json"
[ ] ]
[ ] ]
[~] AWS::CloudFormation::Stack data.NestedStack/data.NestedStackResource dataxxx
└─ [~] TemplateURL
└─ [~] .Fn::Join:
└─ @@ -13,6 +13,6 @@
[ ] {
[ ] "Fn::Sub": "cdk-xxx-assets-${AWS::AccountId}-${AWS::Region}"
[ ] },
[-] "/a73f28963b6adae78ab7be28904a93e4df5cc6303c41882c05e7defb4ba2f1ba.json"
[+] "/e72957a2e5949da1ff343471a691e2d82d73bea40b925b27158c9eadc21d43dc.json"
[ ] ]
[ ] ]
Stack amplify-xxx-backendadminprod-branch-xxx-auth179371D7-YW65J8PXS1H9
Resources
[~] Custom::SecretFetcherResource auth/AZURE_AD_CLIENT_IDSecretFetcherResource AZUREADCLIENTIDSecretFetcherResource
└─ [~] secretLastUpdated
├─ [-] 1726614685011
└─ [+] 1726615686452
[~] Custom::SecretFetcherResource auth/AZURE_AD_CLIENT_SECRETSecretFetcherResource AZUREADCLIENTSECRETSecretFetcherResource
└─ [~] secretLastUpdated
├─ [-] 1726614685011
└─ [+] 1726615686452
Stack amplify-xxxx-backendadminprod-branch-b36a66850a-data7552DF31-EBPERYWBKO06
Resources
[~] AWS::AppSync::ApiKey data/amplifyData/GraphQLAPI/DefaultApiKey amplifyDataGraphQLAPIDefaultApiKey1C8ED374
└─ [~] Expires
├─ [-] 1758150685
└─ [+] 1758151686
Stack amplify-dxxx-backendadminprod-bra-amplifyDataAmplifyTableManagerNestedStackA-N2S40YJVA23C
There were no differences
Stack amplify-xxx-backendadminprod-bra-amplifyDataFavourInfoNestedStackFavourInfo-104HTZGUDERS7
There were no differences
Stack amplify-xxx-backendadminprod-bra-amplifyDataFavourInfoVersionNestedStackFav-89P23LWED8LQ
There were no differences
Stack amplify-xxx-backendadminprod-bra-amplifyDataConnectionStackNestedStackConne-1MRIAROINF4GS
There were no differences
Stack amplify-xxx-backendadminprod-branch-b36a66850a-storage0EC3F24A-6Q611OREY5KF
There were no differences
Implementation Steps:
- Review the AWS Amplify backend code and ensure that the cdk diff command is properly integrated.
- Configure access controls using AWS IAM roles and permissions to restrict access to the
cdkdiff command. - Set up auditing mechanisms using AWS CloudTrail or AWS CloudWatch to track changes made using the
cdkdiff command. - Develop a validation and approval process for changes proposed by the
cdk diffcommand. - Implement IaC best practices by using version control systems and tracking changes to IaC templates.
Example Code (AWS CDK):
import * as cdk from 'aws-cdk-lib';
import * as iam from 'aws-cdk-lib/aws-iam';
export class AmplifyBackendStack extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// Define IAM role for cdk diff command
const cdkDiffRole = new iam.Role(this, 'CdkDiffRole', {
assumedBy: new iam.ServicePrincipal('cdk.amazonaws.com'),
});
// Grant necessary permissions to cdk diff role
cdkDiffRole.addToPolicy(
new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
actions: ['cloudformation:DescribeStacks', 'cloudformation:DescribeStackResources'],
resources: ['*'],
}),
);
// Define validation and approval process for changes
const validationLambda = new cdk.aws_lambda.Function(
this,
'ValidationLambda',
{
runtime: cdk.aws_lambda.Runtime.NODEJS_14_X,
handler: 'index.handler',
code: cdk.aws_lambda.Code.fromAsset('lambda'),
},
);
// Grant validation lambda execution role to cdk diff role
cdkDiffRole.grantExecute(validationLambda);
// Define IaC template for infrastructure changes
const infraTemplate = new cdk.aws_cloudformation.CloudFormationStack(
this,
'InfraTemplate',
{
templateBody: JSON.stringify({
Resources: {
MyResource: {
Type: 'AWS::EC2::Instance',
Properties: {
ImageId: 'ami-abc123',
},
},
},
}),
},
);
// Use version control system to track changes to IaC template
const gitRepo = new cdk.aws_codecommit.Repository(
this,
'GitRepo',
{
repositoryName: 'my-infra-repo',
},
);
// Grant git repo access to cdk diff role
cdkDiffRole.grantRead(gitRepo);
}
}