Skip to content

Commit

Permalink
Add Grafana Cloud provider (#3)
Browse files Browse the repository at this point in the history
  • Loading branch information
peterbuecker-form3 authored May 7, 2021
1 parent ef67ef9 commit 79a9885
Show file tree
Hide file tree
Showing 2,316 changed files with 758,602 additions and 2 deletions.
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/bin
/dist
/tags*
/.vscode
/.idea

.terraform.lock.hcl
terraform.tfstate*
.terraform
37 changes: 37 additions & 0 deletions .goreleaser.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Visit https://goreleaser.com for documentation on how to customize this
# behavior.
builds:
- env:
# goreleaser does not work with CGO, it could also complicate
# usage by users in CI/CD systems like Terraform Cloud where
# they are unable to install libraries.
- CGO_ENABLED=0
mod_timestamp: '{{ .CommitTimestamp }}'
flags:
- -trimpath
ldflags:
- '-s -w -X main.version={{.Version}} -X main.commit={{.Commit}}'
goos:
- freebsd
- windows
- linux
- darwin
goarch:
- amd64
- '386'
- arm
- arm64
ignore:
- goos: darwin
goarch: '386'
binary: '{{ .ProjectName }}_v{{ .Version }}'
archives:
- format: zip
name_template: '{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}'
checksum:
name_template: '{{ .ProjectName }}_{{ .Version }}_SHA256SUMS'
algorithm: sha256
release:
prerelease: auto
changelog:
skip: true
15 changes: 15 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
language: go
os: linux
dist: focal
go:
- 1.16.x
env:
global:
secure: "fefqe9CJmuwVbP5xMBLCc3G01l5yFQg966Y5fGdDJO6HLd+m7jOmpOn1HfQibMH9CkyDjz25kKS7il3Qz+NZtvfPl3JBnniJf7KYdUCBWqCOGfvXXeKEED48HIagqGL2OJZ7Y/QmjBfOvI58unsp3k0WORlPMQUb6rkrWWuXr+78Hpy9FK7jZbBSOM73qofxMxwWq9/WDg2UC3n0H6WEs5Km63k0T/EYFeLHrfo+2tMRWSWprO2h2+Jhf4PKbcSinSurf0qMt6+Yo/yGfdjWDyupfWbhM8TAVYgPWziVBUzhVoLmUqj2JP50uveDMwntCIbmIqfQaOM8zKz6k65D+xsS616hSbQafnkVoueSLpHXHeNx4scYihwQvcgP5oTXY0rHDuRN2G+k4mCFPF5Kq6nTj5lAuo4taVwxHLk4ifrZst5AKQ75y3jx/9MW+HEJ/V8pajTBNBbQYKqRrLtsMAJTwcOdJ9v/3V+7kUif6UhCR4Jw+6UwiXFO7MGG76mj0RP9oxe/6MHHezSi4L1FDkNqFUmXtmUhNrpVT1Y+bsAgKbiqbhuz/UMOFCBwqmvEAJUz6yEn8QLNDDBf5mZaNQkbb5sZSrPsCkWaXoE2YUTzUi20Vy6kKoLNIttRJwCBq7/Ev0whsxlSIJ6VwjtE4ZUULzgbTN0O3IJoGDOjxXQ="
script:
- make deps testacc lint
deploy:
- provider: script
script: make deps release
on:
tags: true
65 changes: 65 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
include Makefile.deps

VERSION := 0.0.1
INSTALL_DIR := ~/.terraform.d/plugins/github.com/form3tech-oss/grafanacloud/$(VERSION)/linux_amd64
BINARY := terraform-provider-grafanacloud_v$(VERSION)
SHELL := /bin/bash
PATH := $(PATH):$(PWD)/bin

# Default values used by tests
GRAFANA_CLOUD_MOCK ?= 1
GRAFANA_CLOUD_API_KEY ?= very-secret
GRAFANA_CLOUD_ORGANISATION ?= dummy-org
GRAFANA_CLOUD_STACK ?= dummy-stack

build: lint testacc
mkdir -p bin
go build -o bin/$(BINARY) main.go

test:
GRAFANA_CLOUD_MOCK=$(GRAFANA_CLOUD_MOCK) \
go test -count 1 -v ./...

testacc:
TF_ACC=1 \
GRAFANA_CLOUD_API_KEY=$(GRAFANA_CLOUD_API_KEY) \
GRAFANA_CLOUD_ORGANISATION=$(GRAFANA_CLOUD_ORGANISATION) \
GRAFANA_CLOUD_STACK=$(GRAFANA_CLOUD_STACK) \
GRAFANA_CLOUD_MOCK=$(GRAFANA_CLOUD_MOCK) \
go test -count=1 ./... -v $(TESTARGS) -timeout 120m

lint: vet tflint tffmtcheck

vet:
go vet ./...

tflint:
find ./examples/ -type d -exec tflint \{\} \;

tffmtcheck:
terraform fmt -check -recursive ./examples/

fmt:
go fmt ./...
terraform fmt -recursive ./examples/

install: test build
mkdir -p $(INSTALL_DIR)
cp bin/$(BINARY) $(INSTALL_DIR)/

release:
goreleaser

docs:
tfplugindocs generate

tf-plan: install
cd examples/full && rm -f .terraform.lock.hcl && terraform init && terraform plan

tf-apply: install
cd examples/full && rm -f .terraform.lock.hcl && terraform init && terraform apply

tf-destroy: install
cd examples/full && rm -f .terraform.lock.hcl && terraform init && terraform destroy

.PHONY: build test testacc lint vet tffmtcheck fmt install release docs tf-plan tf-apply tf-destroy
38 changes: 38 additions & 0 deletions Makefile.deps
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
.PHONY: deps
deps: bin/goreleaser bin/tfplugindocs bin/tflint bin/terraform

bin/goreleaser:
mkdir -p bin
wget https://github.com/goreleaser/goreleaser/releases/download/v0.164.0/goreleaser_Linux_x86_64.tar.gz
tar -C bin -xzf goreleaser*tar.gz goreleaser
rm goreleaser*tar.gz*

bin/tfplugindocs:
@if [[ "$$OSTYPE" == "linux-gnu"* ]]; then \
wget https://github.com/hashicorp/terraform-plugin-docs/releases/download/v0.4.0/tfplugindocs_0.4.0_linux_amd64.zip; \
elif [[ "$$OSTYPE" == "darwin"* ]]; then \
wget https://github.com/hashicorp/terraform-plugin-docs/releases/download/v0.4.0/tfplugindocs_0.4.0_darwin_amd64.zip; \
fi
mkdir -p bin
unzip -d bin tfplugindocs*zip tfplugindocs
rm tfplugindocs*zip*

bin/tflint:
@if [[ "$$OSTYPE" == "linux-gnu"* ]]; then \
wget https://github.com/terraform-linters/tflint/releases/download/v0.28.1/tflint_linux_amd64.zip; \
elif [[ "$$OSTYPE" == "darwin"* ]]; then \
wget https://github.com/terraform-linters/tflint/releases/download/v0.28.1/tflint_darwin_amd64.zip; \
fi
mkdir -p bin
unzip -d bin tflint*zip tflint
rm tflint*zip*

bin/terraform:
@if [[ "$$OSTYPE" == "linux-gnu"* ]]; then \
wget https://releases.hashicorp.com/terraform/0.15.2/terraform_0.15.2_linux_amd64.zip; \
elif [[ "$$OSTYPE" == "darwin"* ]]; then \
wget https://releases.hashicorp.com/terraform/0.15.2/terraform_0.15.2_darwin_amd64.zip; \
fi
mkdir -p bin
unzip -d bin terraform*zip terraform
rm terraform*zip*
84 changes: 82 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,82 @@
# terraform-provider-grafanacloud
A Terraform provider for Grafana Cloud resources
# Terraform Provider Grafana Cloud

A Terraform provider for managing Grafana Cloud resources.

## Use Cases

A few possible use-cases for `terraform-provider-grafanacloud` are:

- Managing Grafana Cloud stacks
- Managing API keys for both Grafana Cloud and Grafana instances inside stacks
- Rolling API keys by tainting TF resources
- Collecting information about configured stacks, such as Prometheus / Alertmanager endpoints or user IDs
- Reading Grafana data sources

## Requirements

- [Terraform](https://www.terraform.io/downloads.html) >= 0.13.x
- [Go](https://golang.org/doc/install) >= 1.15

## Installing the provider

1. Clone the repository
1. Enter the repository directory
1. Build the provider using `make build`
1. Install the provider locally using `make install`
1. Add the following code snippet to your Terraform code:
```tf
terraform {
required_providers {
grafanacloud = {
source = "github.com/form3tech-oss/grafanacloud"
version = "0.0.1"
}
}
}
```

## Using the provider

### Configuration

The following provider block variables are available for configuration:

| Name | Description | Default |
| ---- | ----------- | ------- |
| `url` | The URL to Grafana Cloud API | `https://grafana.com/api` |
| `api_key` | The API key used to authenticate with Grafana Cloud. If you want to manage API keys using this provider, this needs to have the `Admin` role | - |
| `organisation` | Slug name of the organisation to manage | - |

For more detailed docs, please refer to the [generated docs](/docs/index.md).

## Developing the provider

If you wish to work on the provider, you'll first need [Go](http://www.golang.org) installed on your machine (see [Requirements](#requirements) above).

To compile the provider, run `make build install`. This will build the provider and put the provider binary in the Terraform plugin directory.

To generate or update documentation, run `go generate`.

## Testing the provider

Both unit tests (`make test`) and acceptance tests (`make testacc`) are provided.

By default, the acceptance tests run against a mock implementation of the Grafana Cloud/Grafana APIs provided by the __internal/mock__ package. If you'd like to instead run acceptance tests against the real API endpoints, please run the following command with proper values for the placeholder variables:

```sh
GRAFANA_CLOUD_MOCK=0 \
GRAFANA_CLOUD_ORGANISATION=my-org-slug \
GRAFANA_CLOUD_STACK=my-stack-slug \
GRAFANA_CLOUD_API_KEY=a-secret-admin-api-key \
make testacc
```

Due to API rate limits, such a test run may not actually pass or might even impact your production API usage, so please be careful about that.

You can obtain debugging output from the `go-resty` HTTP client by setting `HTTP_DEBUG=1` when running tests.

## Releasing the provider

In order to release a new version of the provider to GitHub releases, create and merge a PR to `master`. We currently don't publish to Terraform Registry.

Once that's done, create a new draft release with a tag that follows the [SemVer](https://semver.org/) standard. Travis CI will pick this up, build the binaries for the provider, and convert your pre-release to a final release.
37 changes: 37 additions & 0 deletions docs/data-sources/stack.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "grafanacloud_stack Data Source - terraform-provider-grafanacloud"
subcategory: ""
description: |-
Reads a single Grafana Cloud stack from the organisation by the given name.
---

# grafanacloud_stack (Data Source)

Reads a single Grafana Cloud stack from the organisation by the given name.

## Example Usage

```terraform
data "grafanacloud_stack" "demo" {
slug = "demo"
}
```

<!-- schema generated by tfplugindocs -->
## Schema

### Required

- **slug** (String) Slug name of the stack.

### Read-Only

- **alertmanager_url** (String) Base URL of the Alertmanager instance configured for this stack. Please note that since this URL isn't provided by the Grafana Cloud API, this provider tries to obtain it from the Grafana data sources instead.
- **alertmanager_user_id** (Number) User ID of the Alertmanager instance configured for this stack.
- **id** (Number) ID of the stack.
- **name** (String) Name of the stack.
- **prometheus_url** (String) Base URL of the Prometheus instance configured for this stack.
- **prometheus_user_id** (Number) User ID of the Prometheus instance configured for this stack.


44 changes: 44 additions & 0 deletions docs/data-sources/stacks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "grafanacloud_stacks Data Source - terraform-provider-grafanacloud"
subcategory: ""
description: |-
Reads all Grafana Cloud stacks which are provisioned inside the organisation.
---

# grafanacloud_stacks (Data Source)

Reads all Grafana Cloud stacks which are provisioned inside the organisation.

## Example Usage

```terraform
data "grafanacloud_stacks" "all" {
}
```

<!-- schema generated by tfplugindocs -->
## Schema

### Optional

- **id** (String) The ID of this resource.

### Read-Only

- **stacks** (List of Object) (see [below for nested schema](#nestedatt--stacks))

<a id="nestedatt--stacks"></a>
### Nested Schema for `stacks`

Read-Only:

- **alertmanager_url** (String)
- **alertmanager_user_id** (Number)
- **id** (Number)
- **name** (String)
- **prometheus_url** (String)
- **prometheus_user_id** (Number)
- **slug** (String)


42 changes: 42 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "grafanacloud Provider"
subcategory: ""
description: |-
---
# grafanacloud Provider

A Terraform provider for managing Grafana Cloud resources.

## Use Cases

A few possible use-cases are:

- Managing API keys for both Grafana Cloud and Grafana instances inside stacks
- Revoking API keys by tainting TF resources
- Collecting information about configured Stacks, such as Prometheus / Alertmanager endpoints
- Reading Grafana data sources


## Example Usage

```terraform
provider "grafanacloud" {
# Can also be provided via GRAFANA_CLOUD_API_KEY
api_key = var.your_secret_api_key
# Can also be provided via GRAFANA_CLOUD_ORGANISATION
organisation = "org-slug"
}
```
<!-- schema generated by tfplugindocs -->
## Schema

### Optional

- **api_key** (String, Sensitive) API key used to authenticate with the API. Must have `Admin` role if API keys need to be managed. Might also be provided via `GRAFANA_CLOUD_API_KEY`.
- **organisation** (String) Organisation which the API key belongs to (as slug name). Might also be provided via `GRAFANA_CLOUD_ORGANISATION`
- **temp_key_expires** (Number) Time after which temporary Grafana API admin tokens used to read Grafana API resources expire. Might also be provided via `GRAFANA_CLOUD_TEMP_KEY_EXPIRES`
- **temp_key_prefix** (String) Prefix for temporary Grafana API admin tokens used to read Grafana API resources. Might also be provided via `GRAFANA_CLOUD_TEMP_KEY_PREFIX`
- **url** (String) Grafana Cloud API endpoint including the final `/api`. Might also be provided via `GRAFANA_CLOUD_URL`.
Loading

0 comments on commit 79a9885

Please sign in to comment.