@@ -324,6 +324,65 @@ def ensure_ec2_instance_profile(region, profile_name="axon-ec2-autogenerated-ins
324324 return instance_profile .arn
325325
326326
327+ def ensure_s3_bucket (region ):
328+ """
329+ Ensures that a matching S3 bucket exists.
330+
331+ :param region: The region, or `None` to pull the region from the environment.
332+ :return: The name of the bucket.
333+ """
334+ client = make_client ("s3" , region )
335+ prefix = "axon-autogenerated-" # Used to identify the bucket that Axon manages
336+
337+ def get_axon_bucket ():
338+ buckets = client .list_buckets ()["Buckets" ]
339+
340+ # Return the first matching bucket name, if there is one
341+ for bucket in buckets :
342+ if bucket ["Name" ].startswith (prefix ):
343+ return bucket ["Name" ]
344+
345+ return None
346+
347+ axon_bucket = get_axon_bucket ()
348+ if axon_bucket is not None :
349+ return axon_bucket
350+
351+ # There is no matching bucket name, so create a new one
352+ import random
353+ import string
354+ while True :
355+ bucket_name = prefix + '' .join (
356+ random .choice (string .ascii_lowercase + string .digits ) for _ in range (30 ))
357+
358+ # If the user wants a region in this list, we need to set it
359+ if region in ['EU' , 'eu-west-1' , 'us-west-1' , 'us-west-2' ,
360+ 'ap-south-1' , 'ap-southeast-1' , 'ap-southeast-2' ,
361+ 'ap-northeast-1' , 'sa-east-1' , 'cn-north-1' ,
362+ 'eu-central-1' ]:
363+ client .create_bucket (ACL = 'private' , Bucket = bucket_name ,
364+ CreateBucketConfiguration = {'LocationConstraint' : region })
365+ else :
366+ # Otherwise the region will be us-east-1
367+ client .create_bucket (ACL = 'private' , Bucket = bucket_name )
368+
369+ # Busy loop until the bucket is created. Otherwise, we will set the public access block
370+ # too early and its configuration will be lost
371+ while True :
372+ axon_bucket = get_axon_bucket ()
373+ if axon_bucket is not None :
374+ break
375+
376+ client .put_public_access_block (Bucket = bucket_name , PublicAccessBlockConfiguration = {
377+ 'BlockPublicAcls' : True ,
378+ 'IgnorePublicAcls' : True ,
379+ 'BlockPublicPolicy' : True ,
380+ 'RestrictPublicBuckets' : True
381+ })
382+
383+ return bucket_name
384+
385+
327386def ensure_cluster (ecs_client , cluster_name ):
328387 """
329388 Ensures that a matching cluster exists. If there are no matching clusters, one is created.
@@ -420,6 +479,7 @@ def impl_ensure_configuration(cluster_name, task_family, region):
420479 :param region: The region, or `None` to pull the region from the environment.
421480 """
422481 client = make_client ("ecs" , region )
482+ ensure_s3_bucket (region )
423483 ensure_cluster (client , cluster_name )
424484 ensure_task (client , task_family , region , 2048 , 4096 )
425485 ensure_ec2_security_group (region )
0 commit comments