Skip to content

Commit 3805a2c

Browse files
committed
WIP: import github resources into terraform
1 parent 6a0a494 commit 3805a2c

File tree

8 files changed

+5347
-3
lines changed

8 files changed

+5347
-3
lines changed

flake.lock

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

flake.nix

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,23 @@
33

44
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
55
inputs.systems.url = "github:nix-systems/default";
6-
inputs.treefmt-nix.url = "github:numtide/treefmt-nix";
7-
inputs.treefmt-nix.inputs.nixpkgs.follows = "nixpkgs";
6+
inputs.treefmt-nix = {
7+
url = "github:numtide/treefmt-nix";
8+
inputs.nixpkgs.follows = "nixpkgs";
9+
};
10+
inputs.opentofu-registry = {
11+
url = "github:opentofu/registry";
12+
flake = false;
13+
};
814

915
outputs =
1016
{
1117
self,
1218
nixpkgs,
1319
systems,
1420
treefmt-nix,
15-
}:
21+
...
22+
}@inputs:
1623
let
1724
eachSystem = f: nixpkgs.lib.genAttrs (import systems) (system: f nixpkgs.legacyPackages.${system});
1825
in
@@ -22,7 +29,10 @@
2229
default = pkgs.mkShell {
2330
packages = [
2431
pkgs.findutils
32+
pkgs.gh
2533
pkgs.gnumake
34+
pkgs.jq
35+
(pkgs.callPackage ./tofu { inherit (inputs) opentofu-registry; })
2636
];
2737
};
2838
}

tofu/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.terraform*
2+
terraform.tfstate*

tofu/default.nix

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# Copyright manveru. https://gist.github.com/manveru/bcd2b4e0d3a30abbdec19573083b34b7
2+
{
3+
fetchurl,
4+
go,
5+
lib,
6+
opentofu,
7+
opentofu-registry,
8+
stdenv,
9+
unzip,
10+
}:
11+
let
12+
mkTerraformProvider =
13+
{
14+
owner,
15+
repo,
16+
version,
17+
src,
18+
registry ? "registry.opentofu.org",
19+
}:
20+
let
21+
inherit (go) GOARCH GOOS;
22+
provider-source-address = "${registry}/${owner}/${repo}";
23+
in
24+
stdenv.mkDerivation {
25+
pname = "terraform-provider-${repo}";
26+
inherit version src;
27+
28+
unpackPhase = "unzip -o $src";
29+
30+
nativeBuildInputs = [ unzip ];
31+
32+
buildPhase = ":";
33+
34+
# The upstream terraform wrapper assumes the provider filename here.
35+
installPhase = ''
36+
dir=$out/libexec/terraform-providers/${provider-source-address}/${version}/${GOOS}_${GOARCH}
37+
mkdir -p "$dir"
38+
mv terraform-* "$dir/"
39+
'';
40+
41+
passthru = {
42+
inherit provider-source-address;
43+
};
44+
};
45+
46+
readJSON = f: builtins.fromJSON (lib.readFile f);
47+
48+
# fetch the latest version
49+
providerFor =
50+
owner: repo:
51+
let
52+
json = readJSON (opentofu-registry + "/providers/${lib.substring 0 1 owner}/${owner}/${repo}.json");
53+
latest = lib.head json.versions;
54+
matching = lib.filter (e: e.os == "linux" && e.arch == "amd64") latest.targets;
55+
target = lib.head matching;
56+
in
57+
mkTerraformProvider {
58+
inherit (latest) version;
59+
inherit owner repo;
60+
src = fetchurl {
61+
url = target.download_url;
62+
sha256 = target.shasum;
63+
};
64+
};
65+
in
66+
opentofu.withPlugins (_: [ (providerFor "integrations" "github") ])

tofu/init.rb

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#!/usr/bin/env ruby
2+
#
3+
4+
require "json"
5+
require "pp"
6+
7+
TF = "tofu"
8+
ORG = "NixOS"
9+
10+
# Just wrap `gh`, it's easier than to depend on Octokit
11+
def gh(*command)
12+
# HACK: assume there are less than 500 items
13+
# HACK: assume that the command doesn't require shell escaping
14+
IO.popen("gh --limit=500 #{command.map(&:to_s).join(" ")}") do |io|
15+
JSON.load(io)
16+
end
17+
end
18+
19+
20+
def tf(*command)
21+
system(TF, *command.map(&:to_s))
22+
end
23+
24+
def tf!(*command)
25+
if !tf(*command)
26+
throw "terraform command #{command.join(" ")} failed"
27+
end
28+
end
29+
30+
### Import Organization settings
31+
32+
org_id = gh(:api, "/orgs/#{ORG}", "--jq", ".id").strip
33+
34+
File.open("import_org.tf", "w") do |f|
35+
f.puts(<<~EOM)
36+
import {
37+
id = "#{org_id}"
38+
to = github_organization_settings.#{ORG}
39+
}
40+
EOM
41+
end
42+
43+
### Import REPOS ###
44+
45+
repos = gh(:repo, :list, ORG, "--json=name")
46+
47+
File.open("import_repos.tf", "w") do |f|
48+
repos.each do |repo|
49+
name = repo["name"]
50+
51+
id_name = name.gsub(".", "_dot_").gsub(/\d/, "_")
52+
53+
f.puts(<<~EOM)
54+
import {
55+
id = "#{name}"
56+
to = github_repository.#{id_name}
57+
}
58+
59+
import {
60+
id = "#{name}"
61+
to = github_repository_collaborators.#{id_name}
62+
}
63+
64+
EOM
65+
end
66+
end
67+
68+
### TODO: import teams
69+
70+
71+
### Import the resources in the terraform state and generate the terraform resources
72+
73+
tf!(:plan, "-generate-config-out=repos.tf")

0 commit comments

Comments
 (0)