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

Support for Code Signing For AWS Lambda #16384

Merged
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) },
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Followup note: GovCloud (US) support is not present for initial release, will need to skip testing in that environment

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am on gov cloud and am not using this data source however i am getting errors on all my pipelines after release. ref #16398

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.*"),
bflad marked this conversation as resolved.
Show resolved Hide resolved
),
},
},
})
}

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.*"),
bflad marked this conversation as resolved.
Show resolved Hide resolved
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.*"),
bflad marked this conversation as resolved.
Show resolved Hide resolved
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 err
bflad marked this conversation as resolved.
Show resolved Hide resolved
}

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 @@ -281,6 +281,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 @@ -730,6 +731,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