CLI tool
einaregilsson/beanstalk-deploy avatar
einaregilsson/beanstalk-deploy

beanstalk-deploy is a GitHub action for Elastic Beanstalk that never rolls back

GitHub action (and command line script) to deploy apps to Elastic Beanstalk

667 stars142 forksJavaScriptMIT

At a glance

What is it?
beanstalk-deploy uploads a zip to S3, creates an Elastic Beanstalk application version from it and deploys that version, waiting for the environment to report Ready and Green. It works as a GitHub action or as a command line script, and the three caveats in its own documentation, no rollback, a single PUT upload and no Git integration, define where it fits.
Who is it for?
beanstalk-deploy suits a team that already produces a zip per release and wants a small, readable deployment step in GitHub Actions with the environment state left visible in the AWS console, and it does not suit a team that needs automatic rollback or packages of many megabytes.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 157 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A five parameter deploy to Elastic Beanstalk

Beanstalk Deploy is a GitHub action and a command line script for deploying applications to AWS Elastic Beanstalk. The mechanism is a fixed sequence, and it is worth knowing because each step has a failure condition of its own.

It takes the application name, the environment name, the version name, the region and a filename. It uploads the file to S3, creates a new version in Elastic Beanstalk, and then deploys that version to the environment. It waits until the deployment is finished, logging any messages that the environment produces during the update, and it exits with a non-zero exit code if the deployment fails.

What it does not do is roll back the environment. That single sentence in the opening paragraph is the most important fact in the documentation for anyone considering it, and it is repeated in the caveats section at the end.

The project is written in JavaScript, published on npm as beanstalk-deploy, and released under the MIT licence. The repository is small and readable: an action.yml for the action definition, beanstalk-deploy.js as the entry point, aws-api-request.js for the AWS API calls, a package.json and a .jshintrc. The last push was on 2026-05-19, and the most recent tags are v23 from 2026-05-19, v22 from 2024-02-16 and v21 from 2022-11-15, the last of which was the change to a node16 runner.

Wiring the action into a workflow

The action expects you to have already produced a zip file containing the version to deploy. The documented workflow checks out the source, zips it, and then calls the action with the deployment parameters and the AWS credentials taken from repository secrets.

The zip step is one line:

yaml
      run: zip -r deploy.zip . -x '*.git*'

and the deploy step is this:

yaml
    - name: Deploy to EB
      uses: einaregilsson/beanstalk-deploy@v22
      with:
        aws_access_key: ${{ secrets.AWS_ACCESS_KEY_ID }}
        aws_secret_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        application_name: MyApplicationName
        environment_name: MyApplication-Environment
        version_label: 12345
        region: us-west-2
        deployment_package: deploy.zip

Two things stand out. The version label is passed explicitly, which means the caller decides the version identity rather than the tool deriving it from a commit, and the credentials come from secrets rather than from a role assumption, although the optional session token parameter exists for exactly that case.

The permissions the credentials need are stated simply: the AWSElasticBeanstalkWebTier policy and the AWSElasticBeanstalkManagedUpdatesCustomerRolePolicy attached to the AWS user should be enough to deploy a project. If you deploy through a temporary role rather than a long lived user, the aws_session_token parameter takes the session token, and the documentation points at the configure-aws-credentials action as the way to obtain one.

Deploying a version that already exists

The action can also deploy a version that is already in Elastic Beanstalk, and the switch is the absence of one input.

Omit the deployment_package parameter and the action assumes the version named in version_label already exists in Beanstalk and attempts to deploy that. The documented example of that variant is:

yaml
    - name: Deploy to EB
      uses: einaregilsson/beanstalk-deploy@v22
      with:
        aws_access_key: ${{ secrets.AWS_ACCESS_KEY_ID }}
        aws_secret_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        application_name: MyApplicationName
        environment_name: MyApplication-Environment
        version_label: 12345
        region: us-west-2

There is a second, more flexible way to get the same behaviour, added in version 5. The use_existing_version_if_available parameter can be set to true, and then the program deploys a version that already exists in Elastic Beanstalk if there is one, but creates it from the deployment package if there is not. The documentation gives the motivation: deploying to multiple environments based on the commit message.

That parameter is optional in the strict sense, and if you leave it out the program behaves exactly as before, deciding between creating a version and deploying one by looking at whether a deployment package was supplied. The project also links an issue where this pattern is discussed in practice.

Waiting for Ready, then checking for Green

The action's waiting behaviour is configurable in three places, and the defaults are conservative.

wait_for_deployment controls whether the action blocks until the deployment is complete. The default is true, and the documentation gives the reason to consider changing it: deployments, and immutable deployments in particular, can take a long time and eat a lot of GitHub Actions minutes. Set it to false and the action starts the deployment and returns, leaving the outcome to the Beanstalk console.

wait_for_environment_recovery addresses the gap between a finished deployment and a healthy environment. The default is to wait 30 seconds after the deployment before deciding whether the environment is fine, and the parameter takes a number of seconds to change that. The documentation notes that smaller environments with fewer resources can take longer to return to normal.

The failure rules are specific. If you are uploading a new version, the action fails when the file already exists in S3, and it also fails when the application version already exists in Beanstalk. Otherwise the action waits until Beanstalk reports that the environment is running the version you passed in and that the status is Ready. If health is not Green once the version is deployed, the action waits 30 seconds to see whether it recovers, and fails the deployment if it has not.

