Class LocalStackCdkAssetPublisher

java.lang.Object
com.cloudforgeci.localstack.LocalStackCdkAssetPublisher

public final class LocalStackCdkAssetPublisher extends Object
Publishes CDK synth assets from cdk.out/*.assets.json to S3 so Custom::AWS Lambdas and other asset-backed resources can deploy — used by both LocalStackDeployer (this module) and AwsDirectDeployer (cloudforge-api, which already depends on this module for orchestrating the local-emulator deploy pipelines it dispatches to; despite the class's LocalStack-flavored name, its logic is a plain S3 upload against whatever S3Client it's given and was never actually LocalStack-specific).

Resolves CDK's ${AWS::AccountId}/${AWS::Partition} pseudo-parameter tokens in bucketName/objectKey before using them as literal S3 API values — an account-agnostic CDK synthesis (no concrete AWS account known at synth time, e.g. CloudForgeSynthesizer's deploy:create path) leaves these as unresolved literal token strings in the asset manifest, which the S3 SDK then rejects outright ("Bucket name should not contain '$'") since a real S3 API call has no CloudFormation pseudo-parameter evaluator to fall back on — CloudFormation resolves them fine inside the template body itself, but never for values an S3 client uses directly. ${AWS::Region} is deliberately not substituted the same way: every manifest destination this class has ever seen already carries its own concrete region field, so there's nothing to resolve there in practice.

  • Method Details

    • publish

      public static void publish(Path cdkOutDirectory, String contextStackName, software.amazon.awssdk.services.s3.S3Client s3, String accountId, boolean createBucketIfMissing) throws IOException
      Parameters:
      accountId - substituted for any ${AWS::AccountId} token in a destination's bucketName/objectKey — the real account id for a real-AWS caller (e.g. via sts:GetCallerIdentity), or LocalStack's well-known fixed test account (000000000000) for a local-emulator caller.
      createBucketIfMissing - whether to self-create an asset destination bucket that doesn't exist yet, rather than require it already exist. true for a local emulator (LocalStack/MiniStack have no separate cdk bootstrap concept — this class creating the bucket on first use IS the bootstrap, for that target). false for real AWS: the destination bucket named here is CDK's own bootstrap staging bucket (cdk-hnb659fds-assets-<account>-<region>), which cdk bootstrap is supposed to create and own as a tracked CloudFormation resource (versioning, encryption, lifecycle rules, an SSL-only bucket policy). Self-creating a bare, untracked bucket with that exact name papers over an unbootstrapped account instead of surfacing it, and then permanently blocks the real cdk bootstrap from ever creating its own properly-configured copy of that bucket (CloudFormation's early-validation resource- existence check refuses to "adopt" a bucket the stack doesn't already own) — a connected account's first cross-account deploy attempt would otherwise silently pre-create this bucket before the account had ever been bootstrapped.
      Throws:
      IOException - if the destination bucket doesn't exist and createBucketIfMissing is false — the actionable signal that the target account needs cdk bootstrap run against it before this deploy can proceed