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

Lambda@Edge Always Updating Without Changes #3776

Closed
armaneous opened this issue Apr 4, 2024 · 5 comments
Closed

Lambda@Edge Always Updating Without Changes #3776

armaneous opened this issue Apr 4, 2024 · 5 comments
Assignees
Labels
awaiting-feedback Blocked on input from the author bug/diff kind/bug related to Pulumi generating wrong diffs on preview or up. kind/bug Some behavior is incorrect or out of spec needs-repro Needs repro steps before it can be triaged or fixed resolution/no-repro This issue wasn't able to be reproduced service/lambda Lambda issues
Milestone

Comments

@armaneous
Copy link

armaneous commented Apr 4, 2024

What happened?

Without any changes made to the code that's deployed or the configuration, the Lambda function seems to keep registering a change requiring update which cascades to the Cloudfront Distribution requiring an update as well every time.

Example

Output of pulumi up --diff:

  pulumi:pulumi:Stack: (same)
    [urn=urn:pulumi:prd::infra::pulumi:pulumi:Stack::infra-prd]
    ~ aws:lambda/function:Function: (update)
        [id=<lambda-id>]
        [urn=urn:pulumi:prd::infra::aws:lambda/function:Function::<lambda-id>]
        [provider=urn:pulumi:prd::infra::pulumi:providers:<region>::<uuid>]
        code                        : archive(file:2087429) { /path/to/code.zip }
        environment                 : {
            variables : {}
        }
        handler                     : "router.handler"
        layers                      : []
        memorySize                  : 128
        name                        : "<lambda-name>"
        packageType                 : "Zip"
        publish                     : true
        reservedConcurrentExecutions: -1
        role                        : "arn:aws:iam::<account-id>:role/<role-name>"
        runtime                     : "nodejs20.x"
        skipDestroy                 : false
        tags                        : {
            environment: "..."
            project    : "..."
            service    : "..."
        }
        tagsAll                     : {
            environment: "..."
            project    : "..."
            service    : "..."
        }
        timeout                     : 3
        vpcConfig                   : {
            ipv6AllowedForDualStack: false
            securityGroupIds       : []
            subnetIds              : []
        }
    ~ aws:cloudfront/distribution:Distribution: (update)
        [id=<cf-id>]
        [urn=urn:pulumi:prd::infra::aws:cloudfront/distribution:Distribution::<cf-name>]
        [provider=urn:pulumi:prd::infra::pulumi:providers:aws::default_6_25_1::<uuid>]
      ~ defaultCacheBehavior: {
          ~ lambdaFunctionAssociations: [
              ~ [0]: {
                      ~ eventType  : "origin-request" => "origin-request"
                      + includeBody: false
                      ~ lambdaArn  : "<lambda-arn>:<lambda-version>" => output<string>
                    }
            ]
        }

Unsure if this is the problem, but the ARN is assembled using the output of the lambda resource like so:

example_lambda = lambda_.Function(...)
arn = Output.all(arn=example_lambda.arn, version=example_lambda.version).apply(lambda args: f'{args["arn"]}:{args["version"]}')

Output of pulumi about

pulumi about
CLI          
Version      3.109.0
Go Version   go1.22.1
Go Compiler  gc

Plugins
NAME           VERSION
aws            6.25.1
python         unknown
random         4.16.0
synced-folder  0.11.1

Host
OS       ubuntu
Version  22.04
Arch     x86_64

This project is written in python: executable='/home/<current-user>/.pyenv/shims/python3' version='3.11.4'

Current Stack: armaneous/infra/prd

TYPE                                                    URN
pulumi:pulumi:Stack                                     urn:pulumi:prd::infra::pulumi:pulumi:Stack::infra-prd
...
...
...


Found no pending operations associated with prd

Backend
Name           pulumi.com
URL            https://app.pulumi.com/<org>
User           <org>
Organizations  <org>
Token type     personal

