Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function not found after manually deleting a function in a SAM CloudFormation stack

I am using sam deploy to deploy lambda function and API gateway. It works fine but it doesn't work after I manually deleted the lambda function via AWS console. I got below error:

"ResourceStatusReason": "Function not found: 
  arn:aws:lambda:ap-southeast-2:286334053171:function:polaroid (Service: 
  AWSLambdaInternal; Status Code: 404; Error Code: ResourceNotFoundException;
  Request ID: b431cbfc-7772-11e9-8022-1b92fa2cfa9e)

What is the proper way to delete the lambda and do a refresh deployment? If this happens, how can I force SAM to create the missing lambda function?

My lambda in template yaml looks like:

...
Resources:
  PolaroidFunction:
    Type: AWS::Serverless::Function 
    Properties:
      FunctionName: test
      CodeUri: ./lambdas
      Handler: lib/index.fun
      Runtime: nodejs8.10
      Events:
        polaroid:
          Type: Api 
          Properties:
            Path: /test
            Method: post
...
like image 250
Joey Yi Zhao Avatar asked May 16 '19 00:05

Joey Yi Zhao


People also ask

What happens when you delete a CloudFormation stack?

During deletion, CloudFormation deletes the stack but doesn't delete the retained resources. Retaining resources is useful when you can't delete a resource, such as a non-empty S3 bucket, but you want to delete the stack.

How do I delete a stack aws Sam?

To delete a stack, you run the aws cloudformation delete-stack command. You must specify the name of the stack that you want to delete. When you delete a stack, you delete the stack and all its resources.

What happens if we delete the resource created by CloudFormation and try to create the same stack?

Short description. If you delete a resource that was created by a CloudFormation stack, then your stack fails to update, and you get an error message.


3 Answers

I guess you already learnt the hard way that you should never manually delete resources managed by SAM or CloudFormation.

In general, if you just want to change the function, you can just call sam build and sam deploy, and the new version of it will be deployed. There is no need to delete anything. If you need a more advanced workflow, you will need to read blog posts. There is no one right way to do this.

To fix your immediate problem however, here is what you can do.1

Firstly, you need to get the generated AWS CloudFormation template:

▶ aws cloudformation get-template --stack-name HelloWorld \
    --template-stage Processed --query TemplateBody | cfn-flip -y > processed.yml

Next, you need to comment out the function in the processed.yml file you just created, and also comment out the Lambda Permissions that refer to it. Save a backup of the original processed.yml file too.

Also, update any other template references to it if possible with the actual values CloudFormation computed when you built the stack, by getting them from your AWS console. For example, if you had references to ${HelloWorldFunction.Arn} you might have to update those references in the template with a string like arn:aws:lambda:ap-southeast-2:123456789012:function:HelloWorld-HelloWorldFunction-1NJGQI7GEAUM1.

Next, validate the template using AWS CloudFormation commands:

▶ aws cloudformation validate-template --template-body file://processed.yml
{
    "CapabilitiesReason": "The following resource(s) require capabilities: [AWS::IAM::Role]",                                                                         
    "Description": "sam-app\nSample SAM Template for sam-app\n",
    "Parameters": [],
    "Capabilities": [
        "CAPABILITY_IAM"
    ]
}

Next, you will update the stack using this modified template. By updating the stack this way, you get your template and real state to be back in sync from CloudFormation's point of view:

▶ aws cloudformation update-stack --template-body file://processed.yml --stack-name HelloWorld --capabilities CAPABILITY_IAM                        
{
    "StackId": "arn:aws:cloudformation:ap-southeast-2:885164491973:stack/HelloWorld/af2c6810-7884-11e9-9bb3-068b1a8e1450"
}

If all goes well, your stack goes into UPDATE_COMPLETE state. Great!

Finally, uncomment all the resources you commented out, and restore all the original values. Then update stack a second time, and your stack should be restored to its original state.

See also:

  • AWS Knowledge Base, 2016, 2019, How do I update an AWS CloudFormation stack that's failing because of a resource that I manually deleted?.
  • More on the cfn-flip utility, if you don't have it.

1 Note that I tested this method using the default HelloWorld Python 2.7 example that ships with SAM.

like image 63
Alex Harvey Avatar answered Oct 08 '22 23:10

Alex Harvey


I had a similar issue. In my case I had deleted the Lambda as an experiment while trying to reset the TRIM_HORIZON to get it to reprocess old events in a DynamoDB Stream.

I found a simpler solution:

Go into the CloudFormation Console and delete the deployed Stack.

sam deploy works fine again after that.

like image 40
Alex R Avatar answered Oct 08 '22 21:10

Alex R


So as suggested in other answers I deleted the function manually from the console.

I was deploying the stack from CDK

The solution

  • comment the lambda function code (in cdk) of the function I deleted manually.
  • Deploy stack
  • Un-comment the code and deploy again
like image 1
Kartik Avatar answered Oct 08 '22 21:10

Kartik