best-salesclerk-82359
11/22/2018, 1:32 PMroles/storage.admin
(whats also weird is that using roles/editor
works). Using gcloud projects add-iam-policy-binding ...
however works as expected and the storage admin role is associated
* I can't get the k8s.core.v1.Secret
class to accept the created service account key as the data for the secret
I am using the following code, any help is greatly appreciated!
js
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
import * as k8s from "@pulumi/kubernetes";
const gcloudProjectId = '...'
const resourceName = "team-v1-tyll-kaniko";
const serviceAccount = new gcp.serviceAccount.Account(`${resourceName}`, {
accountId: "team-v1-tyll-kaniko",
displayName: "team-v1-tyll-kaniko",
project: gcloudProjectId
});
const serviceAccountKey = pulumi
.all([serviceAccount.email, serviceAccount.project])
.apply(([email, project]) => {
return new gcp.serviceAccount.Key(`${resourceName}-key`, {
serviceAccountId: `projects/${project}/serviceAccounts/${email}`
});
});
const serviceAccountBinding = pulumi
.all([serviceAccount.email, serviceAccount.project])
.apply(([email, project]) => {
return new gcp.serviceAccount.IAMBinding(`${resourceName}-binding`, {
// Throws with Role roles/storage.admin is not supported for this resource.
// role: "roles/storage.admin",
role: "roles/editor",
serviceAccountId: `projects/${project}/serviceAccounts/${email}`,
members: [`serviceAccount:${email}`]
});
});
const secret = new k8s.core.v1.Secret("kaniko-secret", {
type: "generic",
metadata: { name: "kaniko-secret" },
data: {
// Throws with ObjectMeta: v1.ObjectMeta: TypeMeta: Kind: Data: decode base64: illegal base64 data at input byte 17, parsing 205
"kaniko-secret": serviceAccountKey
}
});
best-salesclerk-82359
11/22/2018, 2:54 PMjs
const secret = serviceAccountKey.apply(key => {
return pulumi.all([key.privateKey]).apply(([privateKey]) => {
return new k8s.core.v1.Secret("kaniko-secret", {
type: "generic",
metadata: { name: "kaniko-secret" },
stringData: {
"kaniko-secret": Buffer.from(privateKey, "base64").toString("utf8")
}
});
});
});
glamorous-printer-66548
11/23/2018, 5:04 AMserviceAccount.accountId
. That saves you from having unwrap all the properties like project and email from the serviceAccount.
2. I recommend using IAMMember over iam policy or binding, since the the latter two may cause weird surprises when you assign the same role in other parts of your code or via the cloud console
3. IAMBinding has no property serviceAccountId
- why are you putting it there?
4. Use TypesScript - saves you from mistakes like the one at 3. 😛glamorous-printer-66548
11/23/2018, 5:10 AMgcp.projects
namespace. I.e. gcp.projects.IAMMember
or gcp.projects.IAMBinding
. The binding / member resources in the gcp.serviceAccount
namespace are to grant a service account (A) or user (B) the permissions to *use*/assume another service account (C). This is also described in the docs: https://pulumi.io/reference/pkg/nodejs/@pulumi/gcp/serviceAccount/#IAMMemberbest-salesclerk-82359
11/24/2018, 4:09 PMgcp.projects.IAMMember
works like a charm.
Just one thing, when using serviceAccount.accountId
as the value for the serviceAccountId
property on the gcp.serviceAccount.Key
class terraform throws an error stating project: required field is not set
.
Using serviceAccount.name
instead works, e.g.
ts
const serviceAccount = new gcp.serviceAccount.Account(
"kaniko-service-account",
{
accountId: config.iam.serviceAccountName,
displayName: config.iam.serviceAccountName,
project: globalConfig.gcloud.projectId
}
);
const serviceAccountKey = new gcp.serviceAccount.Key(
`kaniko-service-account-key`,
{
// Using serviceAccount.accountId results in an error would be thrown stating `project: required field is not set`
serviceAccountId: serviceAccount.name
}
);