Skip to content

Commit

Permalink
Add webhook support (#14)
Browse files Browse the repository at this point in the history
* Add webhook support

* fix outputs

* fix args

* Ignore special characters

* change to form

* add missing secret

* format

* use json

* Update docs

* Update desc
  • Loading branch information
osterman authored and joshmyers committed Jan 14, 2019
1 parent ff2e84c commit 223f30c
Show file tree
Hide file tree
Showing 6 changed files with 180 additions and 9 deletions.
50 changes: 47 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
# terraform-aws-ecs-codepipeline [![Build Status](https://travis-ci.org/cloudposse/terraform-aws-ecs-codepipeline.svg?branch=master)](https://travis-ci.org/cloudposse/terraform-aws-ecs-codepipeline) [![Latest Release](https://img.shields.io/github/release/cloudposse/terraform-aws-ecs-codepipeline.svg)](https://github.com/cloudposse/terraform-aws-ecs-codepipeline/releases/latest) [![Slack Community](https://slack.cloudposse.com/badge.svg)](https://slack.cloudposse.com)


Terraform Module for CI/CD with AWS Code Pipeline and Code Build for ECS.
Terraform Module for CI/CD with AWS Code Pipeline using GitHub webhook triggers and Code Build for ECS.


---
Expand Down Expand Up @@ -42,8 +42,32 @@ We literally have [*hundreds of terraform modules*][terraform_modules] that are

## Usage


### Trigger on GitHub Push

In this example, we'll trigger the pipeline anytime the `master` branch is updated.
```hcl
module "ecs_push_pipeline" {
source = "git::https://github.com/cloudposse/terraform-aws-ecs-codepipeline.git?ref=tags/0.1.2"
name = "app"
namespace = "eg"
stage = "staging"
github_oauth_token = "xxxxxxxxxxxxxx"
repo_owner = "cloudposse"
repo_name = "example"
branch = "master"
service_name = "example"
ecs_cluster_name = "example-ecs-cluster"
privileged_mode = "true"
}
```

### Trigger on GitHub Releases

In this example, we'll trigger anytime a new GitHub release is cut by setting the even type to `release` and using the `json_path` to *exactly* match an `action` of `published`.

```hcl
module "ecs_codepipeline" {
module "ecs_release_pipeline" {
source = "git::https://github.com/cloudposse/terraform-aws-ecs-codepipeline.git?ref=tags/0.1.2"
name = "app"
namespace = "eg"
Expand All @@ -55,8 +79,12 @@ module "ecs_codepipeline" {
service_name = "example"
ecs_cluster_name = "example-ecs-cluster"
privileged_mode = "true"
github_webhook_events = ["release"]
webhook_filter_json_path = "$.action"
webhook_filter_match_equals = "published"
}
```
(Thanks to [Stack Overflow](https://stackoverflow.com/questions/52516087/trigger-aws-codepipeline-by-github-release-webhook#comment91997146_52524711))



Expand Down Expand Up @@ -94,23 +122,31 @@ Available targets:
| enabled | Enable `CodePipeline` creation | string | `true` | no |
| environment_variables | A list of maps, that contain both the key 'name' and the key 'value' to be used as additional environment variables for the build. | list | `<list>` | no |
| github_oauth_token | GitHub Oauth Token with permissions to access private repositories | string | - | yes |
| github_webhook_events | A list of events which should trigger the webhook. See a list of [available events](https://developer.github.com/v3/activity/events/types/). | list | `<list>` | no |
| image_repo_name | ECR repository name to store the Docker image built by this module. Used as CodeBuild ENV variable when building Docker images. [For more info](http://docs.aws.amazon.com/codebuild/latest/userguide/sample-docker.html) | string | `UNSET` | no |
| image_tag | Docker image tag in the ECR repository, e.g. 'latest'. Used as CodeBuild ENV variable when building Docker images. [For more info](http://docs.aws.amazon.com/codebuild/latest/userguide/sample-docker.html) | string | `latest` | no |
| name | Solution name, e.g. 'app' or 'jenkins' | string | `app` | no |
| namespace | Namespace, which could be your organization name, e.g. 'cp' or 'cloudposse' | string | `global` | no |
| poll_source_changes | Periodically check the location of your source content and run the pipeline if changes are detected | string | `true` | no |
| poll_source_changes | Periodically check the location of your source content and run the pipeline if changes are detected | string | `false` | no |
| privileged_mode | If set to true, enables running the Docker daemon inside a Docker container on the CodeBuild instance. Used when building Docker images | string | `false` | no |
| repo_name | GitHub repository name of the application to be built and deployed to ECS. | string | - | yes |
| repo_owner | GitHub Organization or Username. | string | - | yes |
| service_name | ECS Service Name | string | - | yes |
| stage | Stage, e.g. 'prod', 'staging', 'dev', or 'test' | string | `default` | no |
| tags | Additional tags (e.g. `map('BusinessUnit', 'XYZ')` | map | `<map>` | no |
| webhook_authentication | The type of authentication to use. One of IP, GITHUB_HMAC, or UNAUTHENTICATED. | string | `GITHUB_HMAC` | no |
| webhook_enabled | Set to false to prevent the module from creating any webhook resources | string | `true` | no |
| webhook_filter_json_path | The JSON path to filter on. | string | `$.ref` | no |
| webhook_filter_match_equals | The value to match on (e.g. refs/heads/{Branch}) | string | `refs/heads/{Branch}` | no |
| webhook_target_action | The name of the action in a pipeline you want to connect to the webhook. The action must be from the source (first) stage of the pipeline. | string | `Source` | no |

## Outputs

| Name | Description |
|------|-------------|
| badge_url | The URL of the build badge when badge_enabled is enabled |
| webhook_id | The CodePipeline webhook's ARN. |
| webhook_url | The CodePipeline webhook's URL. POST events to this endpoint to trigger the target. |



Expand All @@ -136,6 +172,14 @@ Check out these related projects.




## References

For additional context, refer to some of these links.

- [aws_codepipeline_webhook](https://www.terraform.io/docs/providers/aws/r/codepipeline_webhook.html) - Provides a CodePipeline Webhook


## Help

**Got a question?**
Expand Down
39 changes: 37 additions & 2 deletions README.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,36 @@ related:

# Short description of this project
description: |-
Terraform Module for CI/CD with AWS Code Pipeline and Code Build for ECS.
Terraform Module for CI/CD with AWS Code Pipeline using GitHub webhook triggers and Code Build for ECS.
# How to use this project
usage: |-
### Trigger on GitHub Push
In this example, we'll trigger the pipeline anytime the `master` branch is updated.
```hcl
module "ecs_push_pipeline" {
source = "git::https://github.com/cloudposse/terraform-aws-ecs-codepipeline.git?ref=tags/0.1.2"
name = "app"
namespace = "eg"
stage = "staging"
github_oauth_token = "xxxxxxxxxxxxxx"
repo_owner = "cloudposse"
repo_name = "example"
branch = "master"
service_name = "example"
ecs_cluster_name = "example-ecs-cluster"
privileged_mode = "true"
}
```
### Trigger on GitHub Releases
In this example, we'll trigger anytime a new GitHub release is cut by setting the even type to `release` and using the `json_path` to *exactly* match an `action` of `published`.
```hcl
module "ecs_codepipeline" {
module "ecs_release_pipeline" {
source = "git::https://github.com/cloudposse/terraform-aws-ecs-codepipeline.git?ref=tags/0.1.2"
name = "app"
namespace = "eg"
Expand All @@ -70,8 +94,14 @@ usage: |-
service_name = "example"
ecs_cluster_name = "example-ecs-cluster"
privileged_mode = "true"
github_webhook_events = ["release"]
webhook_filter_json_path = "$.action"
webhook_filter_match_equals = "published"
}
```
(Thanks to [Stack Overflow](https://stackoverflow.com/questions/52516087/trigger-aws-codepipeline-by-github-release-webhook#comment91997146_52524711))
# Example usage
examples: |-
Expand All @@ -86,6 +116,11 @@ include:
- "docs/targets.md"
- "docs/terraform.md"

references:
- name: "aws_codepipeline_webhook"
description: "Provides a CodePipeline Webhook"
url: "https://www.terraform.io/docs/providers/aws/r/codepipeline_webhook.html"

# Contributors to this project
contributors:
- name: "Erik Osterman"
Expand Down
10 changes: 9 additions & 1 deletion docs/terraform.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,29 @@
| enabled | Enable `CodePipeline` creation | string | `true` | no |
| environment_variables | A list of maps, that contain both the key 'name' and the key 'value' to be used as additional environment variables for the build. | list | `<list>` | no |
| github_oauth_token | GitHub Oauth Token with permissions to access private repositories | string | - | yes |
| github_webhook_events | A list of events which should trigger the webhook. See a list of [available events](https://developer.github.com/v3/activity/events/types/). | list | `<list>` | no |
| image_repo_name | ECR repository name to store the Docker image built by this module. Used as CodeBuild ENV variable when building Docker images. [For more info](http://docs.aws.amazon.com/codebuild/latest/userguide/sample-docker.html) | string | `UNSET` | no |
| image_tag | Docker image tag in the ECR repository, e.g. 'latest'. Used as CodeBuild ENV variable when building Docker images. [For more info](http://docs.aws.amazon.com/codebuild/latest/userguide/sample-docker.html) | string | `latest` | no |
| name | Solution name, e.g. 'app' or 'jenkins' | string | `app` | no |
| namespace | Namespace, which could be your organization name, e.g. 'cp' or 'cloudposse' | string | `global` | no |
| poll_source_changes | Periodically check the location of your source content and run the pipeline if changes are detected | string | `true` | no |
| poll_source_changes | Periodically check the location of your source content and run the pipeline if changes are detected | string | `false` | no |
| privileged_mode | If set to true, enables running the Docker daemon inside a Docker container on the CodeBuild instance. Used when building Docker images | string | `false` | no |
| repo_name | GitHub repository name of the application to be built and deployed to ECS. | string | - | yes |
| repo_owner | GitHub Organization or Username. | string | - | yes |
| service_name | ECS Service Name | string | - | yes |
| stage | Stage, e.g. 'prod', 'staging', 'dev', or 'test' | string | `default` | no |
| tags | Additional tags (e.g. `map('BusinessUnit', 'XYZ')` | map | `<map>` | no |
| webhook_authentication | The type of authentication to use. One of IP, GITHUB_HMAC, or UNAUTHENTICATED. | string | `GITHUB_HMAC` | no |
| webhook_enabled | Set to false to prevent the module from creating any webhook resources | string | `true` | no |
| webhook_filter_json_path | The JSON path to filter on. | string | `$.ref` | no |
| webhook_filter_match_equals | The value to match on (e.g. refs/heads/{Branch}) | string | `refs/heads/{Branch}` | no |
| webhook_target_action | The name of the action in a pipeline you want to connect to the webhook. The action must be from the source (first) stage of the pipeline. | string | `Source` | no |

## Outputs

| Name | Description |
|------|-------------|
| badge_url | The URL of the build badge when badge_enabled is enabled |
| webhook_id | The CodePipeline webhook's ARN. |
| webhook_url | The CodePipeline webhook's URL. POST events to this endpoint to trigger the target. |

47 changes: 45 additions & 2 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,10 @@ data "aws_iam_policy_document" "codebuild" {
}
}

data "aws_caller_identity" "default" {}

data "aws_region" "default" {}

module "build" {
source = "git::https://github.com/cloudposse/terraform-aws-codebuild.git?ref=tags/0.11.0"
enabled = "${var.enabled}"
Expand Down Expand Up @@ -260,6 +264,45 @@ resource "aws_codepipeline" "source_build_deploy" {
}
}

data "aws_caller_identity" "default" {}
resource "random_string" "webhook_secret" {
count = "${var.webhook_enabled == "true" ? 1 : 0}"
length = 32

data "aws_region" "default" {}
# Special characters are not allowed in webhook secret (AWS silently ignores webhook callbacks)
special = false
}

locals {
webhook_secret = "${join("", random_string.webhook_secret.*.result)}"
webhook_url = "${join("", aws_codepipeline_webhook.webhook.*.url)}"
}

resource "aws_codepipeline_webhook" "webhook" {
count = "${var.webhook_enabled == "true" ? 1 : 0}"
name = "${module.codepipeline_label.id}"
authentication = "${var.webhook_authentication}"
target_action = "${var.webhook_target_action}"
target_pipeline = "${aws_codepipeline.source_build_deploy.name}"

authentication_configuration {
secret_token = "${local.webhook_secret}"
}

filter {
json_path = "${var.webhook_filter_json_path}"
match_equals = "${var.webhook_filter_match_equals}"
}
}

module "github_webhooks" {
source = "git::https://github.com/cloudposse/terraform-github-repository-webhooks.git?ref=tags/0.1.1"
enabled = "${var.webhook_enabled}"
github_organization = "${var.repo_owner}"
github_repositories = ["${var.repo_name}"]
github_token = "${var.github_oauth_token}"
webhook_url = "${local.webhook_url}"
webhook_secret = "${local.webhook_secret}"
webhook_content_type = "json"
name = "web"
events = ["${var.github_webhook_events}"]
}
11 changes: 11 additions & 0 deletions outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,14 @@ output "badge_url" {
description = "The URL of the build badge when badge_enabled is enabled"
value = "${module.build.badge_url}"
}

output "webhook_id" {
description = "The CodePipeline webhook's ARN."
value = "${join("", aws_codepipeline_webhook.webhook.*.id)}"
}

output "webhook_url" {
description = "The CodePipeline webhook's URL. POST events to this endpoint to trigger the target."
value = "${local.webhook_url}"
sensitive = true
}
32 changes: 31 additions & 1 deletion variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ variable "github_oauth_token" {
description = "GitHub Oauth Token with permissions to access private repositories"
}

variable "github_webhook_events" {
description = "A list of events which should trigger the webhook. See a list of [available events](https://developer.github.com/v3/activity/events/types/)."
default = ["push"]
}

variable "repo_owner" {
description = "GitHub Organization or Username."
}
Expand Down Expand Up @@ -75,7 +80,7 @@ variable "buildspec" {
# It is recommended you avoid using boolean values and use explicit strings
variable "poll_source_changes" {
type = "string"
default = "true"
default = "false"
description = "Periodically check the location of your source content and run the pipeline if changes are detected"
}

Expand Down Expand Up @@ -136,3 +141,28 @@ variable "environment_variables" {

description = "A list of maps, that contain both the key 'name' and the key 'value' to be used as additional environment variables for the build."
}

variable "webhook_enabled" {
description = "Set to false to prevent the module from creating any webhook resources"
default = "true"
}

variable "webhook_target_action" {
description = "The name of the action in a pipeline you want to connect to the webhook. The action must be from the source (first) stage of the pipeline."
default = "Source"
}

variable "webhook_authentication" {
description = "The type of authentication to use. One of IP, GITHUB_HMAC, or UNAUTHENTICATED."
default = "GITHUB_HMAC"
}

variable "webhook_filter_json_path" {
description = "The JSON path to filter on."
default = "$.ref"
}

variable "webhook_filter_match_equals" {
description = "The value to match on (e.g. refs/heads/{Branch})"
default = "refs/heads/{Branch}"
}

0 comments on commit 223f30c

Please sign in to comment.