Anyone have a AWS lambda development->deploymen...
# aws
Anyone have a AWS lambda development->deployment experience they're happy with? I historically use AWS SAM w/ VS Code for local development. This allows me to easily build and test lambda functions locally Then it seems (AI answer) I should upload a CloudFormation template to S3 and point Pulumi at it, but I'd rather have all my infra build files checked into the codebase as opposed to a mix of local files and S3.
I mostly deploy software as containerized lambdas. I build the container image in github actions, then use pulumi to deploy the image as a lambda.
I'm using ECR to store the lambdas
Thanks Kenji!! I think the downside there is without using AWS SAM, you also have to manually specify roles, API gateways etc.If you have an example template you use I'd be most grateful!
Roles yes. I'm not using api gateways for my lambdas since they're mainly getting triggered by schedules or events. here's a sample
Copy code
 * Create a container lambda function.
 * In addition to creating the lambda function, this function also
 * - creates a role for the function with a set of base permissions
 *  as well as any specified in `extraPolicyStatements`
 * - creates an invoke config that defines the retry policy for the function.
 * - associates the function with the event rule for triggering
 * @param name name of function
 * @param args arguments for creating the function
 * @returns function
export function createContainerLambda(
  name: string,
    description = '',
    extraPolicyStatements = [],
    ephemeralStorageMb = 512,
    memorySizeMb = 128,
    timeoutSeconds = 300,
    maximumRetryAttempts = 0,
    maximumEventAgeInSeconds = (maximumRetryAttempts + 1) *
      (60 + timeoutSeconds),
    environment = {},
    tags = {},
  }: ContainerLambdaArgs
) {
  const lambdaRole = createLambdaRole(name, extraPolicyStatements, tags)

  const lambdaFunction = new aws.lambda.Function(`${name}-function`, {
    description: description || `lambda function for ${name}`,
    role: lambdaRole.arn,
    packageType: 'Image',
    architectures: ['x86_64'],
    ephemeralStorage: {
      size: ephemeralStorageMb,
    memorySize: memorySizeMb,
    environment: {
      variables: environment,
    timeout: timeoutSeconds,
    vpcConfig: vpcConfig,
    publish: true,
    tags: tags,

  const destinationConfig: inputs.lambda.FunctionEventInvokeConfigDestinationConfig =

  if (onSuccessDestination) {
    destinationConfig['onSuccess'] = {
      destination: onSuccessDestination,
  if (onFailureDestination) {
    destinationConfig['onFailure'] = {
      destination: onFailureDestination,

  new aws.lambda.FunctionEventInvokeConfig(`${name}-invoke`, {
    maximumRetryAttempts: maximumRetryAttempts,
    maximumEventAgeInSeconds: maximumEventAgeInSeconds,

  if (eventRule) {
    eventRule.onEvent(`${name}-event`, lambdaFunction)

  return lambdaFunction

 * Creates a role for a lambda function with a set of base permissions as well
 * as any specified in `extraPolicyStatements`.
 * @param name  name of the lambda function
 * @param extraPolicyStatements extra policy statements to add to the role
 * @param tags tags to associate with resources that accept them
 * @returns role
export function createLambdaRole(
  name: string,
  extraPolicyStatements: inputs.iam.GetPolicyDocumentStatement[],
  tags: aws.Tags
) {
  const lambdaRole = new aws.iam.Role(`${name}-role`, {
    assumeRolePolicy: {
      Version: '2012-10-17',
      Statement: [
          Action: 'sts:AssumeRole',
          Principal: {
            Service: ['', ''],
          Effect: 'Allow',
          Sid: '',

   * Base policy statements for lambda
  const basePolicyStatements: inputs.iam.GetPolicyDocumentStatement[] = [
      actions: [
        // cloudwatch logs
        // read/write s3
        // needed for vpc access
        // cloudwatch metrics
        // get secrets
        // needed for ecr
        // needed to publish to sns
        // needed to send messages to sqs
      resources: ['*'],
      effect: 'Allow',
  const policyDoc = aws.iam.getPolicyDocumentOutput({
    statements: basePolicyStatements.concat(extraPolicyStatements),

  const policy = new aws.iam.Policy(`${name}-policy`, {
    path: '/',
    description: 'Allow lambda to write logs and read/write objects in s3',
    policy: policyDoc.json,

  new aws.iam.RolePolicyAttachment(`${name}-policy-attachment`, {
    role: lambdaRole,
    policyArn: policy.arn,
  return lambdaRole