pulumi/pulumi-kubernetesx

Add an easy way to create a Docker config Secret for private image pulling

ringods opened this issue ยท 5 comments

export const imagePullSecret = new k8s.core.v1.Secret(
    "docker-hub",
    {
        type: "kubernetes.io/dockerconfigjson",
        metadata: {
            namespace: "community"
        },
        stringData: {
            ".dockerconfigjson": config
                .requireSecret("docker-hub-token")
                .apply(value => {
                    return JSON.stringify({
                        auths: {
                            "https://index.docker.io/v1/": {
                                auth: value
                            }
                        }
                    })
                })
        },
    },
    {
        provider: kubernetesProvider
    }
);

The above snippet is the current way to create a Secret which can be used to pull private Docker images from Docker Hub. Please provide an easier way to create such a secret.

Context:

Issue created on request of @lblackstone

Note for the documentation: the configured Pulumi secret named docker-hub-token is actually more than just the personal access token. It should be the base64 encoded version of a string of the form:

<username>:<password>
or
<username>:<personal access token>

It took me a while to get this right so please add this to the documentation so other people do not have to waste time too.

If you created the registry with pulumi (for example on azure) you can use the outputs from the registry object to generate your secret.

const registry = new azure.containerservice.Registry(....

Then call the below function as follows

const secret = createImagePullSecret(registry.adminUsername, 
    registry.adminPassword, registry.loginServer, k8sProvider)

And to create the secret.

export function createImagePullSecret(username: pulumi.Output<string>,
    password: pulumi.Output<string>, 
    registry : pulumi.Output<string>,
    k8sProvider : k8s.Provider): k8s.core.v1.Secret {

    // Put the username password into dockerconfigjson format.
    let base64JsonEncodedCredentials : pulumi.Output<string> = 
        pulumi.all([username, password, registry])
        .apply(([username, password, registry]) => {
            const base64Credentials = Buffer.from(username + ':' + password).toString('base64')
            const json =  `{"auths":{"${registry}":{"auth":"${base64Credentials}"}}}`
            console.log(json)
            return Buffer.from(json).toString('base64')
        })

    return new k8s.core.v1.Secret('image-pull-secret', {
        metadata: {
            name: 'image-pull-secret',
        },
        type: 'kubernetes.io/dockerconfigjson',
        data: {
            ".dockerconfigjson": base64JsonEncodedCredentials,
        },
    }, { provider: k8sProvider })
}

For DigitalOcean:

// Private container registry to deploy images into
export const registry = new digitalocean.ContainerRegistry(`container-registry`);

export const registryCreds = pulumi.secret(new digitalocean.ContainerRegistryDockerCredentials("container-registry-creds", { registryName: registry.name }).dockerCredentials);

const registryCredsKubeSecretName = new k8s.core.v1.Secret('registry-creds-secret', {
  type: 'kubernetes.io/dockerconfigjson',
  data: {
    ".dockerconfigjson": registryCreds.apply(v => Buffer.from(v).toString('base64')),
  },
}, { provider })

Thanks @snipebin <3

And how do you patch the default ServiceAccount for a given namespace to use this secret? @snipebin @ianpurton