boto3
boto3 copied to clipboard
`InstanceProfile` "has" `Roles`, but it should "hasMany" `Roles`
An IAM instance profile can have a collection of roles attached to it. I think in the giant JSON that needs to be reflected as a hasMany and not a has. Otherwise it looks like an instance profile has only one role, but that it gets returned in an array.
https://github.com/boto/boto3/blob/0b82bf9843ad6d350b48442c47f4a484a886ee3f/boto3/data/iam/2010-05-08/resources-1.json#L732-L742
Hi @adamnovak,
Thanks for your feedback. I'm looking into what the expectations on this structure are, but my feeling is that we will not be able to make a change to this resource definition as it would not be backwards compatible.
Have you confirmed that when you use this resource that you only get back a single role for the instance profile instead of a list of roles?
Notably, one of the other AWS SDKs that supports resources, the PHP SDK, has the same configuration:
https://github.com/awslabs/aws-sdk-php-resources/blob/07dc483fc45d38dacfb5e030de676fb967a8fca4/src/models/iam-2010-05-08.resources.php#L1136-L1151
I haven't noticed this resulting in only a single role actually being returned by boto3, but I also haven't tested with an instance profile attached to multiple roles. My guess is that path is consulted and the correct array is fished out of the JSON, even if it has multiple entries.
Either way, I get a returned value of list type, even if there's just one entry:
python3 <<'EOF'
import boto3
iam = boto3.resource('iam')
instance_profile = iam.InstanceProfile('ecsInstanceRole')
print(instance_profile.roles)
EOF
Enter MFA code for arn:aws:iam::652235167018:mfa/[email protected]:
[iam.Role(name='ecsInstanceRole')]
Where this issue affects me right now is that this JSON specification is used by the code that generates the boto3-stubs module with the type information for boto3, and that module decides that the roles field should have type Role and not List[Role]. Then my attempts to iterate over it don't type-check. See https://github.com/vemel/mypy_boto3_builder/issues/122.
I'm not certain if the type stub generator keys on has vs. hasMany, or whether it just looks in type, sees Role, and spits out Role, but the type annotations disagree with the actual returned type. I assumed that the type generator is probably right in general and the spec is probably wrong here, but it could be the other way around. Where are the intended semantics of has, hasMany, and the type field documented?
The official documentation also lists just Role as the type of the field here. Compare to this other method where policy.attached_roles.all() has a return type described as list(iam.Role). Presumably the plural name and the clear intention of multi-value semantics are enough to make sure people reading the docs write correct code, but a literal reading of the docs' type information says this is specced as a single value, just like the type stub generator says.
Maybe the docs generator and the type stub generator are both interpreting the file wrong?
Hi @adamnovak,
I'm looking into this further, but I don't have any good answers for you right now. Specifically:
Where are the intended semantics of has, hasMany, and the type field documented?
I do not believe there's documentation specifically for these fields, or for the schema of the JSON files themselves.
I'll need to dig into the code a bit as to what the current behavior is - as you've determined on https://github.com/vemel/mypy_boto3_builder/issues/122 it seems that boto3 does return it as a list!
With respect to support for these, we're not actively developing or improving the resource implementations, but it has been discussed as a useful feature that should get more attention. I don't have any specific timeline on when development efforts might resume on resources at the moment.