Skip to content

Commit

Permalink
Support for Code Signing For AWS Lambda (#16384)
Browse files Browse the repository at this point in the history
Add support in Lambda Layers for Code Signing for AWS Lambda

Output from acceptance testing in AWS Commercial:

```
--- PASS: TestAccDataSourceAWSLambdaCodeSigningConfig_PolicyConfigId (12.24s)
--- PASS: TestAccDataSourceAWSLambdaCodeSigningConfig_basic (12.34s)
--- PASS: TestAccDataSourceAWSLambdaCodeSigningConfig_Description (12.50s)

--- PASS: TestAccDataSourceAWSLambdaFunction_environment (36.94s)
--- PASS: TestAccDataSourceAWSLambdaFunction_alias (47.40s)
--- PASS: TestAccDataSourceAWSLambdaFunction_basic (50.94s)
--- PASS: TestAccDataSourceAWSLambdaFunction_version (57.76s)
--- PASS: TestAccDataSourceAWSLambdaFunction_layers (67.52s)

--- PASS: TestAccDataSourceAWSLambdaLayerVersion_version (14.99s)
--- PASS: TestAccDataSourceAWSLambdaLayerVersion_basic (19.91s)
--- PASS: TestAccDataSourceAWSLambdaLayerVersion_runtime (28.28s)

--- PASS: TestAccAWSLambdaCodeSigningConfig_basic (15.36s)
--- PASS: TestAccAWSLambdaCodeSigningConfig_UpdatePolicy (23.63s)
--- PASS: TestAccAWSLambdaCodeSigningConfig_UpdatePublishers (24.60s)

--- PASS: TestAccAWSLambdaFunction_basic (71.96s)
--- PASS: TestAccAWSLambdaFunction_codeSigningConfig (1046.52s)
--- PASS: TestAccAWSLambdaFunction_concurrency (1040.52s)
--- PASS: TestAccAWSLambdaFunction_concurrencyCycle (120.33s)
--- PASS: TestAccAWSLambdaFunction_DeadLetterConfig (1040.64s)
--- PASS: TestAccAWSLambdaFunction_DeadLetterConfigUpdated (122.58s)
--- PASS: TestAccAWSLambdaFunction_disablePublish (1025.85s)
--- PASS: TestAccAWSLambdaFunction_disappears (1003.11s)
--- PASS: TestAccAWSLambdaFunction_EmptyVpcConfig (57.58s)
--- PASS: TestAccAWSLambdaFunction_enablePublish (1217.32s)
--- PASS: TestAccAWSLambdaFunction_encryptedEnvVariables (135.35s)
--- PASS: TestAccAWSLambdaFunction_envVariables (161.05s)
--- PASS: TestAccAWSLambdaFunction_expectFilenameAndS3Attributes (19.21s)
--- PASS: TestAccAWSLambdaFunction_FileSystemConfig (1903.63s)
--- PASS: TestAccAWSLambdaFunction_KmsKeyArn_NoEnvironmentVariables (108.09s)
--- PASS: TestAccAWSLambdaFunction_Layers (924.06s)
--- PASS: TestAccAWSLambdaFunction_LayersUpdate (1050.35s)
--- PASS: TestAccAWSLambdaFunction_localUpdate (1052.39s)
--- PASS: TestAccAWSLambdaFunction_localUpdate_nameOnly (1053.93s)
--- PASS: TestAccAWSLambdaFunction_nilDeadLetterConfig (1150.88s)
--- PASS: TestAccAWSLambdaFunction_runtimes (405.97s)
--- PASS: TestAccAWSLambdaFunction_s3 (39.31s)
--- PASS: TestAccAWSLambdaFunction_s3Update_basic (64.29s)
--- PASS: TestAccAWSLambdaFunction_s3Update_unversioned (64.31s)
--- PASS: TestAccAWSLambdaFunction_tags (84.06s)
--- PASS: TestAccAWSLambdaFunction_tracingConfig (1032.25s)
--- PASS: TestAccAWSLambdaFunction_UnpublishedCodeUpdate (1211.68s)
--- PASS: TestAccAWSLambdaFunction_versioned (65.28s)
--- PASS: TestAccAWSLambdaFunction_versionedUpdate (1234.96s)
--- PASS: TestAccAWSLambdaFunction_VPC (788.22s)
--- PASS: TestAccAWSLambdaFunction_VPC_withInvocation (966.94s)
--- PASS: TestAccAWSLambdaFunction_VpcConfig_ProperIamDependencies (962.36s)
--- PASS: TestAccAWSLambdaFunction_VPCRemoval (1375.17s)
--- PASS: TestAccAWSLambdaFunction_VPCUpdate (2505.36s)

--- PASS: TestAccAWSLambdaLayerVersion_basic (14.36s)
--- PASS: TestAccAWSLambdaLayerVersion_compatibleRuntimes (19.15s)
--- PASS: TestAccAWSLambdaLayerVersion_licenseInfo (25.70s)
--- PASS: TestAccAWSLambdaLayerVersion_description (29.40s)
--- PASS: TestAccAWSLambdaLayerVersion_s3 (29.94s)
--- PASS: TestAccAWSLambdaLayerVersion_update (30.76s)
```

Co-authored-by: Sarah Fallah-adl <[email protected]>
Co-authored-by: Veda Raman <[email protected]>
Co-authored-by: Young Jeong <[email protected]>
Co-authored-by: angie pinilla <[email protected]>
Co-authored-by: Brian Flad <[email protected]>
  • Loading branch information
6 people authored Nov 23, 2020
1 parent 8dff100 commit d9e7b9a
Show file tree
Hide file tree
Showing 19 changed files with 1,206 additions and 12 deletions.
114 changes: 114 additions & 0 deletions aws/data_source_aws_lambda_code_signing_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package aws

import (
"fmt"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/lambda"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func dataSourceAwsLambdaCodeSigningConfig() *schema.Resource {
return &schema.Resource{
Read: dataSourceAwsLambdaCodeSigningConfigRead,

Schema: map[string]*schema.Schema{
"arn": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validateArn,
},
"allowed_publishers": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"signing_profile_version_arns": {
Type: schema.TypeSet,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
Set: schema.HashString,
},
},
},
},
"policies": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"untrusted_artifact_on_deployment": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
"description": {
Type: schema.TypeString,
Computed: true,
},
"config_id": {
Type: schema.TypeString,
Computed: true,
},
"last_modified": {
Type: schema.TypeString,
Computed: true,
},
},
}
}

