aws-amplify / amplify-cli

The AWS Amplify CLI is a toolchain for simplifying serverless web and mobile development.
Apache License 2.0
2.81k stars 819 forks source link

Amplify Custom Resource deployment errors, "S3 Error Message: The specified bucket does not exist" #13142

Closed Mafiend closed 1 year ago

Mafiend commented 1 year ago

How did you install the Amplify CLI?

nom

If applicable, what version of Node.js are you using?

18.16.1

Amplify CLI Version

12.3.0

What operating system are you using?

Mac

Did you make any manual changes to the cloud resources managed by Amplify? Please describe the changes made.

"No manual changes made"

Describe the bug

We added a custom resource to modify one of the amplify sources. We added the custom resource by using the "amplify add custom" command from terminal. The issue we are having, is that when the custom resource contains certain constructs, in our case a route53 RecordSet. We did lose some time thinking the stack wasn't deploying the custom resource, after looking in the console we noticed that indeed the custom resources. Below is the output from the cli after performing "amplify push"

These are the actually errors reported from the cli.:

🛑 The following resources failed to deploy: Resource Name: AWS679f53fac002430cb0da5b7982bd22872D164C4C (AWS::Lambda::Function) Event Type: create Reason: Resource handler returned message: "Error occurred while GetObject. S3 Error Code: NoSuchBucket. S3 Error Message: The specified bucket does not exist (Service: Lambda, Status Code: 400, Request ID: f89fd0c2-2279-4852-8fc3-284d952b063c)" (RequestToken: 96ed14c9-d1bf-328e-2b4c-7c29d947857a, HandlerErrorCode: InvalidRequest)

🛑 CFN Deployment failed for custom resources. Name: AWS679f53fac002430cb0da5b7982bd22872D164C4C (AWS::Lambda::Function), Event Type: create, Reason: Resource handler returned message: "Error occurred while GetObject. S3 Error Code: NoSuchBucket. S3 Error Message: The specified bucket does not exist (Service: Lambda, Status Code: 400, Request ID: f89fd0c2-2279-4852-8fc3-284d952b063c)" (RequestToken: 96ed14c9-d1bf-328e-2b4c-7c29d947857a, HandlerErrorCode: InvalidRequest), IsCustomResource: true

Expected behavior

Should complete without errors, as after using "amplify push" all the resources are deployed as expected and work. If there is a need for amplify to create a lambda for a custom resource, which not sure in our case is really needed, it should create the bucket or use the existing deployment bucket.

Reproduction steps

1.) Create a new amplify project, with auth backend resource.

2.) Run "amplify add custom" and enter any name for the custom resource name

3.) In the custom resource add the code below, you will need to change the domain to one that can be verified in your project.

import * as cdk from 'aws-cdk-lib';
import * as AmplifyHelpers from '@aws-amplify/cli-extensibility-helper';
import { AmplifyDependentResourcesAttributes } from '../../types/amplify-dependent-resources-ref';
import { Construct } from 'constructs';
import * as route53 from 'aws-cdk-lib/aws-route53';
import * as targets from 'aws-cdk-lib/aws-route53-targets';
import * as acm from 'aws-cdk-lib/aws-certificatemanager';
import * as cognito from 'aws-cdk-lib/aws-cognito';
import * as cloudfront from 'aws-cdk-lib/aws-cloudfront';

export class cdkStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps, amplifyResourceProps?: AmplifyHelpers.AmplifyResourceProps) {
    super(scope, id, props);
    /* Do not remove - Amplify CLI automatically injects the current deployment environment in this input parameter */
    new cdk.CfnParameter(this, 'env', {
      type: 'String',
      description: 'Current Amplify CLI env name',
    });

    const dependencies:AmplifyDependentResourcesAttributes = AmplifyHelpers.addResourceDependency(this, 
      amplifyResourceProps.category, 
      amplifyResourceProps.resourceName, 
      [
        {
          category: "api", 
          resourceName: "restapi"
        },
        {
          category: "auth", 
          resourceName: "cognitoAuth"
        },
      ]
    );

    const hostedZone = route53.HostedZone.fromHostedZoneAttributes(this, 'HostedZone', {
      hostedZoneId: 'Z03851282ABCDEFGHI',
      zoneName: 'example.com'
    });
    const userPool = cognito.UserPool.fromUserPoolId(this, 'UserPool', cdk.Fn.ref(dependencies.auth. cognitoAuth.UserPoolId));
    const envName = AmplifyHelpers.getProjectInfo().envName;

    let authDomainName = "staging.auth.example.com";

    if (envName === "prod") {
      authDomainName = "auth.example.com";
    }

    const authCertificate = new acm.Certificate(this, 'Certificate', {
      domainName: authDomainName,
      validation: acm.CertificateValidation.fromDns(hostedZone),
    });

    const userPoolDomain = new cognito.UserPoolDomain(this, 'UserPoolDomain', {
      userPool,
      customDomain: {
        domainName: authDomainName,
        certificate: authCertificate,
      },
    });

    const recordSet = new route53.RecordSet(this, 'MyRecordSet', {
      recordType: route53.RecordType.A,
      target: route53.RecordTarget.fromAlias(
        new targets.UserPoolDomainTarget(userPoolDomain)
      ),
      zone: hostedZone,
    });
  }
}

Project Identifier

No response

Log output

``` # Put your logs below this line ```

Additional information

I also tried changing route53.RecordSet to route53.ARecord and used a binding for and passed the hostedzoneId for CloudFontDist and the user pool cloud front domain. My thinking was maybe the describe cert need for the target type UserPoolDomainTarget was why it was trying to create the lambda. Changing it to ARecord also worked and created the resources as expected but also returned the same bucket error.

If I leave only the Cert and UserPoolDomain constructs, the lambda and role are not made and there is no error, it's only upon using any route53 record construct.

Before submitting, please confirm:

ykethan commented 1 year ago

Hey @Mafiend, thank you for reaching. I was able to reproduce the issue. Observed the Recordset is deploying a lambda function and failing due to assets in the following generated cloudformation template.

"AWS679f53fac002430cb0da5b7982bd22872D164C4C": {
      "Type": "AWS::Lambda::Function",
      "Properties": {
        "Code": {
          "S3Bucket": {
            "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}"
          },
          "S3Key": "bb459fac5f6b4b052aac9803443226d161a5cfe96f4648b21f9e4912c698bf30.zip"
        },
        "Role": {
          "Fn::GetAtt": [
            "AWS679f53fac002430cb0da5b7982bd2287ServiceRoleC1EA0FF2",
            "Arn"
          ]
        },

The Amplify custom resources does not support deploying assets/Lambda functions and this is currently being tracked on https://github.com/aws-amplify/amplify-cli/issues/9055.

josefaidt commented 1 year ago

Closing in favor of tracking #9055 for limitation with CDK resource deployments from assets

github-actions[bot] commented 1 year ago

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see. If you need more assistance, please open a new issue that references this one. If you wish to keep having a conversation with other community members under this issue feel free to do so.