kubernetes/kops · error
found IAM instance profile assigned to multiple Instance Gro
Error message
found IAM instance profile assigned to multiple Instance Group roles %v and %v: %v
What it means
During cluster model building, kOps allows a single pre-existing IAM instance profile (specified via spec.iam.profile on an InstanceGroup) to be shared, but only by Instance Groups that have the SAME InstanceGroupRole (e.g. two Node groups). If the same profile ARN appears on Instance Groups with different roles, the generated IAM policy documents would conflict, so Build aborts with this error listing both roles and the offending ARN.
Source
Thrown at pkg/model/awsmodel/iam.go:70
"Effect": "Allow",
"Principal": { "Service": "{{ IAMServiceEC2 }}"},
"Action": "sts:AssumeRole"
}
]
}`
func (b *IAMModelBuilder) Build(c *fi.CloudupModelBuilderContext) error {
// Collect managed Instance Group roles
managedRoles := make(map[kops.InstanceGroupRole]bool)
// Collect Instance Profile ARNs and their associated Instance Group roles
sharedProfileARNsToIGRole := make(map[string]kops.InstanceGroupRole)
for _, ig := range b.AllInstanceGroups {
if ig.Spec.IAM != nil && ig.Spec.IAM.Profile != nil {
specProfile := fi.ValueOf(ig.Spec.IAM.Profile)
if matchingRole, ok := sharedProfileARNsToIGRole[specProfile]; ok {
if matchingRole != ig.Spec.Role {
return fmt.Errorf("found IAM instance profile assigned to multiple Instance Group roles %v and %v: %v",
ig.Spec.Role, sharedProfileARNsToIGRole[specProfile], specProfile)
}
} else {
sharedProfileARNsToIGRole[specProfile] = ig.Spec.Role
}
} else {
managedRoles[ig.Spec.Role] = true
}
}
// Generate IAM tasks for each shared role
for profileARN, igRole := range sharedProfileARNsToIGRole {
lchPermissions := false
defaultWarmPool := b.Cluster.Spec.CloudProvider.AWS.WarmPool
for _, ig := range b.InstanceGroups {
warmPool := defaultWarmPool.ResolveDefaults(ig)
if ig.Spec.Role == igRole && warmPool.IsEnabled() && warmPool.EnableLifecycleHook {
lchPermissions = trueView on GitHub (pinned to 4c8573c808)
Solutions
- Give each role its own instance profile: set a distinct spec.iam.profile ARN per InstanceGroup role.
- If the groups should truly share an identity, make their spec.role identical (e.g. both Node).
- Remove spec.iam.profile from one group so it falls back to the kOps-managed profile for its role.
Example fix
// before
apiVersion: kops.k8s.io/v1alpha2
kind: InstanceGroup
metadata:
name: control-plane-1
spec:
role: ControlPlane
iam:
profile: arn:aws:iam::123456789012:instance-profile/shared
---
kind: InstanceGroup
metadata:
name: nodes-1
spec:
role: Node
iam:
profile: arn:aws:iam::123456789012:instance-profile/shared
// after
spec:
role: Node
iam:
profile: arn:aws:iam::123456789012:instance-profile/nodes-profile Defensive patterns
Strategy: validation
Validate before calling
profiles := map[string]string{}
for _, ig := range instanceGroups {
if ig.Spec.IAM != nil && ig.Spec.IAM.Profile != nil {
arn := fi.ValueOf(ig.Spec.IAM.Profile)
if prev, ok := profiles[arn]; ok && prev != string(ig.Spec.Role) {
return fmt.Errorf("profile %s shared across roles %s and %s", arn, prev, ig.Spec.Role)
}
profiles[arn] = string(ig.Spec.Role)
}
} Prevention
- Keep a one-to-one mapping between instance profile ARNs and InstanceGroup roles in your manifests.
- Review `kops get ig -o yaml` before update and grep for duplicate iam.profile values.
- Let kOps manage profiles unless a shared profile is a hard requirement, and then only within one role.
When it happens
Trigger: Running `kops update cluster` / `kops edit cluster` when two or more InstanceGroups set spec.iam.profile to the same ARN while their spec.role values differ (e.g. one Node group and one ControlPlane group both point at the same instance profile ARN).
Common situations: Copy-pasting an existing profile ARN into a new instance group manifest and forgetting to change the role; consolidating groups to save IAM resources; migrating from managed to custom profiles on only part of the cluster.
Related errors
- unable to find IAM profile link for instance group %q: %w
- unable to parse instance profile name from arn %q: %v
- IP version is incorrect
- ErrAlreadyExists
- provider ID cannot be empty
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/6519f5934dfb369d.
Report an issue: GitHub.