aws-cloudformation / cloudformation-resource-schema

The CloudFormation Resource Schema defines the shape and semantic for resources provisioned by CloudFormation. It is used by provider developers using the CloudFormation RPDK.
Apache License 2.0
90 stars 38 forks source link

Incomprehensible error message when using AWS::CloudFormation::ResourceVersion & AWS::CloudFormation::PublicTypeVersion #129

Closed SHxKM closed 2 years ago

SHxKM commented 2 years ago

Hi,

We are using a StackSet to deploy our custom Public Type to all regions in tandem. For that, we are utilizing çAWS::CloudFormation::ResourceVersion, AWS::CloudFormation::ResourceDefaultVersion, AWS::CloudFormation::Publisher, and AWS::CloudFormation::PublicTypeVersion. They are listed in the same order as specified here, and each item DependsOn the item that precedes it.

Unfortunately, we are unable to pass the tests, and get this error:

ResourceLogicalId:SomeProductPublicTypeVersion, ResourceType:AWS::CloudFormation::PublicTypeVersion, ResourceStatusReason:Resource handler returned message: "Model validation failed (#: #: only 1 subschema matches out of 2) #: #: 2 subschemas matched instead of one (#)" (RequestToken: b8399ca3-0aec-572d-XXX-XXXX, HandlerErrorCode: InvalidRequest).

