Support for multi-cloud/account setups in Jenkins plugins

66 views
Skip to first unread message

Chris Kilding

unread,
Feb 12, 2021, 6:40:27 AM2/12/21
to jenkin...@googlegroups.com
Hello,

Interest in multi-cloud and multi-account cloud setups is increasing at my company, and I have had correspondence from people in other companies about this too. It's worth thinking about how Jenkins is going to work in this scenario going forward.

There are quite a few Jenkins plugins that connect to cloud providers (e.g. EC2 plugin, S3 plugin, my own Secrets Manager plugin, plus all the Azure, GCP, Kubernetes equivalents). At the moment, these plugins are (at the risk of generalising) built with the assumption that they connect to a single cloud account. They work well within this assumption, but not outside it.

The key issues at the moment are:

1. Name clashes (due to lack of namespacing facilities) when two resources in different accounts have the same name.
2. Slowness/unavailability from interactions with one cloud account affecting interactions with other accounts.

To resolve the first problem, I would propose that we introduce a namespacing feature of some kind, to allow resources from different accounts to safely coexist.

For the second problem, perhaps some partitioning of operations could be done within the namespacing feature, so that if one API call goes bad or slower than the others, it doesn't affect interactions with other accounts.

At a minimum this would need to be done in the credentials API plugin: I'm thinking an optional `namespace` argument could be specified for the `withCredentials` or `credentials` bindings, implemented by the credential providers. But I'm not sure that namespaces should be limited to just the credentials system. Are there other parts of the Jenkins pipeline which deal with cloud resources, and so would need to be aware of the namespacing feature as well?

Regards,

Chris

PS: In the past I have considered generalising the folders credentials provider for this purpose, but this does not seem like the right fit. This is really a namespacing problem, not an access control problem (which is what folders are for).

Matt Sicker

unread,
Feb 12, 2021, 10:18:09 AM2/12/21
to chris+...@chriskilding.com, jenkin...@googlegroups.com
This sounds like something that belongs in an identity and access
management solution in general since it's a common problem to be
solved for all your other applications using those auth sources.
> --
> You received this message because you are subscribed to the Google Groups "Jenkins Developers" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to jenkinsci-de...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/jenkinsci-dev/3e423f19-b3d1-4827-9881-b89d3b73b051%40www.fastmail.com.



--
Matt Sicker
Senior Software Engineer, CloudBees

Chris Kilding

unread,
Feb 12, 2021, 1:23:26 PM2/12/21
to jenkin...@googlegroups.com
Hi Matt,

Definitely agree that the various Jenkins access control solutions should be aware of namespaces, so that sysadmins can specify rules like 'this identity principal can access resources in that namespace'.

Chris
> https://groups.google.com/d/msgid/jenkinsci-dev/CAEot4owhMdnn5gNQGrkCdv%3D_dCD9oMHmy81khELxZfzgHiTOOA%40mail.gmail.com.
>

Chris Kilding

unread,
Feb 15, 2021, 7:29:19 AM2/15/21
to jenkin...@googlegroups.com
This is my starter for ten for how namespaces could look in the credentials API...

A `credentials` binding in your Jenkinsfile would look like this:

pipeline {
agent any
stages {
stage('Deploy to staging') {
environment {
API_KEY = credentials('api-key', namespace: '1111111111')
}
steps {
sh 'curl -X POST -u "foo:$API_KEY" https://example.com'
}
}
stage('Deploy to production') {
environment {
API_KEY = credentials('api-key', namespace: '2222222222')
}
steps {
sh 'curl -X POST -u "foo:$API_KEY" https://example.com'
}
}
}
}

A `withCredentials` binding would look like this:

node {
withCredentials(bindings: [string(credentialsId: 'api-key', variable: 'API_KEY', namespace: '1111111111')]) {
echo 'Hello world'
}
}

It will be up to the credentials providers how to implement namespacing. I would expect this to be driven by the plugin configuration for those providers. For example each AWS account namespace will be accompanied by information to drive the necessary sts:assumeRole operation, which lets the AWS SDK do things in the alternate account.

A namespace could correspond to:

- An AWS/Azure etc account (as shown above).
- An infrastructure environment within an account. (E.g. if secrets are given prefixes, like /environments/staging/api-key and /environments/production/api-key, the prefix should be usable as a namespace qualifier together with filtering.)

An implicit default namespace exists for credentials with no namespace information. This is what will be used if we call `credentials` or `withCredentials` with no `namespace` argument, like we do today.

The default namespace enables:

- Credentials to be put there by choice (e.g. credentials stored in the same AWS account as Jenkins).
- Backwards compatibility (credentials from providers that don't support namespaces - in other words any existing provider - are deemed to be in the default namespace).

Some questions that arise from this:

1. How does this generalise to other parts of Jenkins? (For example, could the EC2 plugin use namespaces to allow instances to be launched in alternate AWS accounts?)
2. How to ensure namespaces are unique? (If namespaces are declared solely within individual plugins' configs, there is the possibility that two configs could declare the same namespace.) Perhaps this dovetails into the next question...
3. Where should namespaces be declared in Jenkins config, so that the access control systems can also use them?

Chris
> https://groups.google.com/d/msgid/jenkinsci-dev/40b34fd2-06d7-4261-9fef-204fb015223b%40www.fastmail.com.
>
Reply all
Reply to author
Forward
0 new messages