Repository: Miserlou/Zappa

Issue:
Tried creating a deploy group/policy from scratch and ran into issues
<!--- Provide a general summary of the issue in the Title above -->
There is an issue with deploys where it can get stuck in a state where it will give the following error.

<!--- Provide a more detailed introduction to the issue itself, and why you consider it to be a bug -->
ClientError: An error occurred (ResourceConflictException) when calling the CreateFunction operation: Function already exist: test-dev

Deleting 
<!--- Also, please make sure that you are running Zappa _from a virtual environment_ and are using Python 2.7 --> 

## Expected Behavior
<!--- Tell us what should happen -->

## Actual Behavior
<!--- Tell us what happens instead -->

I will be introducing a PR soon with the fix. It will require the "lambda:GetFunction" permission.
<!--- Not obligatory, but suggest a fix or reason for the bug -->

Create a profile with the following policies attached:
"iam:PassRole"
"s3:GetObject"
"lambda:CreateFunction"
"iam:GetRole"
"s3:PutObject"
"s3:CreateBucket"

now try zappa deploy dev a couple of times.
<!--- Provide a link to a live example, or an unambiguous set of steps to -->
<!--- reproduce this bug include code to reproduce, if relevant -->


## Context
<!--- How has this bug affected you? What were you trying to accomplish? -->
I'm trying to figure out minimum amount of policy requirements per zappa commands.
## Your Environment
<!--- Include as many relevant details about the environment you experienced the bug in -->
* Zappa version used: latest from pip
* Operating System and Python version: ubuntu 16.04 and python 2.7.12 on pyenv
* Link to your project (optional):
* Your `zappa_settings.py`: 
I'm using cookie cutter settings and app.py

Tried creating a deploy group/policy from scratch and ran into issues
<!--- Provide a general summary of the issue in the Title above -->
There is an issue with deploys where it can get stuck in a state where it will give the following error.

<!--- Provide a more detailed introduction to the issue itself, and why you consider it to be a bug -->
ClientError: An error occurred (ResourceConflictException) when calling the CreateFunction operation: Function already exist: test-dev

Deleting 
<!--- Also, please make sure that you are running Zappa _from a virtual environment_ and are using Python 2.7 --> 

## Expected Behavior
<!--- Tell us what should happen -->

## Actual Behavior
<!--- Tell us what happens instead -->

I will be introducing a PR soon with the fix. It will require the "lambda:GetFunction" permission.
<!--- Not obligatory, but suggest a fix or reason for the bug -->

Create a profile with the following policies attached:
"iam:PassRole"
"s3:GetObject"
"lambda:CreateFunction"
"iam:GetRole"
"s3:PutObject"
"s3:CreateBucket"

now try zappa deploy dev a couple of times.
<!--- Provide a link to a live example, or an unambiguous set of steps to -->
<!--- reproduce this bug include code to reproduce, if relevant -->


## Context
<!--- How has this bug affected you? What were you trying to accomplish? -->
I'm trying to figure out minimum amount of policy requirements per zappa commands.
## Your Environment
<!--- Include as many relevant details about the environment you experienced the bug in -->
* Zappa version used: latest from pip
* Operating System and Python version: ubuntu 16.04 and python 2.7.12 on pyenv
* Link to your project (optional):
* Your `zappa_settings.py`: 
I'm using cookie cutter settings and app.py



Discussion:
What's happening here?
Starting from no permissions and gradually granting more led to an infinite loop situation where I needed to first try getting a function arn. Deleting my s3 zip files and deleting the lambda function had no effect on advanceing the deployer.

I broke some tests on travis inadvertently so I will try updating on the cli side of things and reopen my PR
Oh, okay, great. Thanks!
What's happening here?
Starting from no permissions and gradually granting more led to an infinite loop situation where I needed to first try getting a function arn. Deleting my s3 zip files and deleting the lambda function had no effect on advanceing the deployer.

I broke some tests on travis inadvertently so I will try updating on the cli side of things and reopen my PR
Oh, okay, great. Thanks!

Resolving patch:
diff --git a/zappa/cli.py b/zappa/cli.py
--- a/zappa/cli.py
+++ b/zappa/cli.py
@@ -523,16 +523,24 @@ def deploy(self):
         if not success: # pragma: no cover
             raise ClickException("Unable to upload to S3. Quitting.")
 
-        # Register the Lambda function with that zip as the source
-        # You'll also need to define the path to your lambda_handler code.
-        self.lambda_arn = self.zappa.create_lambda_function(bucket=self.s3_bucket_name,
-                                                       s3_key=self.zip_path,
-                                                       function_name=self.lambda_name,
-                                                       handler=self.lambda_handler,
-                                                       description=self.lambda_description,
-                                                       vpc_config=self.vpc_config,
-                                                       timeout=self.timeout_seconds,
-                                                       memory_size=self.memory_size)
+
+        # Fixes https://github.com/Miserlou/Zappa/issues/613
+        try:
+            self.lambda_arn = self.zappa.get_lambda_function(
+                function_name=self.lambda_name)
+        except botocore.client.ClientError:
+            # Register the Lambda function with that zip as the source
+            # You'll also need to define the path to your lambda_handler code.
+            self.lambda_arn = self.zappa.create_lambda_function(
+                bucket=self.s3_bucket_name,
+                s3_key=self.zip_path,
+                function_name=self.lambda_name,
+                handler=self.lambda_handler,
+                description=self.lambda_description,
+                vpc_config=self.vpc_config,
+                timeout=self.timeout_seconds,
+                memory_size=self.memory_size
+            )
 
         # Schedule events for this deployment
         self.schedule()
diff --git a/zappa/zappa.py b/zappa/zappa.py
--- a/zappa/zappa.py
+++ b/zappa/zappa.py
@@ -736,13 +736,25 @@ def rollback_lambda_function_version(self, function_name, versions_back=1, publi
 
         return response['FunctionArn']
 
+    def get_lambda_function(self, function_name):
+        """
+        Returns the lambda function ARN, given a name
+
+        This requires the "lambda:GetFunction" role.
+        """
+        response = self.lambda_client.get_function(
+                FunctionName=function_name)
+        return response['Configuration']['FunctionArn']
+
     def get_lambda_function_versions(self, function_name):
         """
         Simply returns the versions available for a Lambda function, given a function name.
 
         """
         try:
-            response = self.lambda_client.list_versions_by_function(FunctionName=function_name)
+            response = self.lambda_client.list_versions_by_function(
+                FunctionName=function_name
+            )
             return response.get('Versions', [])
         except Exception:
             return []


Test patch: