In the wake of Google’s Next ’17 event and the AWS San Francisco Summit 2017, I wanted to continue the AWS vs GCP comparison series. In this part though, I wanted to focus on each public cloud vendor’s Platform as a Service (PaaS). In basic terms, AWS’ Elastic Beanstalk and Google’s App Engine enable development teams to deploy their application without the need to understand how to build or scale the underlying infrastructure. The promise is great, and for most use cases, that promise delivers. More advanced applications requiring more complex integrations and customizations may require users to leave the PaaS in favor of a different platform. But let’s get back to Elastic Beanstalk vs. App Engine.
The first component to compare is what platforms each PaaS supports:
.NET / C#
That was easy, they both support pretty much the same languages. What about custom environments?
Single Container Docker
|Multi Container Docker
While I think for customers using containers it would make more sense to focus on ECS vs. GKE, that comparison is coming in a future post. The take away from the PaaS custom environments is that Elastic Beanstalk supports the use of a custom AMI created with a tool Foghorn uses often, Packer. This provides some flexibility as customers who are comfortable using Elastic Beanstalk can branch out of the standard application support listed above (if needed). Take care though, Elastic Beanstalk and Custom AMIs can increase build times and introduce more complications, like prepping the AMI to be used by Elastic Beanstalk.
Enough with the basics and how they are similar, let’s turn our focus to how they are different.
I am not talking about how fast your app will run, that introduces a multitude of possibilities that have nothing to do with the platform you are running on. I am specifically focusing on how fast the PaaS can build and scale. The first part in understanding the speed of Elastic Beanstalk is to understand what the platform is built on. In basic terms, Elastic Beanstalk uses CloudFormation, Auto Scaling Groups, custom code to tie those components to the application stack, a user interface and CLI, and lastly a deployment agent to push your code. The fact that Elastic Beanstalk uses these components means that it is bound to their characteristics. Some changes that you make may require a new EC2 instance, which means your seemingly simple change will actually:
- Update CloudFormation
- Create new Launch Configuration
- Update Auto Scaling Group
- Terminate Instance(s)
- Provision Instance(s)
- Run Elastic Beanstalk Code
- Deploy your application
You could easily be waiting for 5-10 minutes for this to happen. This is a critical component to understand of Elastic Beanstalk. Some changes require the full lifecycle to trigger which can take significant time. Ok, not as long as ordering hardware for the data center.
App Engine on the other hand does not visibly have the same dependency structure on other services. In addition, while you have a user interface, it is really a dashboard not a full configuration interface. Interacting with App Engine is more like using the Elastic Beanstalk CLI. You define your application in an App Engine app.yaml file in your source code. For example, here is the Go hello world file:
runtime: go api_version: go1 handlers: - url: /.* script: _go_app
This is about the absolute minimum to use the default settings, which is likely fine as you are getting started. And this is also the appropriate time to mention one of the best features of App Engine. You can terminate your instances to reduce costs, and as soon as you are ready to use the application again, App Engine will provision an instance and fire up your application on the first request. While in Elastic Beanstalk you could create scheduled auto scaling to reduce your environment to zero instances and back up to one before your day starts, the on-demand activation of App Engine is quite nice. Not to mention we are talking about seconds (or perhaps even less than a second) for App Engine vs. minutes (or perhaps as many as 10 minutes) for Elastic Beanstalk.
The App Engine app.yaml is akin to the Elastic Beanstalk CLI eb create command where you can define everything in a single action.
$ eb create dev-vpc --vpc.id vpc-0ce8dd99 --vpc.elbsubnets subnet-b356d7c6,subnet-02f74b0c --vpc.ec2subnets subnet-0bb7f0cd,subnet-3b6697c1 --vpc.securitygroup sg-70cff265 Creating application version archive "app-160312_014309". Uploading test/app-160312_014309.zip to S3. This may take a while. Upload Complete. Environment details for: dev-vpc Application name: test Region: us-east-1 Deployed Version: app-160312_014309 Environment ID: e-pqkcip3mns Platform: 64bit Amazon Linux 2015.09 v2.0.8 running Java 8 Tier: WebServer-Standard CNAME: UNKNOWN Updated: 2016-03-12 01:43:14.057000+00:00 Printing Status: ...
And like the App Engine app.yaml, you can also provide configuration information for your Elastic Beanstalk environment using .ebextensions:
~/workspace/my-app/ |-- .ebextensions | |-- environmentvariables.config | `-- healthcheckurl.config |-- .elasticbeanstalk | `-- config.yml |-- index.php `-- styles.css
What AWS has provided is a rich Console GUI to enable users to build, clone and manage (most) settings. While the goal in both platforms is to meet the developer at their source control repository, this extensive GUI may be a welcome feature for some users.
Another cool feature that App Engine supports that is not really replicated in Elastic Beanstalk is their traffic splitting. Whereas Elastic Beanstalk does support the idea of a Blue/Green deployment, the end result is a DNS cutover (or rollback). Traffic splitting inside App Engine allows you to specify a percentage of traffic to go to a different version of the service. This is closer to a canary style deployment and may be a big advantage for some applications. This deployment style can be replicated in Elastic Beanstalk by using multiple environments and Route53 weighted DNS entries.
What about these PaaS’ in the real world? Personally I prefer the simplicity and fast changes of App Engine. I have found the random times to deploy changes within Elastic Beanstalk to be tedious in daily use. That said, if your use case does not require many environment changes and little to know configuration management, Elastic Beanstalk is probably a really easy way to get your app stood up on AWS. I also like that App Engine can basically be shut down by terminating your running instances (for development and testing use cases). You can’t really “delete” Elastic Beanstalk unless you want to remove the entire application environment.
I think Elastic Beanstalk is a solid PaaS. For users who want an intuitive GUI that allows for easy configuration, Elastic Beanstalk wins. That said, I personally have spent significant time to get the desired results out of it when an app requires complex configuration not available in the GUI. There is a certain degree of mystery (though the same can be said for App Engine) that in some circumstances becomes a hindrance to progress. I would prefer to use my own code to control the underlying resources (Launch Configuration, Auto Scaling Groups, RDS, Security Groups, etc.), where I have a clear understanding of all the code running, and perhaps more importantly, I am finding the fastest infrastructure deployment model to get changes out quickly and effectively.
Next up in the GCP vs AWS match up is something I am particularly interested in sharing. How GCP project level boundaries can solve a challenging security paradigm in AWS.