Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

'package' command should be able to create deterministic zip archives #195

Open
Dreamescaper opened this issue Dec 2, 2021 · 4 comments
Labels
feature-request A feature should be added or improved. module/cli-ext p2 This is a standard priority issue queued

Comments

@Dreamescaper
Copy link

We create zip archives for our lambdas using "dotnet lambda package" command, and then use "cdk deploy" to deploy them to our environments. Currently this has an issue - created zip archives contain timestamps, therefore those archives are different for each build, and therefore CDK deploys them each time even if nothing is changed.

As a workaround, currently we provide custom AssetHash (based on archive content), but I'd prefer to remove it.

Describe the Feature

'package' command should produce zip archives with striped timestamps and with consistent order.

Is your Feature Request related to a problem?

Slower CDK deployments.

Describe alternatives you've considered

Custom AssetHash.

Additional Context

This issue was actually solved in CDK itself: aws/aws-cdk#2931 . Probably same approach could be used.


This is a 🚀 Feature Request

@Dreamescaper Dreamescaper added feature-request A feature should be added or improved. needs-triage This issue or PR still needs to be triaged. labels Dec 2, 2021
@ashishdhingra
Copy link
Contributor

Appears to be a valid feature request. May be introduce a flag to alter this behavior. Needs discussion with the team.

@ashishdhingra ashishdhingra added needs-review and removed needs-triage This issue or PR still needs to be triaged. labels Jan 20, 2022
@ashishdhingra ashishdhingra added the p2 This is a standard priority issue label Dec 8, 2022
@lowkasen
Copy link

+1

@lowkasen
Copy link

What is the workaround for this issue?

I currently use:
source_code_hash = data.archive_file.zip_file.output_base64sha256

And this doesn't work and updates all the time when I build it

@DanielBickler
Copy link

DanielBickler commented Jan 22, 2025

This is a confusing issue when AWS's Lambda CDK C# documentation recommends using dotnet lambda package to build and deploy with CDK without warning that this is going to cause the Lambda to be updated every time CDK is deployed due to the package command's current behavior.

@lowkasen The workaround I found for anybody else who stumbles across this - I adapted from here which used the zip but it seemed better to me to use the file contents directly.

var lambdaCode = Code.FromAsset(pathToSourceCode,
    new Amazon.CDK.AWS.S3.Assets.AssetOptions {
        AssetHash = HashForZipContent(pathToSourceCode),
        AssetHashType = AssetHashType.CUSTOM,
        Bundling = new BundlingOptions {
            Image = Runtime.DOTNET_8.BundlingImage,
            User = "root",
            OutputType = BundlingOutput.ARCHIVED,
            Command = new[] {
                "/bin/sh",
                "-c",
                " dotnet tool install -g Amazon.Lambda.Tools" +
                " && dotnet build" +
                " && dotnet lambda package --output-package /asset-output/function.zip"
            }
        }
});

/* ... */

private static readonly string[] ValidExtensions = { ".cs", ".json", ".csproj" };
private static readonly string[] ExcludedDirs = { "bin", "obj" };

// Workaround for https://github.com/aws/aws-extensions-for-dotnet-cli/issues/195
private static string HashForZipContent(string directoryPath) {
        using var sha256 = SHA256.Create();
        using var fileHashes = new MemoryStream();
        
        var files = Directory.EnumerateFiles(directoryPath, "*.*", new EnumerationOptions 
            {
                // Could change this to parameter if some Lambdas grew in complexity to require extra directories
                RecurseSubdirectories = false,
                AttributesToSkip = FileAttributes.System
            })
            .Where(f => ValidExtensions.Contains(Path.GetExtension(f)) && 
                       !ExcludedDirs.Any(dir => 
                           f.Contains($"{Path.DirectorySeparatorChar}{dir}{Path.DirectorySeparatorChar}")))
            .OrderBy(f => f);
        
        foreach (var filePath in files)
        {
            using var fileStream = File.OpenRead(filePath);
            var fileHash = sha256.ComputeHash(fileStream);
            fileHashes.Write(fileHash, 0, fileHash.Length);
        }

        var finalHash = sha256.ComputeHash(fileHashes.ToArray());
        return Convert.ToBase64String(finalHash);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature-request A feature should be added or improved. module/cli-ext p2 This is a standard priority issue queued
Projects
None yet
Development

No branches or pull requests

4 participants