123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452 |
- ##
- ## Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- ##
- ## Licensed under the Amazon Software License (the "License"). You may not use this
- ## file except in compliance with the License. A copy of the License is located at
- ##
- ## http://aws.amazon.com/asl/
- ##
- ## or in the "license" file accompanying this file. This file is distributed on an
- ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or implied.
- ## See the License for the specific language governing permissions and limitations
- ## under the License.
- ##
- import troposphere
- import troposphere.ec2
- import troposphere.s3
- import troposphere.cloudformation
- import troposphere.sqs
- import troposphere.logs
- import troposphere.iam
- import troposphere.ecs
- import ipaddress
- t = troposphere.Template()
- t.add_version("2010-09-09")
- S3ArchiveBucket = t.add_parameter(troposphere.Parameter(
- "S3ArchiveBucket",
- Default="",
- Description="S3 Bucket where you will store the output archives. If empty, it will be created. An existing bucket needs to notify S3BundlerQueueName on new manifests written by s3grouper.",
- Type="String",
- ))
- NeedsArchiveBucket = t.add_condition(
- "NeedsArchiveBucket",
- troposphere.Equals(troposphere.Ref(S3ArchiveBucket), ""))
- S3ArchivePrefix = t.add_parameter(troposphere.Parameter(
- "S3ArchivePrefix",
- Default="archive",
- Description="Prefix within S3 Bucket where you will store the output archives",
- Type="String",
- ))
- S3ManifestPrefix = t.add_parameter(troposphere.Parameter(
- "S3ManifestPrefix",
- Default="manifests",
- Description="Prefix in the S3 archive bucket where you will store the intermediate manifests.",
- Type="String",
- ))
- S3InventoryBucket = t.add_parameter(troposphere.Parameter(
- "S3InventoryBucket",
- Description="S3 Bucket where you sent your S3 Storage Inventory. http://docs.aws.amazon.com/AmazonS3/latest/dev/storage-inventory.html",
- Type="String",
- ))
- S3InventoryPrefix = t.add_parameter(troposphere.Parameter(
- "S3InventoryPrefix",
- Default="",
- Description="Prefix within the S3 Bucket where you sent your S3 Storage Inventory. http://docs.aws.amazon.com/AmazonS3/latest/dev/storage-inventory.html",
- Type="String",
- ))
- S3SourceBuckets = t.add_parameter(troposphere.Parameter(
- "S3SourceBuckets",
- Default="*",
- Description="Comma separated list of S3 buckets in ARN format with trailing '/*' with objects that need to be compressed and bundled. Leave '*' for all buckets in the account. e.g. arn:aws:s3:::foo/*,arn:aws:s3:::bar/*,arn:aws:s3:::baz/*",
- Type="CommaDelimitedList"
- ))
- S3GrouperURL = t.add_parameter(troposphere.Parameter(
- "S3GrouperURL",
- Description="Docker URL for s3grouper container",
- Type="String",
- ))
- S3BundlerURL = t.add_parameter(troposphere.Parameter(
- "S3BundlerURL",
- Description="Docker URL for s3bundler container",
- Type="String",
- ))
- S3BundlerQueueARN = t.add_parameter(troposphere.Parameter(
- "S3BundlerQueueARN",
- Default="",
- Description="SQS queue to tell s3bundler what manifests to work on. Leave empty to create a new queue. If it already exists, it needs to allow S3ArchiveBucket to send it messages and to be configured to send messages to S3BundlerDLQ.",
- Type="String",
- ))
- NeedsQueue = t.add_condition(
- "NeedsQueue",
- troposphere.Equals(troposphere.Ref(S3BundlerQueueARN), ""))
- S3BundlerDLQARN = t.add_parameter(troposphere.Parameter(
- "S3BundlerDLQARN",
- Default="",
- Description="SQS queue for messages that s3bundler failed to process. Leave empty to create a new queue. If it already exists, it needs to allow S3BundlerQueue to send it messages.",
- Type="String",
- ))
- NeedsDLQ = t.add_condition(
- "NeedsDLQ",
- troposphere.Equals(troposphere.Ref(S3BundlerDLQARN), ""))
- MaxSize = t.add_parameter(troposphere.Parameter(
- "MaxSize",
- Type="String",
- Description="Objects greater than maxsize will be copied directly to the destination bucket. Metadata will be stored alongside them. Checksums will not be calculated.",
- Default="2GB",
- AllowedPattern="^\\d+(GB|G|MB|M|KB|K|gb|g|mb|m|kb|k)?$"
- ))
- Compress = t.add_parameter(troposphere.Parameter(
- "Compress",
- Type="String",
- Description="Compress archives with gzip",
- Default="true",
- AllowedValues=["true","false"]
- ))
- CompressTrue = t.add_condition(
- "CompressTrue",
- troposphere.Equals("true", troposphere.Ref(Compress)))
- sqsdlq = t.add_resource(troposphere.sqs.Queue(
- "sqsdlq",
- MessageRetentionPeriod=1209600,
- DeletionPolicy=troposphere.Retain,
- Condition="NeedsDLQ"
- ))
- DLQChoice = troposphere.If("NeedsDLQ",
- troposphere.GetAtt(sqsdlq, "Arn"),
- troposphere.Ref(S3BundlerDLQARN))
- ManifestQueue = t.add_resource(troposphere.sqs.Queue(
- "ManifestQueue",
- MessageRetentionPeriod=1209600,
- VisibilityTimeout=1800,
- RedrivePolicy=troposphere.sqs.RedrivePolicy(
- deadLetterTargetArn=DLQChoice,
- maxReceiveCount=10
- ),
- DeletionPolicy=troposphere.Retain,
- Condition="NeedsQueue"
- ))
- QueueChoice = troposphere.If("NeedsQueue",
- troposphere.GetAtt(ManifestQueue, "Arn"),
- troposphere.Ref(S3BundlerQueueARN))
- ManifestQueuePolicy = t.add_resource(troposphere.sqs.QueuePolicy(
- "ManifestQueuePolicy",
- Queues=[troposphere.Ref(ManifestQueue)],
- PolicyDocument={
- "Version": "2012-10-17",
- "Id": "manifestqueuepolicy",
- "Statement": [
- {
- "Sid": "q1",
- "Effect": "Allow",
- "Principal": {"Service": "s3.amazonaws.com"},
- "Action": "SQS:SendMessage",
- "Resource": troposphere.GetAtt(ManifestQueue,"Arn"),
- "Condition": troposphere.If("NeedsArchiveBucket",
- {"ForAllValues:ArnLike": {
- "aws:SourceArn": troposphere.Join("",
- ["arn:aws:s3:::",
- troposphere.Ref(troposphere.AWS_STACK_NAME),"-archivebucket-*"])
- }},
- {"ForAllValues:ArnEquals": {
- "aws:SourceArn": troposphere.Join("", ["arn:aws:s3:::", troposphere.Ref(S3ArchiveBucket)])
- }})
- }
- ]
- },
- DeletionPolicy=troposphere.Retain,
- Condition="NeedsQueue"
- ))
- DLQPolicy = t.add_resource(troposphere.sqs.QueuePolicy(
- "DLQPolicy",
- Queues=[troposphere.Ref(sqsdlq)],
- PolicyDocument={
- "Version": "2012-10-17",
- "Id": "dlqpolicy",
- "Statement": [
- {
- "Sid": "dlq1",
- "Effect": "Allow",
- "Principal": "*",
- "Action": "SQS:SendMessage",
- "Resource": troposphere.GetAtt(sqsdlq,"Arn"),
- "Condition": {
- "ArnEquals": {
- "aws:SourceArn": troposphere.GetAtt(ManifestQueue, "Arn")
- }
- }
- }
- ]
- },
- DeletionPolicy=troposphere.Retain,
- Condition="NeedsDLQ"
- ))
- ArchiveBucket = t.add_resource(troposphere.s3.Bucket(
- "ArchiveBucket",
- Condition="NeedsArchiveBucket",
- DependsOn="ManifestQueuePolicy",
- DeletionPolicy=troposphere.Retain,
- NotificationConfiguration=troposphere.s3.NotificationConfiguration(
- QueueConfigurations=[
- troposphere.s3.QueueConfigurations(
- Filter=troposphere.s3.Filter(
- S3Key=troposphere.s3.S3Key(
- Rules=[
- troposphere.s3.Rules(Name="prefix", Value=troposphere.Ref(S3ManifestPrefix)),
- troposphere.s3.Rules(Name="suffix", Value=".index")
- ]
- )
- ),
- Event="s3:ObjectCreated:Put",
- Queue=QueueChoice
- )
- ]
- ),
- AccessControl="BucketOwnerFullControl",
- ))
- ArchiveS3Choice = troposphere.If("NeedsArchiveBucket",
- troposphere.Ref(ArchiveBucket),
- troposphere.Ref(S3ArchiveBucket))
- TaskRole = t.add_resource(troposphere.iam.Role(
- "TaskRole",
- AssumeRolePolicyDocument={
- "Version": "2012-10-17",
- "Statement": [
- {
- "Principal": {
- "Service": "ecs-tasks.amazonaws.com"
- },
- "Action": "sts:AssumeRole",
- "Sid": "",
- "Effect": "Allow"
- }
- ]
- },
- Policies=[
- troposphere.iam.Policy(PolicyName="s3bundler", PolicyDocument={
- "Version": "2012-10-17",
- "Statement": [
- {
- "Sid": "readonly",
- "Effect": "Allow",
- "Action": [
- "s3:GetObject",
- "s3:GetObjectTagging",
- "s3:GetObjectVersion"
- ],
- "Resource": troposphere.Ref(S3SourceBuckets)
- },
- {
- "Sid": "inventory",
- "Effect": "Allow",
- "Action": [
- "s3:ListBucket",
- "s3:GetBucketTagging",
- "s3:GetBucketLocation",
- "s3:GetObject",
- "s3:GetObjectTagging",
- "s3:GetObjectVersion"
- ],
- "Resource": [
- troposphere.Join("", ["arn:aws:s3:::", troposphere.Join("/", [
- troposphere.Ref(S3InventoryBucket),
- troposphere.Ref(S3InventoryPrefix),
- "*"
- ])]),
- troposphere.Join("", ["arn:aws:s3:::", troposphere.Join("/", [
- troposphere.Ref(S3InventoryBucket),
- ])])
- ]
- },
- {
- "Sid": "archivebucket",
- "Effect": "Allow",
- "Action": [
- "s3:ListBucket",
- "s3:GetBucketLocation",
- "s3:GetObject",
- "s3:PutObject"
- ],
- "Resource": [
- troposphere.Join("", ["arn:aws:s3:::", troposphere.Join("/", [
- ArchiveS3Choice,
- troposphere.Ref(S3ArchivePrefix),
- "*"
- ])]),
- troposphere.Join("", ["arn:aws:s3:::", troposphere.Join("/", [
- ArchiveS3Choice,
- troposphere.Ref(S3ManifestPrefix),
- "*"
- ])]),
- troposphere.Join("", ["arn:aws:s3:::", troposphere.Join("/", [
- ArchiveS3Choice
- ])])
- ]
- },
- {
- "Sid": "s3bundlerqueueaccess",
- "Effect": "Allow",
- "Action": [
- "sqs:ChangeMessageVisibility",
- "sqs:DeleteMessage",
- "sqs:ReceiveMessage",
- "sqs:GetQueueUrl",
- "sqs:GetQueueAttributes"
- ],
- "Resource": [ QueueChoice, DLQChoice ]
- }
- ]
- }
- )]
- ))
- s3grouperlogs = t.add_resource(troposphere.logs.LogGroup(
- "s3grouperlogs",
- ))
- s3bundlerlogs = t.add_resource(troposphere.logs.LogGroup(
- "s3bundlerlogs",
- ))
- # LMF1MJK9 = t.add_resource(troposphere.logs.MetricFilter(
- # "LMF1MJK9",
- # LogGroupName=troposphere.Ref(s3grouperlogs),
- # ))
- #
- S3BundlerErrors = t.add_resource(troposphere.logs.MetricFilter(
- "S3BundlerErrors",
- LogGroupName=troposphere.Ref(s3bundlerlogs),
- FilterPattern="\"ERROR:\" -glaciered -deleted",
- MetricTransformations=[troposphere.logs.MetricTransformation(
- MetricNamespace="S3Bundler",
- MetricName="Errors",
- MetricValue="1"
- )]
- ))
- ECSCluster = t.add_resource(troposphere.ecs.Cluster(
- "ECSCluster",
- ))
- s3bundlertask = t.add_resource(troposphere.ecs.TaskDefinition(
- "s3bundlertask",
- TaskRoleArn=troposphere.Ref(TaskRole),
- NetworkMode="host",
- Family="s3bundler",
- Volumes=[troposphere.ecs.Volume(Name="data")],
- ContainerDefinitions=[troposphere.ecs.ContainerDefinition(
- Name="s3bundler",
- Cpu=170,
- MemoryReservation=128,
- Image=troposphere.Ref(S3BundlerURL),
- Environment=[
- troposphere.ecs.Environment(
- Name="AWS_DEFAULT_REGION",
- Value=troposphere.Ref(troposphere.AWS_REGION)),
- troposphere.ecs.Environment(
- Name="TMP",
- Value="/mnt" )
- ],
- Command=[troposphere.If("CompressTrue", "-c", ""),
- "-q",troposphere.Select("5", troposphere.Split(":", QueueChoice)),
- "-b",ArchiveS3Choice,
- "-p",troposphere.Ref(S3ArchivePrefix),
- "-s",troposphere.Ref(MaxSize)],
- DockerLabels= {"Project": "S3Bundler"},
- LogConfiguration=troposphere.ecs.LogConfiguration(
- LogDriver="awslogs",
- Options={
- "awslogs-group": troposphere.Ref(s3bundlerlogs),
- "awslogs-region": troposphere.Ref(troposphere.AWS_REGION)
- }),
- Essential=True,
- DisableNetworking=False,
- ReadonlyRootFilesystem=False,
- MountPoints=[troposphere.ecs.MountPoint(
- SourceVolume="data",
- ContainerPath="/mnt"
- )]
- )]
- ))
- s3groupertask = t.add_resource(troposphere.ecs.TaskDefinition(
- "s3groupertask",
- TaskRoleArn=troposphere.Ref(TaskRole),
- NetworkMode="host",
- Family="s3grouper",
- ContainerDefinitions=[troposphere.ecs.ContainerDefinition(
- Name="s3grouper",
- MemoryReservation=64,
- Image=troposphere.Ref(S3GrouperURL),
- Environment=[troposphere.ecs.Environment(Name="AWS_DEFAULT_REGION",
- Value=troposphere.Ref(troposphere.AWS_REGION))],
- DockerLabels= {"Project": "S3Bundler"},
- LogConfiguration=troposphere.ecs.LogConfiguration(
- LogDriver="awslogs",
- Options={
- "awslogs-group": troposphere.Ref(s3grouperlogs),
- "awslogs-region": troposphere.Ref(troposphere.AWS_REGION)
- }),
- Essential=True,
- DisableNetworking=False,
- ReadonlyRootFilesystem=False,
- )]
- ))
- s3bundlerservice = []
- for n in range(0,50):
- s3bundlerservice.append(t.add_resource(troposphere.ecs.Service(
- "s3bundlerservice{0}".format(str(n)),
- Cluster=troposphere.Ref(ECSCluster),
- TaskDefinition=troposphere.Ref(s3bundlertask),
- DesiredCount=0
- )))
- t.add_output(troposphere.Output(
- "ECSCluster",
- Value=troposphere.Ref(ECSCluster)
- ))
- t.add_output(troposphere.Output(
- "ArchiveBucket",
- Value=ArchiveS3Choice
- ))
- t.add_output(troposphere.Output(
- "ManifestQueue",
- Value=QueueChoice
- ))
- t.add_output(troposphere.Output(
- "S3GrouperTask",
- Value=troposphere.Ref(s3groupertask)
- ))
- print(t.to_json())
|