From 69625baf8cd7367386d76ce1eda7e84130084023 Mon Sep 17 00:00:00 2001 From: abikouo Date: Tue, 15 Nov 2022 16:05:11 +0100 Subject: [PATCH 1/4] Terminator policies for CloudFront modules --- aws/policy/paas.yaml | 24 ++++++++++++++++ aws/terminator/application_services.py | 38 ++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/aws/policy/paas.yaml b/aws/policy/paas.yaml index 641f58ad..c2380380 100644 --- a/aws/policy/paas.yaml +++ b/aws/policy/paas.yaml @@ -24,6 +24,14 @@ Statement: - Sid: AllowResourceRestrictedActionsWhichIncurNoFees Effect: Allow Action: + - cloudfront:CreateDistribution + - cloudfront:CreateDistributionWithTags + - cloudfront:DeleteDistribution + - cloudfront:UpdateDistribution + - cloudfront:TagResource + - cloudfront:UntagResource + - cloudfront:ListTagsForResource + - cloudfront:DeleteStreamingDistribution - ecr:DeleteLifecyclePolicy - ecr:DeleteRepository - ecr:DeleteRepositoryPolicy @@ -86,6 +94,7 @@ Statement: - lightsail:StopInstance - lightsail:ReleaseStaticIp Resource: + - 'arn:aws:cloudfront::{{ aws_account_id }}:distribution/*' - 'arn:aws:ecr:{{ aws_region }}:{{ aws_account_id }}:repository/*' - 'arn:aws:eks:{{ aws_region }}:{{ aws_account_id }}:cluster/*' - 'arn:aws:eks:{{ aws_region }}:{{ aws_account_id }}:fargateprofile/*/*/*' @@ -115,6 +124,21 @@ Statement: - lambda:ListFunctions - lambda:ListLayers - lambda:ListVersionsByFunction + - cloudfront:GetDistribution + - cloudfront:GetDistributionConfig + - cloudfront:GetStreamingDistribution + - cloudfront:GetStreamingDistributionConfig + - cloudfront:ListCloudFrontOriginAccessIdentities + - cloudfront:ListDistributions + - cloudfront:ListDistributionsByWebACLId + - cloudfront:ListStreamingDistributions + - cloudfront:CreateCloudFrontOriginAccessIdentity + - cloudfront:DeleteCloudFrontOriginAccessIdentity + - cloudfront:GetCloudFrontOriginAccessIdentity + - cloudfront:GetCloudFrontOriginAccessIdentityConfig + - cloudfront:UpdateCloudFrontOriginAccessIdentity + - cloudfront:GetInvalidation + - cloudfront:CreateInvalidation Resource: - "*" diff --git a/aws/terminator/application_services.py b/aws/terminator/application_services.py index 09e76249..1b5e8fbd 100644 --- a/aws/terminator/application_services.py +++ b/aws/terminator/application_services.py @@ -367,3 +367,41 @@ def name(self): def terminate(self): self.client.delete_document(Name=self.name) + + +class CloudFrontDistribution(Terminator): + @staticmethod + def create(credentials): + def paginate_distributions(client): + return client.get_paginator('list_distributions').paginate().build_full_result()['DistributionList']['Items'] + return Terminator._create(credentials, CloudFrontDistribution, 'cloudfront', paginate_distributions) + + @property + def created_time(self): + return self.instance['LastModifiedTime'] + + @property + def name(self): + return self.instance['DomainName'] + + def terminate(self): + self.client.delete_distribution(Id=self.instance['Id']) + + +class CloudFrontStreamingDistribution(Terminator): + @staticmethod + def create(credentials): + def paginate_streaming_distributions(client): + return client.get_paginator('list_streaming_distributions').paginate().build_full_result()['StreamingDistributionList']['Items'] + return Terminator._create(credentials, CloudFrontStreamingDistribution, 'cloudfront', paginate_streaming_distributions) + + @property + def created_time(self): + return self.instance['LastModifiedTime'] + + @property + def name(self): + return self.instance['DomainName'] + + def terminate(self): + self.client.delete_streaming_distribution(Id=self.instance['Id']) From ec5e9046dad82ca4e97ce59ef5d606e0c019a908 Mon Sep 17 00:00:00 2001 From: abikouo Date: Fri, 18 Nov 2022 12:12:42 +0100 Subject: [PATCH 2/4] code review updates --- aws/policy/paas.yaml | 41 ++++++------- aws/terminator/application_services.py | 38 ------------ aws/terminator/paas.py | 83 ++++++++++++++++++++++++++ 3 files changed, 100 insertions(+), 62 deletions(-) diff --git a/aws/policy/paas.yaml b/aws/policy/paas.yaml index c2380380..edfe57a3 100644 --- a/aws/policy/paas.yaml +++ b/aws/policy/paas.yaml @@ -14,7 +14,12 @@ Statement: - ecr:InitiateLayerUpload - ecr:PutImage - ecr:UploadLayerPart + - cloudfront:CreateDistribution + - cloudfront:CreateStreamingDistribution + - cloudfront:CreateStreamingDistributionWithTags Resource: + - 'arn:aws:cloudfront::{{ aws_account_id }}:distribution/*' + - 'arn:aws:cloudfront::{{ aws_account_id }}:streaming-distribution/*' - 'arn:aws:eks:{{ aws_region }}:{{ aws_account_id }}:cluster/*' - 'arn:aws:eks:{{ aws_region }}:{{ aws_account_id }}:nodegroup/*/*/*' - 'arn:aws:lambda:{{ aws_region }}:{{ aws_account_id }}:function:*' @@ -24,13 +29,10 @@ Statement: - Sid: AllowResourceRestrictedActionsWhichIncurNoFees Effect: Allow Action: - - cloudfront:CreateDistribution - - cloudfront:CreateDistributionWithTags - cloudfront:DeleteDistribution - cloudfront:UpdateDistribution - cloudfront:TagResource - cloudfront:UntagResource - - cloudfront:ListTagsForResource - cloudfront:DeleteStreamingDistribution - ecr:DeleteLifecyclePolicy - ecr:DeleteRepository @@ -95,6 +97,7 @@ Statement: - lightsail:ReleaseStaticIp Resource: - 'arn:aws:cloudfront::{{ aws_account_id }}:distribution/*' + - 'arn:aws:cloudfront::{{ aws_account_id }}:streaming-distribution/*' - 'arn:aws:ecr:{{ aws_region }}:{{ aws_account_id }}:repository/*' - 'arn:aws:eks:{{ aws_region }}:{{ aws_account_id }}:cluster/*' - 'arn:aws:eks:{{ aws_region }}:{{ aws_account_id }}:fargateprofile/*/*/*' @@ -104,12 +107,15 @@ Statement: - 'arn:aws:lightsail:{{ aws_region }}:{{ aws_account_id }}:*' - 'arn:aws:lambda:{{ aws_region }}:{{ aws_account_id }}:layer:*' - # - Sid: AllowUnrestrictedResourceActionsWhichIncurFees - # Effect: Allow - # Action: - # - - # Resource: - # - "*" + - Sid: AllowUnrestrictedResourceActionsWhichIncurFees + Effect: Allow + Action: + - cloudfront:CreateCloudFrontOriginAccessIdentity + - cloudfront:DeleteCloudFrontOriginAccessIdentity + - cloudfront:UpdateCloudFrontOriginAccessIdentity + - cloudfront:CreateInvalidation + Resource: + - "*" - Sid: AllowUnrestrictedResourceActionsWhichIncurNoFees Effect: Allow @@ -124,21 +130,8 @@ Statement: - lambda:ListFunctions - lambda:ListLayers - lambda:ListVersionsByFunction - - cloudfront:GetDistribution - - cloudfront:GetDistributionConfig - - cloudfront:GetStreamingDistribution - - cloudfront:GetStreamingDistributionConfig - - cloudfront:ListCloudFrontOriginAccessIdentities - - cloudfront:ListDistributions - - cloudfront:ListDistributionsByWebACLId - - cloudfront:ListStreamingDistributions - - cloudfront:CreateCloudFrontOriginAccessIdentity - - cloudfront:DeleteCloudFrontOriginAccessIdentity - - cloudfront:GetCloudFrontOriginAccessIdentity - - cloudfront:GetCloudFrontOriginAccessIdentityConfig - - cloudfront:UpdateCloudFrontOriginAccessIdentity - - cloudfront:GetInvalidation - - cloudfront:CreateInvalidation + - cloudfront:Get* + - cloudfront:List* Resource: - "*" diff --git a/aws/terminator/application_services.py b/aws/terminator/application_services.py index 1b5e8fbd..09e76249 100644 --- a/aws/terminator/application_services.py +++ b/aws/terminator/application_services.py @@ -367,41 +367,3 @@ def name(self): def terminate(self): self.client.delete_document(Name=self.name) - - -class CloudFrontDistribution(Terminator): - @staticmethod - def create(credentials): - def paginate_distributions(client): - return client.get_paginator('list_distributions').paginate().build_full_result()['DistributionList']['Items'] - return Terminator._create(credentials, CloudFrontDistribution, 'cloudfront', paginate_distributions) - - @property - def created_time(self): - return self.instance['LastModifiedTime'] - - @property - def name(self): - return self.instance['DomainName'] - - def terminate(self): - self.client.delete_distribution(Id=self.instance['Id']) - - -class CloudFrontStreamingDistribution(Terminator): - @staticmethod - def create(credentials): - def paginate_streaming_distributions(client): - return client.get_paginator('list_streaming_distributions').paginate().build_full_result()['StreamingDistributionList']['Items'] - return Terminator._create(credentials, CloudFrontStreamingDistribution, 'cloudfront', paginate_streaming_distributions) - - @property - def created_time(self): - return self.instance['LastModifiedTime'] - - @property - def name(self): - return self.instance['DomainName'] - - def terminate(self): - self.client.delete_streaming_distribution(Id=self.instance['Id']) diff --git a/aws/terminator/paas.py b/aws/terminator/paas.py index 7d5ef3dd..e422602c 100644 --- a/aws/terminator/paas.py +++ b/aws/terminator/paas.py @@ -44,3 +44,86 @@ def created_time(self): def terminate(self): for version in self.client.list_layer_versions(LayerName=self.name)['LayerVersions']: self.client.delete_layer_version(LayerName=self.name, VersionNumber=version['Version']) + + +def wait_until_deployed(client, Id, waiter_name, wait_timeout=1800): + waiter = client.get_waiter(waiter_name) + attempts = 1 + int(wait_timeout / 60) + waiter.wait(Id=Id, WaiterConfig={'MaxAttempts': attempts}) + + +class CloudFrontDistribution(Terminator): + @staticmethod + def create(credentials): + def list_cloudfront_distributions(client): + result = client.get_paginator('list_distributions').paginate().build_full_result() + return result.get('DistributionList', {}).get('Items', []) + + return Terminator._create(credentials, CloudFrontDistribution, 'cloudfront', list_cloudfront_distributions) + + @property + def created_time(self): + return self.instance['LastModifiedTime'] + + @property + def name(self): + return self.instance['DomainName'] + + @property + def Id(self): + return self.instance['Id'] + + def terminate(self): + + distribution = self.client.get_distribution(Id=self.Id) + ETag = distribution['ETag'] + distribution = distribution['Distribution'] + if distribution.get('Status') == "Deployed": + if distribution['DistributionConfig']['Enabled']: + distribution['DistributionConfig']['Enabled'] = False + self.client.update_distribution(DistributionConfig=distribution['DistributionConfig'], Id=self.Id, IfMatch=ETag) + # wait until the distribution is deployed + wait_until_deployed(self.client, self.Id, 'distribution_deployed') + # Get ETag value after update + distribution = self.client.get_distribution(Id=self.Id) + ETag = distribution['ETag'] + self.client.delete_distribution(Id=self.Id, IfMatch=ETag) + + +class CloudFrontStreamingDistribution(Terminator): + @staticmethod + def create(credentials): + def list_cloudfront_streaming_distributions(client): + result = client.get_paginator('list_streaming_distributions').paginate().build_full_result() + return result.get('StreamingDistributionList', {}).get('Items', []) + + return Terminator._create(credentials, CloudFrontStreamingDistribution, 'cloudfront', list_cloudfront_streaming_distributions) + + @property + def created_time(self): + return self.instance['LastModifiedTime'] + + @property + def name(self): + return self.instance['DomainName'] + + @property + def Id(self): + return self.instance['Id'] + + def terminate(self): + streaming_distribution = self.client.get_streaming_distribution(Id=self.Id) + ETag = streaming_distribution['ETag'] + streaming_distribution = streaming_distribution['StreamingDistribution'] + if streaming_distribution.get('Status') == "Deployed": + if streaming_distribution['StreamingDistributionConfig']['Enabled']: + streaming_distribution['StreamingDistributionConfig']['Enabled'] = False + self.client.update_streaming_distribution(StreamingDistributionConfig=streaming_distribution['StreamingDistributionConfig'], + Id=self.Id, + IfMatch=ETag) + # wait until the streaming distribution is deployed + wait_until_deployed(self.client, self.Id, 'streaming_distribution_deployed') + # Get ETag value after update + streaming_distribution = self.client.get_streaming_distribution(Id=self.Id) + ETag = streaming_distribution['ETag'] + self.client.delete_streaming_distribution(Id=self.Id, IfMatch=ETag) From 3ae9d941f8bb7906bb0307c60845aaf632fbeb41 Mon Sep 17 00:00:00 2001 From: abikouo Date: Tue, 29 Nov 2022 16:49:30 +0100 Subject: [PATCH 3/4] remove waiter when deleting cloudfront distribution --- aws/policy/paas.yaml | 16 +++++++--------- aws/terminator/paas.py | 26 ++++++++------------------ 2 files changed, 15 insertions(+), 27 deletions(-) diff --git a/aws/policy/paas.yaml b/aws/policy/paas.yaml index edfe57a3..29710576 100644 --- a/aws/policy/paas.yaml +++ b/aws/policy/paas.yaml @@ -14,12 +14,7 @@ Statement: - ecr:InitiateLayerUpload - ecr:PutImage - ecr:UploadLayerPart - - cloudfront:CreateDistribution - - cloudfront:CreateStreamingDistribution - - cloudfront:CreateStreamingDistributionWithTags Resource: - - 'arn:aws:cloudfront::{{ aws_account_id }}:distribution/*' - - 'arn:aws:cloudfront::{{ aws_account_id }}:streaming-distribution/*' - 'arn:aws:eks:{{ aws_region }}:{{ aws_account_id }}:cluster/*' - 'arn:aws:eks:{{ aws_region }}:{{ aws_account_id }}:nodegroup/*/*/*' - 'arn:aws:lambda:{{ aws_region }}:{{ aws_account_id }}:function:*' @@ -29,11 +24,8 @@ Statement: - Sid: AllowResourceRestrictedActionsWhichIncurNoFees Effect: Allow Action: - - cloudfront:DeleteDistribution - - cloudfront:UpdateDistribution - cloudfront:TagResource - cloudfront:UntagResource - - cloudfront:DeleteStreamingDistribution - ecr:DeleteLifecyclePolicy - ecr:DeleteRepository - ecr:DeleteRepositoryPolicy @@ -111,9 +103,15 @@ Statement: Effect: Allow Action: - cloudfront:CreateCloudFrontOriginAccessIdentity + - cloudfront:CreateDistribution + - cloudfront:CreateInvalidation + - cloudfront:CreateStreamingDistribution + - cloudfront:CreateStreamingDistributionWithTags - cloudfront:DeleteCloudFrontOriginAccessIdentity + - cloudfront:DeleteDistribution + - cloudfront:DeleteStreamingDistribution - cloudfront:UpdateCloudFrontOriginAccessIdentity - - cloudfront:CreateInvalidation + - cloudfront:UpdateDistribution Resource: - "*" diff --git a/aws/terminator/paas.py b/aws/terminator/paas.py index e422602c..5df85809 100644 --- a/aws/terminator/paas.py +++ b/aws/terminator/paas.py @@ -46,12 +46,6 @@ def terminate(self): self.client.delete_layer_version(LayerName=self.name, VersionNumber=version['Version']) -def wait_until_deployed(client, Id, waiter_name, wait_timeout=1800): - waiter = client.get_waiter(waiter_name) - attempts = 1 + int(wait_timeout / 60) - waiter.wait(Id=Id, WaiterConfig={'MaxAttempts': attempts}) - - class CloudFrontDistribution(Terminator): @staticmethod def create(credentials): @@ -80,14 +74,12 @@ def terminate(self): distribution = distribution['Distribution'] if distribution.get('Status') == "Deployed": if distribution['DistributionConfig']['Enabled']: + # disable distribution distribution['DistributionConfig']['Enabled'] = False self.client.update_distribution(DistributionConfig=distribution['DistributionConfig'], Id=self.Id, IfMatch=ETag) - # wait until the distribution is deployed - wait_until_deployed(self.client, self.Id, 'distribution_deployed') - # Get ETag value after update - distribution = self.client.get_distribution(Id=self.Id) - ETag = distribution['ETag'] - self.client.delete_distribution(Id=self.Id, IfMatch=ETag) + else: + # delete distribution + self.client.delete_distribution(Id=self.Id, IfMatch=ETag) class CloudFrontStreamingDistribution(Terminator): @@ -117,13 +109,11 @@ def terminate(self): streaming_distribution = streaming_distribution['StreamingDistribution'] if streaming_distribution.get('Status') == "Deployed": if streaming_distribution['StreamingDistributionConfig']['Enabled']: + # disable streaming distribution streaming_distribution['StreamingDistributionConfig']['Enabled'] = False self.client.update_streaming_distribution(StreamingDistributionConfig=streaming_distribution['StreamingDistributionConfig'], Id=self.Id, IfMatch=ETag) - # wait until the streaming distribution is deployed - wait_until_deployed(self.client, self.Id, 'streaming_distribution_deployed') - # Get ETag value after update - streaming_distribution = self.client.get_streaming_distribution(Id=self.Id) - ETag = streaming_distribution['ETag'] - self.client.delete_streaming_distribution(Id=self.Id, IfMatch=ETag) + else: + # delete streaming distribution + self.client.delete_streaming_distribution(Id=self.Id, IfMatch=ETag) From d7b552f958ee9766bbadba4ebbef0ff8bc1cca88 Mon Sep 17 00:00:00 2001 From: Mike Graves Date: Thu, 1 Dec 2022 09:57:33 -0500 Subject: [PATCH 4/4] Reorganize permissions --- aws/policy/paas.yaml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/aws/policy/paas.yaml b/aws/policy/paas.yaml index 29710576..2a476931 100644 --- a/aws/policy/paas.yaml +++ b/aws/policy/paas.yaml @@ -24,8 +24,14 @@ Statement: - Sid: AllowResourceRestrictedActionsWhichIncurNoFees Effect: Allow Action: + - cloudfront:CreateInvalidation + - cloudfront:DeleteCloudFrontOriginAccessIdentity + - cloudfront:DeleteDistribution + - cloudfront:DeleteStreamingDistribution - cloudfront:TagResource - cloudfront:UntagResource + - cloudfront:UpdateCloudFrontOriginAccessIdentity + - cloudfront:UpdateDistribution - ecr:DeleteLifecyclePolicy - ecr:DeleteRepository - ecr:DeleteRepositoryPolicy @@ -89,6 +95,7 @@ Statement: - lightsail:ReleaseStaticIp Resource: - 'arn:aws:cloudfront::{{ aws_account_id }}:distribution/*' + - 'arn:aws:cloudfront::{{ aws_account_id }}:origin-access-identity/*' - 'arn:aws:cloudfront::{{ aws_account_id }}:streaming-distribution/*' - 'arn:aws:ecr:{{ aws_region }}:{{ aws_account_id }}:repository/*' - 'arn:aws:eks:{{ aws_region }}:{{ aws_account_id }}:cluster/*' @@ -102,22 +109,16 @@ Statement: - Sid: AllowUnrestrictedResourceActionsWhichIncurFees Effect: Allow Action: - - cloudfront:CreateCloudFrontOriginAccessIdentity - cloudfront:CreateDistribution - - cloudfront:CreateInvalidation - cloudfront:CreateStreamingDistribution - cloudfront:CreateStreamingDistributionWithTags - - cloudfront:DeleteCloudFrontOriginAccessIdentity - - cloudfront:DeleteDistribution - - cloudfront:DeleteStreamingDistribution - - cloudfront:UpdateCloudFrontOriginAccessIdentity - - cloudfront:UpdateDistribution Resource: - "*" - Sid: AllowUnrestrictedResourceActionsWhichIncurNoFees Effect: Allow Action: + - cloudfront:CreateCloudFrontOriginAccessIdentity - ecr:GetAuthorizationToken - ecr:CreateRepository - ecr:DescribeRepositories