diff --git a/pkg/model/awsmodel/iam.go b/pkg/model/awsmodel/iam.go index 0d05662c6c..3db649b784 100644 --- a/pkg/model/awsmodel/iam.go +++ b/pkg/model/awsmodel/iam.go @@ -202,15 +202,19 @@ func (b *IAMModelBuilder) buildIAMRole(role iam.Subject, iamName string, c *fi.M Lifecycle: b.Lifecycle, RolePolicyDocument: rolePolicy, - Tags: b.CloudTags(iamName, false), } if isServiceAccount { // e.g. kube-system-dns-controller iamRole.ExportWithID = fi.String(roleKey) + sa, ok := role.ServiceAccount() + if ok { + iamRole.Tags = b.CloudTagsForServiceAccount(iamName, sa) + } } else { // e.g. nodes iamRole.ExportWithID = fi.String(roleKey + "s") + iamRole.Tags = b.CloudTags(iamName, false) } if b.Cluster.Spec.IAM != nil && b.Cluster.Spec.IAM.PermissionsBoundary != nil { diff --git a/pkg/model/context.go b/pkg/model/context.go index 0bb2609571..f2ccbc27c3 100644 --- a/pkg/model/context.go +++ b/pkg/model/context.go @@ -21,6 +21,7 @@ import ( "net" "strings" + "k8s.io/apimachinery/pkg/types" "k8s.io/kops/pkg/apis/kops" "k8s.io/kops/pkg/apis/kops/model" "k8s.io/kops/pkg/apis/kops/util" @@ -189,6 +190,13 @@ func (b *KopsModelContext) CloudTagsForInstanceGroup(ig *kops.InstanceGroup) (ma return labels, nil } +func (b *KopsModelContext) CloudTagsForServiceAccount(name string, sa types.NamespacedName) map[string]string { + tags := b.CloudTags(name, false) + tags[awstasks.CloudTagServiceAccountName] = sa.Name + tags[awstasks.CloudTagServiceAccountNamespace] = sa.Namespace + return tags +} + // CloudTags computes the tags to apply to a normal cloud resource with the specified name func (b *KopsModelContext) CloudTags(name string, shared bool) map[string]string { tags := make(map[string]string) diff --git a/upup/pkg/fi/cloudup/awstasks/iamrole.go b/upup/pkg/fi/cloudup/awstasks/iamrole.go index feda9699d3..d68a89c317 100644 --- a/upup/pkg/fi/cloudup/awstasks/iamrole.go +++ b/upup/pkg/fi/cloudup/awstasks/iamrole.go @@ -34,6 +34,12 @@ import ( "k8s.io/kops/upup/pkg/fi/cloudup/terraformWriter" ) +// CloudTagServiceAccountName is a tag that defines the service account's name +const CloudTagServiceAccountName = "service-account.kops.k8s.io/name" + +// CloudTagServiceAccountNamespace is a tag that defines the service account's namespace +const CloudTagServiceAccountNamespace = "service-account.kops.k8s.io/namespace" + // +kops:fitask type IAMRole struct { ID *string