Skip to content

Error when creating a deploy key with extras/0-cicd-github #1317

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

Closed
Tutuchan opened this issue Apr 11, 2023 · 6 comments · Fixed by #1328
Closed

Error when creating a deploy key with extras/0-cicd-github #1317

Tutuchan opened this issue Apr 11, 2023 · 6 comments · Fixed by #1328

Comments

@Tutuchan
Copy link
Contributor

Hello,

I'm running into an error when creating the deploy key with the 0-cicd extra stage, namely:

│ Error: POST https://api.github.com/repos/myorg/myorg/cloud-foundation-fabric/keys: 404 Not Found []
│
│   with github_repository_deploy_key.default[0],
│   on main.tf line 112, in resource "github_repository_deploy_key" "default":
│  112: resource "github_repository_deploy_key" "default" {
│

My organization name myorg is included twice in the API call.

Here is my terraform.tfvars file for this stage:

organization = "myorg"

modules_config = {
  repository_name = "myorg/cloud-foundation-fabric"
  module_prefix   = "modules/"
  key_config = {
    create_key     = true
    create_secrets = true
  }
}

As mentioned in the documentation, I'm writing the complete name of the repository in modules_config.repository_name. However, I think the organization is added a 2nd time because of the github provider being declared as

provider "github" {
  owner = var.organization
}

I looked at the source code of the Terraform Google provider and the repository name is taken from the repository field of the github_repository_deploy_key resource - i.e. myorg/cloud-foundation-fabric here - but the owner is taken, I assume, from what is declared in the provider - i.e. myorg.

func resourceGithubRepositoryDeployKeyCreate(d *schema.ResourceData, meta interface{}) error {
	client := meta.(*Owner).v3client

	repoName := d.Get("repository").(string)
	key := d.Get("key").(string)
	title := d.Get("title").(string)
	readOnly := d.Get("read_only").(bool)
	owner := meta.(*Owner).name
	ctx := context.Background()

	resultKey, _, err := client.Repositories.CreateKey(ctx, owner, repoName, &github.Key{
		Key:      github.String(key),
		Title:    github.String(title),
		ReadOnly: github.Bool(readOnly),
	})
...
}

Finally, in CreateKey, the URL is built using both owner and repoName which would explain why the organization name is duplicated:

func (s *RepositoriesService) CreateKey(ctx context.Context, owner string, repo string, key *Key) (*Key, *Response, error) {
	u := fmt.Sprintf("repos/%v/%v/keys", owner, repo)

	req, err := s.client.NewRequest("POST", u, key)

        ...
}

Please let me know if I'm mistaken. Otherwise, I think this could be solved by requiring only the repository name (without the organization) in the modules_config and updating the github_repository_file resource to also take var.organization when replacing the source path.

I can submit a PR for this if this solution works for you.

@Tutuchan
Copy link
Contributor Author

For the record, I removed the organization from the modules_config.repository_name and ran terraform apply --target=github_repository_deploy_key.default and the key was properly set up in the repository.

@ludoo
Copy link
Collaborator

ludoo commented Apr 14, 2023

As you found out, repository names cannot contain the organization name which is passed via the dedicated variable. I'm closing this but feel free to reopen if our documentation is unclear and we can make a better job of explaining this point.

@ludoo ludoo closed this as completed Apr 14, 2023
@Tutuchan
Copy link
Contributor Author

Thanks for your answer @ludoo !

However, I'm sorry but I think I need to reopen this issue because the documentation explicitly states that modules_config.repository_name should be configured with the organization.

I forked the cloud-foundation-fabric repository to my organization and I ran the extras/0-ci-cd stage with this terraform.tfvars:

organization = "myorg"

modules_config = {
  repository_name = "myorg/cloud-foundation-fabric"
  module_prefix   = "modules/"
  key_config = {
    create_key     = true
    create_secrets = true
  }
}

repositories = {
  fast_00_bootstrap = {
    create_options = {
      description = "Bootstrap stage for FAST."
    }
    populate_from = "../../stages/0-bootstrap"
  }
  fast_01_resman = {
    create_options = {
      description = "Resource management stage for FAST."
    }
    populate_from = "../../stages/1-resman"
  }
}

pull_request_config = {
  create   = true
  title    = "FAST: initial loading or update"
  body     = ""
  base_ref = "main"
  head_ref = "fast-loader"
}

All ressources are created correctly, except the github_repository_deploy_key where I get the error I mentioned in my initial comment.

Then, if I don't include the organization in modules_config.repository_name, i.e.

modules_config = {
  repository_name = "cloud-foundation-fabric"
  module_prefix   = "modules/"
  key_config = {
    create_key     = true
    create_secrets = true
  }
}

all resources are created correctly, including the deploy key.

However, the generated files all use source = "[email protected]:cloud-foundation-fabric.git//modules/project" instead of source = "[email protected]:myorg/cloud-foundation-fabric.git//modules/project" in the modules definitions.

When I try to tf init the resulting fast_00_bootstrap repository, I get the following error for all files:

│ Error: Failed to download module
│
│ Could not download module "organization" (organization.tf:127) source code from "git::ssh://[email protected]/cloud-foundation-fabric.git": error downloading
│ 'ssh://[email protected]/cloud-foundation-fabric.git': /opt/homebrew/bin/git exited with 128: Cloning into '.terraform/modules/organization'...
│ ERROR: Repository not found.
│ fatal: Could not read from remote repository.
│
│ Please make sure you have the correct access rights
│ and the repository exists.

Then again, I may have misunderstood how to run this stage and I'm sorry for taking some of your time with this but I feel this needs some clarification.

Best,
Pierre

@ludoo
Copy link
Collaborator

ludoo commented Apr 17, 2023

I see your point, and sorry for making this harder than it should have been (I was also on vacation so lagging a bit). WDYT about removing the interpolated org from where modules_config.repository_name is used, so that we also allow using module repos from outside the org like this one?

@ludoo ludoo reopened this Apr 17, 2023
@ludoo
Copy link
Collaborator

ludoo commented Apr 17, 2023

Checking the code, we don't interpolate the org in the repo name used for key creation which is defined in this local

  modules_repo  = try(var.modules_config.repository_name, null)

and then reused directly in the resource

resource "github_repository_deploy_key" "default" {
  count = (
    try(var.modules_config.key_config.create_key, null) == true ? 1 : 0
  )
  title      = "Modules repository access"
  repository = local.modules_repo

What I think is happening is the GitHub provider injecting the configured owner in the API URL.

So it appears that deploy key repos need to belong to the same org configured in the provider, which makes sense. I see two options

  • don't allow the org to be specified in modules_config.repository_name and interpolated it when doing module path substitutions on files
  • leave modules_config.repository_name as is and remove the org from the repo name used for the deploy key

I would prefer the second option, as it would allow passing in a repo external to the org for substitutions (and then skip deploy key creation of course). I'll send a PR that implements it, let me know if this works for you.

@Tutuchan
Copy link
Contributor Author

Thanks for the quick reply and sorry for bothering you on your vacation !

Your solution works perfectly well for me, thank you. I'll try it out during the day and get back to you if there is an issue.

Cheers !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants