terraform-provider-github icon indicating copy to clipboard operation
terraform-provider-github copied to clipboard

github_repository_webhook: 404s on API call

Open milosgajdos opened this issue 5 years ago • 18 comments

Terraform Version

$ terraform -v
Terraform v0.11.11
+ provider.aws v2.0.0
+ provider.github v1.3.0
+ provider.random v2.0.0

Affected Resource(s)

  • github_repository_webhook

Terraform Configuration Files

resource "random_string" "webhook_secret" {
  length  = 16
  special = false
}

locals {
  webhook_secret = "${random_string.webhook_secret.result}"
}

resource "github_repository_webhook" "default" {
  name       = "web"
  repository = "${var.github_repo}"

  configuration {
    url = "${aws_codepipeline_webhook.default.url}"

    content_type = "json"
    insecure_ssl = true
    secret       = "${local.webhook_secret}"
  }

  events = ["push"]

}

Debug Output

https://gist.github.com/milosgajdos83/39af1f290c75f0ff2d2c81385dfabaf7

Expected Behavior

New GitHub webhook should be created.

Actual Behavior

terraform fails [to create new GitHub webhook] with the error shown below

Error: Error applying plan:

1 error(s) occurred:

* module.foo.github_repository_webhook.default: 1 error(s) occurred:

* github_repository_webhook.default: POST https://api.github.com/repos/tellerhq/foo/hooks: 404 Not Found []

Steps to Reproduce

Please list the steps required to reproduce the issue, for example:

  1. configure webhook
  2. terraform plan
  3. terraform apply

Important Factoids

As you can see from the hcl snippet above the GitHub webhook I've tried to create was for AWS Cdepipeline Source action. I think that's pretty much the most interesting thing, about this. I have however tested this in a standalone configuration (i.e. without hooking it up with AWS CodePipeline) to no avail.

References

It seems terraform does issue POST request to correct GitHub API endpoint as expected:

