|
| 1 | +# `create-aws-codedeploy-deployment` GitHub Action |
| 2 | + |
| 3 | +This action creates [AWS CodeDeploy](https://aws.amazon.com/codedeploy/) deployments from your GitHub Actions workflow. |
| 4 | + |
| 5 | +This document assumes you are familiar with the [basic AWS CodeDeploy concepts](https://docs.aws.amazon.com/codedeploy/latest/userguide/primary |
| 6 | +-components.html). |
| 7 | + |
| 8 | +## Design Goals |
| 9 | + |
| 10 | +While this Action tries to mostly get out of our way, it makes a few basic assumptions: |
| 11 | + |
| 12 | +* For your GitHub repository, there is a corresponding CodeDeploy Application already set up. |
| 13 | +* Git branches (and so, GitHub Pull Requests) will be mapped to CodeDeploy Deployment Groups. The action will create these, or update existing ones. |
| 14 | +* Ultimately, a CodeDeploy Deployment is created with a [reference to the current commit in your GitHub repository] |
| 15 | +(https://docs.aws.amazon.com/codedeploy/latest/userguide/integrations-partners-github.html). |
| 16 | + |
| 17 | +The necessary configuration will be parsed from an additional `branch_config` key inside the `appspec.yml` file – which is the core config file for |
| 18 | +AWS CodeDeploy that you will need to keep in your repository anyway. |
| 19 | + |
| 20 | +This makes it possible to create a matching configuration once, and then run deployments in different environments automatically. For example, |
| 21 | +updating a production system for commits or merges on `master`, and independent staging environments for every open Pull Request branch. |
| 22 | + |
| 23 | +## Example Use Case |
| 24 | + |
| 25 | +Please consider the following example Actions workflow that illustrates how this action can be used. |
| 26 | + |
| 27 | +```yaml |
| 28 | +# .github/workflows/deployment.yml |
| 29 | + |
| 30 | +on: |
| 31 | + push: |
| 32 | + branches: |
| 33 | + - master |
| 34 | + pull_request: |
| 35 | + |
| 36 | +jobs: |
| 37 | + deploy: |
| 38 | + runs-on: ubuntu-latest |
| 39 | + steps: |
| 40 | + - uses: aws-actions/configure-aws-credentials@v1 |
| 41 | + with: |
| 42 | + aws-access-key-id: ${{ secrets.ACCESS_KEY_ID }} |
| 43 | + aws-secret-access-key: ${{ secrets.SECRET_ACCESS_KEY }} |
| 44 | + aws-region: eu-central-1 |
| 45 | + - uses: actions/checkout@v2 |
| 46 | + - id: deploy |
| 47 | + uses: webfactory/[email protected] |
| 48 | + - uses: peter-evans/commit-comment@v1 |
| 49 | + with: |
| 50 | + token: ${{ secrets.GITHUB_TOKEN }} |
| 51 | + body: | |
| 52 | + @${{ github.actor }} this was deployed as [${{ steps.deploy.outputs.deploymentId }}](https://console.aws.amazon.com/codesuite/codedeploy/deployments/${{ steps.deploy.outputs.deploymentId }}?region=eu-central-1) to group `${{ steps.deploy.outputs.deploymentGroupName }}`. |
| 53 | +``` |
| 54 | +
|
| 55 | +First, this configures AWS Credentials in the GitHub Action runner. The [aws-actions/configure-aws-credentials](https://github.com/aws-actions/configure-aws-credentials) action is used for that, and credentials are kept in [GitHub Actions Secrets](https://help.github.com/en/actions/configuring-and-managing-workflows |
| 56 | +/creating-and-storing-encrypted-secrets). |
| 57 | +
|
| 58 | +Second, the repo is checked out because we at least need to access the `appspec.yml` file. |
| 59 | + |
| 60 | +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. |
| 61 | + |
| 62 | +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 |
| 63 | +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. |
| 64 | + |
| 65 | +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 |
| 66 | +being opened or pushed to. With that in mind, let's look at the [`appspec.yml` configuration file](https://docs.aws.amazon.com/codedeploy/latest |
| 67 | +/userguide/reference-appspec-file.html). |
| 68 | + |
| 69 | +```yaml |
| 70 | +# .appspec.yml |
| 71 | +
|
| 72 | +# ... here be your existing CodeDeploy configuration. |
| 73 | +
|
| 74 | +# This section controls the action: |
| 75 | +branch_config: |
| 76 | + wip\/.*: ~ |
| 77 | +
|
| 78 | + master: |
| 79 | + deploymentGroupName: production |
| 80 | + deploymentGroupConfig: |
| 81 | + serviceRoleArn: arn:aws:iam::1234567890:role/CodeDeployProductionRole |
| 82 | + ec2TagFilters: |
| 83 | + - { Type: KEY_AND_VALUE, Key: node_class, Value: production } |
| 84 | + deploymentConfig: |
| 85 | + autoRollbackConfiguration: |
| 86 | + enabled: true |
| 87 | +
|
| 88 | + '.*': |
| 89 | + deploymentGroupName: $BRANCH.staging.acme.tld |
| 90 | + deploymentGroupConfig: |
| 91 | + serviceRoleArn: arn:aws:iam::1234567890:role/CodeDeployStagingRole |
| 92 | + ec2TagFilters: |
| 93 | + - { Type: KEY_AND_VALUE, Key: hostname, Value: phobos.stage } |
| 94 | + deploymentConfig: |
| 95 | + autoRollbackConfiguration: |
| 96 | + enabled: false |
| 97 | +``` |
| 98 | + |
| 99 | +The purpose of the `branch_config` section is to tell the action how to configure CodeDeploy Deployment Groups and Deployments, based on the |
| 100 | +branch name the action is run on. |
| 101 | + |
| 102 | +The subkeys are evaluated as regular expressions in the order listed, and the first matching one is used. |
| 103 | + |
| 104 | +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 |
| 105 | +can use this for example if you have a convention for things that are not ready for deployment yet, or if branches are created automatically by other |
| 106 | +tooling and you don't want to deploy them automatically. |
| 107 | + |
| 108 | +Commits on the `master` branch are to be deployed in a Deployment Group called `production`. All other commits will create or update a Deployment |
| 109 | +Group named `$BRANCH.staging.acme.tld`, where `$BRANCH` will be replaced with a DNS-safe name derived from the current branch. Basically, a branch |
| 110 | +called `feat/123/new_gimmick` will use `feat-123-new-gimmick` for `$BRANCH`. Since the Deployment Group Name is available in the |
| 111 | +`$DEPLOYMENT_GROUP_NAME` environment variable inside your CodeDeploy Lifecycle Scripts, you can use that to create "staging" environments with a |
| 112 | +single, generic configuration statement. |
| 113 | + |
| 114 | +The `deploymentGroupConfig` and `deploymentConfig` keys in each of the two cases contain configuration that is passed as-is to the |
| 115 | +[`CreateDeploymentGroup`](https://docs.aws.amazon.com/codedeploy/latest/APIReference/API_CreateDeploymentGroup.html) or |
| 116 | +[`UpdateDeploymentGroup`](https://docs.aws.amazon.com/codedeploy/latest/APIReference/API_UpdateDeploymentGroup.html) API calls (for |
| 117 | +`deploymentGroupConfig`), and to [`CreateDeployment`](https://docs.aws.amazon.com/codedeploy/latest/APIReference/API_CreateDeployment.html) for |
| 118 | +`deploymentConfig`. That way, you should be able to configure about every CodeDeploy setting. Note that the `ec2TagFilters` will be used to control |
| 119 | +to which EC2 instances (in the case of instance-based deployments) the deployment will be directed. |
| 120 | + |
| 121 | +The only addition made will be that the `revision` parameter for `CreateDeployment` will be set to the current GitHub repository and the commit-ID |
| 122 | +that that action is actually run for. |
| 123 | + |
| 124 | +## Usage |
| 125 | + |
| 126 | +0. The basic CodeDeploy setup, including the creation of Service Roles, IAM credentials with sufficient permissions and installation of the |
| 127 | + CodeDeploy Agent on your target hosts is outside the scope of this action. Follow [the documentation](https://docs.aws.amazon.com/codedeploy/latest/userguide/getting-started-codedeploy.html). |
| 128 | +1. [Create a CodeDeploy Application](https://docs.aws.amazon.com/codedeploy/latest/userguide/applications-create.html) that corresponds to your |
| 129 | + repository. By default, this action will assume your application is named by the "short" repository name (so, `myapp` for a `myorg/myapp` GitHub |
| 130 | + repository), but you can also pass the application name as an input to the action. |
| 131 | +2. Connect your CodeDeploy Application with your repository following [these instructions](https://docs.aws.amazon.com/codedeploy/latest/userguide/deployments-create-cli-github.html). |
| 132 | +3. Configure the [aws-actions/configure-aws-credentials](https://github.com/aws-actions/configure-aws-credentials) action in your workflow and |
| 133 | + provide the necessary IAM credentials as secrets. |
| 134 | +4. Add the `branch_config` section to your `appspec.yml` file to map branches to Deployment Groups and their configuration. In the above example, the |
| 135 | +`master` and `.*` sub-sections show the minimal configuration required. |
| 136 | +5. Add `uses: webfactory/[email protected]` as a step to your workflow file. If you want to use the action's outputs, you |
| 137 | + will also need to provide an `id` for the step. |
| 138 | + |
| 139 | +## Action Input and Output Parameters |
| 140 | + |
| 141 | +### Input |
| 142 | + |
| 143 | +* `application`: The name of the CodeDeploy Application to work with. Defaults to the "short" repo name. |
| 144 | + |
| 145 | +### Outputs |
| 146 | + |
| 147 | +* `deploymentId`: AWS CodeDeployment Deployment-ID of the deployment created |
| 148 | +* `deploymentGroupName`: AWS CodeDeployment Deployment Group name used |
| 149 | +* `deploymentGroupCreated`: True, if a new deployment group was created. False, if an existing group was updated. |
| 150 | + |
| 151 | +## Hacking |
| 152 | + |
| 153 | +As a note to my future self, in order to work on this repo: |
| 154 | + |
| 155 | +* Clone it |
| 156 | +* Run `npm install` to fetch dependencies |
| 157 | +* _hack hack hack_ |
| 158 | +* Run `npm run build` to update `dist/*`, which holds the files actually run |
| 159 | +* Read https://help.github.com/en/articles/creating-a-javascript-action if unsure. |
| 160 | +* Maybe update the README example when publishing a new version. |
| 161 | + |
| 162 | +## Credits, Copyright and License |
| 163 | + |
| 164 | +This action was written by webfactory GmbH, Bonn, Germany. We're a software development |
| 165 | +agency with a focus on PHP (mostly [Symfony](http://github.com/symfony/symfony)). We're big |
| 166 | +fans of automation, DevOps, CI and CD, and we're happily using the AWS platform for more than 10 years now. |
| 167 | + |
| 168 | +If you're a developer looking for new challenges, we'd like to hear from you! |
| 169 | + |
| 170 | +- <https://www.webfactory.de> |
| 171 | +- <https://twitter.com/webfactory> |
| 172 | + |
| 173 | +Copyright 2020 webfactory GmbH, Bonn. Code released under [the MIT license](LICENSE). |
0 commit comments