I am trying to create a job with Amazon Glue, using boto3. I'm using STS to connect to the AWS account, as per the following code:
session_name = 'glue_job_creation'
client = boto3.client("sts",region_name="eu-west-1",endpoint_url="https://sts.eu-west-1.amazonaws.com")
response = client.assume_role(RoleArn=arn , RoleSessionName=session_name)
temp_credentials = response["Credentials"]
glue = boto3.client(service_name='glue', region_name='eu-west-1',
endpoint_url='https://glue.eu-west-1.amazonaws.com',
aws_access_key_id=temp_credentials["AccessKeyId"],
aws_secret_access_key=temp_credentials["SecretAccessKey"],
aws_session_token=temp_credentials["SessionToken"])
def list_glue_jobs():
response = glue.list_jobs()
print(response)
def create_glue_job():
print('creating new glue job...')
print(response)
myJob = glue.create_job(Name='sample', Role=JobRole,
Command={'Name': 'glueetl',
'ScriptLocation': script_location})
myNewJobRun = glue.start_job_run(JobName=myJob['Name'])
return myNewJobRun
The list_job
function works alright, but the create_job
doesn't work. I get the following error:
botocore.errorfactory.AccessDeniedException: An error occurred (AccessDeniedException) when calling the CreateJob operation: User: arn:aws:sts::xxxxxxxxxxxx:assumed-role/assumed-role-name/session-name is not authorized to perform: iam:PassRole on resource: arn:aws:iam::xxxxxxxxx:role/assumed-role because no identity-based policy allows the iam:PassRole action
I do not understand why the session-name
is appended to the User ARN in this case. Also, is the solution to this simply to create an IAM role with the session name appended to the role name like assumed-role/role-name
, or is there something I am missing?
CodePudding user response:
Session name is just an arbitrary string to identify when someone/something is using an IAM role. Since IAM roles have no credentials like IAM users, the only way to use IAM roles is to assume them. For example EC2 machines assume the IAM role attached to them and use their instance ID as the session name so in the CloudTrail logs you can see which instance is using that IAM role, even if multiple instances are assuming the same IAM role.
So when you see something like this:
arn:aws:sts::xxxxxxxxxxxx:assumed-role/assumed-role-name/session-name
it just means:
I am
session-name
and I am using IAM rolearn:aws:iam::xxxxxxxxxxxx:role/assumed-role-name
Note that the actual IAM role has aws:iam
in the ARN and the assumed roles have aws:sts
in the ARN. The assumed role ARN with the session name is a temporary session and not an existing IAM resource/document that you can create/update. More details about assuming IAM roles can be found in the STS AssumeRole API reference.
So in your example, the session-name
who is using the IAM role assumed-role-name
wants to call iam:PassRole
with arn:aws:iam::xxxxxxxxx:role/assumed-role
.
The solution is to extend your arn:aws:iam::xxxxxxxxxxxx:role/assumed-role-name
role with this policy statement:
{
"Action": [
"iam:PassRole"
],
"Effect": "Allow",
"Resource": "arn:aws:iam::xxxxxxxxxxxx:role/assumed-role",
"Condition": {
"StringLike": {
"iam:PassedToService": [
"glue.amazonaws.com"
]
}
}
}
This will allow the user of the assumed-role-name
IAM role to pass the assumed-role
IAM role to the created Glue jobs, so the new Glue jobs can run as assumed-role
and use the permissions specified in that IAM role.
If interested, you can read more on iam:PassRole
in the "Granting permissions to pass a role to a service" AWS IAM doc.
And the AWS Glue documentation "Attach a policy to IAM users that access AWS Glue" has more info about why this is needed for AWS Glue (note the Important section bout the PassRole requirement).