diff --git a/docs/resources/external_id.md b/docs/resources/external_id.md new file mode 100644 index 00000000..b238afa9 --- /dev/null +++ b/docs/resources/external_id.md @@ -0,0 +1,37 @@ +--- +subcategory: "Other Resources" +layout: "lacework" +page_title: "Lacework: lacework_external_id" +description: |- + Generates an External ID using Lacework format. +--- + +# lacework\_external\_id + +This resource generates an External ID (EID) using Lacework format. These IDs are used to create integrations. + +The v2 format is: +``` +lweid::::: +``` + +## Example Usage + +```hcl +resource "lacework_external_id" "aws_123456789012" { + csp = "aws" + account_id = "123456789012" +} +``` + +## Argument Reference + +* `csp` - (Required) The Cloud Service Provider. Valid CSP's include: `aws`, `google`, `oci`, and `azure`. +* `account_id` - (Required) The account id from the CSP to be integrated. + +## Attribute Reference + +The following attributes are exported: + +* `v2` - The generated External ID version 2. + diff --git a/examples/resource_lacework_external_id/main.tf b/examples/resource_lacework_external_id/main.tf new file mode 100644 index 00000000..2d5ee0ec --- /dev/null +++ b/examples/resource_lacework_external_id/main.tf @@ -0,0 +1,27 @@ +terraform { + required_providers { + lacework = { + source = "lacework/lacework" + } + } +} + +provider "lacework" {} + +# Format +# +# lweid::::: +# +resource "lacework_external_id" "aws_123456789012" { + csp = "aws" + account_id = "123456789012" +} + +# Example output +# +# lweid:aws:v2:customerdemo:123456789012:dkl31.09ip +# +output "external_id" { + value = lacework_external_id.aws_123456789012.v2 +} + diff --git a/integration/resource_lacework_external_id_test.go b/integration/resource_lacework_external_id_test.go new file mode 100644 index 00000000..0d1fe4f2 --- /dev/null +++ b/integration/resource_lacework_external_id_test.go @@ -0,0 +1,21 @@ +package integration + +import ( + "testing" + + "github.com/gruntwork-io/terratest/modules/terraform" + "github.com/stretchr/testify/assert" +) + +// TestExternalIdCreate uses the Terraform plan at: +// => '../examples/resource_lacework_external_id' +func TestExternalIdCreate(t *testing.T) { + terraformOptions := terraform.WithDefaultRetryableErrors(t, &terraform.Options{ + TerraformDir: "../examples/resource_lacework_external_id", + }) + defer terraform.Destroy(t, terraformOptions) + + terraform.InitAndApplyAndIdempotent(t, terraformOptions) + externalId := terraform.Output(t, terraformOptions, "external_id") + assert.NotEmpty(t, externalId) +} diff --git a/lacework/provider.go b/lacework/provider.go index f57a219d..bb1ce510 100644 --- a/lacework/provider.go +++ b/lacework/provider.go @@ -87,6 +87,7 @@ func Provider() *schema.Provider { "lacework_alert_profile": resourceLaceworkAlertProfile(), "lacework_alert_rule": resourceLaceworkAlertRule(), "lacework_data_export_rule": resourceLaceworkDataExportRule(), + "lacework_external_id": resourceLaceworkExternalID(), "lacework_integration_aws_agentless_scanning": resourceLaceworkIntegrationAwsAgentlessScanning(), "lacework_integration_aws_org_agentless_scanning": resourceLaceworkIntegrationAwsOrgAgentlessScanning(), "lacework_integration_aws_cfg": resourceLaceworkIntegrationAwsCfg(), diff --git a/lacework/rand.go b/lacework/rand.go index ed31807c..fc3cb179 100644 --- a/lacework/rand.go +++ b/lacework/rand.go @@ -6,14 +6,19 @@ import ( ) var ( - charset = "abcdefghijklmnopqrstuvwxyz0123456789" - randomSeed *rand.Rand = rand.New(rand.NewSource(time.Now().UnixNano())) + charset = "abcdefghijklmnopqrstuvwxyz0123456789" + randomSeed = rand.New(rand.NewSource(time.Now().UnixNano())) + charsetAWSExternalID = "=,.@:/-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890" ) func randomString(length int) string { return stringFromCharset(length, charset) } +func randomStringExternalID(length int) string { + return stringFromCharset(length, charsetAWSExternalID) +} + func stringFromCharset(length int, charset string) string { bytes := make([]byte, length) for i := range bytes { diff --git a/lacework/resource_lacework_external_id.go b/lacework/resource_lacework_external_id.go new file mode 100644 index 00000000..5869fc5b --- /dev/null +++ b/lacework/resource_lacework_external_id.go @@ -0,0 +1,72 @@ +package lacework + +import ( + "fmt" + "strings" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + "github.com/pkg/errors" + + "github.com/lacework/go-sdk/api" + "github.com/lacework/go-sdk/lwdomain" +) + +var externalIDValidCsp = []string{"aws", "google", "oci", "azure"} + +func resourceLaceworkExternalID() *schema.Resource { + return &schema.Resource{ + Read: schema.Noop, + Create: resourceLaceworkExternalIDCreate, + Delete: schema.Noop, + Schema: map[string]*schema.Schema{ + "csp": { + Type: schema.TypeString, + Description: fmt.Sprintf("The Cloud Service Provider (%s)", strings.Join(externalIDValidCsp, ", ")), + ValidateFunc: validation.StringInSlice(externalIDValidCsp, false), + Required: true, + ForceNew: true, + }, + "account_id": { + Type: schema.TypeString, + Description: "The account id from the CSP to be integrated", + Required: true, + ForceNew: true, + }, + "v2": { + Type: schema.TypeString, + Description: "Generated EID version 2 ('lweid:::::')", + Computed: true, + }, + }, + } +} + +func resourceLaceworkExternalIDCreate(d *schema.ResourceData, meta interface{}) error { + lacework := meta.(*api.Client) + url, err := lwdomain.New(lacework.URL()) + if err != nil { + return errors.Wrap(err, "Unable to get the Lacework account") + } + + // EID V2 Format + // + // lweid::::: + // + var ( + version = "v2" + EID = strings.Join([]string{ + "lweid", + d.Get("csp").(string), + version, + url.Account, + d.Get("account_id").(string), + randomStringExternalID(10), + }, ":") + ) + + d.SetId(EID) + d.Set("v2", EID) + + return nil +}