-
Notifications
You must be signed in to change notification settings - Fork 744
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
[Feature Request] Manage GitHub Apps via Terraform #509
Comments
I've been playing around with this a little bit, and the public API support for GitHub Apps isn't where it needs to be in order to support standard CRUD operations on a GitHub App. I've spoken with the team internally and they're aware of the issue but it isn't an immediate priority. The GraphQL API doesn't support App operations at the moment. The auth used for creating Apps on the In any event, I wanted to create a proof of concept, so I created a sample app with hard-coded values but I haven't been able to successfully get an App created. When skipping the OTP, I get a There might be something I'm missing on how the screen-scraping package of the In the meantime, we'll look into what operations we can support given an existing App. |
I've investigated a little bit more on how to programmatically support the requested GitHub Apps operations.
I can't find anything in the API documentation about changing the name. I don't think the API that works behind the UI is public.
Can be managed when creating an installation, but updating doesn't appear to be supported in the public API either.
REST docs are here, but that functionality doesn't appear to be available in
I believe these are managed through the same API as permissions above. It definitely feels like we're working without tools on this feature a bit. |
Thanks for scoping this out and reporting back to the rest of us on this. Definitely feels like the wrong time to be implementing automation around GitHub App creation as support for this via My suggestion is we park this for now given the complexity of the creation path. However, we could pave paths for import-and-manage style workflows if there is more feedback from the community that this would be used. |
This would definitely be of huge value. We are heading towards of managing dozens of GitHub Apps in our organization. Since |
I'm really craving for this feature... |
We manage tens of github apps across 3 orgs (github enterprise) in our company. Changing everything manually and keeping in sync is PITA. |
I've asked around internally and linked this issue along to the team. I know there's a lot of interest in this recorded. The team is looking at it but is not working on it presently and I can't offer a timeframe now, unfortunately. |
Thank you for that @kfcampbell , there's definitely keen interest! |
Also, and I'm not sure if this is the right issue to ask for it, it'd be nice to have a fine grained token that'd allow to install one or more specific apps, while not allowing to install other apps, in some or all org repos. Having a GitOps operation where there's an admin PAT running code is dangerous and right now we are forced to run the |
+1 this would be a lovely feature. Is there any update on if this might be explored? |
I agree that this would be an excellent feature. I've seen some more people asking for it internally, which is good, but no idea on a timeframe for implementation/release yet unfortunately. |
+1 here. We also recently started to use |
+1 here. At my day job at $very_large_corp we could really use this. At the moment it introduces a manual step in an otherwise largely automated process. |
+1 here My team has to be able to add/remove thousands, yes, thousands of repositories from a given GitHub Application "Repository Access", having to manually perform this task is madness. Terraform Integrations/github provider does support Does anybody know any workaround for now?? API calls or anything that can be somewhat automated?? Thanks |
+1 here Spend a couple of hours today trying to achieve a behavior that depended on accesses managed by a Github app, if the feature was available the visibility would be in plain sight so the access could be managed easily in the IaC scenario I'm working on. |
it seems there is a rest api for it now https://github.com/google/go-github/blob/master/github/apps.go#L16 |
This part of the API has existed for some time, it can be used to manage app installations, but not apps |
+1 Registering interest in this one also - same as above it would be nice to fully automate this. Does anybody know where we can register interest in the required API change with github? |
@phill-lewis it would be worth filing a request here. |
Come on GitHub, almost 4 years later and we still don't have access to this resource🥲 |
For what it's worth, if you're using pulumi here is a simple dynamic provider to manage GitHub App info I've been using internally for the past 6 months or so: import * as pulumi from '@pulumi/pulumi';
import { Octokit } from '@octokit/core';
import { AppAuthentication, createAppAuth } from '@octokit/auth-app';
export interface ConfigurationResourceInputs {
appId: pulumi.Input<string>;
privateKey: pulumi.Input<string>;
clientId: pulumi.Input<string>;
clientSecret: pulumi.Input<string>;
url: pulumi.Input<string>;
secret: pulumi.Input<string>;
contentType?: pulumi.Input<string> | undefined;
}
export class Configuration extends pulumi.dynamic.Resource {
public readonly appId!: pulumi.Output<pulumi.ID>;
public readonly privateKey!: pulumi.Output<string>;
public readonly clientId!: pulumi.Output<string>;
public readonly clientSecret!: pulumi.Output<string>;
public readonly url!: pulumi.Output<string>;
public readonly secret!: pulumi.Output<string>;
public readonly contentType!: pulumi.Output<string>;
constructor(name: string, args: ConfigurationResourceInputs, opts?: pulumi.CustomResourceOptions) {
super(new ConfigurationProvider(), name, args, opts, 'github-app', 'Configuration');
}
}
interface ConfigurationInputs {
appId: string;
privateKey: string;
clientId: string;
clientSecret: string;
url: string;
secret: string;
contentType?: string | undefined;
}
export interface ConfigurationOutputs extends Omit<ConfigurationInputs, 'url' | 'secret'> {
url?: string | undefined;
secret?: string | undefined;
}
export class ConfigurationProvider implements pulumi.dynamic.ResourceProvider {
async auth({
appId,
privateKey,
clientId,
clientSecret,
}: Pick<
ConfigurationInputs,
'appId' | 'clientId' | 'clientSecret' | 'privateKey'
>): Promise<AppAuthentication> {
const auth = createAppAuth({
appId: appId,
privateKey: privateKey,
clientId: clientId,
clientSecret: clientSecret,
});
return await auth({ type: 'app' });
}
async create(inputs: ConfigurationInputs): Promise<pulumi.dynamic.CreateResult> {
const auth = await this.auth(inputs);
const octokit = new Octokit({ auth: auth.token });
try {
const { data } = await octokit.request('PATCH /app/hook/config', {
data: JSON.stringify({
url: inputs.url,
secret: inputs.secret,
insecure_ssl: '0',
content_type: inputs.contentType || 'json',
}),
});
return {
id: inputs.appId,
outs: {
appId: inputs.appId,
privateKey: inputs.privateKey,
clientId: inputs.clientId,
clientSecret: inputs.clientSecret,
url: data.url,
secret: data.secret,
contentType: data.content_type,
},
};
} catch (err) {
await pulumi.log.error(`${JSON.stringify(err, null, 2)}`);
throw new Error('Failed to set github app webhook config');
}
}
async diff(
_id: pulumi.ID,
olds: ConfigurationOutputs,
news: ConfigurationInputs,
): Promise<pulumi.dynamic.DiffResult> {
let changes: boolean = false;
let replaces: string[] = [];
let keys = Object.keys(news) as Array<Extract<keyof typeof news, string>>;
for (const key of keys) {
if (JSON.stringify(olds[key]) !== JSON.stringify(news[key])) {
changes = true;
if (key === 'appId' || key === 'privateKey' || key === 'clientId' || key === 'clientSecret') {
replaces.push(key);
}
}
}
return { changes, replaces };
}
async update(
id: pulumi.ID,
_olds: ConfigurationOutputs,
news: ConfigurationInputs,
): Promise<pulumi.dynamic.UpdateResult> {
const auth = await this.auth(news);
const octokit = new Octokit({ auth: auth.token });
try {
const { data } = await octokit.request('PATCH /app/hook/config', {
data: JSON.stringify({
url: news.url,
secret: news.secret,
insecure_ssl: '0',
content_type: news.contentType || 'json',
}),
});
return {
outs: {
appId: id,
privateKey: news.privateKey,
clientId: news.clientId,
clientSecret: news.clientSecret,
url: data.url,
secret: data.secret,
contentType: data.content_type,
},
};
} catch (err) {
await pulumi.log.error(`${JSON.stringify(err, null, 2)}`);
throw new Error('Failed to set github app webhook config');
}
}
async read(id: pulumi.ID, props?: ConfigurationOutputs): Promise<pulumi.dynamic.ReadResult> {
if (!props) {
throw new Error('Props undefined');
}
const auth = await this.auth({ ...props, appId: id });
const octokit = new Octokit({ auth: auth.token });
try {
const { data } = await octokit.request('GET /app/hook/config');
return {
id,
props: {
appId: id,
privateKey: props.privateKey,
clientId: props.clientId,
clientSecret: props.clientSecret,
url: data.url,
secret: data.secret,
contentType: data.content_type,
},
};
} catch (err) {
await pulumi.log.error(`${JSON.stringify(err, null, 2)}`);
throw new Error('Failed to set github app webhook config');
}
}
} Just in case that would help others who were trying to figure out how to deal with that situation. Pulumi's GitHub provider is generated based on the terraform provider sources, so faces the same problem documented in this thread. |
+1. I would love to contribute as well. |
Hey Team,
I was looking for a way to manage GitHub apps [1] via Terraform but quickly realized there is none. It would be great to be able to setup a GitHub app, here are some exemplary settings one might want to manage:
Cheers!
Terraform Version
References
[1] https://developer.github.com/apps/about-apps/
The text was updated successfully, but these errors were encountered: