View all files | ||||
This action creates AWS CodeDeploy deployments from your GitHub Actions workflow. Deployment Group and Deployment configuration itself are derived from an additional configuration section in .appspec.yml.
Note: This README assumes you are familiar with the basic AWS CodeDeploy concepts.
While this Action tries to mostly get out of our way, it makes a few basic assumptions:
The necessary configuration will be parsed from an additional branch_config key inside the appspec.yml file – which is the core config file for AWS CodeDeploy that you will need to keep in your repository anyway.
This makes it possible to create a matching configuration once, and then run deployments in different environments automatically. For example, updating a production system for commits or merges on master, and independent staging environments for every open Pull Request branch.
Please consider the following example Actions workflow that illustrates how this action can be used.
First, this configures AWS Credentials in the GitHub Action runner. The aws-actions/configure-aws-credentials action is used for that, and credentials are kept in GitHub Actions Secrets.
Second, the current repository is checked out because we at least need to access the appspec.yml file.
Third, this action is run. It does not need any additional configuration in the workflow file, but we'll look at the appspec.yml file in a second.
Last, another action is used to show how output generated by this action can be used. In this example, it will leave a GitHub comment on the current commit, @notifying the commit author that a deployment was made, and point to the AWS Management Console where details for the deployment can be found.
Due to the first few lines in this example, the action will be run for commits pushed to the master branch and for Pull Requests being opened or pushed to. With that in mind, let's look at the appspec.yml configuration file.
The purpose of the branch_config section is to tell the action how to configure CodeDeploy Deployment Groups and Deployments, based on the branch name the action is run on.
The subkeys are evaluated as regular expressions in the order listed, and the first matching one is used.
The first entry makes the action skip the deployment (do nothing at all) when the current branch is called something like wip/add-feature-x. You can use this, for example, if you have a convention for branches that are not ready for deployment yet, or if branches are created automatically by other tooling and you don't want to deploy them automatically.
Commits on the master branch are to be deployed in a Deployment Group called production. All other commits will create or update a Deployment Group named $BRANCH.staging.acme.tld, where $BRANCH will be replaced with a DNS-safe name derived from the current branch. Basically, a branch called feat/123/new_gimmick will use feat-123-new-gimmick for $BRANCH. Since the Deployment Group Name is available in the $DEPLOYMENT_GROUP_NAME environment variable inside your CodeDeploy Lifecycle Scripts, you can use that to create "staging" environments with a single, generic configuration statement.
Similar to $BRANCH, for workflows triggered by Pull Requests, the string $PR_NUMBER will be replaced by the pull request number.
The deploymentGroupConfig and deploymentConfig keys in each of the two cases contain configuration that is passed as-is to the CreateDeploymentGroup or UpdateDeploymentGroup API calls (for deploymentGroupConfig), and to CreateDeployment for deploymentConfig. That way, you should be able to configure about every CodeDeploy setting. Note that the ec2TagFilters will be used to control to which EC2 instances (in the case of instance-based deployments) the deployment will be directed.
The only addition made will be that the revision parameter for CreateDeployment will be set to point to the current commit (the one the action is running for) in the current repository.
The IAM User that is used to run the action requires the following IAM permissions. Note that depending on your policies you might want to specify narrower Resource ARNs, that is, more specifically tailor the permission to one particular repository and/or application.
As of writing, the AWS CodeDeploy API does not accept new deployment requests for an application and deployment group as long as another deployment is still in progress. So, this action will retry a few times and eventually (hopefully) succeed.
There might be situations where several workflow runs are triggered in quick succession - for example, when merging several approved pull requests in a short time. Since your test suites or workflow runs might take a varying amount of time to finish and to reach the deployment phase (this action), you cannot be sure that the triggered deployments will happen in the order you merged the pull requests (to stick with the example). You could not even be sure that the last deployment made was based on the last commit in your repository.
To work around this, this action includes the GitHub Actions "run id" in the description field for created deployments. Before creating a new deployment, it will fetch the last attempted deployment from the AWS API and compare its run id with the current run. If the current run has a lower id than the last attempted deployment, the deployment will be aborted.
This workaround should catch a good share of possible out-of-order deployments. There is a slight chance for mishaps, however: If a newer deployment happens to start after we checked the run id and finishes before we commence our own deployment (just a few lines of code later), this might go unnoticed. To really prevent this from happening, ordering deployments probably needs to be supported on the AWS API side, see aws/aws-codedeploy-agent#248.
You can use the expression if: steps.<your-deployment-step>.outputs.deploymentGroupCreated==true (or ...==false) on subsequent workflow steps to run actions only if the deployment created a new deployment group (or updated an existing deployment, respectively).
Sooner or later you might want to get rid of the CodeDeploy Deployment Groups created by this action. For example, when you create deployments for pull requests opened in a repo, you might want to delete those once the PR has been closed or merged.
To help you with this, a second action is included in this repo that can delete Deployment Groups, and uses the same rules to derive the group name as described above.
Here is an example workflow that runs for closed pull requests:
As a note to my future self, in order to work on this repo:
This action was written by webfactory GmbH, Bonn, Germany. We're a software development agency with a focus on PHP (mostly Symfony). We're big fans of automation, DevOps, CI and CD, and we're happily using the AWS platform for more than 10 years now.
If you're a developer looking for new challenges, we'd like to hear from you! Otherwise, if this Action is useful for you, add a ⭐️.
Copyright 2020 - 2026 webfactory GmbH, Bonn. Code released under the MIT license.