A few things are worth noting here:

  1. In the log files that are directly uploaded to our S3 (using the LogDeliveryBucket property of PublicTypeVersion), our custom type version seems to pass 100% of the tests. There is not indication of any errors.

  2. If we publish the type manually (through the cli, it's a multi-step, lengthy process), all goes fine and we can successfully publish the type (publicly). We are using the same SchemaHandlerPackage URL for both the manual flow, and the StackSet. The former works, the latter doesn't. The error message is close to useless given that the log files show no errors at all.

  3. The schema itself passes cfn validate

Please advise.

ammokhov commented 2 years ago

Hi,

We are using a StackSet to deploy our custom Public Type to all regions in tandem. For that, we are utilizing çAWS::CloudFormation::ResourceVersion, AWS::CloudFormation::ResourceDefaultVersion, AWS::CloudFormation::Publisher, and AWS::CloudFormation::PublicTypeVersion. They are listed in the same order as specified here, and each item DependsOn the item that precedes it.

Unfortunately, we are unable to pass the tests, and get this error:


ResourceLogicalId:SomeProductPublicTypeVersion, ResourceType:AWS::CloudFormation::PublicTypeVersion, ResourceStatusReason:Resource handler returned message: "Model validation failed (#: #: only 1 subschema matches out of 2) #: #: 2 subschemas matched instead of one (#)" (RequestToken: b8399ca3-0aec-572d-XXX-XXXX, HandlerErrorCode: InvalidRequest).

A few things are worth noting here:

  1. In the log files that are directly uploaded to our S3 (using the LogDeliveryBucket property of PublicTypeVersion), our custom type version seems to pass 100% of the tests. There is not indication of any errors.

  2. If we publish the type manually (through the cli, it's a multi-step, lengthy process), all goes fine and we can successfully publish the type (publicly). We are using the same SchemaHandlerPackage URL for both the manual flow, and the StackSet. The former works, the latter doesn't. The error message is close to useless given that the log files show no errors at all.

  3. The schema itself passes cfn validate

Please advise.

Based on the information provided it's hard to identify the issue exactly. This error is coming from json engine during the request validation. Most likely, provided template does not satisfy schema requirements for one of the resources.

SHxKM commented 2 years ago

Most likely, provided template does not satisfy schema requirements for one of the resources.

But:

The schema itself passes cfn validate

If we publish the type manually (through the cli, it's a multi-step, lengthy process), all goes fine and we can successfully publish the type (publicly)

So if anything, there’s a discrepancy between the manual publishing and the publishing flow using StackSets, and one of them is buggy.

ammokhov commented 2 years ago

The schema itself passes cfn validate

that just means that schema is correct and complies with json + cfn schema requirements. Validation error happens on the runtime when you provide property values, java plugin validates that the values are within restricted constrains or there are no unmodelled properties provided - validateModel

So if anything, there’s a discrepancy between the manual publishing and the publishing flow using StackSets, and one of them is buggy.

would you mind to elaborate on this?

ugudip commented 2 years ago

Hi SHxKM, the issue here is not the Stacksets/Registry publishing, but it's related to the template you have given as an input. The above error is thrown when the template you provided does not satisfy the resource type schema validation. The cfn validate command checks if the template (your resource type schema that you want to make public) is valid, but the issue here is the input template you gave for AWS::CloudFormation::PublicTypeVersion is not valid. Can you share the template you used to help us identify the issue? Did you check if your template follows the syntax given here https://docs.aws.amazon.com/AWSCloudFormation/latest//UserGuide/aws-resource-cloudformation-publictypeversion.html ??

SHxKM commented 2 years ago

that just means that schema is correct and complies with json + cfn schema requirements. Validation error happens on the runtime when you provide property values, java plugin validates that the values are within restricted constrains or there are no unmodelled properties provided - validateModel

@ammokhov I’m not sure I understand. If the schema is valid, and we are using the “inputs” directory to provide test inputs, and it is passing cfn test and cfn validate, and all the contract tests, and we can publish it successfully if done manually (and not via a StackSet), where can we fail? Can I trigger this “validateModel” directly so I can get a slight idea of where the “problem” is?

would you mind to elaborate on this?

What I mean is, we can (have) successfully publish the same custom type, with the same schema handler package, in any region, when done via the CLI. However, we cannot do the same when using a StackSet.

@ugudip

Hi SHxKM, the issue here is not the Stacksets/Registry publishing, but it's related to the template you have given as an input. We throw this error when the template you provided does not satisfy the resource type schema validation. The cfn validate command checks if the template (your resource type schema that you want to make public) is valid, but the issue here is the template you gave for AWS::CloudFormation::PublicTypeVersion is not valid. Can you share the template you used to help us identify the issue? Did you check if your template follows the syntax given here https://docs.aws.amazon.com/AWSCloudFormation/latest//UserGuide/aws-resource-cloudformation-publictypeversion.html ??

Sure, SchemaHandlerUrl and VersionToPublish are parameters passed to the template. I did my best to follow the syntax, and I hope it's a mistake on my end - please let me know: (I've only adjusted the names of the bucket and the resource)

Resources:
  MyTypePrivateTypeVersion: 
    Type: AWS::CloudFormation::ResourceVersion
    Properties:
      SchemaHandlerPackage: !Ref SchemaHandlerUrl
      TypeName: MyCompany::MyCategory::MyType
  ResourceDefaultVersion:    
    Type: AWS::CloudFormation::ResourceDefaultVersion
    DependsOn: MyTypePrivateTypeVersion
    Properties:
      TypeVersionArn: !Ref MyTypePrivateTypeVersion
  CustomTypePublisher:
    Type: AWS::CloudFormation::Publisher
    DependsOn: ResourceDefaultVersion
    Properties:
      AcceptTermsAndConditions: true
  MyTypePublicTypeVersion:     
    Type: AWS::CloudFormation::PublicTypeVersion
    DependsOn: CustomTypePublisher
    Properties:
      Arn: !Ref ResourceDefaultVersion
      LogDeliveryBucket: my-s3-logs-bucket
      PublicVersionNumber: !Ref VersionToPublish
SHxKM commented 2 years ago

I think I know where the issue is, if it is indeed the issue. I've named the resource ResourceDefaultVersion, the same as the type (and its type): AWS::CloudFormation::ResourceDefaultVersion. I will test it later and close this issue if it turns out to be the problem.

SHxKM commented 2 years ago

Even after changing the template to look like this:

Resources:
  MyTypePrivateTypeVersion: 
    Type: AWS::CloudFormation::ResourceVersion
    Properties:
      SchemaHandlerPackage: !Ref SchemaHandlerUrl
      TypeName: MyCompany::MyCategory::MyType
  MyTypeResourceDefaultVersion:    
    Type: AWS::CloudFormation::ResourceDefaultVersion
    DependsOn: MyTypePrivateTypeVersion
    Properties:
      TypeVersionArn: !Ref MyTypePrivateTypeVersion
  CustomTypePublisher:
    Type: AWS::CloudFormation::Publisher
    DependsOn: MyTypeResourceDefaultVersion
    Properties:
      AcceptTermsAndConditions: true
  MyTypePublicTypeVersion:     
    Type: AWS::CloudFormation::PublicTypeVersion
    DependsOn: CustomTypePublisher
    Properties:
      Arn: !Ref MyTypeResourceDefaultVersion
      LogDeliveryBucket: my-s3-logs-bucket
      PublicVersionNumber: !Ref VersionToPublish

I am still getting the same error. @ugudip can you shed some light on what I'm doing wrong then with my template?

ugudip commented 2 years ago

Hey SHxKM, Thanks for the template. I don't think it makes any difference by changing the resource name you give, you are allowed to give any name as a logical Id. Your template looks good at first glance, but I will need to investigate on why it isn't working for you. I will get back to you shortly with my findings. Meanwhile, as a workaround, can you please try by giving TypeName and Type instead of Arn for PublicTypeVersion resource?

SHxKM commented 2 years ago

Hey SHxKM, Thanks for the template. I don't think it makes any difference by changing the resource name you give, you are allowed to give any name as a logical Id. Your template looks good at first glance, but I will need to investigate on why it isn't working for you. I will get back to you shortly with my findings. Meanwhile, as a workaround, can you please try by giving TypeName and Type instead of Arn for PublicTypeVersion resource?

Hi @ugudip - thanks for updating me and for the workaround suggestion. It seems to work. We'd much rather use the ARN though, so please do update me on findings.

ammokhov commented 2 years ago

so please do update me on findings.

We can confirm that the issue is on CFN side. Java plugin library executes validation during runtime. The issue is that resource request is subject to mutation after subsequent reinvocations, which fails validation. The fix is out and under review https://github.com/aws-cloudformation/cloudformation-cli-java-plugin/pull/371. Deployment of the fix should not take long. We will update the issue

ugudip commented 2 years ago

Hi SHxKM, the fix is now deployed. Would you please use the "Arn" in the properties and let us know if you are able to create a stack. Keeping this open till we hear back from you. Thanks.

SHxKM commented 2 years ago

Hi SHxKM, the fix is now deployed. Would you please use the "Arn" in the properties and let us know if you are able to create a stack. Keeping this open till we hear back from you. Thanks.

Thanks for the update and the fix. We have an upcoming version deployment in the next few days. You can close this issue and I'll reopen if we face any issues.

ugudip commented 2 years ago

Sure. Closing this as requested. Thanks for the update :)