Open kadrach opened 7 years ago
More than willing to entertain this idea.
My initial thought was that Zappa would be the one spitting out the template, but also would be willing to go the other way. Propose an interface?
The other way around is feasible too - probably easier to integrate with existing toolchains. I'm not sure what the best solution would be.
Seeking in put on a template
command from @collingreen @mathom @bjinwright and others
What are the users-stories around this? Is it okay for template
to deploy to S3? The issue I see is that it requires an exiting Lambda ARN..
In my original PR I had more of Zappa templated, but the problem is you have to maintain a zip for lambda in s3 to be able to manage that bit. There are probably a few other gotchas related to how the other commands work as well.
I'm at the moment using Zappa with Sceptre: https://github.com/cloudreach/sceptre to do this. Sceptre can also be invoked using python which is why it would be suitable for Zappa. I strongly recommend looking at sceptre rather than implementing own code to manage CF.
Originally I was interested in this as well, but thinking more on it I'd say a good half step is simply using Outputs and Exporting the relevant Zappa bits. Especially the API Gateway URL.
Another thought might be looking at integrating Zappa with the aws CLIs package
and deploy
commands. In theory Zappa could package and prepare the app, then drop a CFN template referring to the package using a relative path.
The prepared Zappa template should have parameters that could be set for things.
Some advantages to this would be:
package
and deploy
commands Starting with Exports would be a huge help, as long as zappa works by changing the existing stack rather than deleting and recreating it (I haven't checked).
Another very nice use case would be to import values from other CloudFormation stacks within my zappa config. I often have to either hardcode these values from other stacks (and then manually update them later), or create an awkward deploy pipeline where I dynamically generate the zappa config file after querying CloudFormation for stack values. An example of this is VPC subnets, security groups. I'm actually not sure if there're other compelling use-cases for this... Maybe S3 buckets. Neither of these should change frequently unless we're maybe redeploying from scratch for blue/green reasons, or creating new regions, etc. so maybe this isn't a worthwhile feature.
Would love to see a proposal on an interface to some of these features..
In regards to the outputs, I'd propose that any Zappa created resource (S3 bucket, IAM role, API Gateway, etc..) be made available for reference via exported outputs.
http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/outputs-section-structure.html
I looked though, and I believe only the API Gateway pieces are build using a CF stack. Is that correct?
Exports must be globally unique across the AWS account, so a naming convention similar to how the stack name is created would be necessary. For this, though, I'd use CloudFormations convention for resources.
<ProjectName><StageName><Export>
MyZappaAppDevURL MyZappaAppDevS3Bucket
For generating the CF template, there is a related issue on troposphere's repo:
https://github.com/cloudtools/troposphere/issues/567
But my preference would be to have a generate
command:
zappa generate <stage> --output-file=zappa_app.yaml
Without output-file
the command generates to the console, with it the file extension is parsed for the format (YAML / JSON).
The template that gets output can be deployed on its own using aws cloudformation deploy
or it can be referenced as a nested stack within a larger app template. All configuration variables are output as Parameters so that they can be overridden in a nested stack using CF's !Ref syntax.
I think something like this would require all resources to be provisioned using a CF template though. Not sure what the LOE on that would be.
You can still declare exports in a CFN stack for resources created outside that stack, as a workaround. As long as Zappa provisions those resources simultaneously with creating the stack (and before creating the stack), it should be safe enough.
Decoupling stack deployment from everything else in Zappa would make this dangerous (i.e. your generate
proposal) so I'd say having everything be provisioned by CloudFormation would be a blocker on that.
There is now a template
command which spits out the simple CF template we use. I needed it for a thing.
I'm not really happy with it because it can't create other resources, so I'm leaving this ticket up open for now until I change my mind.
I want to experiment next with using zappa package
+ managing the cloudformation template independently, deploying it via awscli or sceptre. This might be a learning opportunity to see how to best adapt Zappa. I wonder whether longer term it makes sense to narrow the scope of what Zappa itself provides, and integrate with more canonical tooling for other parts.
I was able to deploy the results of zappa package
using Amazon's SAM templates but ran into a couple of gaps.
Permissions. I tried using some of the built in managed policies, but ended up simply applying the created ZappaExecutionRole to the function once deployed. Once permissions are figured out, it's easy to include a role for the function in the template.
Binary Support. From what I've researched CF isn't supporting adding the Binary Support patterns for API Gateway within a template yet.
That's as far as I took it, but I don't think its far off.
Seems someone got binary support working in Cloudformation at the end here: https://forums.aws.amazon.com/thread.jspa?threadID=243438
I tried this in a SAM template and it didn't work. It fails with an error stating that it isn't supported.
AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Resources:
ApplicationLambda:
Type: 'AWS::Serverless::Function'
Properties:
Handler: handler.lambda_handler
Runtime: python2.7
CodeUri: ./src/server/app-prod-1493327007.zip
MemorySize: 512
Events:
Root:
Type: Api
Properties:
Path: /
Method: any
ApplicationResource:
Type: Api
Properties:
Path: /{proxy+}
Method: any
x-amazon-apigateway-binary-media-types: "*/*"
Failed to create the changeset: Waiter ChangeSetCreateComplete failed: Waiter encountered a terminal failure state Status: FAILED. Reason: Transform AWS::Serverless-2016-10-31 failed with: Invalid Serverless Application Specification document. Number of errors found: 1. Resource with id [ApplicationLambdaApplicationResource] is invalid. property x-amazon-apigateway-binary-media-types not defined for resource of type Api
Thanks! Next I'd be interested to try this with a non-SAM CloudFormation template.
I have a Terraform based one that is semi-working, but honestly it seems like Zappa is better at setting this stuff up itself than the other tools..
On Fri, Apr 28, 2017 at 12:44 PM, Alex Ehlke notifications@github.com wrote:
Thanks! Next I'd be interested to try this with a non-SAM CloudFormation template.
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/Miserlou/Zappa/issues/634#issuecomment-298048014, or mute the thread https://github.com/notifications/unsubscribe-auth/AAIi01sp0AW1fTzGNiUdSuZubRFSOg2uks5r0hdggaJpZM4Lw9c- .
Ok, I ended up getting a response from AWS regarding the permissions issue and they said sometimes IAM roles can take longer to propagate than usual and that's why I had some issues. So, at the moment, this template works:
AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Resources:
ApplicationLambda:
Type: 'AWS::Serverless::Function'
Properties:
Handler: handler.lambda_handler
Runtime: python2.7
CodeUri: ./src/server/app-prod-1493327007.zip
MemorySize: 512
Policies:
- AWSLambdaExecute
- AWSLambdaFullAccess
Events:
Root:
Type: Api
Properties:
Path: /
Method: any
ApplicationResource:
Type: Api
Properties:
Path: /{proxy+}
Method: any
I'm using AWS managed policies vs. the zappa created role and it looks to be working.
I have a Terraform based one that is semi-working, but honestly it seems like Zappa is better at setting this stuff up itself than the other tools..
CloudFormation is particularly compelling for a few reasons:
undeploy
safer and trivial - just delete the stack.That's what comes to mind from my own experiences.
Jeff Barr just tweeted out this serverless plugin:
https://github.com/SAPessi/serverless-sam
It exports a SAM template that can be used via the AWS CLI.
What I see from this discussion Zappa is offering very wide feature set and it seems it is starting to be too opinionated and limiting when comes to parts other than Lambda <-> WSGI bridge + nice Lambda packaging utility (utilizing bridge mentioned). How about splitting the project to smaller pieces (starting from Lambda <-> WSGI bridge) while keeping framework (which Zappa is right now) as a recommended way of using it / quick start? What Zappa is trying to do right now:
It would definitely simplify things after split and get broader audience to adapt/utilize smaller parts currently needed.
I'd be quite satisfied if Zappa supported !ImportValue
for things like security groups, or really anything that might go in a normal zappa config file that might reference some infrastructure resource.
Is there a facility to include custom CloudFormation resources in the generated CF stack? My APIs often require some kind of data source, e.g. a DynamoDB table.
The template is already generated via troposphere, it'd be nice to hook into this and add a resource. (And wishful thinking - Zappa to translate
Ref
where required).Also, the CF stack does not generate outputs (or I can't see the switch to enable them), so the stack cannot be reused in a nested template.