awslabs / aws-solutions-constructs

The AWS Solutions Constructs Library is an open-source extension of the AWS Cloud Development Kit (AWS CDK) that provides multi-service, well-architected patterns for quickly defining solutions
https://docs.aws.amazon.com/solutions/latest/constructs/
Apache License 2.0
1.23k stars 247 forks source link

[CloudFrontToS3] Cannot read property 'metadata' of undefined #367

Closed tmarcinkowski-logitech closed 3 years ago

tmarcinkowski-logitech commented 3 years ago

cdk synth exits with an error: "Cannot read property 'metadata' of undefined".

It doesn't matter what props I pass. It fails even for the most primitive example straight from the docs.

Reproduction Steps

export class MyStack extends cdk.Stack {
    constructor(scope: cdk.Construct, id: string, props: MyProps) {
        super(scope, id, props);

        new CloudFrontToS3(this, 'CloudFrontToS3', {});
    }
}

const app = new cdk.App();

new MyStack(app, 'test', {
    env: {
        account: 'xxxxx',
        region: 'xxxx',
    },
});

Error Log

cdk synth just shows the message, but running with ts-node bin/cdk.ts shows a stacktrace below:

/Users/tmarcinkowski/work/my-project/cdk/node_modules/@aws-solutions-constructs/core/lib/utils.ts:144
  if (resource.cfnOptions.metadata?.cfn_nag?.rules_to_suppress) {
                          ^
TypeError: Cannot read property 'metadata' of undefined
    at Object.addCfnSuppressRules (/Users/tmarcinkowski/work/my-project/cdk/node_modules/@aws-solutions-constructs/core/lib/utils.ts:144:27)
    at updateSecurityPolicy (/Users/tmarcinkowski/work/my-project/cdk/node_modules/@aws-solutions-constructs/core/lib/cloudfront-distribution-helper.ts:31:3)
    at Object.CloudFrontDistributionForS3 (/Users/tmarcinkowski/work/my-project/cdk/node_modules/@aws-solutions-constructs/core/lib/cloudfront-distribution-helper.ts:99:3)
    at new CloudFrontToS3 (/Users/tmarcinkowski/work/my-project/cdk/node_modules/@aws-solutions-constructs/aws-cloudfront-s3/lib/index.ts:55:20)
    at new MyStack (/Users/tmarcinkowski/work/my-project/cdk/lib/my-stack.ts:28:3)
    at Object.<anonymous> (/Users/tmarcinkowski/work/my-project/cdk/bin/cdk.ts:9:1)
    at Module._compile (internal/modules/cjs/loader.js:1068:30)
    at Module.m._compile (/Users/tmarcinkowski/.nvm/versions/node/v14.17.0/lib/node_modules/ts-node/src/index.ts:1225:23)
    at Module._extensions..js (internal/modules/cjs/loader.js:1097:10)
    at Object.require.extensions.<computed> [as .ts] (/Users/tmarcinkowski/.nvm/versions/node/v14.17.0/lib/node_modules/ts-node/src/index.ts:1228:12)

Environment

This is :bug: Bug Report

biffgaut commented 3 years ago

Are you certain that you are using 1.112.0 for all your CDK and Solutions Constructs references? We addressed this issue in release 1.112.0, changing the line of code in question to:

resource.cfnOptions.metadata?.cfn_nag?.rules_to_suppress

Note the ? operator after cfn_nag that fixes the issue. When I run your code in 1.112.0 it works, when I run it in 1.111.0 I see the behavior you cite. If all your references in package.json are 1.112.0, try deleting package-lock.json and node_modules and running npm install to make sure that's exactly what's included.

tmarcinkowski-logitech commented 3 years ago

Yes, I'm certain that I'm using 1.120 - the latest version as of this moment. (see below for an evidence) The issue you describe is something different. Notice that my error message tells that it is cfnOptions that is undefined so ? after metadata does not help here.

A work-around for now - downgrading to 1.112 works indeed. So the issue must have been introduced somewhere after that release.

$ npm ls aws-cdk @aws-cdk/core @aws-solutions-constructs/aws-cloudfront-s3
cdk@0.1.0 /Users/tmarcinkowski/work/my-project/cdk
├─┬ @aws-cdk/assert@1.120.0
│ └── @aws-cdk/core@1.120.0 
├── @aws-cdk/core@1.120.0 
├─┬ @aws-solutions-constructs/aws-cloudfront-s3@1.120.0 
│ ├─┬ @aws-cdk/aws-certificatemanager@1.120.0
│ │ ├─┬ @aws-cdk/aws-cloudwatch@1.120.0
│ │ │ └── @aws-cdk/core@1.120.0 
│ │ ├─┬ @aws-cdk/aws-iam@1.120.0
│ │ │ └── @aws-cdk/core@1.120.0 
│ │ ├─┬ @aws-cdk/aws-route53@1.120.0
│ │ │ ├── @aws-cdk/core@1.120.0 
│ │ │ └─┬ @aws-cdk/custom-resources@1.120.0
│ │ │   ├─┬ @aws-cdk/aws-cloudformation@1.120.0
│ │ │   │ └── @aws-cdk/core@1.120.0 
│ │ │   └── @aws-cdk/core@1.120.0 
│ │ └── @aws-cdk/core@1.120.0 
│ ├─┬ @aws-cdk/aws-cloudfront@1.120.0
│ │ ├─┬ @aws-cdk/aws-ec2@1.120.0
│ │ │ └── @aws-cdk/core@1.120.0 
│ │ ├─┬ @aws-cdk/aws-kms@1.120.0
│ │ │ └── @aws-cdk/core@1.120.0 
│ │ ├─┬ @aws-cdk/aws-ssm@1.120.0
│ │ │ └── @aws-cdk/core@1.120.0 
│ │ └── @aws-cdk/core@1.120.0 
│ ├─┬ @aws-cdk/aws-cloudfront-origins@1.120.0
│ │ ├─┬ @aws-cdk/aws-elasticloadbalancingv2@1.120.0
│ │ │ └── @aws-cdk/core@1.120.0 
│ │ └── @aws-cdk/core@1.120.0 
│ ├─┬ @aws-cdk/aws-lambda@1.120.0
│ │ ├─┬ @aws-cdk/aws-applicationautoscaling@1.120.0
│ │ │ ├─┬ @aws-cdk/aws-autoscaling-common@1.120.0
│ │ │ │ └── @aws-cdk/core@1.120.0 
│ │ │ └── @aws-cdk/core@1.120.0 
│ │ ├─┬ @aws-cdk/aws-codeguruprofiler@1.120.0
│ │ │ └── @aws-cdk/core@1.120.0 
│ │ ├─┬ @aws-cdk/aws-ecr@1.120.0
│ │ │ └── @aws-cdk/core@1.120.0 
│ │ ├─┬ @aws-cdk/aws-ecr-assets@1.120.0
│ │ │ ├─┬ @aws-cdk/assets@1.120.0
│ │ │ │ └── @aws-cdk/core@1.120.0 
│ │ │ └── @aws-cdk/core@1.120.0 
│ │ ├─┬ @aws-cdk/aws-efs@1.120.0
│ │ │ └── @aws-cdk/core@1.120.0 
│ │ ├─┬ @aws-cdk/aws-events@1.120.0
│ │ │ └── @aws-cdk/core@1.120.0 
│ │ ├─┬ @aws-cdk/aws-logs@1.120.0
│ │ │ └── @aws-cdk/core@1.120.0 
│ │ ├─┬ @aws-cdk/aws-s3-assets@1.120.0
│ │ │ └── @aws-cdk/core@1.120.0 
│ │ ├─┬ @aws-cdk/aws-signer@1.120.0
│ │ │ └── @aws-cdk/core@1.120.0 
│ │ ├─┬ @aws-cdk/aws-sqs@1.120.0
│ │ │ └── @aws-cdk/core@1.120.0 
│ │ └── @aws-cdk/core@1.120.0 
│ ├─┬ @aws-cdk/aws-s3@1.120.0
│ │ └── @aws-cdk/core@1.120.0 
│ ├── @aws-cdk/core@1.120.0 
│ └─┬ @aws-solutions-constructs/core@1.120.0
│   ├─┬ @aws-cdk/aws-apigateway@1.120.0
│   │ └── @aws-cdk/core@1.120.0 
│   ├─┬ @aws-cdk/aws-cognito@1.120.0
│   │ └── @aws-cdk/core@1.120.0 
│   ├─┬ @aws-cdk/aws-dynamodb@1.120.0
│   │ └── @aws-cdk/core@1.120.0 
│   ├─┬ @aws-cdk/aws-elasticsearch@1.120.0
│   │ └── @aws-cdk/core@1.120.0 
│   ├─┬ @aws-cdk/aws-glue@1.120.0
│   │ └── @aws-cdk/core@1.120.0 
│   ├─┬ @aws-cdk/aws-iot@1.120.0
│   │ └── @aws-cdk/core@1.120.0 
│   ├─┬ @aws-cdk/aws-kinesis@1.120.0
│   │ └── @aws-cdk/core@1.120.0 
│   ├─┬ @aws-cdk/aws-kinesisanalytics@1.120.0
│   │ └── @aws-cdk/core@1.120.0 
│   ├─┬ @aws-cdk/aws-kinesisfirehose@1.120.0
│   │ └── @aws-cdk/core@1.120.0 
│   ├─┬ @aws-cdk/aws-lambda-event-sources@1.120.0
│   │ ├─┬ @aws-cdk/aws-sns-subscriptions@1.120.0
│   │ │ └── @aws-cdk/core@1.120.0 
│   │ └── @aws-cdk/core@1.120.0 
│   ├─┬ @aws-cdk/aws-mediastore@1.120.0
│   │ └── @aws-cdk/core@1.120.0 
│   ├─┬ @aws-cdk/aws-s3-notifications@1.120.0
│   │ └── @aws-cdk/core@1.120.0 
│   ├─┬ @aws-cdk/aws-sagemaker@1.120.0
│   │ └── @aws-cdk/core@1.120.0 
│   ├─┬ @aws-cdk/aws-secretsmanager@1.120.0
│   │ ├─┬ @aws-cdk/aws-sam@1.120.0
│   │ │ └── @aws-cdk/core@1.120.0 
│   │ └── @aws-cdk/core@1.120.0 
│   ├─┬ @aws-cdk/aws-sns@1.120.0
│   │ ├─┬ @aws-cdk/aws-codestarnotifications@1.120.0
│   │ │ └── @aws-cdk/core@1.120.0 
│   │ └── @aws-cdk/core@1.120.0 
│   ├─┬ @aws-cdk/aws-stepfunctions@1.120.0
│   │ └── @aws-cdk/core@1.120.0 
│   └── @aws-cdk/core@1.120.0 
└── aws-cdk@1.120.0
biffgaut commented 3 years ago

Is there anything else in your code? This program (all included here) works fine in my environment (builds and deploys):

import * as cdk from '@aws-cdk/core';
import { CloudFrontToS3 } from '@aws-solutions-constructs/aws-cloudfront-s3';

export class Issue367Stack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

      new CloudFrontToS3(this, 'CloudFrontToS3', {});
  }
}

