Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: Add README and getting started docs #6

Merged
merged 8 commits into from
Oct 24, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1 +1,55 @@
# Hookdeck Terraform Provider

_[Hookdeck](https://hookdeck.com) is a prebuilt webhook infrastructure. It gives developers the tooling they need to monitor and troubleshoot all their inbound webhooks. For more information, see the [Hookdeck documentation](https://hookdeck.com/docs)._
leggetter marked this conversation as resolved.
Show resolved Hide resolved

This is a Terraform provider for Hookdeck that enables you to manage your Hookdeck account using IaC (Infrastructure-as-Code), including managing your sources, destinations, connections, transformations, and more. It also enables some webhook registration workflow that allows you to configure webhooks as part of your CI/CD processes.
leggetter marked this conversation as resolved.
Show resolved Hide resolved

## Installation

To install Hookdeck Terraform provider:

1. Obtain your Hookdeck API key from [the dashboard](https://dashboard.hookdeck.com/workspace/secrets)
2. Add the following to your Terraform configuration file
leggetter marked this conversation as resolved.
Show resolved Hide resolved

```hcl
terraform {
required_providers {
hookdeck = {
source = "hookdeck/hookdeck"
version = "0.1.2"
}
}
}

provider "hookdeck" {
# set HOOKDECK_API_KEY env var or optionally specify the key in the provider configuration
api_key = var.hookdeck_api_key
}
```

## Using the provider

This readme gives a basic example; for more examples see the [examples/](examples/) folder, rendered documentation on the [Terraform Registry](https://registry.terraform.io/providers/hookdeck/hookdeck/latest/docs), or [docs folder](docs/) in this repository.
leggetter marked this conversation as resolved.
Show resolved Hide resolved

```hcl
# Configure a source
resource "hookdeck_source" "my_source" {
name = "my_source"
}

# Configure a destination
resource "hookdeck_destination" "my_destination" {
name = "my_destination"
url = "https://mock.hookdeck.com"
}

# Configure a connection
resource "hookdeck_connection" "my_connection" {
source_id = hookdeck_source.my_source.id
destination_id = hookdeck_destination.my_destination.id
}
```

## Dependencies

This provider uses [Hookdeck API](https://hookdeck.com/api-ref) and [Hookdeck Go SDK](https://github.com/hookdeck/hookdeck-go-sdk) under the hood.
188 changes: 188 additions & 0 deletions docs/guides/getting-started.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
---
page_title: "Getting Started"
description: "Getting Started with Hookdeck Provider"
---

# Getting Started with Hookdeck Provider

## Hookdeck

Hookdeck is a prebuilt webhook infrastructure. It gives developers the tooling they need to monitor and troubleshoot all their inbound webhooks.

Once integrated, Hookdeck unlocks an entire suite of tools: [alerting](https://hookdeck.com/docs/notifications), [rate limiting](https://hookdeck.com/docs/set-a-rate-limit), [automatic retries](https://hookdeck.com/docs/automatically-retry-events), [one-to-many delivery](https://hookdeck.com/docs/create-a-destination), [payload transformations](https://hookdeck.com/docs/transformations), local testing via the [CLI](https://hookdeck.com/docs/using-the-cli), a feature-rich [API](https://hookdeck.com/docs/using-the-api), and more. It acts as a proxy – routing webhooks from any [source](https://hookdeck.com/docs/sources) to a specified [destination](destinations) – so you can spend less time maintaining an asynchronous event infrastructure and more time building the features your users care about.

-> Visit the [Documentation](https://hookdeck.com/docs/introduction) to learn more about Hookdeck.
leggetter marked this conversation as resolved.
Show resolved Hide resolved

## Terraform

[Terraform](https://developer.hashicorp.com/terraform/intro) is an open-source Infrastructure as Code (IaC) tool that allows you to define and manage infrastructure resources using HashiCorp Configuration Language (HCL). It can be used to manage a wide range of resources, including servers, storage, networks, and cloud services. Terraform is a popular choice for infrastructure automation because it is easy to use, flexible, and powerful.

Hookdeck provides a Terraform provider that helps you utilize Terraform to configure your workspace declaratively instead of relying on the dashboard. You can run Terraform in your CI/CD pipeline and maintain Hookdeck workspace configuration programmatically as part of your deployment workflow.

To get started, follow its documentation to [install Terraform CLI locally](https://developer.hashicorp.com/terraform/downloads).

## Tutorial

Before you begin, make sure you have Terraform CLI installed locally and a Hookdeck API Key obtained from [the dashboard](https://dashboard/hookdeck.com/workspace/secrets).

### Initialize Terraform

In a directory of your choice, create a Terraform config file `main.tf`.

```hcl
# main.tf

terraform {
required_providers {
hookdeck = {
source = "hookdeck/hookdeck"
version = "~> 0.1"
}
}
}

provider "hookdeck" {
api_key = "<YOUR_API_KEY>"
}
```

-> Replace `<YOUR_API_KEY>` with your Hookdeck workspace API key.

After creating your basic configuration in HCL, initialize Terraform and ask it to apply the configuration to Cloudflare.

```sh
$ terraform init
```

Running `terraform init` will download every required plugins in the configuration file, such as Hookdeck Terraform provider, to a local `.terraform`` directory.

Afterwards, you can run `terraform plan` to confirm that you have Terraform properly installed. As you haven't added any resource to for Terraform to manage yet, it will indicate that there are no changes planned with the current state of your infrastructure.

```
$ terraform plan
```

### Source

First, let's create a source resource with Terraform. You can add this resource block to the end of your Terraform configuration file

```hcl
resource "hookdeck_source" "my_source" {
name = "my_source"
}
```

Now, try `terraform plan` again to see what Terraform may suggest

```sh
$ terraform plan
```

```
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create

Terraform will perform the following actions:

# hookdeck_source.my_source will be created
+ resource "hookdeck_source" "my_source" {
+ allowed_http_methods = [
+ "POST",
+ "PUT",
+ "PATCH",
+ "DELETE",
]
+ archived_at = (known after apply)
+ created_at = (known after apply)
+ id = (known after apply)
+ name = "my_source"
+ team_id = (known after apply)
+ updated_at = (known after apply)
+ url = (known after apply)
}

Plan: 1 to add, 0 to change, 0 to destroy.

─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.
```

You can execute this change and create a source in your workspace like so.

```sh
$ terraform apply
```

You can check the dashboard to confirm that a new source was created in your workspace.

To learn more about what options you have with Hookdeck's Source on Terraform, check out [its documentation here](https://registry.terraform.io/providers/hookdeck/hookdeck/latest/docs/resources/source).

### Destination

Here's what a simple destination resource should look with Terraform

```hcl
resource "hookdeck_destination" "my_destination" {
name = "my_destination"
url = "https://mock.hookdeck.com"
}
```

This is a Mock destination which will accepts all of your events so you can inspect on Hookdeck's dashboard.

Similarly, you can run `terraform apply` to create your new destination. As you should see, when running `terraform apply`, Terraform will show the plan and ask for your confirmation before executing it, so you don't need to run `terraform plan` beforehand.

To learn more about what options you have with Hookdeck's Destination on Terraform, check out [its documentation here](https://registry.terraform.io/providers/hookdeck/hookdeck/latest/docs/resources/destination).

### Connection

Lastly, you can create a Hookdeck connection to connect your newly created source and destination.

```hcl
resource "hookdeck_connection" "my_connection" {
source_id = hookdeck_source.my_source.id
destination_id = hookdeck_destination.my_destination.id
}
```

To learn more about what options you have with Hookdeck's Connection on Terraform, check out [its documentation here](https://registry.terraform.io/providers/hookdeck/hookdeck/latest/docs/resources/connection).

### Summary

In this tutorial, you have

- installed Terraform CLI locally and initialized a Terraform project with Hookdeck provider with `terraform init`
- written the configuration code for a Hookdeck source, destination, and connection using Terraform's own declarative programming language HCL
- reviewed and executed the Terraform plan with `terraform plan` and `terraform apply`

Here's the final `main.tf` file:

```
terraform {
required_providers {
hookdeck = {
source = "hookdeck/hookdeck"
version = "~> 0.1"
}
}
}

provider "hookdeck" {
api_key = "<YOUR_API_KEY>"
}

resource "hookdeck_source" "my_source" {
name = "my_source"
}

resource "hookdeck_destination" "my_destination" {
name = "my_destination"
url = "https://mock.hookdeck.com"
}

resource "hookdeck_connection" "my_connection" {
source_id = hookdeck_source.my_source.id
destination_id = hookdeck_destination.my_destination.id
}
```
148 changes: 148 additions & 0 deletions docs/guides/register-external-webhooks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
---
page_title: "Register External Webhooks"
description: "Register External Webhooks with Hookdeck Provider"
---

# Register External Webhooks

Hookdeck Terraform provider provides a solution to help register and unregister webhooks with your providers. It's provider-agnostic, so as long as there's an endpoint to manage webhooks programmatically, you should be able to configure it as part of your workflow.

## Setup

For example, let's say you're using Stripe for payment and want to listen to `charge.succeeded` and `charge.failed` webhook events. Let's start with connection to start listening to incoming webhooks from Stripe.

```hcl
resource "hookdeck_source" "stripe" {
name = "stripe"
}

resource "hookdeck_destination" "payment_service" {
name = "my_destination"
url = "https://api.my-app.com/webhooks/stripe"
}

resource "hookdeck_connection" "stripe_payment_service" {
source_id = hookdeck_source.stripe.id
destination_id = hookdeck_destination.payment_service.id
}
```

## Register Stripe webhook

Stripe provides API endpoints to [create a new webhook](https://stripe.com/docs/api/webhook_endpoints/create) and [delete existing webhook](https://stripe.com/docs/api/webhook_endpoints/delete) which we will use in this example.

```hcl
resource "webhook_registration" "stripe" {
provider = hookdeck

register = {
request = {
method = "POST"
url = "https://api.stripe.com/v1/webhook_endpoints"
headers = jsonencode({
"content-type" = "application/json"
authorization = "Bearer <STRIPE_SECRET_KEY>"
})
body = jsonencode({
url = hookdeck_source.stripe.url
enabled_events = [
"charge.failed",
"charge.succeeded"
]
})
}
}
unregister = {
request = {
method = "DELETE"
url = "https://api.stripe.com/v1/webhook_endpoints/{{.register.response.body.id}}"
headers = jsonencode({
authorization = "Bearer <STRIPE_SECRET_KEY>"
})
}
}
}
```

For many API, you will need the ID of the registered webhook to unregister. You can usually get the ID of the newly registered webhook from the register API response itself. Because of that, Hookdeck Terraform provider will save that response for use in the `unregister` flow. The string values when you configure your `unregister` property are string templates where you'll have access to `.register.response` data which is the HTTP response from the original registration API request.

## Use webhook secret to verify with Hookdeck

Another way you can use the `webhook_registration` resource is to configure Hookdeck [source verification](https://hookdeck.com/docs/signature-verification) as part of your Terraform workflow. With the `webhook_registration` resource above, you can now configure Hookdeck verification like so:

```hcl
resource "hookdeck_source_verification" "stripe_verification" {
source_id = hookdeck_source.stripe.id
verification = {
stripe = {
webhook_secret_key = jsondecode(webhook_registration.stripe.register.response).body.secret
}
}
}
```

As mentioned in the section earlier, the provider will save the response from the registration request to be used later (unregister flow). For some API, that response will also contain some secret information that you can use for verification purposes. As the `webhook_registration` is provider-agnostic, it saves the response in a strigified JSON with 2 fields "body" and "headers". When using that data in the unregistration flow, the provider constructs that response and use it in the template for you to use. When using it in other resources, you will need to decode the stringified JSON using [`jsondecode`](https://developer.hashicorp.com/terraform/language/functions/jsondecode) like the example above.

Putting everything together, to register Stripe webhook with Hookdeck source with source verification, here's how your Terraform code would look like:

```hcl
# Configure Hookdeck source, destination, and connection

resource "hookdeck_source" "stripe" {
name = "stripe"
}

resource "hookdeck_destination" "payment_service" {
name = "my_destination"
url = "https://api.my-app.com/webhooks/stripe"
}

resource "hookdeck_connection" "stripe_payment_service" {
source_id = hookdeck_source.stripe.id
destination_id = hookdeck_destination.payment_service.id
}

# Register Stripe webhook

resource "webhook_registration" "stripe" {
provider = hookdeck

register = {
request = {
method = "POST"
url = "https://api.stripe.com/v1/webhook_endpoints"
headers = jsonencode({
"content-type" = "application/json"
authorization = "Bearer <STRIPE_SECRET_KEY>"
})
body = jsonencode({
url = hookdeck_source.stripe.url
enabled_events = [
"charge.failed",
"charge.succeeded"
]
})
}
}
unregister = {
request = {
method = "DELETE"
url = "https://api.stripe.com/v1/webhook_endpoints/{{.register.response.body.id}}"
headers = jsonencode({
authorization = "Bearer <STRIPE_SECRET_KEY>"
})
}
}
}

# Configure source verification

resource "hookdeck_source_verification" "stripe_verification" {
source_id = hookdeck_source.stripe.id
verification = {
stripe = {
webhook_secret_key = jsondecode(webhook_registration.stripe.register.response).body.secret
}
}
}
```
Loading