func dataSourceAwsLambdaCodeSigningConfigRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).lambdaconn

arn := d.Get("arn").(string)

configOutput, err := conn.GetCodeSigningConfig(&lambda.GetCodeSigningConfigInput{
CodeSigningConfigArn: aws.String(arn),
})

if err != nil {
return fmt.Errorf("error getting Lambda code signing config (%s): %s", arn, err)
}

if configOutput == nil {
return fmt.Errorf("error getting Lambda code signing config (%s): empty response", arn)
}

codeSigningConfig := configOutput.CodeSigningConfig
if codeSigningConfig == nil {
return fmt.Errorf("error getting Lambda code signing config (%s): empty CodeSigningConfig", arn)
}

if err := d.Set("config_id", codeSigningConfig.CodeSigningConfigId); err != nil {
return fmt.Errorf("error setting lambda code signing config id: %s", err)
}

if err := d.Set("description", codeSigningConfig.Description); err != nil {
return fmt.Errorf("error setting lambda code signing config description: %s", err)
}

if err := d.Set("last_modified", codeSigningConfig.LastModified); err != nil {
return fmt.Errorf("error setting lambda code signing config last modified: %s", err)
}

if err := d.Set("allowed_publishers", flattenLambdaCodeSigningConfigAllowedPublishers(codeSigningConfig.AllowedPublishers)); err != nil {
return fmt.Errorf("error setting lambda code signing config allowed publishers: %s", err)
}

if err := d.Set("policies", []interface{}{
map[string]interface{}{
"untrusted_artifact_on_deployment": codeSigningConfig.CodeSigningPolicies.UntrustedArtifactOnDeployment,
},
}); err != nil {
return fmt.Errorf("error setting lambda code signing config code signing policies: %s", err)
}

d.SetId(aws.StringValue(codeSigningConfig.CodeSigningConfigArn))

return nil
}
124 changes: 124 additions & 0 deletions aws/data_source_aws_lambda_code_signing_config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
package aws

import (
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
)

func TestAccDataSourceAWSLambdaCodeSigningConfig_basic(t *testing.T) {
dataSourceName := "data.aws_lambda_code_signing_config.test"
resourceName := "aws_lambda_code_signing_config.test"
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccDataSourceAWSLambdaCodeSigningConfigBasic,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrPair(dataSourceName, "arn", resourceName, "arn"),
resource.TestCheckResourceAttrPair(dataSourceName, "allowed_publishers.0.signing_profile_version_arns.#", resourceName, "allowed_publishers.0.signing_profile_version_arns.#"),
),
},
},
})
}

func TestAccDataSourceAWSLambdaCodeSigningConfig_PolicyConfigId(t *testing.T) {
dataSourceName := "data.aws_lambda_code_signing_config.test"
resourceName := "aws_lambda_code_signing_config.test"
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccDataSourceAWSLambdaCodeSigningConfigConfigurePolicy,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrPair(dataSourceName, "arn", resourceName, "arn"),
resource.TestCheckResourceAttrPair(dataSourceName, "allowed_publishers.0.signing_profile_version_arns.#", resourceName, "allowed_publishers.0.signing_profile_version_arns.#"),
resource.TestCheckResourceAttrPair(dataSourceName, "policies", resourceName, "policies"),
resource.TestCheckResourceAttrPair(dataSourceName, "config_id", resourceName, "config_id"),
),
},
},
})
}

