[Pulumi] Use Pulumi GitHub provider TypeScript SDK to manage Github

Pulumi is a Modern Infrastructure as Code (IaC) to create, deploy, and manage infrastructure on any cloud using familiar programming languages and tools.

The GitHub provider for Pulumi can be used to provision any of the cloud resources available in GitHub. The GitHub provider must be configured with credentials to deploy and update resources in GitHub.

This article is about how to use Pulumi Github provider and TypeScript SDK to manage Github.

Prerequisites

Install Pulumi and NodeJS

Pulumi

Install the Pulumi - https://www.pulumi.com/ CLI.

1
2
# Mac OS X
$ brew install pulumi

NodeJS Language Runtime

Install Node.js - https://nodejs.org/en/.

1
2
# Mac OS X
$ brew install node

Pulumi New

First, create a directory col-pulumi-github-typescript or with your prefer name.

1
2
$ mkdir col-pulumi-github-typescript
$ cd col-pulumi-github-typescript

Pulumi login into local file system.

1
2
3
$ pulumi login file://.
Logged in to cloudolife as cloudolife (file://.)
or visit https://pulumi.com/docs/reference/install/ for manual instructions and release notes.

Pulumi new a project with TypeScript SDK.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
$ pulumi new typescript
This command will walk you through creating a new Pulumi project.

Enter a value or leave blank to accept the (default), and press <ENTER>.
Press ^C at any time to quit.

project name: (col-pulumi-github-typescript)
project description: (A minimal TypeScript Pulumi program)
Created project 'col-pulumi-github-typescript'

stack name: (dev)
Created stack 'dev'
Enter your passphrase to protect config/secrets:
Re-enter your passphrase to confirm:

Enter your passphrase to unlock config/secrets
(set PULUMI_CONFIG_PASSPHRASE or PULUMI_CONFIG_PASSPHRASE_FILE to remember):
Installing dependencies...


> [email protected] postinstall /Users/cloudoLife/col-pulumi/col-pulumi-github-typescript/node_modules/protobufjs
> node scripts/postinstall

added 90 packages from 133 contributors and audited 90 packages in 6.586s

18 packages are looking for funding
run `npm fund` for details

found 0 vulnerabilities

Finished installing dependencies

Your new project is ready to go! ✨

To perform an initial deployment, run 'pulumi up'

The above command will create some files within the current directory.

1
2
3
4
5
6
7
8
9
10
$ tree .
.
├── Pulumi.dev.yaml
├── Pulumi.yaml
├── README.md
├── index.ts
├── node_modules
├── package-lock.json
├── package.json
└── tsconfig.json

See and modify index.ts file.

1
2
3
4
5
6
7
8
9
10
# main.ts

import * as pulumi from "@pulumi/pulumi";

import * as github from "@pulumi/github";

const repo = new github.Repository("demo-repo", {
description: "Generated from automated test",
visibility: "private",
});

NPM Install

Then, install pulumi-github TypeScript SDK.

1
$ npm install @pulumi/github

Pulumi Conf

The Pulumi GitHub Provider needs to be configured with GitHub credentials before it can be used to create resources.

Once obtained, there are two ways to communicate your authorization tokens to Pulumi:

Set the environment variable GITHUB_TOKEN:

1
export GITHUB_TOKEN=XXXXXXXXXXXXXX

Set them using configuration, if you prefer that they be stored alongside your Pulumi stack for easy multi-user access:

1
2
3
4
5
6
7
8
pulumi config set github:token XXXXXXXXXXXXXX --secret

Or pulumi config set github:token --secret
```shell
$ pulumi config set github:token --secret
value:
Enter your passphrase to unlock config/secrets
(set PULUMI_CONFIG_PASSPHRASE or PULUMI_CONFIG_PASSPHRASE_FILE to remember):

It will put github:token and value into ./Pulumi.dev.yaml.

1
2
3
4
5
6
# Pulumi.dev.yaml

encryptionsalt: < Encryptionsalt >
config:
github:token:
secure: < Secure >

Remember to pass --secret when setting github:token so that it is properly encrypted. A full set of configuration parameters can be found listed on the Project README.

The GitHub provider supports several options for providing access to GitHub credentials. See the GitHub setup page pulumi/pulumi-github: A Pulumi package to facilitate interacting with GitHub - https://github.com/pulumi/pulumi-github/ for details.

Pulumi up

Create Repository

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
$ pulumi up
Enter your passphrase to unlock config/secrets
(set PULUMI_CONFIG_PASSPHRASE or PULUMI_CONFIG_PASSPHRASE_FILE to remember):
Previewing update (dev):
Type Name Plan
pulumi:pulumi:Stack col-pulumi-github-typescript-dev
+ └─ github:index:Repository demo-repo create

Resources:
+ 1 to create
1 unchanged

Permalink: file:///Users/cloudoLife/col-pulumi/col-pulumi-github-typescript/.pulumi/stacks/dev.json
Do you want to perform this update? details
pulumi:pulumi:Stack: (same)
[urn=urn:pulumi:dev::col-pulumi-github-typescript::pulumi:pulumi:Stack::col-pulumi-github-typescript-dev]
+ github:index/repository:Repository: (create)
[urn=urn:pulumi:dev::col-pulumi-github-typescript::github:index/repository:Repository::demo-repo]
[provider=urn:pulumi:dev::col-pulumi-github-typescript::pulumi:providers:github::default_2_4_2::564af3f5-1154-432e-8aab-683031b8258f]
allowMergeCommit : true
allowRebaseMerge : true
allowSquashMerge : true
archived : false
deleteBranchOnMerge: false
description : "Generated from automated test"
name : "demo-repo-40447f2"
visibility : "private"

Do you want to perform this update? yes
Updating (dev):
Type Name Status
pulumi:pulumi:Stack col-pulumi-github-typescript-dev
+ └─ github:index:Repository demo-repo created

Resources:
+ 1 created
1 unchanged

Duration: 10s

Permalink: file:///Users/cloudoLife/col-pulumi/col-pulumi-github-typescript/.pulumi/stacks/dev.json

You cant visit Clodolife/demo-repo-c192cd1 - https://github.com/benjamincloudolife/demo-repo-40447f2 to see the demo-repo-40447f2 repository or with your prefer name.

Rename Repository

You can rename the repository from demo-repo-40447f2 to demo-repo or with your prefer name…

Modify index.ts file.

1
2
3
4
5
6
7
8
9
10
11
# main.ts

import * as pulumi from "@pulumi/pulumi";

import * as github from "@pulumi/github";

const repo = new github.Repository("demo-repo", {
name: "demo-repo",
description: "Generated from automated test",
visibility: "private",
});

Run pulumi up.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
$ pulumi up
Enter your passphrase to unlock config/secrets
(set PULUMI_CONFIG_PASSPHRASE or PULUMI_CONFIG_PASSPHRASE_FILE to remember):
Previewing update (dev):
Type Name Plan Info
pulumi:pulumi:Stack col-pulumi-github-typescript-dev
+- └─ github:index:Repository demo-repo replace [diff: ~name]

Resources:
+-1 to replace
1 unchanged

Permalink: file:///Users/cloudoLife/col-pulumi/col-pulumi-github-typescript/.pulumi/stacks/dev.json
Do you want to perform this update? details
pulumi:pulumi:Stack: (same)
[urn=urn:pulumi:dev::col-pulumi-github-typescript::pulumi:pulumi:Stack::col-pulumi-github-typescript-dev]
--github:index/repository:Repository: (delete-replaced)
[id=demo-repo-c192cd1]
[urn=urn:pulumi:dev::col-pulumi-github-typescript::github:index/repository:Repository::demo-repo]
[provider=urn:pulumi:dev::col-pulumi-github-typescript::pulumi:providers:github::default_2_4_2::564af3f5-1154-432e-8aab-683031b8258f]
+-github:index/repository:Repository: (replace)
[id=demo-repo-c192cd1]
[urn=urn:pulumi:dev::col-pulumi-github-typescript::github:index/repository:Repository::demo-repo]
[provider=urn:pulumi:dev::col-pulumi-github-typescript::pulumi:providers:github::default_2_4_2::564af3f5-1154-432e-8aab-683031b8258f]
~ name: "demo-repo-c192cd1" => "demo-repo"
++github:index/repository:Repository: (create-replacement)
[id=demo-repo-c192cd1]
[urn=urn:pulumi:dev::col-pulumi-github-typescript::github:index/repository:Repository::demo-repo]
[provider=urn:pulumi:dev::col-pulumi-github-typescript::pulumi:providers:github::default_2_4_2::564af3f5-1154-432e-8aab-683031b8258f]
~ name: "demo-repo-c192cd1" => "demo-repo"

Do you want to perform this update? yes
Updating (dev):
Type Name Status Info
pulumi:pulumi:Stack col-pulumi-github-typescript-dev
+- └─ github:index:Repository demo-repo replaced [diff: ~name]

Resources:
+-1 replaced
1 unchanged

Duration: 13s

Permalink: file:///Users/cloudoLife/col-pulumi/col-pulumi-github-typescript/.pulumi/stacks/dev.json

You cant visit Clodolife/demo-repo - https://github.com/benjamincloudolife/demo-repo to see the demo-repo repository or with your prefer name.

Pulumi Destroy

Destroy all resources created by Pulumi.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
$ pulumi destroy
Enter your passphrase to unlock config/secrets
(set PULUMI_CONFIG_PASSPHRASE or PULUMI_CONFIG_PASSPHRASE_FILE to remember):
Previewing destroy (dev):
Type Name Plan
- pulumi:pulumi:Stack col-pulumi-github-typescript-dev delete
- └─ github:index:Repository demo-repo delete

Resources:
- 2 to delete

Permalink: file:///Users/cloudoLife/col-pulumi/col-pulumi-github-typescript/.pulumi/stacks/dev.json
Do you want to perform this destroy? details
- github:index/repository:Repository: (delete)
[id=demo-repo]
[urn=urn:pulumi:dev::col-pulumi-github-typescript::github:index/repository:Repository::demo-repo]
[provider=urn:pulumi:dev::col-pulumi-github-typescript::pulumi:providers:github::default_2_4_2::564af3f5-1154-432e-8aab-683031b8258f]
- pulumi:pulumi:Stack: (delete)
[urn=urn:pulumi:dev::col-pulumi-github-typescript::pulumi:pulumi:Stack::col-pulumi-github-typescript-dev]

Do you want to perform this destroy? yes
Destroying (dev):
Type Name Status
- pulumi:pulumi:Stack col-pulumi-github-typescript-dev deleted
- └─ github:index:Repository demo-repo deleted

Resources:
- 2 deleted

Duration: 2s

Permalink: file:///Users/cloudoLife/col-pulumi/col-pulumi-github-typescript/.pulumi/stacks/dev.json
The resources in the stack have been deleted, but the history and configuration associated with the stack are still maintained.
If you want to remove the stack completely, run 'pulumi stack rm dev'.

Github Organization

If you want to manage Github organization resource, you must use pulumi config organization first.

Remember to rename CloudoLife with your prefer organization name.

1
$ pulumi config github:organization CloudoLife

It will put github:organization and value into ./Pulumi.dev.yaml.

1
2
3
4
5
6
7
# Pulumi.dev.yaml

encryptionsalt: < Encryptionsalt >
config:
github:organization: CloudoLife
github:token:
secure: < Secure >

References

[1] GitHub | Pulumi - https://www.pulumi.com/docs/intro/cloud-providers/github/

[2] GitHub Setup | Pulumi - https://www.pulumi.com/docs/intro/cloud-providers/github/setup/

[3] pulumi/pulumi-github: A Pulumi package to facilitate interacting with GitHub - https://github.com/pulumi/pulumi-github/

[4] Pulumi - Modern Infrastructure as Code - https://www.pulumi.com/

[5] Node.js - https://nodejs.org/en/

[6] Personal Access Tokens - https://github.com/settings/tokens

[7] GitHub: Where the world builds software · GitHub - https://github.com/