const app = new cdk.App();
new Issue367Stack(app, 'Issue367Stack', {
  env: { account: '123456789012', region: 'us-east-1' },   // used my real account number to deploy
});

My versions align with yours:

▶ cdk --version
1.120.0 (build 6c15150)

Constructs/clients/Issue367  master ✗                                                                                            ✖ ⚑ ✚ ◒  
▶ npm ls aws-cdk @aws-cdk/core @aws-solutions-constructs/aws-cloudfront-s3
issue367@0.1.0 /Users/biffgaut/Documents/Active/AWS/Constructs/clients/Issue367
├─┬ @aws-cdk/assert@1.120.0
│ └── @aws-cdk/core@1.120.0 deduped
├── @aws-cdk/core@1.120.0
├─┬ @aws-solutions-constructs/aws-cloudfront-s3@1.120.0
│ ├─┬ @aws-cdk/aws-certificatemanager@1.120.0
│ │ ├─┬ @aws-cdk/aws-cloudwatch@1.120.0
│ │ │ └── @aws-cdk/core@1.120.0 deduped
│ │ ├─┬ @aws-cdk/aws-iam@1.120.0
│ │ │ └── @aws-cdk/core@1.120.0 deduped
│ │ ├─┬ @aws-cdk/aws-route53@1.120.0
│ │ │ ├── @aws-cdk/core@1.120.0 deduped
│ │ │ └─┬ @aws-cdk/custom-resources@1.120.0
│ │ │   ├─┬ @aws-cdk/aws-cloudformation@1.120.0
│ │ │   │ └── @aws-cdk/core@1.120.0 deduped
│ │ │   └── @aws-cdk/core@1.120.0 deduped
│ │ └── @aws-cdk/core@1.120.0 deduped
│ ├─┬ @aws-cdk/aws-cloudfront-origins@1.120.0
│ │ ├─┬ @aws-cdk/aws-elasticloadbalancingv2@1.120.0
│ │ │ └── @aws-cdk/core@1.120.0 deduped
│ │ └── @aws-cdk/core@1.120.0 deduped
│ ├─┬ @aws-cdk/aws-cloudfront@1.120.0
│ │ ├─┬ @aws-cdk/aws-ec2@1.120.0
│ │ │ └── @aws-cdk/core@1.120.0 deduped
│ │ ├─┬ @aws-cdk/aws-kms@1.120.0
│ │ │ └── @aws-cdk/core@1.120.0 deduped
│ │ ├─┬ @aws-cdk/aws-ssm@1.120.0
│ │ │ └── @aws-cdk/core@1.120.0 deduped
│ │ └── @aws-cdk/core@1.120.0 deduped
│ ├─┬ @aws-cdk/aws-lambda@1.120.0
│ │ ├─┬ @aws-cdk/aws-applicationautoscaling@1.120.0
│ │ │ ├─┬ @aws-cdk/aws-autoscaling-common@1.120.0
│ │ │ │ └── @aws-cdk/core@1.120.0 deduped
│ │ │ └── @aws-cdk/core@1.120.0 deduped
│ │ ├─┬ @aws-cdk/aws-codeguruprofiler@1.120.0
│ │ │ └── @aws-cdk/core@1.120.0 deduped
│ │ ├─┬ @aws-cdk/aws-ecr-assets@1.120.0
│ │ │ ├─┬ @aws-cdk/assets@1.120.0
│ │ │ │ └── @aws-cdk/core@1.120.0 deduped
│ │ │ └── @aws-cdk/core@1.120.0 deduped
│ │ ├─┬ @aws-cdk/aws-ecr@1.120.0
│ │ │ └── @aws-cdk/core@1.120.0 deduped
│ │ ├─┬ @aws-cdk/aws-efs@1.120.0
│ │ │ └── @aws-cdk/core@1.120.0 deduped
│ │ ├─┬ @aws-cdk/aws-events@1.120.0
│ │ │ └── @aws-cdk/core@1.120.0 deduped
│ │ ├─┬ @aws-cdk/aws-logs@1.120.0
│ │ │ └── @aws-cdk/core@1.120.0 deduped
│ │ ├─┬ @aws-cdk/aws-s3-assets@1.120.0
│ │ │ └── @aws-cdk/core@1.120.0 deduped
│ │ ├─┬ @aws-cdk/aws-signer@1.120.0
│ │ │ └── @aws-cdk/core@1.120.0 deduped
│ │ ├─┬ @aws-cdk/aws-sqs@1.120.0
│ │ │ └── @aws-cdk/core@1.120.0 deduped
│ │ └── @aws-cdk/core@1.120.0 deduped
│ ├─┬ @aws-cdk/aws-s3@1.120.0
│ │ └── @aws-cdk/core@1.120.0 deduped
│ ├── @aws-cdk/core@1.120.0 deduped
│ └─┬ @aws-solutions-constructs/core@1.120.0
│   ├─┬ @aws-cdk/aws-apigateway@1.120.0
│   │ └── @aws-cdk/core@1.120.0 deduped
│   ├─┬ @aws-cdk/aws-cognito@1.120.0
│   │ └── @aws-cdk/core@1.120.0 deduped
│   ├─┬ @aws-cdk/aws-dynamodb@1.120.0
│   │ └── @aws-cdk/core@1.120.0 deduped
│   ├─┬ @aws-cdk/aws-elasticsearch@1.120.0
│   │ └── @aws-cdk/core@1.120.0 deduped
│   ├─┬ @aws-cdk/aws-glue@1.120.0
│   │ └── @aws-cdk/core@1.120.0 deduped
│   ├─┬ @aws-cdk/aws-iot@1.120.0
│   │ └── @aws-cdk/core@1.120.0 deduped
│   ├─┬ @aws-cdk/aws-kinesis@1.120.0
│   │ └── @aws-cdk/core@1.120.0 deduped
│   ├─┬ @aws-cdk/aws-kinesisanalytics@1.120.0
│   │ └── @aws-cdk/core@1.120.0 deduped
│   ├─┬ @aws-cdk/aws-kinesisfirehose@1.120.0
│   │ └── @aws-cdk/core@1.120.0 deduped
│   ├─┬ @aws-cdk/aws-lambda-event-sources@1.120.0
│   │ ├─┬ @aws-cdk/aws-sns-subscriptions@1.120.0
│   │ │ └── @aws-cdk/core@1.120.0 deduped
│   │ └── @aws-cdk/core@1.120.0 deduped
│   ├─┬ @aws-cdk/aws-mediastore@1.120.0
│   │ └── @aws-cdk/core@1.120.0 deduped
│   ├─┬ @aws-cdk/aws-s3-notifications@1.120.0
│   │ └── @aws-cdk/core@1.120.0 deduped
│   ├─┬ @aws-cdk/aws-sagemaker@1.120.0
│   │ └── @aws-cdk/core@1.120.0 deduped
│   ├─┬ @aws-cdk/aws-secretsmanager@1.120.0
│   │ ├─┬ @aws-cdk/aws-sam@1.120.0
│   │ │ └── @aws-cdk/core@1.120.0 deduped
│   │ └── @aws-cdk/core@1.120.0 deduped
│   ├─┬ @aws-cdk/aws-sns@1.120.0
│   │ ├─┬ @aws-cdk/aws-codestarnotifications@1.120.0
│   │ │ └── @aws-cdk/core@1.120.0 deduped
│   │ └── @aws-cdk/core@1.120.0 deduped
│   ├─┬ @aws-cdk/aws-stepfunctions@1.120.0
│   │ └── @aws-cdk/core@1.120.0 deduped
│   └── @aws-cdk/core@1.120.0 deduped
└── aws-cdk@1.120.0
tmarcinkowski-logitech commented 3 years ago