The reasoning behind that last rule is worth keeping in mind, because it looks like a weakness and is not. Beanstalk sometimes gets its health checks wrong during a deploy, and they usually recover right after, so failing the build immediately would break builds that are in fact fine.

The same deploy from a shell

The tool is also usable outside GitHub Actions, and the difference from the action is mostly in how parameters arrive.

The command line program assumes the environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are defined, and the rest of the parameters are passed as arguments:

bash
beanstalk-deploy.js MyApplicationName MyApplication-Environment 12345 us-west-2 deploy.zip

The final file parameter is optional in the same way as in the action, so omitting it makes the program attempt to deploy an existing version instead.

It is distributed as an npm package, so installing it globally with npm install -g beanstalk-deploy puts a beanstalk-deploy command, without the .js extension, on your path. The package metadata declares the bin entry mapping that command to the script, and the version there is 22.0.0.

The repository also contains an aws-api-request.js module, which is where the AWS calls are made, and the action.yml that describes the inputs to the GitHub action. Both entry points share the same script, so the command line program and the action behave the same way apart from how the parameters reach them.

The three caveats, and the official CLI alternative

The caveats section is short and each item changes what you can use the tool for.

The first is the upload. The S3 upload is a simple PUT request and chunked upload is not handled. The documentation says this has worked fine for files of a few megabytes and that much larger files may cause problems. There is no multipart path, so a large application bundle is a genuine risk rather than a theoretical one.

The second is that the script does not roll back if a deploy fails, which is stated in the opening paragraph as well. A failed deployment leaves the environment as it was, and it is your job to start a new deployment or restore the previous version.

The third is the absence of Git integration, and this is where the comparison with the official Elastic Beanstalk command line tool matters. The official EB cli has integration with Git, so it can work with source control directly. This script does not, and the documentation is explicit that it only takes an already made zip file and deploys it.

That is the real trade-off, and it cuts both ways. Building the zip in your workflow keeps the packaging step visible and lets you control exactly what is in the artifact. Using the official cli means the tool owns the packaging and the Git interaction, at the cost of the pipeline having to conform to its expectations. The choice is not about capability so much as about where you want the artifact boundary to sit.

For a large package, the fix is to compress the artifact well or to host it in a bucket you control, which the existing_bucket_name parameter, new in version 18, also allows.

Permissions, buckets and the version gap

The remaining operational details are worth collecting in one place.

On buckets, the existing_bucket_name parameter, available since v18, lets you point the action at a bucket you already have and prevents the action from creating one during deployment. If you omit it, the action creates the bucket, and that requires the API key to have the applicable permissions.

On retries, max_backoff_retries, available since v21, exists for heavy load environments that need more than the default 10 exponential back-off retries, which amount to about a minute at the maximum.

On description, version_description sets the description of the version being created, and the documentation suggests using it to record the commit that triggered the build, for example with the GitHub SHA expression. The environment_name parameter became optional in version 10, and when it is omitted the action creates the version and does not deploy it anywhere, which is a useful mode for a build and deploy split.

On maintenance, the version numbers in the tags and in the package metadata do not agree. The most recent release tag is v23, published on 2026-05-19, the same day as the last push, while package.json still declares version 22.0.0. The action examples in the documentation also reference v22. The practical consequence is that when you pin a version in a workflow, you are pinning a tag, and the tag named in the examples may not be the newest one. The licence is MIT, and the repository is not archived.

Editorial conclusion

beanstalk-deploy suits a team that already produces a zip per release and wants a small, readable deployment step in GitHub Actions with the environment state left visible in the AWS console, and it does not suit a team that needs automatic rollback or packages of many megabytes. Before wiring it in, attach the AWSElasticBeanstalkWebTier and AWSElasticBeanstalkManagedUpdatesCustomerRolePolicy policies to the deploying credentials, and remember that a failed deployment is not rolled back and the action reports a non-zero exit.

Frequently asked questions

What does beanstalk-deploy do?

It takes an application name, environment name, version name, region and filename, uploads the file to S3, creates a new version in Elastic Beanstalk, deploys that version to the environment, waits for the deployment to finish while logging environment messages, and exits with a non-zero code if the deployment fails.

How do I deploy an existing Elastic Beanstalk version with beanstalk-deploy?

Omit the deployment_package input, and the action assumes the version given in version_label already exists in Beanstalk and deploys that. The use_existing_version_if_available parameter, added in version 5, does the same thing but creates the version from the package when it does not exist.

Does beanstalk-deploy roll back a failed deployment?

No. The project documentation states in two places that the script does not roll back the environment if a deploy fails, so restoring the environment is your responsibility.

What AWS permissions does beanstalk-deploy need?

The documentation says the AWSElasticBeanstalkWebTier and AWSElasticBeanstalkManagedUpdatesCustomerRolePolicy policies attached to your AWS user should be enough to deploy. If you use temporary credentials from the AWS Security Token Service, pass the session token with the aws_session_token parameter.

How do I use beanstalk-deploy outside GitHub Actions?

Install the npm package globally with npm install -g beanstalk-deploy, set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY, and pass the application name, environment name, version, region and zip file as arguments, for example beanstalk-deploy MyApplicationName MyApplication-Environment 12345 us-west-2 deploy.zip.

Official sources

  1. einaregilsson/beanstalk-deploy on GitHub
  2. Issues
  3. License: MIT
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/einaregilsson-beanstalk-deploy.svg)](https://hysenlabs.com/projects/einaregilsson-beanstalk-deploy)

Was this useful?