Dependencies:
NAME                  VERSION
boto3                 1.34.0
gnureadline           8.1.2
pip                   24.0
pulumi_aws            6.25.1
pulumi_random         4.16.0
pulumi_synced_folder  0.11.1
setuptools            65.5.0
uuid                  1.30

Pulumi locates its logs in /tmp by default

Additional context

Not a blocker, but just a nuisance when deploying. Seems to be doing unnecessary updates.

Contributing

Vote on this issue by adding a 👍 reaction.
To contribute a fix for this issue, leave a comment (and link to your pull request, if you've opened one already).

@armaneous armaneous added kind/bug Some behavior is incorrect or out of spec needs-triage Needs attention from the triage team labels Apr 4, 2024
@t0yv0 t0yv0 added bug/diff kind/bug related to Pulumi generating wrong diffs on preview or up. service/lambda Lambda issues and removed needs-triage Needs attention from the triage team labels Apr 5, 2024
@t0yv0
Copy link
Member

t0yv0 commented Apr 5, 2024

Thanks for reporting this @armaneous , I'm sorry this does not work as expected. Our team will be taking a look subject to time availability.

@mikhailshilkov
Copy link
Member

@t0yv0 Is this another issue of diff calculation in the bridge? Should we link it to the epic then?

@t0yv0 t0yv0 added the needs-repro Needs repro steps before it can be triaged or fixed label Apr 19, 2024
@t0yv0
Copy link
Member

t0yv0 commented Apr 19, 2024

CC @mjeffryes I'm not sure which epic - I've been labelling these as bug/diff for the moment. On the surface it looks very much like one of those issues.

@armaneous if you have a chance to add a source program that reproduces this this could help us out a lot to make it easier to resolve. Thank you!

@arwilczek90
Copy link

arwilczek90 commented Apr 26, 2024

I can confirm that we are seeing this as well with a function that ignores a specific tag. In our use case this is a tag that is updated at deploy time by our CI system to a version for our observability tools to read.

import * as pulumi from '@pulumi/pulumi';
import * as aws from '@pulumi/aws';

const tags = {tag1: 'value1', tag2:'value2'};

function stubNodeArchive(handler: string): pulumi.asset.AssetArchive {
  const parts = handler.split('.');
  if (parts.length !== 2) {
    throw new Error(`handler must be like "module.function"`);
  }

  const fileName = parts[0] + '.js';
  const functionName = parts[1];

  const contents: pulumi.asset.AssetMap = {};
  contents[fileName] = new pulumi.asset.StringAsset(`
          exports.${functionName} = async function(event, context) {
              console.log("EVENT: \n" + JSON.stringify(event, null, 2))
              return context.logStreamName
          };
      `);

  return new pulumi.asset.AssetArchive(contents);
}

const lambdaRole = new aws.iam.Role(
      `lambda-role`,
      {
        assumeRolePolicy: pulumi.jsonStringify({
          Version: '2012-10-17',
          Statement: [
            {
              Action: 'sts:AssumeRole',
              Effect: 'Allow',
              Principal: {
                Service: 'lambda.amazonaws.com',
              },
            },
          ],
        }),
        tags: {...tags},
      }
);
 
const _lambdaPolicyRoleAttachement = new aws.iam.RolePolicyAttachment(
      `basic-lpra`,
      {
        policyArn: 'arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole', // The default lambda policy for cloudwatch,etc.
        role: lambdaRole.name,
      }
 );


const lambda = new aws.lambda.Function(
      `repro-lambda`,
      {
        name: `repro-lambda`,
        code: stubNodeArchive(handler), // This is ignored after first provision because CI updates this using the aws cli, but basically just uploads a zip with a hello world for initial provisioning. You ca
        handler: 'index.handler',
        role: lambdaRole.arn,
        runtime: 'nodejs18.x',
        memorySize: 256,
        layers: [],
        timeout: 10,
        tags: {...tags}, // This is just any object of tags, just change one outside of pulumi and refresh.
      },
      { ignoreChanges: ['code', 'tags.version', 'tags_all.version', 'tagsAll.version']}
);

This accurately ignores all the tags and code updates however it also says the lambda has a 0 change update every time its run because state still sees the version tag.

@corymhall
Copy link
Contributor

@armaneous do you have an example app that we can use to reproduce? I've tried to reproduce this using the below app and I was unable to. There have been some changes since you reported this issue so it is possible that it has been fixed, do you know if you still see this on the latest version?

  const role = new aws.iam.Role('role', {
    assumeRolePolicy: pulumi.jsonStringify({
      Version: '2012-10-17',
      Statement: [
        {
          Action: 'sts:AssumeRole',
          Effect: 'Allow',
          Principal: aws.iam.Principals.EdgeLambdaPrincipal,
        },
        {
          Action: 'sts:AssumeRole',
          Effect: 'Allow',
          Principal: aws.iam.Principals.LambdaPrincipal,
        },
      ],
    }),
    managedPolicyArns: [aws.iam.ManagedPolicy.AWSLambdaBasicExecutionRole],
  });

  const asset = archive.getFile({
    type: 'zip',
    sourceContentFilename: 'index.js',
    sourceContent: `
    export default function handler() {
      return 'Hello World!';
    }
    `,
    outputPath: 'lambda_function_payload.zip',
  });

  const code = new pulumi.asset.FileArchive(asset.then((a) => a.outputPath));
  const func = new aws.lambda.Function(
    'handler',
    {
      publish: true,
      role: role.arn,
      code,
      handler: 'index.handler',
      runtime: 'nodejs20.x',
    },
    {
      customTimeouts: {
        delete: '30m',
      },
    },
  );
  const bucket = new aws.s3.BucketV2('web-bucket', {});
  const id = new aws.cloudfront.OriginAccessIdentity('identity', {
    comment: 'id',
  });
  new aws.cloudfront.Distribution('distro', {
    enabled: false,
    viewerCertificate: {
      cloudfrontDefaultCertificate: true,
    },
    restrictions: {
      geoRestriction: {
        restrictionType: 'none',
      },
    },
    defaultCacheBehavior: {
      defaultTtl: 0,
      maxTtl: 0,
      cachedMethods: ['HEAD', 'GET'],
      allowedMethods: ['HEAD', 'GET'],
      targetOriginId: 'chall-origin',
      viewerProtocolPolicy: 'https-only',
      lambdaFunctionAssociations: [
        {
          eventType: 'viewer-request',
          lambdaArn: pulumi
            .all([func.arn, func.version])
            .apply(([arn, version]) => `${arn}:${version}`),
        },
      ],
      forwardedValues: {
        queryString: false,
        cookies: {
          forward: 'none',
        },
      },
    },
    origins: [
      {
        customHeaders: [
          {
            name: 'key',
            value: 'value',
          },
        ],
        originId: 'chall-origin',
        domainName: bucket.bucketDomainName,
        connectionTimeout: 9,
        connectionAttempts: 2,
        s3OriginConfig: {
          originAccessIdentity: id.cloudfrontAccessIdentityPath,
        },
      },
    ],
  });

@corymhall corymhall added the awaiting-feedback Blocked on input from the author label Jun 11, 2024
@mjeffryes mjeffryes added the resolution/no-repro This issue wasn't able to be reproduced label Jul 1, 2024
@mjeffryes mjeffryes added this to the 0.107 milestone Jul 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
awaiting-feedback Blocked on input from the author bug/diff kind/bug related to Pulumi generating wrong diffs on preview or up. kind/bug Some behavior is incorrect or out of spec needs-repro Needs repro steps before it can be triaged or fixed resolution/no-repro This issue wasn't able to be reproduced service/lambda Lambda issues
Projects
None yet
Development

No branches or pull requests

6 participants