Reputation: 155
I'm trying to attach create an IAM role using Python Boto3 SDK however I keep receiving the following error:
An error occurred (MalformedPolicyDocument) when calling the CreateRole operation: This policy contains invalid JSON
This is my method to create_role:
iam = boto3.client('iam')
try:
with open('IAMPolicy.json') as json_file:
template = json.load(json_file)
template = str(template)
role = iam.create_role(
RoleName = iam_role_name,
AssumeRolePolicyDocument = template,
Description = iam_role_description
)
print(role)
print('IAM role' + iam_role_name + ' successfully created.')
except ClientError as e:
print(e)
sys.exit('Exiting the system because IAM role creation failed.')
And here is my example role I am trying to create.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:PutBucketNotification",
"s3:PutBucketPolicy",
"s3:CreateBucket",
"s3:GetBucketPolicy"
],
"Resource": [
"arn:aws:s3:::*/*",
"arn:aws:s3:::mybucket1729788"
]
}
]
}
The policy is valid according to IAM Management policy validator in the console so I'm not sure where I'm going wrong. Anyone able to help?
Upvotes: 1
Views: 2495
Reputation: 10704
Your JSON does not look valid. I used this JSON and it worked fine:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::81454804xxxx:user/PowerUserxxxx"
},
"Action": "sts:AssumeRole",
"Condition": {}
}
]
}
More information here: How to use trust policies with IAM roles.
I just tested this trusted policy via Java code and it worked perfectly.
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import software.amazon.awssdk.services.iam.model.*;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.iam.IamClient;
import java.io.FileReader;
public class CreateRole {
public static void main(String[] args) {
final String USAGE = "\n" +
"Usage:\n" +
" CreateRole <rolename> <fileLocation> \n\n" +
"Where:\n" +
" rolename - the name of the role to create. \n\n" +
" fileLocation - the location of the JSON document that represents the trust policy. \n\n" ;
if (args.length != 2) {
System.out.println(USAGE);
System.exit(1);
}
String rolename = args[0];
String fileLocation = args[1];
Region region = Region.AWS_GLOBAL;
IamClient iam = IamClient.builder()
.region(region)
.build();
String result = createIAMRole(iam, rolename, fileLocation) ;
iam.close();
}
public static String createIAMRole(IamClient iam, String rolename, String fileLocation ) {
try {
JSONObject jsonObject = (JSONObject) readJson(fileLocation);
CreateRoleRequest request = CreateRoleRequest.builder()
.roleName(rolename)
.assumeRolePolicyDocument(jsonObject.toJSONString())
.description("Created using the AWS SDK for Java")
.build();
CreateRoleResponse response = iam.createRole(request);
System.out.println("The ARN of the role is "+response.role().arn());
} catch (IamException e) {
System.err.println(e.awsErrorDetails().errorMessage());
System.exit(1);
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
public static Object readJson(String filename) throws Exception {
FileReader reader = new FileReader(filename);
JSONParser jsonParser = new JSONParser();
return jsonParser.parse(reader);
}
}
Upvotes: 1
Reputation: 9615
The trouble is you are providing an IAM Policy
when you are supposed to provide a Trust Policy
for the IAM role while creating the role, create_role something like below:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111122223333:root"
},
"Action": "sts:AssumeRole",
"Condition": {}
}
]
}
Trust policy
A JSON policy document in which you define the principals that you trust to assume the role. A role trust policy is a required resource-based policy that is attached to a role in IAM. The principals that you can specify in the trust policy include users, roles, accounts, and services
Below is an example
assume_role_policy_document = json.dumps({
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111122223333:root"
},
"Action": "sts:AssumeRole",
"Condition": {}
}
]
})
create_role_response = iam.create_role(
RoleName = "myrolenamee,
AssumeRolePolicyDocument = assume_role_policy_document
)
After creating the role you attach your custom policy, using attach_role_policy
response = iam.attach_role_policy(
RoleName='myrolename',
PolicyArn='arn:aws:iam::123456789012:policy/mycustompolicy'
)
How to use trust policies with IAM roles
Creating a role to delegate permissions to an AWS service
Upvotes: 0