EC2 RunInstances returns NoSuchEntity for a valid IAM instance profile (regression after IAM-from-moto migration in 2026.03)
#27
ivanpogrebkov-alphapoint
started this conversation in
Bugs
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Summary
Calling
ec2:RunInstanceswith--iam-instance-profile Name=<name>(orArn=<arn>) fails withNoSuchEntity: Instance profile <name> not found, even though the profileexists and
iam:GetInstanceProfilereturns 200 for the same name in the sameaccount.
Reproduces cleanly with direct
awslocalcalls — no Terraform, no CDK, noextra wrappers. Fails with both
Name=andArn=forms, withENFORCE_IAM=1and
ENFORCE_IAM=0, and withEC2_VM_MANAGER=mockand the default dockerbackend.
Environment
localstack/localstack-pro:latestpulled 2026-04-13)Minimal reproduction
Against a vanilla
localstack/localstack-pro:latest(no init hooks, no configcustomizations beyond a valid
LOCALSTACK_AUTH_TOKEN):Without
--iam-instance-profile, step 4 succeeds. Launching withArn=of thesame profile fails identically.
Expected vs actual
iam:GetInstanceProfileabove.NoSuchEntity: Instance profile p not found.Root cause (as far as we can tell from inside the container)
moto's EC2 RunInstances path validates the instance profile via
moto.ec2.utils.filter_iam_instance_profiles, which callsmoto.iam.models.iam_backends[account_id][partition].get_instance_profile(name).Since the 2026.03 release moved IAM/STS out of moto into LocalStack core,
moto.iam.models.iam_backendsis no longer populated by IAM API calls —profiles created through LocalStack IAM go into the LocalStack-native store,
and moto's dict stays permanently empty. Moto's EC2 therefore always raises
NotFoundExceptionhere.Confirmation:
And inspection of the relevant functions:
moto.ec2.utils.filter_iam_instance_profiles— delegates to moto IAM backendmoto.ec2.responses.instances.InstanceResponse.run_instances— callsfilter_iam_instance_profilesbefore creating the instancemoto itself is behaving correctly; the gap is that the LocalStack IAM
migration didn't ship a shim keeping the moto backend in sync (or didn't swap
moto's EC2 lookup for a LocalStack-native one).
Suggested fix
Either would work; we think (a) is the lower-risk option:
(a) In the LocalStack IAM provider, mirror
create_instance_profile/delete_instance_profile/add_role_to_instance_profileintomoto.iam.models.iam_backends[account][partition]so the moto-shapedview stays populated for cross-service consumers.
(b) Replace
filter_iam_instance_profilesat EC2 provider load time with aLocalStack-native lookup (similar to the patching LocalStack already does
for other cross-service boundaries).
Workaround
Until a fix ships, a LocalStack init hook at the
READYstage can monkey-patchmoto.ec2.utils.filter_iam_instance_profilesto fall back to LocalStack IAMwhen moto misses, mirroring the profile (and any attached roles) into moto's
backend on demand. Full implementation here, public domain / happy-to-upstream:
Summary of the hook:
filter_iam_instance_profiles.connect_to(aws_access_key_id=account_id).iam.get_instance_profile(...).into
moto.iam.models.iam_backendsvia the backend's public methods.InstanceProfileobject so downstreamassociate_iam_instance_profileworks.Also rebinds
moto.ec2.models.iam_instance_profile.filter_iam_instance_profilesand
moto.ec2.responses.instances.filter_iam_instance_profilessince thosecapture the function by name at
fromimport time.Beta Was this translation helpful? Give feedback.
All reactions