@@ -31,6 +31,10 @@ def make_client(name, region):
31
31
return boto3 .client (name , region_name = region )
32
32
33
33
34
+ def make_resource (name ):
35
+ return boto3 .resource (name )
36
+
37
+
34
38
def ensure_log_group (group_name , region ):
35
39
"""
36
40
Ensures that a log group is present. If there is a matching log group, nothing is created.
@@ -208,11 +212,12 @@ def ensure_role(client, role_name):
208
212
def ensure_task_role (region ):
209
213
"""
210
214
Ensures a task role exists. If there is one matching role, its Arn is returned. If there are
211
- multiple matching roles, a RuntimeError is raised. If there are no matching roles, a new one
215
+ multiple matching roles, a ` RuntimeError` is raised. If there are no matching roles, a new one
212
216
is created.
213
217
214
- TODO: Fix this.
218
+ TODO: Fix this:
215
219
This method does not check that a matching role has the correct policies.
220
+
216
221
:param region: The region, or `None` to pull the region from the environment.
217
222
:return: The role Arn.
218
223
"""
@@ -253,9 +258,14 @@ def ensure_task_role(region):
253
258
return role_arn
254
259
255
260
256
- def ensure_ec2_role (region ):
257
- role_name = "axon-ec2-autogenerated-role"
258
- profile_name = "axon-ec2-autogenerated-instance-profile"
261
+ def ensure_ec2_role (region , role_name = "axon-ec2-autogenerated-role" ):
262
+ """
263
+ Ensures the EC2 role exists. Creates the role if it does not exist.
264
+
265
+ :param region: The region, or `None` to pull the region from the environment.
266
+ :param role_name: The name of the role to ensure.
267
+ :return: The role Arn.
268
+ """
259
269
client = make_client ("iam" , region )
260
270
role_arn = ensure_role (client , role_name )
261
271
if role_arn is None :
@@ -282,15 +292,36 @@ def ensure_ec2_role(region):
282
292
client .attach_role_policy (RoleName = role_name ,
283
293
PolicyArn = "arn:aws:iam::aws:policy/AmazonS3FullAccess" )
284
294
295
+ return role_arn
296
+
297
+
298
+ def ensure_ec2_instance_profile (region , profile_name = "axon-ec2-autogenerated-instance-profile" ,
299
+ role_name = "axon-ec2-autogenerated-role" ):
300
+ """
301
+ Ensures the EC2 instance profile exists and has the EC2 role attached.
302
+
303
+ :param region: The region, or `None` to pull the region from the environment.
304
+ :param profile_name: The name of the instance profile to ensure.
305
+ :param role_name: The name of the role to ensure.
306
+ :return: The instance profile Arn.
307
+ """
308
+ client = make_client ("iam" , region )
309
+ iam_resource = make_resource ('iam' )
310
+
311
+ # Get or create the instance profile
285
312
try :
286
- client .get_instance_profile (InstanceProfileName = profile_name )
313
+ local_profile = client .get_instance_profile (InstanceProfileName = profile_name )
287
314
except :
288
- client .create_instance_profile (InstanceProfileName = profile_name )
289
- iam_resource = boto3 .resource ('iam' )
290
- instance_profile = iam_resource .InstanceProfile (profile_name )
315
+ local_profile = client .create_instance_profile (InstanceProfileName = profile_name )
316
+
317
+ instance_profile = iam_resource .InstanceProfile (
318
+ local_profile ['InstanceProfile' ]['InstanceProfileName' ])
319
+
320
+ if role_name not in [role .name for role in instance_profile .roles ]:
321
+ # Add the role if it does not exist
291
322
instance_profile .add_role (RoleName = role_name )
292
323
293
- return role_arn
324
+ return instance_profile . arn
294
325
295
326
296
327
def ensure_cluster (ecs_client , cluster_name ):
@@ -395,6 +426,7 @@ def impl_ensure_configuration(cluster_name, task_family, region):
395
426
ensure_ecs_security_group (region )
396
427
ensure_task_role (region )
397
428
ensure_ec2_role (region )
429
+ ensure_ec2_instance_profile (region )
398
430
399
431
400
432
def impl_start_task (cluster_name , task_family , revision , region ):
0 commit comments