Code Monkey home page Code Monkey logo

terraform-provider-stripe's Introduction

Terraform Stripe Provider

This provider enables Stripe merchants to manage certain parts of their Stripe infrastructure—products, plans, webhook endpoints—via Terraform.

Example use cases

  • Create and update resources in a repeatable manner
  • Clone resources across multiple Stripe accounts (e.g. different locales or brands)

Since Terraform 13 and the Terraform Registry, no need to download a release or compile this on your own machine (unless you really want to.) Just jump to the Basic Usage section and get going!

Requirements

  • Terraform 0.11.x to 0.13.x
  • Go 1.8 to 1.14 (to build the provider plugin)

Building The Provider

Clone repository anywhere:

$ git clone https://github.com/franckverrot/terraform-provider-stripe.git

Enter the provider directory and build the provider

$ cd terraform-provider-stripe
$ make compile

Or alternatively, to install it as a plugin, run

$ cd terraform-provider-stripe
$ make install

Using the provider

If you're building the provider, follow the instructions to install it as a plugin. After placing it into your plugins directory, run terraform init to initialize it.

Basic Usage

Set an environment variable, TF_VAR_stripe_api_token to store your Stripe API token. This helps ensure you do not accidentally commit this sensitive token to your repository.

export TF_VAR_stripe_api_token=<your token>

Your token is now accessible in your Terraform configuration as var.stripe_api_token, and can be used to configure the provider.

The example below demonstrates the following operations:

  • create a product
  • create a plan for that product
  • create a webhook endpoint for a few events
terraform {
  required_providers {
    stripe = {
      source = "franckverrot/stripe"
      version = "1.8.0"
    }
  }
}

provider "stripe" {
  # NOTE: This is populated from the `TF_VAR_stripe_api_token` environment variable.
  api_token = "${var.stripe_api_token}"
}

resource "stripe_product" "my_product" {
  name = "My Product"
  type = "service"
}

resource "stripe_plan" "my_product_plan1" {
  product  = "${stripe_product.my_product.id}"
  amount   = 12345
  interval = "month"                           # Options: day week month year
  currency = "usd"
}

resource "stripe_webhook_endpoint" "my_endpoint" {
  url = "https://mydomain.example.com/webhook"

  enabled_events = [
    "charge.succeeded",
    "charge.failed",
    "source.chargeable",
  ]
}

resource "stripe_coupon" "mlk_day_coupon_25pc_off" {
  code     = "MLK_DAY"
  name     = "King Sales Event"
  duration = "once"

  amount_off = 4200
  currency   = "usd" # lowercase

  metadata = {
    mlk   = "<3"
    sales = "yes"
  }

  max_redemptions = 1024
  redeem_by       = "2019-09-02T12:34:56-08:00" # RFC3339, in the future
}