@biffgaut There's absolutely nothing else in my project as I've started it just recently from scratch.
I even followed your approach and simplified my example even more. I've put it in a public repository for you to try out.

https://github.com/tmarcinkowski-logitech/demo-aws-solutions-constructs-issue-367 It fails here too.

It does not synthesize nor deploy even though it somewhat creates cdk.out but I won't expect it to be complete.

biffgaut commented 3 years ago

When I first downloaded your code I saw the same behavior you are seeing. I opened package.json and removed the caret ('^') from the cdk references (I think that was lines 14, 17, 24 and 25), deleted package-lock.json and node_modules, ran npm install.

Then

npm run build && cdk synth

worked.

biffgaut commented 3 years ago
  "devDependencies": {
    "@aws-cdk/assert": "1.120.0",
    "@types/jest": "^26.0.10",
    "@types/node": "10.17.27",
    "aws-cdk": "1.120.0",
    "jest": "^26.4.2",
    "ts-jest": "^26.2.0",
    "ts-node": "^9.0.0",
    "typescript": "~3.9.7"
  },
  "dependencies": {
    "@aws-cdk/core": "1.120.0",
    "@aws-solutions-constructs/aws-cloudfront-s3": "1.120.0",
    "source-map-support": "^0.5.16"
  }
tmarcinkowski-logitech commented 3 years ago

I can confirm that it works without carets. Was trying to make a diff between two invocations of npm ls, but it seems that the version in the repository has some unmet dependencies. I couldn't even revert the state of my dependencies after applying your "fix", so that's something strange. I was installing the libraries as npm i @aws-solutions-constructs/aws-cloudfront-s3@1.120.0 so I don't know what exactly happened.

Let's assume that it resolves the issue.

tmarcinkowski-logitech commented 3 years ago

Nevertheless, I think that the walkthrough instructions should explicitly tell that a construct should be installed as:

npm i --save-exact anything@VERSION_NUMBER
biffgaut commented 3 years ago

Thanks - That sounds like a good idea. I'll leave this issue open until we look into it.

tmarcinkowski-logitech commented 3 years ago

Almost forgot it - thank you @biffgaut for helping me out!

biffgaut commented 3 years ago

👍

Love your Logitech mice, BTW, been a fan for decades. (this is my personal opinion and in no way represents an endorsement by Amazon or it's affiliates :-) )

biffgaut commented 3 years ago

Also - CDK 2.0 should remove the rigid version dependency requirements. Our current plan it support it when it goes to General Availability.

tmarcinkowski-logitech commented 3 years ago

Great to hear that. Can't wait for the day we'll migrate to CDK 2.