Blog

So stellen Sie ein Bereitstellungspaket in CloudFormation mit dem benutzerdefinierten Package Composer Provider zusammen

Dennis Vink

Aktualisiert Oktober 21, 2025
5 Minuten

Mit diesem Custom Provider können Sie ein solches Bereitstellungspaket oder die Objekte, die in einen S3-Bucket geschrieben werden sollen, vollständig in CloudFormation erstellen. Wenn Sie die Objekte in die Vorlage einbetten, wird die Bereitstellungsvorlage versioniert und
vollständig deterministisch.

Einführung

Das Erstellen einer Lambda-Funktion mit Abhängigkeiten oder das Veröffentlichen von Webinhalten in einem
s3 Website-Bucket beinhaltet in der Regel die Erstellung eines Deployment-Pakets als Zip-Datei
oder das Hochladen einer Reihe von HTML-Dateien und Assets in einen S3-Bucket. Normalerweise geschieht dies
außerhalb von CloudFormation, entweder manuell oder als Teil der CI/CD-Pipeline
.Mit diesem Custom Provider können Sie ein solches Bereitstellungspaket oder die
Objekte, die in einen S3-Bucket geschrieben werden sollen, vollständig innerhalb von CloudFormation erstellen. Wenn
Sie die Objekte in die Vorlage einbetten, ist die Bereitstellungsvorlage versioniert und
vollständig deterministisch.

Bereitstellen des benutzerdefinierten Package Composer-Providers

Um den Custom Provider bereitzustellen, fügen Sie das folgende Snippet zu Ihrer bestehenden
CloudFormation-Vorlage hinzu:

PackageComposerLambdaFunction:
  Properties:
    Code:
      S3Bucket: !Sub 'binxio-public-${AWS::Region}'
      S3Key: lambdas/package-composer.zip
    Handler: index.lambda_handler
    Role: !GetAtt 'PackageComposerRole.Arn'
    Runtime: ruby2.5
  Type: AWS::Lambda::Function

PackageComposerPolicy:
  Properties:
    PolicyDocument:
      Statement:
        - Action:
            - logs:CreateLogGroup
            - logs:CreateLogStream
            - logs:PutLogEvents
          Effect: Allow
          Resource:
            - arn:aws:logs:*:*:*
          Sid: Stmt1494445278000
        - Action:
            - s3:PutObject
          Effect: Allow
          Resource: '*'
          Sid: Stmt1494445651000
      Version: '2012-10-17'
    PolicyName: !Sub '${AWS::Region}${AWS::StackName}PackageComposerPolicy'
    Roles:
      - !Ref 'PackageComposerRole'
  Type: AWS::IAM::Policy

PackageComposerRole:
  Properties:
    AssumeRolePolicyDocument:
      Statement:
        - Action: sts:AssumeRole
          Effect: Allow
          Principal:
            Service:
              - lambda.amazonaws.com
      Version: '2012-10-17'
  Type: AWS::IAM::Role

Implementierung der benutzerdefinierten Ressource

Das folgende Snippet implementiert den oben genannten Custom Provider. Dies ist ein funktionierendes
Beispiel, aber Sie können es an Ihre Bedürfnisse anpassen:

MyComposedPackage:
  Properties:
    AWSRegion: !Sub '${AWS::Region}'
    Files:
      - img/icon.jpg:SomeBase64StringdEdf/9k=...
      - index.html:AnotherBase64StringlZkd/1e=...
      - README.md:https://raw.githubusercontent.com/binxio/cfn-secret-provider/master/README.md
      - lib/foo/bar.json:s3://eu-west-1/my-demo-bucket/path/to/object.json
      - LICENSE.txt:plain://This is free and unencumbered software released into the public domain.
    ServiceToken: !GetAtt 'PackageComposerLambdaFunction.Arn'
    UploadBucket: !Ref 'MyPackageS3Bucket'
  Type: Custom::PackageComposer

MyPackageS3Bucket:
  Type: AWS::S3::Bucket

Benutzerdefinierte Ressourceneigenschaften

Das obige Snippet erstellt einen S3-Bucket und implementiert die Custom Resource. Der
Package Composer Provider unterstützt die folgenden Eigenschaften:* AWSRegion + Gültige AWS-Region, z.B.: eu-west-1* Dateien + Array von Strings* UploadBucket + Bucket, in den das Bereitstellungspaket hochgeladen wird* Zip + true oder false (standardmäßig true). Wenn false, wird der Custom Provider

upload the provided Files to the S3 bucket without zipping them.

When true, you can reference the created zip file location with

!GetAtt 'MyComposedPackage.Message'.

Das Array Dateien enthält Zeichenketten in einem bestimmten Format. Jede Zeichenkette ist
wie folgt aufgebaut: <path/to/object>:<payload> Es hängt von der Art der Nutzdaten ab, wie der Package Composer die
Nutzdaten wiedergibt. Er unterstützt Folgendes: * http- oder https-URLs, z. B. http://www.example.com/ + Wenn die Nutzdaten eine URL sind, holt der Custom Provider den Inhalt

of the URL, following any redirects, and place the contents in the

object
  • s3-Objekt, z.B. s3:////path/to/object

    • Der benutzerdefinierte Anbieter ist in der Lage, Inhalte aus einem S3-Bucket abzurufen, sofern

    dass Sie Zugriff auf diesen Bucket haben * Klartext, z.B. plain://my text here + Sie können auf diese Weise Klartext als Payload eines Objekts angeben * Base64-String, z.B. RVhBTVBMRQo= + Wenn keine der oben genannten Composer-Methoden gewählt wird, wird der String angenommen

    mit Base64 kodiert werden. Verwenden des Custom Providers zur Bereitstellung einer Website