[https://developer.github.com/v3/repos/hooks/#create-a-hook](https://developer.github.com/v3/repos/hooks/#create-a-hook)

I have a hunch that this issue might be related to the issue listed below:

  • GH-171

milosgajdos avatar Mar 08 '19 17:03 milosgajdos

Hi @milosgajdos83 !

Thank you for submitting this issue! Unfortunately I have been unable to reproduce it, and I am not able to reach your gist with the link provided. Are you still seeing this issue, and, if so, could you provide an updated link to the gist?

Thanks!

megan07 avatar Jun 25 '19 19:06 megan07

Hi, I no longer use terraform I'm afraid. Will close this issue now.

milosgajdos avatar Jun 26 '19 09:06 milosgajdos

If anybody else comes across this issue like I did, setting the admin:org_hook permission for the GITHUB_TOKEN that you are using will fix this 404 error.

CarlosEspejo avatar Sep 22 '20 01:09 CarlosEspejo

for me it only started to work when i added these lines:

provider "github" {
  version = "> 2.4"
  token = var.your_github_token
  organization = var.your_org_if_any
}

ktamas77 avatar Dec 06 '20 19:12 ktamas77

I'm receiving this issue too, but none of the suggestions have helped yet.

Error: POST https://api.github.com/repos///hooks: 404 Not Found

For me it only started to work when I set the GITHUB_TOKEN env var in Windows.

RobertKeyser avatar Jan 22 '21 18:01 RobertKeyser

I have the same 404 error using the documentation code.

Fraccaman avatar Feb 03 '21 08:02 Fraccaman

My github token has admin:org_hook priviledges, and my provider/versions are:

provider "github" {
  token        = var.github_token
  organization = var.github_org
}

terraform {
  required_providers {
    github = {
      source  = "integrations/github"
      version = "~> 4.4"
    }
  }
  required_version = ">= 0.14"
}

I get the error:

github_organization_webhook.my-module: Creating...

Error: POST https://api.github.com/orgs/my-org/hooks: 404 Not Found []

  on main.tf line 13, in resource "github_organization_webhook" "my-module":
  13: resource "github_organization_webhook" "my-module" {

Releasing state lock. This may take a few moments...
[terragrunt] 2021/02/11 20:39:04 Hit multiple errors:
exit status 1

hyei avatar Feb 12 '21 18:02 hyei

Ran into this problem as well in terraform v0.14.8. Changing permissions on the token didn't work.

In my case, I was actually using github_* resources in a module.

module "other" {
  source = "../../modules/this-module-uses-github"
}

So I had to add a versions.tf file to that module directory:

terraform {
  required_providers {
    aws = {
      source = "hashicorp/aws"
    }
    github = {
      source = "integrations/github"
    }
  }
  required_version = ">= 0.14"
}

achaphiv avatar Mar 13 '21 03:03 achaphiv

It seems like adding some validation around whether or not permissions are correct would help us disambiguate the errors in this code path. Not sure what that would look like yet 🤔 .

jcudit avatar Mar 16 '21 13:03 jcudit

@jcudit In my case and the one like @RobertKeyser 's comment, we know that owner was undefined. Seems like it would be helpful to add a warning around here if owner is undefined you might need to include the versions.tf file in your module? I don't know GO or the terraform very well so feel free to correct me if its too naive and there are valid cases where owner should be undefined.

jonesmac avatar May 24 '21 14:05 jonesmac

I am also running into this while trying to use ecs-codepipeline from Cloudposse. My URL appears correct:

https://api.github.com/repos/my-org/my-repo/hooks

But I'm still getting a 404. The PAT I have set in GITHUB_TOKEN has repo, admin:repo_hook, and admin:org_hook permissions. But when I do this on the command line, I also get a 404:

$ curl -I https://api.github.com/repos/my-org/my-repo/hooks
HTTP/2 404 
server: GitHub.com
[...]

I've tried these things to get around the issue:

  • provider "github" block as suggested by @ktamas77
  • Adding a versions.tf file inside the directory of my module that was calling the ecs-codepipeline module, as suggested by @achaphiv

But I can't get past the 404. Suggestions welcome…

nk9 avatar Jan 21 '22 22:01 nk9

@nk9 Similar to @ktamas77, I have to pass in the owner for it to work for me.

provider "github" {
  owner = var.source_owner
}

CarlosEspejo avatar Jan 24 '22 16:01 CarlosEspejo

This stopped working overnight for me. I have the owner argument defined, but it's still returning a 404. Weird part is that this was working yesterday

Terraform v1.1.2 provider registry.terraform.io/integrations/github v4.19.2

bgrande12 avatar Jan 24 '22 20:01 bgrande12

Thank you @CarlosEspejo for your suggestion! In the end, I tried your code and it didn't change anything for me. Fortunately, I've gotten it working and I now understand what was wrong. For anyone that gets stuck on this, know these three things:

  1. Despite what the documentation claims, GitHub returns 404 Not Found when the user doesn't have permission to access the /hooks endpoint. Other people discussed permissions addressing the error above, but I wasn't sure. The 403 Forbidden status is supposedly returned when the user doesn't have permission to access the endpoint via POST, but in fact my testing shows that you actually get back 404 for both POST and GET requests without a valid token having sufficient permissions. It doesn't seem to matter if the repo is public or private.
  2. In my case (using ecs-codepipeline to create the first instance of a pipline), the PAT permissions necessary to create the webhook on a specific repository are just admin:repo_hook. But you do definitely need to have that scope ticked.
  3. Crucially, the user must have the Admin role on the repo! (Or Owner role in the organization.) The Maintain role is not sufficient.

So this explains why I was seeing a 404 (permissions error) when my user's token had the correct permissions. The user in question was a bot account I created solely to interact with the CI/CD pipeline. I didn't know what role it would need, but I thought surely Maintain would be good enough. It was not.

nk9 avatar Jan 24 '22 22:01 nk9

For me, defining owner as the organization name (Github organization) in additional to token did the trick. Thanks @nk9 for noting that the PAT user must have the Admin role on the repo!

bgrande12 avatar Feb 03 '22 00:02 bgrande12

I ran into the same issue, where github_repository_webhook was trying to POST to the API using my individual namespace, instead of the org. Of course, setting owner on the provider addresses this, but is not very flexible.

Other resources in the provider, such as the github_repository data source, accept a full_name parameter.

One of the following would be optimal:

  1. github_repository_webhook parses the repository attribute and determines whether ORG-NAME/repo-name was given. This might be a bit tricky.
  2. Support an attribute similar to full_name attribute of the github_repository data source, where the user will be required to provide a fully-qualified ORG-NAME/REPO-NAME. Use that for the API call.
  3. Add an optional attribute of organization_name to the resource.

I know we could set up multiple provider aliases with distinct owner attributes on each. But that approach is limiting in real world usage. It would be much more desirable to allow users to create resources across many namespaces, as long as their permissions allow.

IMHO the current behavior violates the principle of least surprise, because an user giving a fully-qualified repo name as ORG-NAME/repo-name probably expects that specific repo to be modified.

geekifier avatar May 06 '22 20:05 geekifier

experiencing this issue and none of the given workarounds remdiate it. Using the provider within a module and configuring it from outside of a module seems to reset the owner configuration

davidsielert avatar Sep 16 '22 21:09 davidsielert

experiencing this issue and none of the given workarounds remdiate it. Using the provider within a module and configuring it from outside of a module seems to reset the owner configuration

It is not recommended to use providers inside modules.

https://www.terraform.io/language/modules/develop/providers

In top-most root workspace:

  • provider "github" {
      owner = ...
      token = ...
    }
    
  • Add versions.tf with integrations/github

In modules:

  • No provider "*" {} ever
  • Add versions.tf with integrations/github if it uses github_* resources.

Note that you have to add versions.tf in multiple places.

I think a lot of the confusion stems from the fact that there are actually two github providers.

One deprecated version by hashicorp, and one that is this current repository.

If you don't declare

terraform {
  required_providers {
    github = {
      source = "integrations/github"
    }
  }
}

then that particular module is using the deprecated hashicorp version.

achaphiv avatar Sep 16 '22 22:09 achaphiv

👋 Hey Friends, this issue has been automatically marked as stale because it has no recent activity. It will be closed if no further activity occurs. Please add the Status: Pinned label if you feel that this issue needs to remain open/active. Thank you for your contributions and help in keeping things tidy!

github-actions[bot] avatar Jun 14 '23 02:06 github-actions[bot]