Skip to content

Commit 0aae6b7

Browse files
author
iru
authored
feat(onboarding,cloud-host-scanner): v2 enables cloud_account GCP WIF usage [SSPROD-35921] (#487)
1 parent 2006771 commit 0aae6b7

File tree

4 files changed

+186
-58
lines changed

4 files changed

+186
-58
lines changed

.envrc.template

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
1-
# prod/kubelab
1+
# export SYSDIG_SECURE_URL=https://secure.sysdig.com
2+
3+
# credentials
24
export SYSDIG_SECURE_API_TOKEN=
35
export SYSDIG_MONITOR_API_TOKEN=
46

5-
# export SYSDIG_SECURE_URL=https://secure.sysdig.com
7+
8+
# whether to run local acc test
9+
export TF_ACC=false
10+
11+
# terraform log level
12+
export TF_LOG=DEBUG

README.md

Lines changed: 30 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,31 @@
11
<a href="https://terraform.io">
2-
<img src="https://raw.githubusercontent.com/hashicorp/terraform-provider-aws/main/.github/terraform_logo.svg" alt="Terraform logo" title="Terraform" align="right" height="50" />
2+
<img src="https://raw.githubusercontent.com/hashicorp/terraform-provider-aws/main/.github/terraform_logo.svg" alt="Terraform logo" title="Terraform" height="50" />
33
</a>
44

55

66
# Terraform Provider for Sysdig
77

8-
98
- **[Terraform Registry - Sysdig Provider Docs](https://registry.terraform.io/providers/sysdiglabs/sysdig/latest/docs)**
109
- [Blog on how to use this provider with Sysdig Secure](https://sysdig.com/blog/using-terraform-for-container-security-as-code/)
11-
- Terraform
12-
- Website https://www.terraform.io
13-
- Mailing list on [Google Groups](http://groups.google.com/group/terraform-tool)
14-
- [![Gitter chat](https://badges.gitter.im/hashicorp-terraform/Lobby.png)](https://gitter.im/hashicorp-terraform/Lobby)
1510

1611

17-
# Contribute
12+
## Contribute
1813

19-
- [Initial Setup](#initial-setup)
14+
- [Requirements](#requirements)
15+
- [Develop](#develop)
16+
- [Compile](#compile)
17+
- [Test](#tests)
18+
- [Install](#install-local)
2019
- [Proposing PR's](#proposing-prs)
2120
- [Release](#release)
2221

23-
## Initial Setup
24-
25-
### Building
26-
27-
#### Requirements
22+
## Requirements
2823

2924
- [Terraform](https://www.terraform.io/downloads.html) > 0.12.x
3025
- [Go](https://golang.org/doc/install) > Go version specified in [go.mod](./go.mod#L3)
3126
- Correctly setup a [GOPATH](http://golang.org/doc/code.html#GOPATH), as well as adding `$GOPATH/bin` to your `$PATH`.
3227

33-
### Develop
28+
## Develop
3429

3530
First **clone** source repository to: `$GOPATH/src/github.com/draios/terraform-provider-sysdig`
3631

@@ -40,37 +35,36 @@ $ cd terraform-provider-sysdig
4035
$ make build
4136
```
4237

43-
### Compile
38+
If you're a rookie, check [Official Terraform Provider development guides](https://developer.hashicorp.com/terraform/plugin/frameworkO)
39+
40+
### Creating new resource / data sources
41+
42+
TL;DR;
43+
- Create the resource/data source item
44+
- Add the created item into the `provider.go` resource or datasource map with its wiring
45+
- With its [acceptance **test**](#tests)
46+
- Add its **documentation** page on `./website/docs/`
47+
48+
## Compile
4449

4550
To **compile** the provider, run `make build`. This will build the provider and put the provider binary in the `$GOPATH/bin` directory.
4651

4752
```sh
4853
$ make build
49-
...
5054
$ $GOPATH/bin/terraform-provider-sysdig
51-
...
5255
```
5356

54-
### Tests
55-
In order to **test** the provider, you can simply run `make test`.
57+
## Tests
5658

57-
```sh
58-
$ make test
59-
```
59+
In order to **test** the provider, you can simply run `make test` to run unit-tests.
60+
For acceptance tests, you can run `make testacc`, but note that
61+
- Sysdig Montir and/or Secure credentials are required, check [`/.envrc.template`](https://github.com/sysdiglabs/terraform-provider-sysdig/blob/master/.envrc.template)
62+
- **acceptance tests rely on the creation of real infrastructure**, you should execute them in an environment where you can remove the resources easily.
6063

61-
### Acceptance Tests
64+
If you're a rookie, check [Terraform acceptance test guidelines](https://developer.hashicorp.com/terraform/plugin/testing)
6265

63-
If you want to execute the **acceptance tests**, you can run `make testacc`.
64-
- Follow [Terraform acceptance test guideliness](https://www.terraform.io/plugin/sdkv2/testing/acceptance-tests)
65-
- Please note that you need a token for Sysdig Monitor and another one for Sysdig Secure, and since the **acceptance tests create real infrastructure**
66-
you should execute them in an environment where you can remove the resources easily.
67-
- Acceptance tests are launched in [Sysdig production `+kubelab` test environment](https://github.com/sysdiglabs/terraform-provider-sysdig/blob/master/.github/workflows/ci-pull-request.yml#L82-L83)
6866

69-
```sh
70-
$ make testacc
71-
```
72-
73-
### Install (local)
67+
## Install (local)
7468
To use the local provider you just built, follow the instructions to [**install** it as a plugin.](https://www.terraform.io/docs/plugins/basics.html#installing-a-plugin) in your machine with:
7569

7670
```sh
@@ -100,20 +94,6 @@ To uninstall the plugin:
10094
$ make uninstall
10195
```
10296

103-
### Creating new resource / data sources
104-
105-
TL;DR;
106-
- Create the resource/data source item
107-
- Add the created item into the `provider.go` resource or datasource map with its wiring
108-
- With its [acceptance **test**](#acceptance-tests)
109-
- Add its **documentation** page on `./website/docs/`
110-
111-
112-
Interesting resources
113-
- https://www.terraform.io/plugin
114-
- https://www.hashicorp.com/blog/testing-hashicorp-terraform
115-
116-
11797
## Proposing PR's
11898

11999
* if it's your first time, validate you're taking into account every aspect of the [`./github/pull_request_template`](.github/pull_request_template.md)
@@ -122,7 +102,7 @@ Interesting resources
122102
- You can work on this before even pushing to remote, using [**pre-commit**](https://pre-commit.com) plugin
123103

124104
* for the PR title use [conventional commit format](https://www.conventionalcommits.org/en/v1.0.0/) so when the branch is squashed to main branch it follows a convention
125-
* for Acceptance Tests `testacc` some credentials are required, check [`/.envrc.template`](https://github.com/sysdiglabs/terraform-provider-sysdig/blob/master/.envrc.template)
105+
* acceptance tests are launched in [Sysdig production `+kubelab` test environment](https://github.com/sysdiglabs/terraform-provider-sysdig/blob/master/.github/workflows/ci-pull-request.yml#L82-L83)
126106

127107

128108
## Release
@@ -135,6 +115,8 @@ github/workflows/release.yml`](https://github.com/sysdiglabs/terraform-provider-
135115
* Review Released Draft Note, and make it as clear as possible.
136116
* Notify Sysdig teams on our internal #release-announcements slack channel and optionally in #terraform-provider
137117

118+
<br/><br/>
119+
138120
Mange takk!
139121

140122
![giphy](https://user-images.githubusercontent.com/1073243/200767344-7435f322-24c0-44d2-ac56-468791c84ca5.gif)

sysdig/resource_sysdig_secure_cloud_auth_account.go

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,20 @@ import (
1111
"strings"
1212
"time"
1313

14-
v2 "github.com/draios/terraform-provider-sysdig/sysdig/internal/client/v2"
15-
cloudauth "github.com/draios/terraform-provider-sysdig/sysdig/internal/client/v2/cloudauth/go"
1614
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
1715
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1816
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
1917
"google.golang.org/protobuf/encoding/protojson"
2018
"google.golang.org/protobuf/reflect/protoreflect"
19+
20+
v2 "github.com/draios/terraform-provider-sysdig/sysdig/internal/client/v2"
21+
cloudauth "github.com/draios/terraform-provider-sysdig/sysdig/internal/client/v2/cloudauth/go"
2122
)
2223

2324
func resourceSysdigSecureCloudauthAccount() *schema.Resource {
2425
timeout := 5 * time.Minute
2526

26-
var accountFeature = &schema.Resource{
27+
accountFeature := &schema.Resource{
2728
Schema: map[string]*schema.Schema{
2829
SchemaType: {
2930
Type: schema.TypeString,
@@ -43,7 +44,7 @@ func resourceSysdigSecureCloudauthAccount() *schema.Resource {
4344
},
4445
}
4546

46-
var accountFeatures = &schema.Resource{
47+
accountFeatures := &schema.Resource{
4748
Schema: map[string]*schema.Schema{
4849
SchemaSecureConfigPosture: {
4950
Type: schema.TypeSet,
@@ -73,7 +74,7 @@ func resourceSysdigSecureCloudauthAccount() *schema.Resource {
7374
},
7475
}
7576

76-
var accountComponents = &schema.Resource{
77+
accountComponents := &schema.Resource{
7778
Schema: map[string]*schema.Schema{
7879
SchemaType: {
7980
Type: schema.TypeString,
@@ -259,7 +260,6 @@ func resourceSysdigSecureCloudauthAccountDelete(ctx context.Context, data *schem
259260
}
260261

261262
errStatus, err := client.DeleteCloudauthAccountSecure(ctx, data.Id())
262-
263263
if err != nil {
264264
if strings.Contains(errStatus, "404") {
265265
return nil
@@ -515,7 +515,7 @@ func componentsToResourceData(components []*cloudauth.AccountComponent) []map[st
515515
case cloudauth.Component_COMPONENT_SERVICE_PRINCIPAL:
516516
// XXX: handle GCP specially because keys are base64 encoded
517517
if component.GetServicePrincipalMetadata().GetGcp() != nil {
518-
gcpKeyBytes := []byte{}
518+
var gcpKeyBytes []byte
519519
if component.GetServicePrincipalMetadata().GetGcp().GetKey() != nil {
520520
var err error
521521
gcpKeyBytes, err = protojson.MarshalOptions{UseProtoNames: true}.Marshal(component.GetServicePrincipalMetadata().GetGcp().GetKey())
@@ -558,10 +558,12 @@ func componentsToResourceData(components []*cloudauth.AccountComponent) []map[st
558558

559559
// internal type redefintion for GCP service principals.
560560
// This exists because in terraform, the key is originally provided in the form of a base64 encoded json string
561+
562+
// note; caution with order of fields, they have to go in alphabetical ASC so that the json marshalled on the tf read phase produces no drift https://github.com/golang/go/issues/27179
561563
type internalServicePrincipalMetadata_GCP struct {
564+
Email string `json:"email,omitempty"`
562565
Key string `json:"key,omitempty"` // base64 encoded
563566
WorkloadIdentityFederation *cloudauth.ServicePrincipalMetadata_GCP_WorkloadIdentityFederation `json:"workload_identity_federation,omitempty"`
564-
Email string `json:"email,omitempty"`
565567
}
566568
type internalServicePrincipalMetadata struct {
567569
Gcp *internalServicePrincipalMetadata_GCP `json:"gcp,omitempty"`

sysdig/resource_sysdig_secure_cloud_auth_account_test.go

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,3 +441,140 @@ func TestAccAWSSecureCloudAccountFCCSPM(t *testing.T) {
441441
},
442442
})
443443
}
444+
445+
func TestGCPAgentlesScanningOnboarding(t *testing.T) {
446+
rText := func() string { return acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum) }
447+
accID := rText()
448+
resource.ParallelTest(t, resource.TestCase{
449+
PreCheck: func() {
450+
if v := os.Getenv("SYSDIG_SECURE_API_TOKEN"); v == "" {
451+
t.Fatal("SYSDIG_SECURE_API_TOKEN must be set for acceptance tests")
452+
}
453+
},
454+
ProviderFactories: map[string]func() (*schema.Provider, error){
455+
"sysdig": func() (*schema.Provider, error) {
456+
return sysdig.Provider(), nil
457+
},
458+
},
459+
Steps: []resource.TestStep{
460+
{
461+
Config: fmt.Sprintf(`
462+
resource "sysdig_secure_cloud_auth_account" "gcp-agentless-scanning" {
463+
provider_id = "gcp-agentless-test-%s"
464+
provider_type = "PROVIDER_GCP"
465+
enabled = true
466+
feature {
467+
secure_agentless_scanning {
468+
enabled = true
469+
components = ["COMPONENT_SERVICE_PRINCIPAL/secure-scanning"]
470+
}
471+
}
472+
component {
473+
type = "COMPONENT_SERVICE_PRINCIPAL"
474+
instance = "secure-scanning"
475+
service_principal_metadata = jsonencode({
476+
gcp = {
477+
workload_identity_federation = {
478+
pool_provider_id = "pool_provider_id_value"
479+
}
480+
email = "email_value"
481+
}
482+
})
483+
}
484+
}`, accID),
485+
Check: resource.ComposeTestCheckFunc(
486+
resource.TestCheckResourceAttr("sysdig_secure_cloud_auth_account.gcp-agentless-scanning", "provider_type", "PROVIDER_GCP"),
487+
resource.TestCheckResourceAttr("sysdig_secure_cloud_auth_account.gcp-agentless-scanning", "enabled", "true"),
488+
resource.TestCheckResourceAttr("sysdig_secure_cloud_auth_account.gcp-agentless-scanning", "feature.0.secure_agentless_scanning.0.enabled", "true"),
489+
resource.TestCheckResourceAttr("sysdig_secure_cloud_auth_account.gcp-agentless-scanning", "feature.0.secure_agentless_scanning.0.components.0", "COMPONENT_SERVICE_PRINCIPAL/secure-scanning"),
490+
resource.TestCheckResourceAttr("sysdig_secure_cloud_auth_account.gcp-agentless-scanning", "component.0.type", "COMPONENT_SERVICE_PRINCIPAL"),
491+
resource.TestCheckResourceAttr("sysdig_secure_cloud_auth_account.gcp-agentless-scanning", "component.0.instance", "secure-scanning"),
492+
resource.TestCheckResourceAttr("sysdig_secure_cloud_auth_account.gcp-agentless-scanning", "component.0.service_principal_metadata", "{\"gcp\":{\"email\":\"email_value\",\"workload_identity_federation\":{\"pool_provider_id\":\"pool_provider_id_value\"}}}"),
493+
),
494+
},
495+
{
496+
ResourceName: "sysdig_secure_cloud_auth_account.gcp-agentless-scanning",
497+
ImportState: true,
498+
ImportStateVerify: true,
499+
},
500+
},
501+
})
502+
}
503+
504+
func TestGCPAgentlesScanningOnboardingWithInventory(t *testing.T) {
505+
rText := func() string { return acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum) }
506+
accountID := rText()
507+
resource.ParallelTest(t, resource.TestCase{
508+
PreCheck: func() {
509+
if v := os.Getenv("SYSDIG_SECURE_API_TOKEN"); v == "" {
510+
t.Fatal("SYSDIG_SECURE_API_TOKEN must be set for acceptance tests")
511+
}
512+
},
513+
ProviderFactories: map[string]func() (*schema.Provider, error){
514+
"sysdig": func() (*schema.Provider, error) {
515+
return sysdig.Provider(), nil
516+
},
517+
},
518+
Steps: []resource.TestStep{
519+
{
520+
Config: fmt.Sprintf(`
521+
resource "sysdig_secure_cloud_auth_account" "gcp-agentless-scanning" {
522+
provider_id = "gcp-agentless-test-%s"
523+
provider_type = "PROVIDER_GCP"
524+
enabled = true
525+
526+
feature {
527+
secure_config_posture {
528+
enabled = true
529+
components = ["COMPONENT_SERVICE_PRINCIPAL/secure-posture"]
530+
}
531+
532+
secure_agentless_scanning {
533+
enabled = true
534+
components = ["COMPONENT_SERVICE_PRINCIPAL/secure-scanning"]
535+
}
536+
}
537+
538+
component {
539+
type = "COMPONENT_SERVICE_PRINCIPAL"
540+
instance = "secure-posture"
541+
service_principal_metadata = jsonencode({
542+
gcp = {
543+
key = "%s"
544+
}
545+
})
546+
}
547+
548+
component {
549+
type = "COMPONENT_SERVICE_PRINCIPAL"
550+
instance = "secure-scanning"
551+
service_principal_metadata = jsonencode({
552+
gcp = {
553+
workload_identity_federation = {
554+
pool_provider_id = "pool_provider_id_value"
555+
}
556+
email = "email_value"
557+
}
558+
})
559+
}
560+
}`, accountID, getEncodedServiceAccountKey("sample-1", accountID)),
561+
Check: resource.ComposeTestCheckFunc(
562+
resource.TestCheckResourceAttr("sysdig_secure_cloud_auth_account.gcp-agentless-scanning", "provider_type", "PROVIDER_GCP"),
563+
resource.TestCheckResourceAttr("sysdig_secure_cloud_auth_account.gcp-agentless-scanning", "enabled", "true"),
564+
resource.TestCheckResourceAttr("sysdig_secure_cloud_auth_account.gcp-agentless-scanning", "feature.0.secure_agentless_scanning.0.enabled", "true"),
565+
resource.TestCheckResourceAttr("sysdig_secure_cloud_auth_account.gcp-agentless-scanning", "feature.0.secure_agentless_scanning.0.components.0", "COMPONENT_SERVICE_PRINCIPAL/secure-scanning"),
566+
resource.TestCheckResourceAttr("sysdig_secure_cloud_auth_account.gcp-agentless-scanning", "component.0.type", "COMPONENT_SERVICE_PRINCIPAL"),
567+
resource.TestCheckResourceAttr("sysdig_secure_cloud_auth_account.gcp-agentless-scanning", "component.0.instance", "secure-posture"),
568+
resource.TestCheckResourceAttr("sysdig_secure_cloud_auth_account.gcp-agentless-scanning", "component.0.service_principal_metadata", "{\"gcp\":{\"key\":\""+getEncodedServiceAccountKey("sample-1", accountID)+"\"}}"),
569+
resource.TestCheckResourceAttr("sysdig_secure_cloud_auth_account.gcp-agentless-scanning", "component.1.instance", "secure-scanning"),
570+
resource.TestCheckResourceAttr("sysdig_secure_cloud_auth_account.gcp-agentless-scanning", "component.1.service_principal_metadata", "{\"gcp\":{\"email\":\"email_value\",\"workload_identity_federation\":{\"pool_provider_id\":\"pool_provider_id_value\"}}}"),
571+
),
572+
},
573+
{
574+
ResourceName: "sysdig_secure_cloud_auth_account.gcp-agentless-scanning",
575+
ImportState: true,
576+
ImportStateVerify: true,
577+
},
578+
},
579+
})
580+
}

0 commit comments

Comments
 (0)