Nachfolgend finden Sie eine vollständige Vorlage, die den Custom Provider einsetzt und
eine Custom Resource implementiert, die die folgenden Aufgaben erfüllt: + Hochladen einer index.html in einen S3-Bucket + Abrufen einer README.md von Github und Hochladen in den S3-Bucket + Erstellen einer 404.html-Seite zur Behandlung von 404-Fehlern Die Vorlage erstellt einen S3-Bucket, der als Website konfiguriert ist, und erstellt eine
Bucket Policy, die den öffentlichen Lesezugriff auf Objekte in diesem Bucket ermöglicht. Zu guter Letzt gibt sie die Website-URL aus, die Sie nach
der Bereitstellung der Vorlage einfach öffnen können. Sie können auch Bilder einbinden, entweder inline als
Base64 kodierter String oder von einer anderen Ressource geholt.

AWSTemplateFormatVersion: '2010-09-09'
Resources:
 MyComposedPackage:
   Properties:
     AWSRegion: !Sub '${AWS::Region}'
     Files:
       - README.md:https://raw.githubusercontent.com/binxio/aws-cfn-update/master/README.md
       - "index.html:PGh0bWw+CiAgPGJvZHk+CiAgICA8aDE+UGFja2FnZSBDb21wb3NlciBEZW1vn
         PC9oMT4KICAgIDxhIGhyZWY9IlJFQURNRS5tZCI+Q2xpY2sgaGVyZSBmb3IgndGhlIFJFQURNRS5tZDwvYT4KICA8L2JvZHk+CjwvaHRtbD4Kn"
       - 404.html:plain://<html><body><center><h1>404 - Not Found.</h1></center></body></html>
     ServiceToken: !GetAtt 'PackageComposerLambdaFunction.Arn'
     UploadBucket: !Ref 'MyPackageS3Bucket'
     Zip: false
   Type: Custom::PackageComposer

 MyPackageS3Bucket:
   Properties:
     AccessControl: PublicRead
     WebsiteConfiguration:
       ErrorDocument: 404.html
       IndexDocument: index.html
   Type: AWS::S3::Bucket

 MyPackageS3BucketBucketPolicy:
   Properties:
     Bucket: !Ref 'MyPackageS3Bucket'
     PolicyDocument:
       Id: !Sub '${AWS::StackName}MyPackageS3BucketBucketPolicy'
       Statement:
         - Action: s3:GetObject
           Effect: Allow
           Principal: '*'
           Resource: !Join
             - ''
             - - 'arn:aws:s3:::'
               - !Ref 'MyPackageS3Bucket'
               - /*
           Sid: PublicReadForGetBucketObjects
       Version: '2012-10-17'
   Type: AWS::S3::BucketPolicy

 PackageComposerLambdaFunction:
   Properties:
     Code:
       S3Bucket: !Sub 'binxio-public-${AWS::Region}'
       S3Key: lambdas/package-composer.zip
     Handler: index.lambda_handler
     Role: !GetAtt 'PackageComposerRole.Arn'
     Runtime: ruby2.5
   Type: AWS::Lambda::Function

 PackageComposerPolicy:
   Properties:
     PolicyDocument:
       Statement:
         - Action:
             - logs:CreateLogGroup
             - logs:CreateLogStream
             - logs:PutLogEvents
           Effect: Allow
           Resource:
             - arn:aws:logs:*:*:*
           Sid: Stmt1494445278000
         - Action:
             - s3:PutObject
           Effect: Allow
           Resource: '*'
           Sid: Stmt1494445651000
       Version: '2012-10-17'
     PolicyName: !Sub '${AWS::Region}${AWS::StackName}PackageComposerPolicy'
     Roles:
       - !Ref 'PackageComposerRole'
   Type: AWS::IAM::Policy

 PackageComposerRole:
   Properties:
     AssumeRolePolicyDocument:
       Statement:
         - Action: sts:AssumeRole
           Effect: Allow
           Principal:
             Service:
               - lambda.amazonaws.com
       Version: '2012-10-17'
   Type: AWS::IAM::Role

Outputs:
 ComposedPackageUrl:
   Value: !GetAtt 'MyPackageS3Bucket.WebsiteURL'
 PackageComposerFunctionArn:
   Value: !GetAtt 'PackageComposerLambdaFunction.Arn'

Beschränkungen

Die maximale Größe einer CloudFormation-Vorlage, die als S3-Objekt übergeben wird, beträgt
460.800 Bytes und als Vorlagenkörper lediglich 51.200 Bytes. Das bedeutet
, dass Sie darauf achten müssen, die Größenbeschränkung von CloudFormation nicht zu überschreiten. Es ist durchaus möglich, ein Inline-Bereitstellungspaket mit einer
begrenzten Anzahl von Abhängigkeiten zu erstellen. Wenn Sie die Grenzen von CloudFormation
überschreiten, können Sie Objekte von S3 oder Webressourcen abrufen, um das Limit zu überwinden.

Verfasst von

Dennis Vink

Crafting digital leaders through innovative AI & cloud solutions. Empowering businesses with cutting-edge strategies for growth and transformation.

Contact

Let’s discuss how we can support your journey.