terraform-provider-github
terraform-provider-github copied to clipboard
GitHub User SSH Key Resource must be replaced
Terraform Version
$ terraform -v
Terraform v1.2.9
on windows_amd64
+ provider registry.terraform.io/hashicorp/local v2.2.3
+ provider registry.terraform.io/integrations/github v5.0.0
Affected Resource(s)
- github_user_ssh_key
Terraform Configuration Files
#############
# GitHub SSH
#############
resource "github_user_ssh_key" "public_key" {
title = "ragedunicorn_ssh_example_key"
key = data.local_sensitive_file.ssh_public_key.content
}
# External SSH public key to register with GitHub
data "local_sensitive_file" "ssh_public_key" {
filename = "${path.module}/id_rsa.pub"
}
####################
# OUTPUT GitHub SSH
####################
output "github_ssh_key_id" {
description = "The ID of the SSH key"
value = github_user_ssh_key.public_key.id
}
output "github_ssh_key_etag" {
description = "ETag"
value = github_user_ssh_key.public_key.etag
}
See example repository here - https://github.com/RagedUnicorn/terraform-github-provider-ssh-example
Debug Output
Log of complete process https://gist.github.com/RagedUnicorn/6211928a2ce8db083af339bd2ab1d55a
With trace logs activated: https://gist.github.com/RagedUnicorn/f9a1575f87b3da0046867535f63ca556
Expected Behavior
Expect terraform to recognize that a key was already uploaded
Actual Behavior
Key is uploaded successfully. A subsequent plan or apply however will always destroy the key and upload the key again.
Steps to Reproduce
-
terraform init
-
terraform apply -auto-approve
- Check GitHub for uploaded key
-
terraform plan
(expecting state to be up to date and no work to do)
References
Repository to reproduce - https://github.com/RagedUnicorn/terraform-github-provider-ssh-example
Some more information
I'm not sure how the GitHub provider is supposed to handle this but it looks to me that the issue is because of the HTTP 304 response of GitHub.
E.g. the response for GET /user/keys/[KEYID] HTTP/1.1
Will be something like
GET /user/keys/71224420 HTTP/1.1
Host: api.github.com
User-Agent: go-github/v47.0.0
Accept: application/vnd.github.v3+json
Accept-Encoding: gzip
Doing calls with curl directly returns the proper response. I'm assuming this is because I'm not sending any etag and thus there is no cache involved.
curl -H "Accept: application/vnd.github+json" -H "Authorization: Bearer [TOKEN]" https://api.github.com/user/keys
curl -H "Accept: application/vnd.github+json" -H "Authorization: Bearer [TOKEN]" https://api.github.com/user/keys/[KEYID]
Welp as I write this ticket I found the actual issue. The reason lies in how I generated the ssh key
ssh-keygen -t ecdsa-sk -C [email protected]
This creates a key such as (Note the "-C" comment)
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCnaZRZBMsLsVIDIAKiCrMrbFsMEZqtvRgbvyGIDcUijjj6BYcB7ONtLeNv9VMDNME6t9VTe7VppR5xHXLc6ZER8XGIxI8HtL+DTPaRVEW3W4DgLgtrECgjjbd9tq4rt/b0EFpG5uIDb4VBiI+wKQYesDt488AQ3GjlJkTVWd3t5E4EaBLf4WataXsWf/SN2yYH6W6JonoHt0uGk4q03xywabz4Sm1XhCR0XuT/y8bB/GzvQ+nMf+HNZYwJFWsrA+QD9myle1ZEpTOFKHF32bOokafHWx+kYw/we0hC07xdrgRuZ9JeqtDaEcngbgJ2zHTUodV4mwJ1J79r37+2Se14frUvQMfrs/92QBdxwCw5494bTfFfZVSjvGPgU/KoogeraENd4XOD4yGYboPvv/nqnXPhjE6/lFO6nr6lbR02wvwmLQ/VuFi8PaHp+onq0T8uNJrLK2qZlOnh6Z/MqP3meX6s6AgekSb2urRYLZgwYRBhOzK6aO8dmugyCE05eqoJsfVPiBlBWsiPtRZGaJX7ozTIBYeLpkXGa0YhqAPBm3tpRHDIYooabkpfFhHL4+Y8im3VpFwQoB4+aWnxsg4SPKlQ11e+CtFNbAL/O+1+X/fGfytVloZmXq/dvnze8EAw2NR4n+tcpp1UxFWwMsEHo0BFOxacGZEgAkuCSP1RxQ== [email protected]
terraform compares what it got from the GitHub backend which does not contain the comment that was added with -C
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCnaZRZBMsLsVIDIAKiCrMrbFsMEZqtvRgbvyGIDcUijjj6BYcB7ONtLeNv9VMDNME6t9VTe7VppR5xHXLc6ZER8XGIxI8HtL+DTPaRVEW3W4DgLgtrECgjjbd9tq4rt/b0EFpG5uIDb4VBiI+wKQYesDt488AQ3GjlJkTVWd3t5E4EaBLf4WataXsWf/SN2yYH6W6JonoHt0uGk4q03xywabz4Sm1XhCR0XuT/y8bB/GzvQ+nMf+HNZYwJFWsrA+QD9myle1ZEpTOFKHF32bOokafHWx+kYw/we0hC07xdrgRuZ9JeqtDaEcngbgJ2zHTUodV4mwJ1J79r37+2Se14frUvQMfrs/92QBdxwCw5494bTfFfZVSjvGPgU/KoogeraENd4XOD4yGYboPvv/nqnXPhjE6/lFO6nr6lbR02wvwmLQ/VuFi8PaHp+onq0T8uNJrLK2qZlOnh6Z/MqP3meX6s6AgekSb2urRYLZgwYRBhOzK6aO8dmugyCE05eqoJsfVPiBlBWsiPtRZGaJX7ozTIBYeLpkXGa0YhqAPBm3tpRHDIYooabkpfFhHL4+Y8im3VpFwQoB4+aWnxsg4SPKlQ11e+CtFNbAL/O+1+X/fGfytVloZmXq/dvnze8EAw2NR4n+tcpp1UxFWwMsEHo0BFOxacGZEgAkuCSP1RxQ==
And thus they will always be different and require the recreation of the resource. So the solution is to remove the comment from the key and afterwards terraform is able to recognize the key is already uploaded.
Maybe someone has an idea how to make this more clear in the documentation. I can't be the first to fall into this trap :)