Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

InconsistentQuantities error when deploying with @sls-next/serverless-component@1.18.0-alpha.5^ #722

Closed
2 tasks done
eddeee888 opened this issue Oct 29, 2020 · 11 comments · Fixed by #723
Closed
2 tasks done

Comments

@eddeee888
Copy link

Describe the bug

I'm currently using @sls-next/serverless-component@1.17.0 with apex domain settings ( full serverless yml below )

I'm trying to use the custom header feature as mentioned in #587 (comment). so I tried to use @sls-next/serverless-component@1.18.0-alpha.5 ( and also @sls-next/serverless-component@1.18.0-alpha.22)

However, when I try to deploy it, I get InconsistentQuantities error in CI. Probably happens if I run it locally too.

Actual behavior

I get the following error as it's trying to deploy:
InconsistentQuantities: The specified quantity of Aliases (1) does not match the actual quantity supplied (2)

Expected behavior

It should deploy without error

Steps to reproduce

Here's a version of my serverless yml without all the credentials:

org: MY_ORG
name: MY_APP

app-one:
  component: "@sls-next/serverless-component@1.18.0-alpha.5"
  inputs:
    bucketName: my-bucket-name
    domain: ${env.APP_DOMAIN}
    domainType: apex
    description: description here
    memory: 512
    timeout:
      defaultLambda: 20
    verbose: true
    build:
      cmd: yarn
      env:
        NODE_ENV: production

Screenshots/Code/Logs

Here's the log when it fails ( v1.18.0-alpha.5 and v1.18.0-alpha.22 ):

