Do czego nam hooki w CloudFormation?
Dzieki nim możemy w pełni zaautomatyzować sprawdzanie konfiguracji zasobów AWS, jeszcze na etapie ich tworzenia, aktualizacji lub usuwania.
Przykładami takich hooków są:
AWSSamples::S3BucketEncrypt::Hook – hook, który sprawdza czy na tworzonym buckecie ustawiona jest encrypcja
AWSSamples::S3BlockPublicAccess::Hook – hook, który sprawdza czy na tworzonym buckecie ustawiona jest publiczny dostęp
Aktywacja hooków
Aby aktywować hooki, należy przejść do CloudFormation -> Public Extensions. W extension type należy zaznaczyć „Hooks”, natomiast w Publisher, wybrać „Third Party”.
Wyszukujemy na liście hook o nazwie „AWSSamples::S3BucketEncrypt::Hook„, następnie klikamy w przycisk Activate. Do aktywacji tego hooka, potrzebujemy utworzyć specjalną rolę, template do Cloud Formation możemy pobrać stąd https://github.com/aws-cloudformation/aws-cloudformation-samples/blob/main/hooks/python-hooks/s3-bucket-encryption/hook-role.yaml
Jako wynik w Outputs otrzymamy ARN do roli, kopiujemy go i wklejamy go do pola „
{
"CloudFormationConfiguration": {
"HookConfiguration": {
"TargetStacks": "ALL",
"FailureMode": "FAIL",
"Properties": {
"encryptionAlgorithm": "aws:kms"
}
}
}
}
TargetStacks, mamy do wyboru:
- ALL – co oznacza, że hook będzie działał dla każdego tworzonego stacku
- NONE – co oznacza, że hook będzie wyłączony
FailureMode, mamy do wyboru:
- FAIL- co oznacza, że hook przerwie generowanie bucketu i zgłosi błąd
- WARN- co oznacza, że hook wygeneruje nam tylko ostrzeżenie i będzie dalej kontynuował tworzenie bucketu
Natomiast w encryptionAlgorithm, mamy do wyboru:
- AES256
- aws:kms
Dzięki takiej konfiguracji, hook podczas tworzenia bucketu S3, będzie sprawdzał, czy ma on włączoną enkrypcję oraz czy jest to aws:kms. Zostało nam kliknąć „Configure extension” i to wszystko 🙂 Ostatnim krokiem jest sprawdzenie, czy wszystko działa tak jak powinno, więc w pierwszym kroku sprawdzimy czy wszystko dobrze zrobiliśmy i Cloud Formation nie utworzy nam bucketu S3, w tym celu wykorzystajmy poniższy szablon
Resources:
S3Bucket:
Type: "AWS::S3::Bucket"
DeletionPolicy: Delete
Properties:
BucketName: wpisznazwebucketujakibyschcial
Jak widać, efekt zgodnie z oczekiwaniem, bucket nie został utworzony.
Połowa sukcesu za nami, ponieważ Cloud Formation nie przepuścił bucketu S3 bez enkrypcji, teraz wykorzystajmy poniższy szablon, który tworzy S3 z enkrypcją ustawioną na aws:kms oraz klucz kms wymagany do tego.
AWSTemplateFormatVersion: "2010-09-09"
Description: This CloudFormation template provisions an encrypted S3 Bucket
Resources:
EncryptedS3Bucket:
Type: "AWS::S3::Bucket"
Properties:
BucketName: !Sub "encryptedbucket-${AWS::Region}-${AWS::AccountId}"
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: "aws:kms"
KMSMasterKeyID: !Ref EncryptionKey
BucketKeyEnabled: true
EncryptionKey:
Type: AWS::KMS::Key
Properties:
Description: KMS key used to encrypt the resource type artifacts
EnableKeyRotation: true
KeyPolicy:
Version: "2012-10-17"
Statement:
- Sid: Enable full access for owning account
Effect: Allow
Principal:
AWS: !Ref "AWS::AccountId"
Action: kms:*
Resource: "*"
Outputs:
EncryptedBucketName:
Value: !Ref EncryptedS3Bucket
Wynik wykonania szablonu, zgodnie z oczekiwaniami, bucket s3 został pomyślnie utworzony.
Jak widać, w krótkim czasie, możemy ograniczyć tworzenie bucketów s3 tylko do takich, które mają włączoną enkrypcję.
Oczywiście oprócz hooków, które znajdziemy na liście, możemy tworzyć własne, w tym celu polecam warsztat AWS https://catalog.us-east-1.prod.workshops.aws/workshops/f09fd78b-ef8a-4a9d-9d2b-f31a3e6ca956/en-US oraz oficjalną dokumentację AWS https://docs.aws.amazon.com/cloudformation-cli/latest/userguide/hooks.html