Supported resources

  • Products

    • name
    • type
    • active (Default: true)
    • attributes (list)
    • metadata (map)
    • statement descriptor
    • unit label
  • Prices

    • active (Default: true)
    • currency
    • metadata (map)
    • nickname
    • product
    • recurring
    • unit_amount
    • billing_scheme
    • unit_amount_decimal
    • tiers (Stripe API doesn't provide the API to update this at the moment, so the deletion should be done via dashboard page)
    • tiers mode
  • Plans

    • active (Default: true)
    • aggregate usage
    • amount
    • amount_decimal
    • billing scheme (Default: per_unit)
    • currency
    • interval
    • interval_count (Default: 1)
    • metadata (map)
    • nickname
    • product
    • tiers
    • tiers mode
    • transform_usage
    • trial period days
    • usage type (Default: licensed)
  • Webhook Endpoints

    • url
    • enabled_events (list)
    • connect
    • Computed:
      • secret
  • Coupons

    • code (aka id)
    • name
    • amount off
      • currency
    • percent off
    • duration
      • duration_in_months
    • max redemptions
    • metadata
    • redeem by (should be RC3339-compliant)
    • Computed:
      • valid
      • created
      • livemode
      • times redeemed
  • TaxRates

    • code (aka id)
    • active
    • description
    • display_name
    • inclusive
    • jurisdiction
    • DELETE API (Stripe API doesn't provide the API at the moment, so the deletion should be done via dashboard page)
    • Computed:
      • created
      • livemode
  • Customer Portal

    • business_profile
      • headline
      • privacy_policy_url
      • terms_of_service_url
    • features
      • customer_update
        • allowed_updates
      • invoice_history
      • payment_method_update
      • subscription_cancel
      • subscription_pause
      • subscription_update
    • default_return_url
    • metadata

Importing existing resources

Scenario: you create something manually and would like to start managing it with Terraform instead.

This provider support a straightforward/naive import procedure, here's how you could do it for a coupon.

First, import the resource:

$ terraform import stripe_coupon.mlk_day_coupon_25pc_off MLK_DAY

...
Before importing this resource, please create its configuration in the root module. For example:

resource "stripe_coupon" "mlk_day_coupon_25pc_off" {
  # (resource arguments)
}

Then after adding these lines to your Terraform file, a plan should result in:

$ terraform plan

...
-/+ stripe_coupon.mlk_day_coupon_25pc_off (new resource required)
      id:              "MLK_DAY" => <computed> (forces new resource)
      amount_off:      "4200" => "4200"
      code:            "" => "MLK_DAY"
      created:         "" => <computed>
      currency:        "usd" => "usd"
      duration:        "once" => "once"
      livemode:        "false" => <computed>
      max_redemptions: "1024" => "1024"
      metadata.%:      "2" => "2"
      metadata.mlk:    "<3" => "<3"
      metadata.sales:  "yes" => "yes"
      name:            "King Sales Event" => "King Sales Event"
      redeem_by:       "" => "2019-09-02T12:34:56-08:00" (forces new resource)
      times_redeemed:  "0" => <computed>
      valid:           "true" => <computed>

Some updates might require replacing existing resources with new ones.

Developing the Provider

If you wish to work on the provider, you'll first need Go installed on your machine (version 1.8+ is required). You'll also need to correctly setup a GOPATH, as well as adding $GOPATH/bin to your $PATH.

To compile the provider, run make. This will build the provider and put the provider binary in the $GOPATH/bin directory.

$ make bin
...
$ $GOPATH/bin/terraform-provider-stripe
...

License

Mozilla Public License Version 2.0 – Franck Verrot – Copyright 2018-2020

terraform-provider-stripe's People

Contributors

alephyud avatar allanlegalstart avatar bradrydzewski avatar clintonb-stripe avatar drselump14 avatar florisvdg avatar franckverrot avatar intrepidd avatar jchorl avatar kabesan avatar magni- avatar mdreem avatar oleg-codaio avatar ralsu091 avatar till avatar trea avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

terraform-provider-stripe's Issues

Managing prices

Updating certain properties of a price will force a replacement of the stripe_price resource. But prices are not deletable via the API - so we have to do this manually in the dashboard. But furthermore, prices can only be deleted in the dashboard as long as they have not been used. If they have been used, the way to go is to update them as inactive.

Now, managing these with terraform becomes a bit tedious. Deleting/deactivating the price in the dashboard, then do a manually terraform state rm on the resource.

Does it make sense to update them as inactive in this terraform provider in case of destroy? Thereby, we could have a working flow - and if they have not been used, I can still go into the dashboard and delete them.

Setting metadata with undefined / empty string

What is the correct way to store metadata properties? Stripe unsets metadata properties by setting an empty string. But if my state stores the metadata property as an empty string, it processes as out of sync: an empty string in the state and an undefined/deleted property in Stripe.

Publish provider for use in Terraform 0.13

👋 Hi, I'm on the Terraform Providers team at HashiCorp. With the release of the Terraform 0.13 beta, users can now download and install community providers from the registry. We are inviting provider authors (especially those for popular community providers) to publish their providers in a closed beta.

To get invited to the closed beta, please email [email protected]. We need:

  • A list of GitHub usernames to add to the beta (you and any team members who will publish)
  • List of provider repositories you plan to publish
  • A GPG public key in ASCII-armor format, which you will be using to sign your provider releases

You can use one key for all of your providers, or separate keys if you prefer. If you are publishing from an organization, this key or keys will be associated with that namespace. Once in the beta, you can manage personal keys in the UI as well.

Support for creating API keys

I'd like to dynamically provision Stripe API keys for my app that are easy to revoke.

The simplest way to do this seems to be using a master API key with this provider and then using this provider to create per-app API keys.

I see that there's support for client secrets for the Stripe Connect API. Is there a technical reason that API keys are not supported?

Different behavior when using release and building from source

When I install a 0.12 compatible GitHub release of this provider (i.e. 1.0.0 and 1.1.0) and terraform validate my 0.12 Terraform code, I get an error that the plugin is outdated:

Error: Failed to instantiate provider "stripe" to obtain schema: 
Incompatible API version with plugin. Plugin version: 4, Client versions: [5]

However, when I make install the corresponding commit, it works just fine.

Cannot set price unit_amount to 0

When I try to create a price with a unit_amount of 0, or unit_amount_decimal of 0.0, I get the following error:

Error: {"status":400,"message":"If the billing scheme is set to per_unit, the amount parameter must be set.","param":"amount","request_id":"req_abcdefghijklmn","type":"invalid_request_error"}

When I look at Stripe logs, the field is left out of the request entirely:

{
  "active": "true",
  "billing_scheme": "per_unit",
  "currency": "usd",
  "product": "prod_abcdefghijklmn",
  "recurring": {
    "interval": "year",
    "interval_count": "1",
    "usage_type": "licensed"
  }
}

This is incorrect - an amount of 0 is valid and I can use the API directly to create the price.

Please consider retagging with Go Modulex prefix

Hi, I've noticed that recent tags to this project don't have the "v" prefix, ie. the tag is 1.4.0 unlike 1.2.0 which was tagged v1.2.0. Please consider adding tags with the v prefix, both so that they can be recognized by Go Modules, and also so that package maintainers building this library have a consistent way to reference releases. Thanks for your time and consideration!

Stripe Product - Add `tax_code` as a resource definition parameter

To help support the ability to automatically collect taxes from the prices of products that make up a description, it would be helpful if the resource definition of a stripe_product could include the tax_code property.

Sample request POST body that features a tax_code

{
  "description": "",
  "metadata": {
    "some_key": "some_value"
  },
  "statement_descriptor": "",
  "images": "",
  "tax_code": "txcd_10000000",
  "feature_list": "",
  "unit_label": "",
  "name": "My Test Product"
}

Updating the stripe/resource_stripe_product.go file with something like

			"tax_code": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
			},

Then updating the create, read, and update functions accordingly.

The biggest challenge I see here is if a developer inputs an invalid tax code, Stripe might yell and give a 400 error, but that should be caught when the client calls to create a new product? It's kind of up to the developer to search Stripe and figure out the tax code they want to use.

Add tax_behavior attribute to prices

It would be great to have this price attribute available as we already have tax rates, but cannot use the tax capabilities completely as prices need to have a tax behavior

'terraform apply' with deleted coupon in state gives error code 'resource_missing'

Hi there, and thank you for this provider! Looking forward to making use of it.
I was fiddling with some of the basic usage stuff outlined in the README and ran into a snag.

  1. Created the example MLK coupon with code = "MLK_DAY"
  2. Changed the code value in my .tf file
  3. Ran terraform apply --auto-approve
  4. Noted in the Stripe Dashboard UI that the coupon code did not change, and remained as MLK_DAY
  5. Ran terraform apply --auto-approve again
  6. Coupon code still stubbornly staying on MLK_DAY
  7. Deleted coupon manually in Stripe Dashboard UI
  8. Ran terraform apply --auto-approve again and got the following:
Error: {
  "code": "resource_missing",
  "doc_url": "https://stripe.com/docs/error-codes/resource-missing",
  "status": 404,
  "message": "No such coupon: 'MLK_DAY'",
  "param": "coupon",
  "request_id": "req_bCoPRMtuRHTxLW",
  "type": "invalid_request_error"
}

Will take a quick look and see if I can put a PR together to straighten things out.

The 2 issues as I see them:

  • can't update coupon code, even if it requires deletion and (re)creation of said coupon
  • if coupon was previously created by Terraform but then deleted outside of a Terraform operation, Terraform should handle it a little more gracefully, and probably attempt to recreate as it sees fit

Stripe throwing 429s with high Terraform parallelism

To speed up diffs in Terraform, we run terraform plan / apply with higher parallelism using the parallelism flag. Unfortunately, that can occasionally result in errors like this from the Stripe provider:

Error: {"code":"rate_limit","status":429,"message":"Testmode request rate limit exceeded, the rate limits in testmode are lower than livemode. You can learn more about rate limits here https://stripe.com/docs/rate-limits.","type":"invalid_request_error"}

This can happen on both testmode and live instances, depending on the parallelism. Meanwhile, we're using AWS and I suppose the rate limits there are more generous, since even having 200x parallelism isn't a problem.

Is it possible to specifically set rate limits on this module? I know this might be more of a general issue with Terraform than specifically this provider (i.e., if Terraform allowed setting the parallelism on a per-module/resource basis, see hashicorp/terraform#14258), but I wanted to log it anyway. I'm not super familiar with the implementation, but maybe we could add some kind of queueing or randomized exponential retry logic to this provider.

Having trouble using Stripe provider resources within a module

First up, thanks a lot for putting in the effort to create this provider, much needed IaC way of dealing with Stripe 🙏

I am having an issue trying to use this provider when I try to put Stripe resources within a module, not sure what am I missing here. When I keep everything within the same file (no modules) and do terraform init and terraform plan, everything works perfectly fine. However when I try to move the Stripe resources to a module and do terraform init, I get the following error:

Initializing modules...

Initializing the backend...

Initializing provider plugins...
- Using previously-installed franckverrot/stripe v1.8.0
- Using previously-installed hashicorp/aws v3.34.0
- Finding latest version of hashicorp/stripe...

Error: Failed to install provider

Error while installing hashicorp/stripe: provider registry
registry.terraform.io does not have a provider named
registry.terraform.io/hashicorp/stripe

I have tried explicitly passing the provider alias to the module as well but to no avail. Would appreciate if anyone can point me in the right direction. Haven't been able to find much through googling, README or issues on the repo.

Additional info

Example of working config ✅

# main.tf
terraform {
  required_providers {
    stripe = {
      source = "franckverrot/stripe"
      version = "1.8.0"
    }
  }
}

provider "stripe" {
  api_token = var.stripe_api_token
}

resource "stripe_webhook_endpoint" "webhook" {
  url = "https://example.com"

  enabled_events = [
    "checkout.session.completed"
  ]
}

Example of failing config 🛑

# main.tf
terraform {
  required_providers {
    stripe = {
      source = "franckverrot/stripe"
      version = "1.8.0"
    }
  }
}

provider "stripe" {
  api_token = var.stripe_api_token
}

module "stripe" {
  source = <path-to-source>
}

# module/main.tf
resource "stripe_webhook_endpoint" "webhook" {
  url = "https://example.com"

  enabled_events = [
    "checkout.session.completed"
  ]
}

Can't create a $0 amount stripe_plan

resource "stripe_plan" "base_platform_fee_0" {
  product    = stripe_product.base_platform_fee.id
  nickname   = "$0/month (Annual Prepaid)"
  amount     = 0
  interval   = "month"
  usage_type = "licensed"
  currency   = "usd"
}

ends up posting this to stripe:

{
  "active": "true",
  "billing_scheme": "per_unit",
  "currency": "usd",
  "interval": "month",
  "interval_count": "1",
  "nickname": "$0/month (Annual Prepaid)",
  "product": "prod_FM8XCymxvqHCB5",
  "usage_type": "licensed"
}

raising a 400 from stripe:

{
  "error": {
    "message": "If the billing scheme is set to per_unit, the amount parameter must be set.",
    "param": "amount",
    "type": "invalid_request_error"
  }
}

TF errors:

Error: {"status":400,"message":"If the billing scheme is set to per_unit, the amount parameter must be set.","param":"amount","request_id":"req_REKuHBMBjmHbEo","type":"invalid_request_error"}
 

 
  on modules/stripe/main.tf line 35, in resource "stripe_plan" "base_platform_fee_0":
 
  35: resource "stripe_plan" "base_platform_fee_0" {

 
Error: {"status":400,"message":"If the billing scheme is set to per_unit, the amount parameter must be set.","param":"amount","request_id":"req_AMXW3u1lDwXQGE","type":"invalid_request_error"}
  on modules/stripe/main.tf line 35, in resource "stripe_plan" "base_platform_fee_0":
 
  35: resource "stripe_plan" "base_platform_fee_0" {

Stripe connect webhook incorrectly set

Hi, I noticed when creating two webhooks:

resource "stripe_webhook_endpoint" "stripe" {
  url = "${aws_api_gateway_stage.stage.invoke_url}${aws_api_gateway_resource.stripe.path}"

  enabled_events = [
    "charge.captured",
    "charge.expired",
    "charge.failed",
    "charge.pending",
    "charge.refund.updated",
    "charge.refunded",
    "charge.succeeded",
    "charge.updated",
    "checkout.session.async_payment_failed",
    "checkout.session.async_payment_succeeded",
    "checkout.session.completed",
  ]
}

resource "stripe_webhook_endpoint" "stripe-connect" {
  url     = "${aws_api_gateway_stage.stage.invoke_url}${aws_api_gateway_resource.stripe-connect.path}"
  connect = true

  enabled_events = [
    "account.application.deauthorized",
    "account.updated",
    "charge.captured",
    "charge.refund.updated",
    "charge.refunded",
    "checkout.session.async_payment_failed",
    "checkout.session.async_payment_succeeded",
    "checkout.session.completed",
    "customer.deleted",
  ]
}

Both webhooks are being created as type "Account" instead of the second one as type "Connect"

When running terraform apply again, it sees this, and shows me in the plan, that it will change the type to "connect". However, no matter how many times I run terraform apply it "succeeds" but never changes the type.

Not an issue!

Not an issue but a thanks, I’ve been searching for something like this for a long time to help document/reflect Stripe configurations in code.

Thanks Frank! 👍🏼

Tiers on stripe_price?

It looks like tiers are supported only on a stripe_plan resource. Stripe UI has support for graduated tiers on a separate price object. Is it possible to provide tiers on a per-price basis?

Is this repo being maintained?

We have PRs with fixes just sitting waiting to be merged for over a month now.

Specifically, there is a PR open which resolves support for arm and M1 Mac support which has been open for quite some time.,

Would be great if the maintainer would take some action and ownership over whats currently awaiting review.

Happy to assist if you need help reviewing PRs and helping keep things current.

Resource : subscription

Hi there,

First of all I would like to thank you for this provider. It's really useful.

How is it possible to add a customer and a subscription (a relation between a customer and a product) ? This is the only thing missing for me before starting using it.

Thanks.

Decimal amounts are passed to API as zeros

I'm trying to create the price with decimal values.

When I'm passing tiers in stripe_price resource:

  tier {
    up_to       = 500
    unit_amount_decimal = 0.0
    flat_amount_decimal = 1000.0
  }

  tier {
    up_to_inf   = true
    unit_amount_decimal = 0.1
    flat_amount_decimal = 0.0
  }

the resulting api call body contains zeroes on prices:

  "tiers": {
    "0": {
      "flat_amount": "0",
      "unit_amount": "0",
      "up_to": "500"
    },
    "1": {
      "flat_amount": "0",
      "unit_amount": "0",
      "up_to": "inf"
    }
  },

Upgrade terraform to v0.12

hey there, really excited to find this terraform plugin. I am getting the below error. I am guessing that this is because I upgraded to terraform 0.12 and this plugins uses client version 0.11.13.

Error: Failed to instantiate provider "stripe" to obtain schema:
Incompatible API version with plugin. Plugin version: 4, Client versions: [5]

I was wondering if you have any plans to upgrade to 0.12?

Provide binaries through github releases

First off - thank you!

Having binary releases would be really nice for those of us that are not Go developers and would like to use this provider with our current CICD processes. You can see an example of another community provider that does this - auth0.

signature: openpgp: key expired

Greetings,

We are running into issues whereby terraform is rejecting the stripe provider due to expired openpgp keys.

Can you please update the openpgp keys as this is causing deployment issues.

Please see the error message below:


│ Error: Failed to install provider

│ Error while installing franckverrot/stripe v1.9.0: error checking
│ signature: openpgp: key expired

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.