func TestAccDataSourceAWSLambdaCodeSigningConfig_Description(t *testing.T) {
dataSourceName := "data.aws_lambda_code_signing_config.test"
resourceName := "aws_lambda_code_signing_config.test"
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccDataSourceAWSLambdaCodeSigningConfigConfigureDescription,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrPair(dataSourceName, "arn", resourceName, "arn"),
resource.TestCheckResourceAttrPair(dataSourceName, "allowed_publishers.0.signing_profile_version_arns.#", resourceName, "allowed_publishers.0.signing_profile_version_arns.#"),
resource.TestCheckResourceAttrPair(dataSourceName, "description", resourceName, "description"),
),
},
},
})
}

const testAccDataSourceAWSLambdaCodeSigningConfigBasic = `
resource "aws_signer_signing_profile" "test" {
platform_id = "AWSLambda-SHA384-ECDSA"
}
resource "aws_lambda_code_signing_config" "test" {
allowed_publishers {
signing_profile_version_arns = [
aws_signer_signing_profile.test.version_arn
]
}
}
data "aws_lambda_code_signing_config" "test" {
arn = aws_lambda_code_signing_config.test.arn
}
`

const testAccDataSourceAWSLambdaCodeSigningConfigConfigurePolicy = `
resource "aws_signer_signing_profile" "test" {
platform_id = "AWSLambda-SHA384-ECDSA"
}
resource "aws_lambda_code_signing_config" "test" {
allowed_publishers {
signing_profile_version_arns = [
aws_signer_signing_profile.test.version_arn
]
}
policies {
untrusted_artifact_on_deployment = "Warn"
}
}
data "aws_lambda_code_signing_config" "test" {
arn = aws_lambda_code_signing_config.test.arn
}
`

const testAccDataSourceAWSLambdaCodeSigningConfigConfigureDescription = `
resource "aws_signer_signing_profile" "test" {
platform_id = "AWSLambda-SHA384-ECDSA"
}
resource "aws_lambda_code_signing_config" "test" {
allowed_publishers {
signing_profile_version_arns = [
aws_signer_signing_profile.test.version_arn
]
}
description = "Code Signing Config for app A"
}
data "aws_lambda_code_signing_config" "test" {
arn = aws_lambda_code_signing_config.test.arn
}
`
39 changes: 39 additions & 0 deletions aws/data_source_aws_lambda_function.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,18 @@ func dataSourceAwsLambdaFunction() *schema.Resource {
Computed: true,
},
"tags": tagsSchemaComputed(),
"signing_profile_version_arn": {
Type: schema.TypeString,
Computed: true,
},
"signing_job_arn": {
Type: schema.TypeString,
Computed: true,
},
"code_signing_config_arn": {
Type: schema.TypeString,
Computed: true,
},
},
}
}
Expand Down Expand Up @@ -243,6 +255,16 @@ func dataSourceAwsLambdaFunctionRead(d *schema.ResourceData, meta interface{}) e
d.Set("memory_size", function.MemorySize)
d.Set("qualified_arn", qualifiedARN)

// Add Signing Profile Version ARN
if err := d.Set("signing_profile_version_arn", function.SigningProfileVersionArn); err != nil {
return fmt.Errorf("Error setting signing profile version arn for Lambda Function: %s", err)
}

// Add Signing Job ARN
if err := d.Set("signing_job_arn", function.SigningJobArn); err != nil {
return fmt.Errorf("Error setting signing job arn for Lambda Function: %s", err)
}

reservedConcurrentExecutions := int64(-1)
if output.Concurrency != nil {
reservedConcurrentExecutions = aws.Int64Value(output.Concurrency.ReservedConcurrentExecutions)
Expand Down Expand Up @@ -281,6 +303,23 @@ func dataSourceAwsLambdaFunctionRead(d *schema.ResourceData, meta interface{}) e
return fmt.Errorf("error setting file_system_config: %s", err)
}

// Get Code Signing Config Output
// If code signing config output exists, set it to that value, otherwise set it empty.
codeSigningConfigInput := &lambda.GetFunctionCodeSigningConfigInput{
FunctionName: aws.String(d.Get("function_name").(string)),
}

getCodeSigningConfigOutput, err := conn.GetFunctionCodeSigningConfig(codeSigningConfigInput)
if err != nil {
return fmt.Errorf("error getting Lambda Function (%s) Code Signing Config: %w", aws.StringValue(function.FunctionName), err)
}

