UNPKG

@pulumi/aws

Version:

A Pulumi package for creating and managing Amazon Web Services (AWS) cloud resources.

554 lines • 23.5 kB
"use strict"; // *** WARNING: this file was generated by pulumi-language-nodejs. *** // *** Do not edit by hand unless you're certain you know what you are doing! *** Object.defineProperty(exports, "__esModule", { value: true }); exports.Function = void 0; const pulumi = require("@pulumi/pulumi"); const utilities = require("../utilities"); /** * Manages an AWS Lambda Function. Use this resource to create serverless functions that run code in response to events without provisioning or managing servers. * * For information about Lambda and how to use it, see [What is AWS Lambda?](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html). For a detailed example of setting up Lambda and API Gateway, see Serverless Applications with AWS Lambda and API Gateway. * * > **Note:** Due to [AWS Lambda improved VPC networking changes that began deploying in September 2019](https://aws.amazon.com/blogs/compute/announcing-improved-vpc-networking-for-aws-lambda-functions/), EC2 subnets and security groups associated with Lambda Functions can take up to 45 minutes to successfully delete. Pulumi AWS Provider version 2.31.0 and later automatically handles this increased timeout, however prior versions require setting the customizable deletion timeouts of those Pulumi resources to 45 minutes (`delete = "45m"`). AWS and HashiCorp are working together to reduce the amount of time required for resource deletion and updates can be tracked in this GitHub issue. * * > **Note:** If you get a `KMSAccessDeniedException: Lambda was unable to decrypt the environment variables because KMS access was denied` error when invoking an `aws.lambda.Function` with environment variables, the IAM role associated with the function may have been deleted and recreated after the function was created. You can fix the problem two ways: 1) updating the function's role to another role and then updating it back again to the recreated role. (When you create a function, Lambda grants permissions on the KMS key to the function's IAM role. If the IAM role is recreated, the grant is no longer valid. Changing the function's role or recreating the function causes Lambda to update the grant.) * * > **Tip:** To give an external source (like an EventBridge Rule, SNS, or S3) permission to access the Lambda function, use the `aws.lambda.Permission` resource. See [Lambda Permission Model](https://docs.aws.amazon.com/lambda/latest/dg/intro-permission-model.html) for more details. On the other hand, the `role` argument of this resource is the function's execution role for identity and access to AWS services and resources. * * ## Example Usage * * ### Container Image Function * * ```typescript * import * as pulumi from "@pulumi/pulumi"; * import * as aws from "@pulumi/aws"; * * const example = new aws.lambda.Function("example", { * name: "example_container_function", * role: exampleAwsIamRole.arn, * packageType: "Image", * imageUri: `${exampleAwsEcrRepository.repositoryUrl}:latest`, * imageConfig: { * entryPoints: ["/lambda-entrypoint.sh"], * commands: ["app.handler"], * }, * memorySize: 512, * timeout: 30, * architectures: ["arm64"], * }); * ``` * * ### Function with Lambda Layers * * > **Note:** The `aws.lambda.LayerVersion` attribute values for `arn` and `layerArn` were swapped in version 2.0.0 of the Pulumi AWS Provider. For version 2.x, use `arn` references. * * ```typescript * import * as pulumi from "@pulumi/pulumi"; * import * as aws from "@pulumi/aws"; * * // Common dependencies layer * const example = new aws.lambda.LayerVersion("example", { * code: new pulumi.asset.FileArchive("layer.zip"), * layerName: "example_dependencies_layer", * description: "Common dependencies for Lambda functions", * compatibleRuntimes: [ * "nodejs20.x", * "python3.12", * ], * compatibleArchitectures: [ * "x86_64", * "arm64", * ], * }); * // Function using the layer * const exampleFunction = new aws.lambda.Function("example", { * code: new pulumi.asset.FileArchive("function.zip"), * name: "example_layered_function", * role: exampleAwsIamRole.arn, * handler: "index.handler", * runtime: aws.lambda.Runtime.NodeJS20dX, * layers: [example.arn], * tracingConfig: { * mode: "Active", * }, * }); * ``` * * ### VPC Function with Enhanced Networking * * ```typescript * import * as pulumi from "@pulumi/pulumi"; * import * as aws from "@pulumi/aws"; * * const example = new aws.lambda.Function("example", { * code: new pulumi.asset.FileArchive("function.zip"), * name: "example_vpc_function", * role: exampleAwsIamRole.arn, * handler: "app.handler", * runtime: aws.lambda.Runtime.Python3d12, * memorySize: 1024, * timeout: 30, * vpcConfig: { * subnetIds: [ * examplePrivate1.id, * examplePrivate2.id, * ], * securityGroupIds: [exampleLambda.id], * ipv6AllowedForDualStack: true, * }, * ephemeralStorage: { * size: 5120, * }, * snapStart: { * applyOn: "PublishedVersions", * }, * }); * ``` * * ### Function with EFS Integration * * ```typescript * import * as pulumi from "@pulumi/pulumi"; * import * as aws from "@pulumi/aws"; * * // EFS file system for Lambda * const example = new aws.efs.FileSystem("example", { * encrypted: true, * tags: { * Name: "lambda-efs", * }, * }); * const config = new pulumi.Config(); * // List of subnet IDs for EFS mount targets * const subnetIds = config.getObject<Array<string>>("subnetIds") || [ * "subnet-12345678", * "subnet-87654321", * ]; * // Mount target in each subnet * const exampleMountTarget: aws.efs.MountTarget[] = []; * for (const range = {value: 0}; range.value < subnetIds.length; range.value++) { * exampleMountTarget.push(new aws.efs.MountTarget(`example-${range.value}`, { * fileSystemId: example.id, * subnetId: subnetIds[range.value], * securityGroups: [efs.id], * })); * } * // Access point for Lambda * const exampleAccessPoint = new aws.efs.AccessPoint("example", { * fileSystemId: example.id, * rootDirectory: { * path: "/lambda", * creationInfo: { * ownerGid: 1000, * ownerUid: 1000, * permissions: "755", * }, * }, * posixUser: { * gid: 1000, * uid: 1000, * }, * }); * // Lambda function with EFS * const exampleFunction = new aws.lambda.Function("example", { * code: new pulumi.asset.FileArchive("function.zip"), * name: "example_efs_function", * role: exampleAwsIamRole.arn, * handler: "index.handler", * runtime: aws.lambda.Runtime.NodeJS20dX, * vpcConfig: { * subnetIds: subnetIds, * securityGroupIds: [lambda.id], * }, * fileSystemConfig: { * arn: exampleAccessPoint.arn, * localMountPath: "/mnt/data", * }, * }, { * dependsOn: [exampleMountTarget], * }); * ``` * * ### Function with Advanced Logging * * ```typescript * import * as pulumi from "@pulumi/pulumi"; * import * as aws from "@pulumi/aws"; * * const example = new aws.cloudwatch.LogGroup("example", { * name: "/aws/lambda/example_function", * retentionInDays: 14, * tags: { * Environment: "production", * Application: "example", * }, * }); * const exampleFunction = new aws.lambda.Function("example", { * code: new pulumi.asset.FileArchive("function.zip"), * name: "example_function", * role: exampleAwsIamRole.arn, * handler: "index.handler", * runtime: aws.lambda.Runtime.NodeJS20dX, * loggingConfig: { * logFormat: "JSON", * applicationLogLevel: "INFO", * systemLogLevel: "WARN", * }, * }, { * dependsOn: [example], * }); * ``` * * ### Function with logging to S3 or Data Firehose * * #### Required Resources * * * An S3 bucket or Data Firehose delivery stream to store the logs. * * A CloudWatch Log Group with: * * * `logGroupClass = "DELIVERY"` * * A subscription filter whose `destinationArn` points to the S3 bucket or the Data Firehose delivery stream. * * * IAM roles: * * * Assumed by the `logs.amazonaws.com` service to deliver logs to the S3 bucket or Data Firehose delivery stream. * * Assumed by the `lambda.amazonaws.com` service to send logs to CloudWatch Logs * * * A Lambda function: * * * In the `loggingConfiguration`, specify the name of the Log Group created above using the `logGroup` field * * No special configuration is required to use S3 or Firehose as the log destination * * For more details, see [Sending Lambda function logs to Amazon S3](https://docs.aws.amazon.com/lambda/latest/dg/logging-with-s3.html). * * ### Example: Exporting Lambda Logs to S3 Bucket * * ```typescript * import * as pulumi from "@pulumi/pulumi"; * import * as aws from "@pulumi/aws"; * * const lambdaFunctionName = "lambda-log-export-example"; * const lambdaLogExportBucket = new aws.s3.Bucket("lambda_log_export", {bucket: `${lambdaFunctionName}-bucket`}); * const _export = new aws.cloudwatch.LogGroup("export", { * name: `/aws/lambda/${lambdaFunctionName}`, * logGroupClass: "DELIVERY", * }); * const logsAssumeRole = aws.iam.getPolicyDocument({ * statements: [{ * actions: ["sts:AssumeRole"], * effect: "Allow", * principals: [{ * type: "Service", * identifiers: ["logs.amazonaws.com"], * }], * }], * }); * const logsLogExport = new aws.iam.Role("logs_log_export", { * name: `${lambdaFunctionName}-lambda-log-export-role`, * assumeRolePolicy: logsAssumeRole.then(logsAssumeRole => logsAssumeRole.json), * }); * const lambdaLogExport = aws.iam.getPolicyDocumentOutput({ * statements: [{ * actions: ["s3:PutObject"], * effect: "Allow", * resources: [pulumi.interpolate`${lambdaLogExportBucket.arn}/*`], * }], * }); * const lambdaLogExportRolePolicy = new aws.iam.RolePolicy("lambda_log_export", { * policy: lambdaLogExport.apply(lambdaLogExport => lambdaLogExport.json), * role: logsLogExport.name, * }); * const lambdaLogExportLogSubscriptionFilter = new aws.cloudwatch.LogSubscriptionFilter("lambda_log_export", { * name: `${lambdaFunctionName}-filter`, * logGroup: _export.name, * filterPattern: "", * destinationArn: lambdaLogExportBucket.arn, * roleArn: logsLogExport.arn, * }); * const logExport = new aws.lambda.Function("log_export", { * name: lambdaFunctionName, * handler: "index.lambda_handler", * runtime: aws.lambda.Runtime.Python3d13, * role: example.arn, * code: new pulumi.asset.FileArchive("function.zip"), * loggingConfig: { * logFormat: "Text", * logGroup: _export.name, * }, * }, { * dependsOn: [_export], * }); * ``` * * ### Function with Error Handling * * ```typescript * import * as pulumi from "@pulumi/pulumi"; * import * as aws from "@pulumi/aws"; * * // Main Lambda function * const example = new aws.lambda.Function("example", { * code: new pulumi.asset.FileArchive("function.zip"), * name: "example_function", * role: exampleAwsIamRole.arn, * handler: "index.handler", * runtime: aws.lambda.Runtime.NodeJS20dX, * deadLetterConfig: { * targetArn: dlq.arn, * }, * }); * // Event invoke configuration for retries * const exampleFunctionEventInvokeConfig = new aws.lambda.FunctionEventInvokeConfig("example", { * functionName: example.name, * maximumEventAgeInSeconds: 60, * maximumRetryAttempts: 2, * destinationConfig: { * onFailure: { * destination: dlq.arn, * }, * onSuccess: { * destination: success.arn, * }, * }, * }); * ``` * * ### CloudWatch Logging and Permissions * * ```typescript * import * as pulumi from "@pulumi/pulumi"; * import * as aws from "@pulumi/aws"; * * const config = new pulumi.Config(); * // Name of the Lambda function * const functionName = config.get("functionName") || "example_function"; * // CloudWatch Log Group with retention * const example = new aws.cloudwatch.LogGroup("example", { * name: `/aws/lambda/${functionName}`, * retentionInDays: 14, * tags: { * Environment: "production", * Function: functionName, * }, * }); * // Lambda execution role * const exampleRole = new aws.iam.Role("example", { * name: "lambda_execution_role", * assumeRolePolicy: JSON.stringify({ * Version: "2012-10-17", * Statement: [{ * Action: "sts:AssumeRole", * Effect: "Allow", * Principal: { * Service: "lambda.amazonaws.com", * }, * }], * }), * }); * // CloudWatch Logs policy * const lambdaLogging = new aws.iam.Policy("lambda_logging", { * name: "lambda_logging", * path: "/", * description: "IAM policy for logging from Lambda", * policy: JSON.stringify({ * Version: "2012-10-17", * Statement: [{ * Effect: "Allow", * Action: [ * "logs:CreateLogGroup", * "logs:CreateLogStream", * "logs:PutLogEvents", * ], * Resource: ["arn:aws:logs:*:*:*"], * }], * }), * }); * // Attach logging policy to Lambda role * const lambdaLogs = new aws.iam.RolePolicyAttachment("lambda_logs", { * role: exampleRole.name, * policyArn: lambdaLogging.arn, * }); * // Lambda function with logging * const exampleFunction = new aws.lambda.Function("example", { * code: new pulumi.asset.FileArchive("function.zip"), * name: functionName, * role: exampleRole.arn, * handler: "index.handler", * runtime: aws.lambda.Runtime.NodeJS20dX, * loggingConfig: { * logFormat: "JSON", * applicationLogLevel: "INFO", * systemLogLevel: "WARN", * }, * }, { * dependsOn: [ * lambdaLogs, * example, * ], * }); * ``` * * ## Specifying the Deployment Package * * AWS Lambda expects source code to be provided as a deployment package whose structure varies depending on which `runtime` is in use. See [Runtimes](https://docs.aws.amazon.com/lambda/latest/dg/API_CreateFunction.html#SSS-CreateFunction-request-Runtime) for the valid values of `runtime`. The expected structure of the deployment package can be found in [the AWS Lambda documentation for each runtime](https://docs.aws.amazon.com/lambda/latest/dg/deployment-package-v2.html). * * Once you have created your deployment package you can specify it either directly as a local file (using the `filename` argument) or indirectly via Amazon S3 (using the `s3Bucket`, `s3Key` and `s3ObjectVersion` arguments). When providing the deployment package via S3 it may be useful to use the `aws.s3.BucketObjectv2` resource to upload it. * * For larger deployment packages it is recommended by Amazon to upload via S3, since the S3 API has better support for uploading large files efficiently. * * ## Import * * ### Identity Schema * * #### Required * * * `function_name` (String) Name of the Lambda function. * * #### Optional * * * `account_id` (String) AWS Account where this resource is managed. * * * `region` (String) Region where this resource is managed. * * Using `pulumi import`, import Lambda Functions using the `function_name`. For example: * * console * * % pulumi import aws_lambda_function.example example */ class Function extends pulumi.CustomResource { /** * Get an existing Function resource's state with the given name, ID, and optional extra * properties used to qualify the lookup. * * @param name The _unique_ name of the resulting resource. * @param id The _unique_ provider ID of the resource to lookup. * @param state Any extra arguments used during the lookup. * @param opts Optional settings to control the behavior of the CustomResource. */ static get(name, id, state, opts) { return new Function(name, state, { ...opts, id: id }); } /** * Returns true if the given object is an instance of Function. This is designed to work even * when multiple copies of the Pulumi SDK have been loaded into the same process. */ static isInstance(obj) { if (obj === undefined || obj === null) { return false; } return obj['__pulumiType'] === Function.__pulumiType; } constructor(name, argsOrState, opts) { let resourceInputs = {}; opts = opts || {}; if (opts.id) { const state = argsOrState; resourceInputs["architectures"] = state?.architectures; resourceInputs["arn"] = state?.arn; resourceInputs["code"] = state?.code; resourceInputs["codeSha256"] = state?.codeSha256; resourceInputs["codeSigningConfigArn"] = state?.codeSigningConfigArn; resourceInputs["deadLetterConfig"] = state?.deadLetterConfig; resourceInputs["description"] = state?.description; resourceInputs["environment"] = state?.environment; resourceInputs["ephemeralStorage"] = state?.ephemeralStorage; resourceInputs["fileSystemConfig"] = state?.fileSystemConfig; resourceInputs["handler"] = state?.handler; resourceInputs["imageConfig"] = state?.imageConfig; resourceInputs["imageUri"] = state?.imageUri; resourceInputs["invokeArn"] = state?.invokeArn; resourceInputs["kmsKeyArn"] = state?.kmsKeyArn; resourceInputs["lastModified"] = state?.lastModified; resourceInputs["layers"] = state?.layers; resourceInputs["loggingConfig"] = state?.loggingConfig; resourceInputs["memorySize"] = state?.memorySize; resourceInputs["name"] = state?.name; resourceInputs["packageType"] = state?.packageType; resourceInputs["publish"] = state?.publish; resourceInputs["qualifiedArn"] = state?.qualifiedArn; resourceInputs["qualifiedInvokeArn"] = state?.qualifiedInvokeArn; resourceInputs["region"] = state?.region; resourceInputs["replaceSecurityGroupsOnDestroy"] = state?.replaceSecurityGroupsOnDestroy; resourceInputs["replacementSecurityGroupIds"] = state?.replacementSecurityGroupIds; resourceInputs["reservedConcurrentExecutions"] = state?.reservedConcurrentExecutions; resourceInputs["role"] = state?.role; resourceInputs["runtime"] = state?.runtime; resourceInputs["s3Bucket"] = state?.s3Bucket; resourceInputs["s3Key"] = state?.s3Key; resourceInputs["s3ObjectVersion"] = state?.s3ObjectVersion; resourceInputs["signingJobArn"] = state?.signingJobArn; resourceInputs["signingProfileVersionArn"] = state?.signingProfileVersionArn; resourceInputs["skipDestroy"] = state?.skipDestroy; resourceInputs["snapStart"] = state?.snapStart; resourceInputs["sourceCodeHash"] = state?.sourceCodeHash; resourceInputs["sourceCodeSize"] = state?.sourceCodeSize; resourceInputs["sourceKmsKeyArn"] = state?.sourceKmsKeyArn; resourceInputs["tags"] = state?.tags; resourceInputs["tagsAll"] = state?.tagsAll; resourceInputs["timeout"] = state?.timeout; resourceInputs["tracingConfig"] = state?.tracingConfig; resourceInputs["version"] = state?.version; resourceInputs["vpcConfig"] = state?.vpcConfig; } else { const args = argsOrState; if (args?.role === undefined && !opts.urn) { throw new Error("Missing required property 'role'"); } resourceInputs["architectures"] = args?.architectures; resourceInputs["code"] = args?.code; resourceInputs["codeSigningConfigArn"] = args?.codeSigningConfigArn; resourceInputs["deadLetterConfig"] = args?.deadLetterConfig; resourceInputs["description"] = args?.description; resourceInputs["environment"] = args?.environment; resourceInputs["ephemeralStorage"] = args?.ephemeralStorage; resourceInputs["fileSystemConfig"] = args?.fileSystemConfig; resourceInputs["handler"] = args?.handler; resourceInputs["imageConfig"] = args?.imageConfig; resourceInputs["imageUri"] = args?.imageUri; resourceInputs["kmsKeyArn"] = args?.kmsKeyArn; resourceInputs["layers"] = args?.layers; resourceInputs["loggingConfig"] = args?.loggingConfig; resourceInputs["memorySize"] = args?.memorySize; resourceInputs["name"] = args?.name; resourceInputs["packageType"] = args?.packageType; resourceInputs["publish"] = args?.publish; resourceInputs["region"] = args?.region; resourceInputs["replaceSecurityGroupsOnDestroy"] = args?.replaceSecurityGroupsOnDestroy; resourceInputs["replacementSecurityGroupIds"] = args?.replacementSecurityGroupIds; resourceInputs["reservedConcurrentExecutions"] = args?.reservedConcurrentExecutions; resourceInputs["role"] = args?.role; resourceInputs["runtime"] = args?.runtime; resourceInputs["s3Bucket"] = args?.s3Bucket; resourceInputs["s3Key"] = args?.s3Key; resourceInputs["s3ObjectVersion"] = args?.s3ObjectVersion; resourceInputs["skipDestroy"] = args?.skipDestroy; resourceInputs["snapStart"] = args?.snapStart; resourceInputs["sourceCodeHash"] = args?.sourceCodeHash; resourceInputs["sourceKmsKeyArn"] = args?.sourceKmsKeyArn; resourceInputs["tags"] = args?.tags; resourceInputs["timeout"] = args?.timeout; resourceInputs["tracingConfig"] = args?.tracingConfig; resourceInputs["vpcConfig"] = args?.vpcConfig; resourceInputs["arn"] = undefined /*out*/; resourceInputs["codeSha256"] = undefined /*out*/; resourceInputs["invokeArn"] = undefined /*out*/; resourceInputs["lastModified"] = undefined /*out*/; resourceInputs["qualifiedArn"] = undefined /*out*/; resourceInputs["qualifiedInvokeArn"] = undefined /*out*/; resourceInputs["signingJobArn"] = undefined /*out*/; resourceInputs["signingProfileVersionArn"] = undefined /*out*/; resourceInputs["sourceCodeSize"] = undefined /*out*/; resourceInputs["tagsAll"] = undefined /*out*/; resourceInputs["version"] = undefined /*out*/; } opts = pulumi.mergeOptions(utilities.resourceOptsDefaults(), opts); super(Function.__pulumiType, name, resourceInputs, opts); } } exports.Function = Function; /** @internal */ Function.__pulumiType = 'aws:lambda/function:Function'; //# sourceMappingURL=function.js.map