Skip to content
malak.cloud
  • Contact
  • Przemek Malak
  • Search Icon

malak.cloud

Cloud-native in everyday life

Jak skasować pliki w S3 przy usuwaniu stacka Cloudformation

Jak skasować pliki w S3 przy usuwaniu stacka Cloudformation

18 stycznia 2022

Często, a właściwie prawie zawsze, jeżeli tworzymy buckety S3 za pomocą CloudFormation, to przy usuwaniu stacka mamy problem. AWS nie usunie bucketa, jeżeli są w nim jakieś pliki. A przewaznie są, bo po coś go w końcu tworzyliśmy. Dziś pokażę, jak skasować pliki w S3 przy usuwaniu stacka Cloudformation.

Jeżeli ktoś nie napotkał jeszcze tego problemu, to szybko go zobrazujemy. Utworzymy bucket za pomocą poniższego template:

AWSTemplateFormatVersion: 2010-09-0920
Description: ---
Resources: 
  Bucket:
    Type: 'AWS::S3::Bucket'
    Properties: 
      LifecycleConfiguration:
        Rules:
          - Id: expiration
            Status: Enabled
            ExpirationInDays: 3

I jeżeli po utworzeniu stacka

Jak skasować pliki w S3 przy usuwaniu stacka Cloudformation - stack

spróbujemy go usunąć, spotka nas rozczarowanie.

Jak skasować pliki w S3 przy usuwaniu stacka Cloudformation - bucket

Przy ponownej próbie usunięcia stacka CloudFormation poinformuje nas, że ma problem z usunięciem bucketa i możemy skasować stack, ale tylko jeżeli zostawimy nasz bucket.

Jak skasować pliki w S3 przy usuwaniu stacka Cloudformation - delete bucket

Ale jest na to sposób. I to wbrew pozorom dość prosty. A to co pokażę w tym artykule i udostępnię na GitHub-ie  możecie użyć w dowolnym template, który będzie tworzył buckety S3.

Jak skasować pliki w S3 przy usuwaniu stacka Cloudformation

Pomoże nam Custom Resource w postaci funkcji Lambda, która w momencie usuwania stacka Cloud Formation, przed usunięciem bucketa, skasuje z niego wszystkie pliki. To co musimy dodatkowo utworzyć w naszym template to:

  • rola z uprawnianiami dla funkcji – Type: AWS::IAM::Role – CleanupBucketOnDeleteLambdaRole
  • funkcja Lambda – Type: AWS::Lambda::Function – CleanupBucketOnDeleteLambda
  • custom resource – Type: Custom::CleanupBucket – CleanupBucketOnDelete

No to po kolei.

Rola dla funkcji Lambda

Nasza funkcja musi mieć możliwość skasowania plików z S3. Ale pliki mogą mieć wersje, plików może być wiele i będą potrzebne paginatory do ich obsługi. Czyli potrzebne są uprawnienia do S3. Dodatkowo dobrze jest mieć logi z działania funkcji, dodamy więc też uprawnienia do logowania.

Policies:
- PolicyName: !Join [ -, [!Ref 'AWS::StackName', 'CleanupBucketOnDeleteLambdaPolicy'] ]
  PolicyDocument:
    Version: '2012-10-17'
    Statement:
    - Effect: Allow
      Action:
      - logs:*
      - s3:*
      Resource: '*'
    - Effect: Deny
      Action:
      - s3:DeleteBucket
      Resource: '*'

Uprawnienia w roli są oczywiście „trochę” za duże i na produkcji proponuję je ograniczyć do tych naprawdę niezbędnych. Wystarczy przejrzeć kod i wyłuskać metody, których funkcja używa. Chciałem jednak ten artykuł uprościć. Dodałem tylko zakaz usuwania samych bucketów,

- Effect: Deny 
  Action: 
  - s3:DeleteBucket 
  Resource: '*'

gdyż jeżeli przez przypadek skasujemy sam bucket w funkcji, to usuwanie stacka także się nie powiedzie.

Funkcja Lambda

Założeniem było to, żeby zmieścić się z kodem w ramach samego template Cloudformation i nie używać dodatkowych plików i bibliotek w samej funkcji. Powinno to uprościć wdrożenia. Użyłem także funkcji send z modułu cfn-response , która zwraca odpowiedni obiekt.

Handler funkcji jest bardzo prosty

def lambda_handler(event, context):
    try:
        bucket = event['ResourceProperties']['BucketName']
        if event['RequestType'] == 'Delete':
            empty_bucket(bucket)
            send(event, context, SUCCESS, {})
        else:
            send(event, context, SUCCESS, {})
    except Exception as e:
        logger.error(str(e))
        send(event, context, FAILED, {})

Wydobywamy z eventu nazwę bucketa i sprawdzamy z jakim zdarzeniem mamy do czynienia. Jeżeli jest to Delete to uruchamiamy usuwanie plików, a jeżeli coś innego to po prostu zwracamy powodzenie. W przypadku błędu zwracamy wartość FAILURE.

Pozostałej częsci funkcji nie będę opisywał. Kasuje ona wszystkie obiekty z bucketa. Kod samej funkcji także jest dostępny w repozytorium.

Custom Resource

CleanupBucketOnDelete:
  DependsOn: Bucket
  Type: Custom::CleanupBucket
  Properties:
    ServiceToken: 
     Fn::GetAtt: 
        - "CleanupBucketOnDeleteLambda"
        - "Arn"
    BucketName: !Ref Bucket

Jako zmienna BucketName do funkcji zostanie przekazana nazwa naszego bucketa.

I to właściwie wszystko. Teraz usuwanie stacka, włącznie z bucketem S3,  powinno powieść się bez najmniejszego problemu.


AWS, CloudNative, DEV
AWS, CloudNative, Dev, serverless

Post navigation

PREVIOUS
AWS i wysyłanie poczty przez SMTP
NEXT
AWS news – styczeń 2022
Comments are closed.
Hi. My name is Przemek Malak. Thanks for visiting. I hope you found what I write about interesting.
If you'd like to chat with me, the easiest way is through LinkedIn.

Losowe wpisy

  • API Gateway – Autoryzacja

    6 października 2017
  • Jak przesłać plik do S3 za pomocą API Gateway

    16 listopada 2022
  • Jak za pomocą funkcji Lambda włączyć i wyłączyć serwer EC2 w AWS

    25 października 2017
  • Serverless – drugi poziom wtajemniczenia

    18 czerwca 2019
  • AWS Step Functions

    13 lutego 2018
  • Apps
  • AWS
  • CloudNative
  • Cookbook
  • Data
  • DEV
  • EN
  • GCP
  • IoT
  • Istio
  • k8s
  • Security
  • Social
  • GitHub
  • LinkedIn
© 2025   All Rights Reserved.
Ta strona korzysta z ciasteczek aby świadczyć usługi na najwyższym poziomie. Dalsze korzystanie ze strony oznacza, że zgadzasz się na ich użycie.Zgoda