Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion docs/resources/export_bigquery.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,33 @@ Export data to Google BigQuery.

- `dataset_id` (String) Target BigQuery dataset (project-id.dataset_id).
- `name` (String) A descriptive name for the integration.
- `service_account_key` (String, Sensitive) Google service account JSON key content.

### Optional

- `credentials` (Attributes) Credentials for the BigQuery export. Provide `wif` for workload identity federation instead of the top-level `service_account_key`. (see [below for nested schema](#nestedatt--credentials))
- `scope_mrn` (String) The MRN of the scope (space, organization, or platform) for the export integration.
- `service_account_key` (String, Sensitive) Google service account JSON key content. Mutually exclusive with `credentials.wif`.
- `space_id` (String, Deprecated) Mondoo space identifier. If there is no space ID, the provider space is used.

### Read-Only

- `mrn` (String) Mondoo resource name (MRN) of the integration.
- `wif_subject` (String) Computed OIDC subject used when Mondoo requests a WIF token for this integration. Configure your cloud provider's trust policy to accept this subject.

<a id="nestedatt--credentials"></a>
### Nested Schema for `credentials`

Optional:

- `wif` (Attributes) Workload identity federation configuration. Mutually exclusive with `service_account_key`. (see [below for nested schema](#nestedatt--credentials--wif))

<a id="nestedatt--credentials--wif"></a>
### Nested Schema for `credentials.wif`

Required:

- `audience` (String) WIF audience URL for GCP workload identity federation.

Optional:

- `service_account_email` (String) Optional GCP service account email to impersonate via workload identity federation.
16 changes: 14 additions & 2 deletions docs/resources/export_gcs_bucket.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ Export data to a Google Cloud Storage bucket.
### Required

- `bucket_name` (String) Name of the Google Cloud Storage bucket to export data to.
- `credentials` (Attributes) Credentials for the Google Cloud Storage bucket. (see [below for nested schema](#nestedatt--credentials))
- `credentials` (Attributes) Credentials for the Google Cloud Storage bucket. Provide either a static service account `private_key` or a `wif` block for workload identity federation. (see [below for nested schema](#nestedatt--credentials))
- `name` (String) Name of the export integration.

### Optional
Expand All @@ -58,6 +58,18 @@ Export data to a Google Cloud Storage bucket.
<a id="nestedatt--credentials"></a>
### Nested Schema for `credentials`

Optional:

- `private_key` (String, Sensitive) Private key for the service account in JSON format. Mutually exclusive with `wif`.
- `wif` (Attributes) Workload identity federation configuration. Mutually exclusive with `private_key`. (see [below for nested schema](#nestedatt--credentials--wif))

<a id="nestedatt--credentials--wif"></a>
### Nested Schema for `credentials.wif`

Required:

- `private_key` (String, Sensitive) Private key for the service account in JSON format.
- `audience` (String) WIF audience URL for GCP workload identity federation.

Optional:

- `service_account_email` (String) Optional GCP service account email to impersonate via workload identity federation.
16 changes: 13 additions & 3 deletions docs/resources/integration_aws.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ resource "mondoo_integration_aws" "name" {

### Required

- `credentials` (Attributes) (see [below for nested schema](#nestedatt--credentials))
- `credentials` (Attributes) Credentials for the AWS integration. Exactly one of `role`, `key`, or `wif` must be configured. (see [below for nested schema](#nestedatt--credentials))
- `name` (String) Name of the integration.

### Optional
Expand All @@ -64,8 +64,9 @@ resource "mondoo_integration_aws" "name" {

Optional:

- `key` (Attributes) (see [below for nested schema](#nestedatt--credentials--key))
- `role` (Attributes) (see [below for nested schema](#nestedatt--credentials--role))
- `key` (Attributes) Static IAM access key credentials. Mutually exclusive with `role` and `wif`. (see [below for nested schema](#nestedatt--credentials--key))
- `role` (Attributes) IAM role credentials. Mutually exclusive with `key` and `wif`. (see [below for nested schema](#nestedatt--credentials--role))
- `wif` (Attributes) Workload identity federation credentials. Uses Mondoo as an OIDC identity provider to assume an IAM role via web identity. Mutually exclusive with `role` and `key`. (see [below for nested schema](#nestedatt--credentials--wif))

<a id="nestedatt--credentials--key"></a>
### Nested Schema for `credentials.key`
Expand All @@ -87,6 +88,15 @@ Optional:

- `external_id` (String, Sensitive)


<a id="nestedatt--credentials--wif"></a>
### Nested Schema for `credentials.wif`

Required:

- `audience` (String) Audience value configured in the AWS IAM OIDC identity provider.
- `role_arn` (String) ARN of the IAM role to assume via web identity federation.

## Import

Import is supported using the following syntax:
Expand Down
16 changes: 14 additions & 2 deletions docs/resources/integration_gcp.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ resource "mondoo_integration_gcp" "name" {

### Required

- `credentials` (Attributes) (see [below for nested schema](#nestedatt--credentials))
- `credentials` (Attributes) Credentials for the GCP integration. Provide either a static service account `private_key` or a `wif` block for workload identity federation. (see [below for nested schema](#nestedatt--credentials))
- `name` (String) Name of the integration.

### Optional
Expand All @@ -89,9 +89,21 @@ resource "mondoo_integration_gcp" "name" {
<a id="nestedatt--credentials"></a>
### Nested Schema for `credentials`

Optional:

- `private_key` (String, Sensitive) GCP service account JSON key. Mutually exclusive with `wif`.
- `wif` (Attributes) Workload identity federation configuration. Mutually exclusive with `private_key`. (see [below for nested schema](#nestedatt--credentials--wif))

<a id="nestedatt--credentials--wif"></a>
### Nested Schema for `credentials.wif`

Required:

- `private_key` (String, Sensitive)
- `audience` (String) WIF audience URL for GCP workload identity federation.

Optional:

- `service_account_email` (String) Optional GCP service account email to impersonate via workload identity federation.

## Import

Expand Down
92 changes: 76 additions & 16 deletions internal/provider/export_bigquery.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"context"
"fmt"

"github.com/hashicorp/terraform-plugin-framework-validators/resourcevalidator"
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/resource"
Expand All @@ -21,6 +22,7 @@ import (

// Ensure provider defined types fully satisfy framework interfaces.
var _ resource.Resource = &ExportBigQueryResource{}
var _ resource.ResourceWithConfigValidators = &ExportBigQueryResource{}

func NewMondooExportBigQueryResource() resource.Resource {
return &ExportBigQueryResource{}
Expand All @@ -42,7 +44,31 @@ type BigQueryExportResourceModel struct {
WifSubject types.String `tfsdk:"wif_subject"`

// credentials
ServiceAccountKey types.String `tfsdk:"service_account_key"`
ServiceAccountKey types.String `tfsdk:"service_account_key"`
Credentials *exportBigQueryCredentialsWrapper `tfsdk:"credentials"`
}

type exportBigQueryCredentialsWrapper struct {
Wif *gcpWifCredentialModel `tfsdk:"wif"`
}

func (m BigQueryExportResourceModel) GetConfigurationOptions() *mondoov1.BigqueryConfigurationOptionsInput {
opts := &mondoov1.BigqueryConfigurationOptionsInput{
DatasetId: mondoov1.String(m.DatasetID.ValueString()),
}

if !m.ServiceAccountKey.IsNull() && !m.ServiceAccountKey.IsUnknown() {
opts.ServiceAccount = mondoov1.NewStringPtr(mondoov1.String(m.ServiceAccountKey.ValueString()))
}

if m.Credentials != nil && m.Credentials.Wif != nil {
opts.WifAudience = mondoov1.NewStringPtr(mondoov1.String(m.Credentials.Wif.Audience.ValueString()))
if !m.Credentials.Wif.ServiceAccountEmail.IsNull() && !m.Credentials.Wif.ServiceAccountEmail.IsUnknown() {
opts.WifServiceAccountEmail = mondoov1.NewStringPtr(mondoov1.String(m.Credentials.Wif.ServiceAccountEmail.ValueString()))
}
}

return opts
}

func (r *ExportBigQueryResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
Expand Down Expand Up @@ -109,11 +135,28 @@ func (r *ExportBigQueryResource) Schema(ctx context.Context, req resource.Schema
},
},
"service_account_key": schema.StringAttribute{
MarkdownDescription: "Google service account JSON key content.",
Required: true,
MarkdownDescription: "Google service account JSON key content. Mutually exclusive with `credentials.wif`.",
Optional: true,
Sensitive: true,
PlanModifiers: []planmodifier.String{
stringplanmodifier.RequiresReplace(),
},
"credentials": schema.SingleNestedAttribute{
MarkdownDescription: "Credentials for the BigQuery export. Provide `wif` for workload identity federation instead of the top-level `service_account_key`.",
Optional: true,
Attributes: map[string]schema.Attribute{
"wif": schema.SingleNestedAttribute{
MarkdownDescription: "Workload identity federation configuration. Mutually exclusive with `service_account_key`.",
Optional: true,
Attributes: map[string]schema.Attribute{
"audience": schema.StringAttribute{
MarkdownDescription: "WIF audience URL for GCP workload identity federation.",
Required: true,
},
"service_account_email": schema.StringAttribute{
MarkdownDescription: "Optional GCP service account email to impersonate via workload identity federation.",
Optional: true,
},
},
},
},
},
"wif_subject": schema.StringAttribute{
Expand All @@ -127,6 +170,15 @@ func (r *ExportBigQueryResource) Schema(ctx context.Context, req resource.Schema
}
}

func (r *ExportBigQueryResource) ConfigValidators(ctx context.Context) []resource.ConfigValidator {
return []resource.ConfigValidator{
resourcevalidator.ExactlyOneOf(
path.MatchRoot("service_account_key"),
path.MatchRoot("credentials").AtName("wif"),
),
}
}

func (r *ExportBigQueryResource) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) {
// Prevent panic if the provider has not been configured.
if req.ProviderData == nil {
Expand Down Expand Up @@ -157,10 +209,7 @@ func (r *ExportBigQueryResource) Create(ctx context.Context, req resource.Create
}

configOpts := mondoov1.ClientIntegrationConfigurationInput{
BigqueryConfigurationOptions: &mondoov1.BigqueryConfigurationOptionsInput{
DatasetId: mondoov1.String(data.DatasetID.ValueString()),
ServiceAccount: mondoov1.NewStringPtr(mondoov1.String(data.ServiceAccountKey.ValueString())),
},
BigqueryConfigurationOptions: data.GetConfigurationOptions(),
}

var integration *CreateClientIntegrationPayload
Expand Down Expand Up @@ -248,8 +297,13 @@ func (r *ExportBigQueryResource) Read(ctx context.Context, req resource.ReadRequ
}

// Update the state with the latest information
opts := integration.ConfigurationOptions.BigqueryConfigurationOptions
data.Name = types.StringValue(integration.Name)
data.WifSubject = types.StringValue(integration.ConfigurationOptions.BigqueryConfigurationOptions.WifSubject)
data.WifSubject = types.StringValue(opts.WifSubject)
if data.Credentials != nil && data.Credentials.Wif != nil {
data.Credentials.Wif.Audience = types.StringValue(opts.WifAudience)
data.Credentials.Wif.ServiceAccountEmail = stringOrNull(opts.WifServiceAccountEmail)
}
// Note: We don't update service_account_key to avoid showing sensitive data

// Save updated data into Terraform state
Expand All @@ -271,10 +325,7 @@ func (r *ExportBigQueryResource) Update(ctx context.Context, req resource.Update
data.Name.ValueString(),
mondoov1.ClientIntegrationTypeBigquery,
mondoov1.ClientIntegrationConfigurationInput{
BigqueryConfigurationOptions: &mondoov1.BigqueryConfigurationOptionsInput{
DatasetId: mondoov1.String(data.DatasetID.ValueString()),
ServiceAccount: mondoov1.NewStringPtr(mondoov1.String(data.ServiceAccountKey.ValueString())),
},
BigqueryConfigurationOptions: data.GetConfigurationOptions(),
})

if err != nil {
Expand Down Expand Up @@ -308,14 +359,23 @@ func (r *ExportBigQueryResource) ImportState(ctx context.Context, req resource.I
return
}

opts := integration.ConfigurationOptions.BigqueryConfigurationOptions
model := BigQueryExportResourceModel{
Mrn: types.StringValue(integration.Mrn),
Name: types.StringValue(integration.Name),
ScopeMrn: types.StringValue(integration.ScopeMRN()),
DatasetID: types.StringValue(integration.ConfigurationOptions.BigqueryConfigurationOptions.DatasetId),
WifSubject: types.StringValue(integration.ConfigurationOptions.BigqueryConfigurationOptions.WifSubject),
DatasetID: types.StringValue(opts.DatasetId),
WifSubject: types.StringValue(opts.WifSubject),
ServiceAccountKey: types.StringPointerValue(nil), // Don't expose sensitive data
}
if opts.WifAudience != "" {
model.Credentials = &exportBigQueryCredentialsWrapper{
Wif: &gcpWifCredentialModel{
Audience: types.StringValue(opts.WifAudience),
ServiceAccountEmail: stringOrNull(opts.WifServiceAccountEmail),
},
}
}

if integration.IsSpaceScoped() {
model.SpaceID = types.StringValue(integration.SpaceID())
Expand Down
Loading
Loading