if getCodeSigningConfigOutput == nil || getCodeSigningConfigOutput.CodeSigningConfigArn == nil {
d.Set("code_signing_config_arn", "")
} else {
d.Set("code_signing_config_arn", getCodeSigningConfigOutput.CodeSigningConfigArn)
}

d.SetId(aws.StringValue(function.FunctionName))

return nil
Expand Down
3 changes: 3 additions & 0 deletions aws/data_source_aws_lambda_function_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ func TestAccDataSourceAWSLambdaFunction_basic(t *testing.T) {
resource.TestCheckResourceAttrPair(dataSourceName, "tracing_config.#", resourceName, "tracing_config.#"),
resource.TestCheckResourceAttrPair(dataSourceName, "tracing_config.0.mode", resourceName, "tracing_config.0.mode"),
resource.TestCheckResourceAttrPair(dataSourceName, "version", resourceName, "version"),
resource.TestCheckResourceAttrPair(dataSourceName, "signing_profile_version_arn", resourceName, "signing_profile_version_arn"),
resource.TestCheckResourceAttrPair(dataSourceName, "signing_job_arn", resourceName, "signing_job_arn"),
resource.TestCheckResourceAttrPair(dataSourceName, "code_signing_config_arn", resourceName, "code_signing_config_arn"),
),
},
},
Expand Down
14 changes: 14 additions & 0 deletions aws/data_source_aws_lambda_layer_version.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,14 @@ func dataSourceAwsLambdaLayerVersion() *schema.Resource {
Type: schema.TypeInt,
Computed: true,
},
"signing_profile_version_arn": {
Type: schema.TypeString,
Computed: true,
},
"signing_job_arn": {
Type: schema.TypeString,
Computed: true,
},
},
}
}
Expand Down Expand Up @@ -142,6 +150,12 @@ func dataSourceAwsLambdaLayerVersionRead(d *schema.ResourceData, meta interface{
if err := d.Set("source_code_size", output.Content.CodeSize); err != nil {
return fmt.Errorf("error setting lambda layer source code size: %s", err)
}
if err := d.Set("signing_profile_version_arn", output.Content.SigningProfileVersionArn); err != nil {
return fmt.Errorf("Error setting lambda layer signing profile arn: %s", err)
}
if err := d.Set("signing_job_arn", output.Content.SigningJobArn); err != nil {
return fmt.Errorf("Error setting lambda layer signing job arn: %s", err)
}

d.SetId(aws.StringValue(output.LayerVersionArn))

Expand Down
2 changes: 2 additions & 0 deletions aws/data_source_aws_lambda_layer_version_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ func TestAccDataSourceAWSLambdaLayerVersion_basic(t *testing.T) {
resource.TestCheckResourceAttrPair(dataSourceName, "created_date", resourceName, "created_date"),
resource.TestCheckResourceAttrPair(dataSourceName, "source_code_hash", resourceName, "source_code_hash"),
resource.TestCheckResourceAttrPair(dataSourceName, "source_code_size", resourceName, "source_code_size"),
resource.TestCheckResourceAttrPair(dataSourceName, "signing_profile_version_arn", resourceName, "signing_profile_version_arn"),
resource.TestCheckResourceAttrPair(dataSourceName, "signing_job_arn", resourceName, "signing_job_arn"),
),
},
},
Expand Down
2 changes: 2 additions & 0 deletions aws/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ func Provider() *schema.Provider {
"aws_kms_secret": dataSourceAwsKmsSecret(),
"aws_kms_secrets": dataSourceAwsKmsSecrets(),
"aws_lambda_alias": dataSourceAwsLambdaAlias(),
"aws_lambda_code_signing_config": dataSourceAwsLambdaCodeSigningConfig(),
"aws_lambda_function": dataSourceAwsLambdaFunction(),
"aws_lambda_invocation": dataSourceAwsLambdaInvocation(),
"aws_lambda_layer_version": dataSourceAwsLambdaLayerVersion(),
Expand Down Expand Up @@ -734,6 +735,7 @@ func Provider() *schema.Provider {
"aws_kms_key": resourceAwsKmsKey(),
"aws_kms_ciphertext": resourceAwsKmsCiphertext(),
"aws_lambda_alias": resourceAwsLambdaAlias(),
"aws_lambda_code_signing_config": resourceAwsLambdaCodeSigningConfig(),
"aws_lambda_event_source_mapping": resourceAwsLambdaEventSourceMapping(),
"aws_lambda_function_event_invoke_config": resourceAwsLambdaFunctionEventInvokeConfig(),
"aws_lambda_function": resourceAwsLambdaFunction(),
Expand Down
Loading

0 comments on commit d9e7b9a

Please sign in to comment.