DEBUG ─ Analyzing the template's components dependencies.
DEBUG ─ Creating the template's components graph.
DEBUG ─ Syncing template state.
DEBUG ─ Executing the template's components graph.
DEBUG ─ Resolving the template's static variables.
DEBUG ─ Collecting components from the template.
DEBUG ─ Downloading any NPM components found in the template.
...
DEBUG ─ Deploying bucket bucket-name in region us-east-1.
DEBUG ─ Checking if bucket bucket-name exists.
DEBUG ─ Setting acceleration to "true" for bucket bucket-name.
DEBUG ─ Bucket bucket-name was successfully deployed to the us-east-1 region.
...
DEBUG ─ Starting deployment of lambda aaaa-bbbb to the us-east-1 region.
DEBUG ─ Syncing role aaaa-dddd in region us-east-1.
DEBUG ─ Saved state for role aaaa-dddd.
DEBUG ─ Role aaaa-dddd was successfully deployed to region us-east-1.
DEBUG ─ Deployed role arn is arn:aws:iam::***:role/aaaa-dddd.
DEBUG ─ Packaging lambda code from /github/workspace/services/app-one/.serverless_nextjs/default-lambda.
...
DEBUG ─ Uploading aaaa-bbbb lambda code.
DEBUG ─ Updating aaaa-bbbb lambda config.
DEBUG ─ Successfully deployed lambda aaaa-bbbb in the us-east-1 region.
DEBUG ─ Starting deployment of CloudFront distribution to the us-east-1 region.
DEBUG ─ Updating CloudFront distribution of ID CLOUDFRONT-VH.
DEBUG ─ CloudFront deployed successfully with URL: https://zzz.cloudfront.net.
DEBUG ─ Starting Domain component deployment.
DEBUG ─ Validating inputs.
DEBUG ─ Formatting domains and identifying cloud services being used.
DEBUG ─ Getting the Hosted Zone ID for the domain myapp.com.
DEBUG ─ Searching for an AWS ACM Certificate based on the domain: myapp.com.
DEBUG ─ Checking the status of AWS ACM Certificate.
DEBUG ─ Adding www.myapp.com domain to CloudFront distribution with URL "https://zzz.cloudfront.net"
{ InconsistentQuantities: The specified quantity of Aliases (1) does not match the actual quantity supplied (2).
    at Request.extractError (/github/home/.serverless/components/registry/npm/@sls-next/serverless-component@1.18.0-alpha.22/node_modules/aws-sdk/lib/protocol/rest_xml.js:53:29)
    at Request.callListeners (/github/home/.serverless/components/registry/npm/@sls-next/serverless-component@1.18.0-alpha.22/node_modules/aws-sdk/lib/sequential_executor.js:106:20)
    at Request.emit (/github/home/.serverless/components/registry/npm/@sls-next/serverless-component@1.18.0-alpha.22/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
    at Request.emit (/github/home/.serverless/components/registry/npm/@sls-next/serverless-component@1.18.0-alpha.22/node_modules/aws-sdk/lib/request.js:688:14)
    at Request.transition (/github/home/.serverless/components/registry/npm/@sls-next/serverless-component@1.18.0-alpha.22/node_modules/aws-sdk/lib/request.js:22:10)
    at AcceptorStateMachine.runTo (/github/home/.serverless/components/registry/npm/@sls-next/serverless-component@1.18.0-alpha.22/node_modules/aws-sdk/lib/state_machine.js:14:12)
    at /github/home/.serverless/components/registry/npm/@sls-next/serverless-component@1.18.0-alpha.22/node_modules/aws-sdk/lib/state_machine.js:26:10
    at Request.<anonymous> (/github/home/.serverless/components/registry/npm/@sls-next/serverless-component@1.18.0-alpha.22/node_modules/aws-sdk/lib/request.js:38:9)
    at Request.<anonymous> (/github/home/.serverless/components/registry/npm/@sls-next/serverless-component@1.18.0-alpha.22/node_modules/aws-sdk/lib/request.js:690:12)
    at Request.callListeners (/github/home/.serverless/components/registry/npm/@sls-next/serverless-component@1.18.0-alpha.22/node_modules/aws-sdk/lib/sequential_executor.js:116:18)
  message:
   'The specified quantity of Aliases (1) does not match the actual quantity supplied (2).',
  code: 'InconsistentQuantities',
  time: 2020-10-29T13:14:07.318Z,
  requestId: '...',
  statusCode: 400,
  retryable: false,
  retryDelay: 60.609886564301775 }
25h
  120s › app-one › InconsistentQuantities: The specified quantity of Aliases (1) does not match the actual quantity supplied (2).

I downgraded back to version 1.17.0 and it works. Here's the log for comparison:

DEBUG ─ Resolving the template's static variables.
DEBUG ─ Collecting components from the template.
DEBUG ─ Downloading any NPM components found in the template.
DEBUG ─ Analyzing the template's components dependencies.
DEBUG ─ Creating the template's components graph.
DEBUG ─ Syncing template state.
DEBUG ─ Executing the template's components graph.
...
DEBUG ─ Deploying bucket bucket-name in region us-east-1.
DEBUG ─ Checking if bucket bucket-name exists.
DEBUG ─ Setting acceleration to "true" for bucket bucket-name.
DEBUG ─ Bucket bucket-name was successfully deployed to the us-east-1 region.
...
DEBUG ─ Starting deployment of lambda aaaa-bbbb to the us-east-1 region.
DEBUG ─ Syncing role aaaa-dddd in region us-east-1.
DEBUG ─ Saved state for role aaaa-dddd.
DEBUG ─ Role aaaa-dddd was successfully deployed to region us-east-1.
DEBUG ─ Deployed role arn is arn:aws:iam::***:role/aaaa-dddd.
DEBUG ─ Packaging lambda code from /github/workspace/services/app-one/.serverless_nextjs/default-lambda.
...
DEBUG ─ Uploading aaaa-bbbb lambda code.
DEBUG ─ Updating aaaa-bbbb lambda config.
DEBUG ─ Successfully deployed lambda aaaa-bbbb in the us-east-1 region.
DEBUG ─ Starting deployment of CloudFront distribution to the us-east-1 region.
DEBUG ─ Updating CloudFront distribution of ID CLOUDFRONT-VH.
DEBUG ─ CloudFront deployed successfully with URL: https://zzz.cloudfront.net.
DEBUG ─ Starting Domain component deployment.
DEBUG ─ Validating inputs.
DEBUG ─ Formatting domains and identifying cloud services being used.
DEBUG ─ Getting the Hosted Zone ID for the domain myapp.com.
DEBUG ─ Searching for an AWS ACM Certificate based on the domain: myapp.com.
DEBUG ─ Checking the status of AWS ACM Certificate.
DEBUG ─ Adding www.myapp.com domain to CloudFront distribution with URL "https://zzz.cloudfront.net"
DEBUG ─ Configuring DNS for distribution "https://zzz.cloudfront.net".
app-one: 
    appUrl:         https://myapp.com
    bucketName:     bucket-name
    distributionId: CLOUDFRONT-VH
25h
  104s › app-one › done

Versions

  • OS/Environment: Linux ( github actions )
  • @sls-next/serverless-component version: 1.18.0-alpha.5, 1.18.0-alpha.22
  • Next.js version: 9.5.4

Additional context

I'm using apex as the domainType with the manual workaround to redirect www -> apex domain

Checklist

  • You have reviewed the README and FAQs, which answers several common questions.
  • Please first try using the latest @sls-next/serverless-component release version, which may have already fixed your issue. Note that the old serverless-next.js component and the serverless-next.js plugin are deprecated and no longer maintained.
@dphang
Copy link
Collaborator

dphang commented Oct 29, 2020

As the error suggests, I think aliases quantity and items in CloudFront distribution config is somehow mismatched, although looking from the code here it doesn't seem like Quantity and Items can be mismatched:

params.DistributionConfig.Aliases.Items.push(subdomain.domain);
params.DistributionConfig.Aliases.Quantity += 1;
if (subdomain.domain.startsWith("www.")) {
if (domainType === "apex") {
params.DistributionConfig.Aliases.Items[-1] = `${subdomain.domain.replace(
"www.",
""
)}`;
} else if (domainType !== "www") {
params.DistributionConfig.Aliases.Items.push(
`${subdomain.domain.replace("www.", "")}`
);
params.DistributionConfig.Aliases.Quantity += 1;
}
}

Unfortunately it looks like we don't have logging on what is actually sent to CloudFront to update the distribution:

What you can do is build this component from source (following the CONTRIBUTING.md guides) and try to add some logging statements around that domain package to print what is the input sent to CloudFront, and that should help narrow down the issue.

In particular, this line seems suspect due to the negative indexing, and it was added in 1.18.0-alpha.2, which is consistent with 1.17 still working. I'll take a look at that + adding logs but in the meantime if you can try to post the request sent to CloudFront log, that will also be helpful.

@dphang
Copy link
Collaborator

dphang commented Oct 29, 2020

Also I think your domain input should be the www domain, correct? I think if you are just using apex for domainType you can remove the www and it should work, as it won't go through that check for www here:

if (subdomain.domain.startsWith("www."))

@dphang
Copy link
Collaborator

dphang commented Oct 29, 2020

Published a fix in the latest alpha, please try and see if it works for you. Thanks!

@eddeee888
Copy link
Author

Hello, thanks for getting on this so quickly! I will test it ASAP and let you know. For what it's worth, my input domain is apex, i.e. https://domain.com.

@dphang
Copy link
Collaborator

dphang commented Oct 30, 2020

I see, thanks! Anyway I did add some logging so if it doesn't work, then it should at least show some logs now for the CloudFront API calls in debug mode. Let me know what the logs say if it doesn't work and we can figure out if there is still another bug.

@dphang
Copy link
Collaborator

dphang commented Oct 30, 2020

Actually there might be a slight issue, I think it still may not be completely fixed due to #658, which is pushing additional aliases instead of overriding all of it when domain input is used, which I think may be causing conflicts.

If the latest alpha does work (but it probably might not?), could you please post some logs of what is sent to CloudFront (should be in debug now)?

Also, please try 1.18.0-alpha.1 or 1.18.0-alpha.0 and see if this issue occurs there (I guess it will be working for you like 1.17). The above change is only in 1.18.0-alpha.2 or later.

@eddeee888
Copy link
Author

Yes, you are right, 1.18.0-alpha.1 works well. :)

@dphang
Copy link
Collaborator

dphang commented Oct 30, 2020

Thanks, let me just do some testing and see if it's safe to revert that change, I think it should be.

@dphang
Copy link
Collaborator

dphang commented Oct 31, 2020

@eddeee888 please try the latest published alpha, which has this change: #731 and let us know if you are facing any issues. This should revert the change that may have been causing issues. (back to 1.17 behavior).

Unfortunately the domain component that handles the domain input is not unit tested and may not too well for more complex domain/certificate setup.

If you are having issues, I suggest to not use the domain input and instead manage domain and certificate outside of this component (e.g using Terraform).

I also recently added inputs.cloudfront.certificate to let you specify a certificate without using domain input (check README under CloudFront inputs section). Then you can actually use inputs.cloudfront.certificate and inputs.cloudfront.aliases together for this purpose.

@eddeee888
Copy link
Author

eddeee888 commented Oct 31, 2020

Hi @dphang , the new version works! Thanks for solving it so quickly!

Just for my understanding, could you help me understand why domain component is hard to unit test?

I find that using domains is very easy to get started with domains but now when I'm thinking about it, I probably should let something else manage it to avoid accidents that may affect the domain. Thanks for the suggestion!

@dphang
Copy link
Collaborator

dphang commented Oct 31, 2020

Sure, no worries. The domain sub component just doesn't have unit tests - not that it's hard to test. I think perhaps it was imported from somewhere else

@dphang dphang closed this as completed Oct 31, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants