diff --git a/docs/resources/integration_aws_serverless.md b/docs/resources/integration_aws_serverless.md
new file mode 100644
index 0000000..05a2ec9
--- /dev/null
+++ b/docs/resources/integration_aws_serverless.md
@@ -0,0 +1,167 @@
+---
+# generated by https://github.com/hashicorp/terraform-plugin-docs
+page_title: "mondoo_integration_aws_serverless Resource - terraform-provider-mondoo"
+subcategory: ""
+description: |-
+ Continuously scan AWS organization and accounts for misconfigurations and vulnerabilities.
+---
+
+# mondoo_integration_aws_serverless (Resource)
+
+Continuously scan AWS organization and accounts for misconfigurations and vulnerabilities.
+
+## Example Usage
+
+```terraform
+variable "mondoo_org" {
+ description = "Mondoo Organization"
+ type = string
+}
+
+variable "origin_aws_account" {
+ description = "Origin AWS Account"
+ type = string
+ default = "764453172858"
+}
+
+variable "aws_region" {
+ description = "AWS Region"
+ type = string
+ default = "us-east-1"
+}
+
+variable "aws_account_id" {
+ description = "value of the AWS account ID"
+ type = string
+}
+
+provider "mondoo" {
+ region = "us"
+}
+
+provider "aws" {
+ region = var.aws_region
+}
+
+data "aws_region" "current" {}
+
+# Create a new space
+resource "mondoo_space" "my_space" {
+ name = "AWS Terraform"
+ org_id = var.mondoo_org
+}
+
+# Setup the AWS integration
+resource "mondoo_integration_aws_serverless" "aws_serverless" {
+ space_id = mondoo_space.my_space.id
+ name = "AWS Integration"
+ region = data.aws_region.current.name
+ is_organization = false
+ console_sign_in_trigger = true
+ instance_state_change_trigger = true
+ account_ids = [var.aws_account_id]
+ scan_configuration = {
+ ec2_scan = true
+ ecr_scan = false
+ ecs_scan = false
+ cron_scan_in_hours = 24
+ ec2_scan_options = {
+ ssm = true
+ ebs_volume_scan = true
+ ebs_scan_options = {
+ target_instances_per_scanner = 5
+ max_asg_instances = 10
+ }
+ instance_connect = false
+ }
+ }
+}
+
+# for single account deploys
+resource "aws_cloudformation_stack" "mondoo_stack" {
+ name = "mondoo-stack"
+ template_url = "https://s3.amazonaws.com/mondoo.${data.aws_region.current.name}/mondoo-lambda-stackset-cf.json"
+ capabilities = ["CAPABILITY_NAMED_IAM"]
+ parameters = {
+ MondooIntegrationMrn = mondoo_integration_aws_serverless.aws_serverless.mrn
+ MondooToken = mondoo_integration_aws_serverless.aws_serverless.token
+ OriginAwsAccount = var.origin_aws_account
+ }
+}
+
+# for organisation wide deploys use aws_cloudformation_stack_set and aws_cloudformation_stack_set_instance instead of aws_cloudformation_stack
+# https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudformation_stack_set
+# https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudformation_stack_set_instance
+```
+
+
+## Schema
+
+### Required
+
+- `name` (String) Name of the integration.
+- `region` (String) AWS region.
+- `scan_configuration` (Attributes) (see [below for nested schema](#nestedatt--scan_configuration))
+- `space_id` (String) Mondoo Space Identifier.
+
+### Optional
+
+- `account_ids` (List of String) List of AWS account IDs.
+- `console_sign_in_trigger` (Boolean) Enable console sign in trigger.
+- `instance_state_change_trigger` (Boolean) Enable instance state change trigger.
+- `is_organization` (Boolean) Is organization.
+
+### Read-Only
+
+- `mrn` (String) Integration identifier
+- `token` (String) Integration token
+
+
+### Nested Schema for `scan_configuration`
+
+Required:
+
+- `ec2_scan_options` (Attributes) (see [below for nested schema](#nestedatt--scan_configuration--ec2_scan_options))
+
+Optional:
+
+- `cron_scan_in_hours` (Number) Cron scan in hours.
+- `ec2_scan` (Boolean) Enable EC2 scan.
+- `ecr_scan` (Boolean) Enable ECR scan.
+- `ecs_scan` (Boolean) Enable ECS scan.
+- `event_scan_triggers` (Attributes) (see [below for nested schema](#nestedatt--scan_configuration--event_scan_triggers))
+
+
+### Nested Schema for `scan_configuration.ec2_scan_options`
+
+Required:
+
+- `ebs_scan_options` (Attributes) (see [below for nested schema](#nestedatt--scan_configuration--ec2_scan_options--ebs_scan_options))
+
+Optional:
+
+- `ebs_volume_scan` (Boolean) Enable EBS volume scan.
+- `instance_connect` (Boolean) Enable instance connect.
+- `instance_ids_filter` (List of String) List of instance IDs filter.
+- `regions_filter` (List of String) List of regions filter.
+- `ssm` (Boolean) Enable SSM.
+- `tags_filter` (Map of String) Tags filter.
+
+
+### Nested Schema for `scan_configuration.ec2_scan_options.ebs_scan_options`
+
+Optional:
+
+- `max_asg_instances` (Number) Max ASG instances.
+- `target_instances_per_scanner` (Number) Target instances per scanner.
+
+
+
+
+### Nested Schema for `scan_configuration.event_scan_triggers`
+
+Optional:
+
+- `event_detail_type` (String) Event detail type.
+- `event_source` (String) Event source.
+- `scan_type` (String) Scan type.
diff --git a/examples/resources/mondoo_integration_aws_serverless/main.tf b/examples/resources/mondoo_integration_aws_serverless/main.tf
new file mode 100644
index 0000000..dd86232
--- /dev/null
+++ b/examples/resources/mondoo_integration_aws_serverless/main.tf
@@ -0,0 +1,12 @@
+terraform {
+ required_providers {
+ mondoo = {
+ source = "mondoohq/mondoo"
+ version = ">= 0.4.0"
+ }
+ aws = {
+ source = "hashicorp/aws"
+ version = "5.50.0"
+ }
+ }
+}
\ No newline at end of file
diff --git a/examples/resources/mondoo_integration_aws_serverless/resource.tf b/examples/resources/mondoo_integration_aws_serverless/resource.tf
new file mode 100644
index 0000000..3e475ae
--- /dev/null
+++ b/examples/resources/mondoo_integration_aws_serverless/resource.tf
@@ -0,0 +1,79 @@
+variable "mondoo_org" {
+ description = "Mondoo Organization"
+ type = string
+}
+
+variable "origin_aws_account" {
+ description = "Origin AWS Account"
+ type = string
+ default = "764453172858"
+}
+
+variable "aws_region" {
+ description = "AWS Region"
+ type = string
+ default = "us-east-1"
+}
+
+variable "aws_account_id" {
+ description = "value of the AWS account ID"
+ type = string
+}
+
+provider "mondoo" {
+ region = "us"
+}
+
+provider "aws" {
+ region = var.aws_region
+}
+
+data "aws_region" "current" {}
+
+# Create a new space
+resource "mondoo_space" "my_space" {
+ name = "AWS Terraform"
+ org_id = var.mondoo_org
+}
+
+# Setup the AWS integration
+resource "mondoo_integration_aws_serverless" "aws_serverless" {
+ space_id = mondoo_space.my_space.id
+ name = "AWS Integration"
+ region = data.aws_region.current.name
+ is_organization = false
+ console_sign_in_trigger = true
+ instance_state_change_trigger = true
+ account_ids = [var.aws_account_id]
+ scan_configuration = {
+ ec2_scan = true
+ ecr_scan = false
+ ecs_scan = false
+ cron_scan_in_hours = 24
+ ec2_scan_options = {
+ ssm = true
+ ebs_volume_scan = true
+ ebs_scan_options = {
+ target_instances_per_scanner = 5
+ max_asg_instances = 10
+ }
+ instance_connect = false
+ }
+ }
+}
+
+# for single account deploys
+resource "aws_cloudformation_stack" "mondoo_stack" {
+ name = "mondoo-stack"
+ template_url = "https://s3.amazonaws.com/mondoo.${data.aws_region.current.name}/mondoo-lambda-stackset-cf.json"
+ capabilities = ["CAPABILITY_NAMED_IAM"]
+ parameters = {
+ MondooIntegrationMrn = mondoo_integration_aws_serverless.aws_serverless.mrn
+ MondooToken = mondoo_integration_aws_serverless.aws_serverless.token
+ OriginAwsAccount = var.origin_aws_account
+ }
+}
+
+# for organisation wide deploys use aws_cloudformation_stack_set and aws_cloudformation_stack_set_instance instead of aws_cloudformation_stack
+# https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudformation_stack_set
+# https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudformation_stack_set_instance
diff --git a/internal/provider/gql.go b/internal/provider/gql.go
index a189250..14e5a63 100644
--- a/internal/provider/gql.go
+++ b/internal/provider/gql.go
@@ -418,8 +418,9 @@ func (c *ExtendedGqlClient) DeletePolicy(ctx context.Context, policyMrn string)
}
type CreateClientIntegrationPayload struct {
- Mrn mondoov1.String
- Name mondoov1.String
+ Mrn mondoov1.String
+ Name mondoov1.String
+ Token mondoov1.String
}
func (c *ExtendedGqlClient) CreateIntegration(ctx context.Context, spaceMrn, name string, typ mondoov1.ClientIntegrationType, opts mondoov1.ClientIntegrationConfigurationInput) (*CreateClientIntegrationPayload, error) {
@@ -448,6 +449,45 @@ func (c *ExtendedGqlClient) CreateIntegration(ctx context.Context, spaceMrn, nam
return &createMutation.CreateClientIntegration.Integration, nil
}
+type GetClientIntegrationTokenInput struct {
+ mrn mondoov1.String
+ longLivedToken mondoov1.Boolean
+}
+
+type ClientIntegrationToken struct {
+ Token mondoov1.String
+}
+
+func (c *ExtendedGqlClient) GetClientIntegrationToken(ctx context.Context, mrn string, longLivedToken bool) (*ClientIntegrationToken, error) {
+ // Define the response structure
+ var query struct {
+ ClientIntegrationToken ClientIntegrationToken `graphql:"getClientIntegrationToken(input: $input)"`
+ }
+
+ // Define the input variables
+ input := GetClientIntegrationTokenInput{
+ mrn: mondoov1.String(mrn),
+ longLivedToken: mondoov1.Boolean(longLivedToken),
+ }
+ variables := map[string]interface{}{
+ "input": input,
+ }
+
+ // Trace the input variables for debugging
+ tflog.Trace(ctx, "GetClientIntegrationTokenInput", map[string]interface{}{
+ "input": fmt.Sprintf("%+v", input),
+ })
+
+ // Perform the GraphQL query
+ err := c.Query(ctx, &query, variables)
+ if err != nil {
+ return nil, err
+ }
+
+ // Return the token from the response
+ return &query.ClientIntegrationToken, nil
+}
+
type UpdateIntegrationPayload struct {
Name mondoov1.String
}
diff --git a/internal/provider/integration_aws_serverless_resource.go b/internal/provider/integration_aws_serverless_resource.go
new file mode 100644
index 0000000..8b303e2
--- /dev/null
+++ b/internal/provider/integration_aws_serverless_resource.go
@@ -0,0 +1,442 @@
+package provider
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/hashicorp/terraform-plugin-framework/path"
+ "github.com/hashicorp/terraform-plugin-framework/resource"
+ "github.com/hashicorp/terraform-plugin-framework/resource/schema"
+ "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
+ "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+ mondoov1 "go.mondoo.com/mondoo-go"
+)
+
+var _ resource.Resource = (*integrationAwsServerlessResource)(nil)
+
+func NewIntegrationAwsServerlessResource() resource.Resource {
+ return &integrationAwsServerlessResource{}
+}
+
+type integrationAwsServerlessResource struct {
+ client *ExtendedGqlClient
+}
+
+type integrationAwsServerlessResourceModel struct {
+ // scope
+ SpaceId types.String `tfsdk:"space_id"`
+
+ // integration details
+ Mrn types.String `tfsdk:"mrn"`
+ Name types.String `tfsdk:"name"`
+ Token types.String `tfsdk:"token"`
+
+ Region types.String `tfsdk:"region"`
+ ScanConfiguration ScanConfigurationInput `tfsdk:"scan_configuration"`
+
+ // (Optional.)
+ AccountIDs types.List `tfsdk:"account_ids"`
+ // (Optional.)
+ IsOrganization types.Bool `tfsdk:"is_organization"`
+
+ // (Optional.)
+ ConsoleSignInTrigger types.Bool `tfsdk:"console_sign_in_trigger"`
+ // (Optional.)
+ InstanceStateChangeTrigger types.Bool `tfsdk:"instance_state_change_trigger"`
+}
+
+type ScanConfigurationInput struct {
+ // (Optional.)
+ Ec2Scan types.Bool `tfsdk:"ec2_scan"`
+ // (Optional.)
+ EcrScan types.Bool `tfsdk:"ecr_scan"`
+ // (Optional.)
+ EcsScan types.Bool `tfsdk:"ecs_scan"`
+ // (Optional.)
+ CronScaninHours types.Int64 `tfsdk:"cron_scan_in_hours"`
+ // (Optional.)
+ EventScanTriggers *[]*AWSEventPatternInput `tfsdk:"event_scan_triggers"`
+ // (Optional.)
+ Ec2ScanOptions *Ec2ScanOptionsInput `tfsdk:"ec2_scan_options"`
+}
+
+type AWSEventPatternInput struct {
+ // (Required.)
+ ScanType types.String `tfsdk:"scan_type"`
+ // (Required.)
+ EventSource types.String `tfsdk:"event_source"`
+ // (Required.)
+ EventDetailType types.String `tfsdk:"event_detail_type"`
+}
+
+type Ec2ScanOptionsInput struct {
+ // (Optional.)
+ Ssm types.Bool `tfsdk:"ssm"`
+ // (Optional.)
+ InstanceIDsFilter types.List `tfsdk:"instance_ids_filter"`
+ // (Optional.)
+ RegionsFilter types.List `tfsdk:"regions_filter"`
+ // (Optional.)
+ TagsFilter types.Map `tfsdk:"tags_filter"`
+ // (Optional.)
+ EbsVolumeScan types.Bool `tfsdk:"ebs_volume_scan"`
+ // (Optional.)
+ EbsScanOptions *EbsScanOptionsInput `tfsdk:"ebs_scan_options"`
+ // (Optional.)
+ InstanceConnect types.Bool `tfsdk:"instance_connect"`
+}
+
+type EbsScanOptionsInput struct {
+ // (Optional.)
+ TargetInstancesPerScanner types.Int64 `tfsdk:"target_instances_per_scanner"`
+ // (Optional.)
+ MaxAsgInstances types.Int64 `tfsdk:"max_asg_instances"`
+}
+
+func (m integrationAwsServerlessResourceModel) GetConfigurationOptions() *mondoov1.AWSConfigurationOptionsInput {
+ var opts *mondoov1.AWSConfigurationOptionsInput
+ var eventScanTriggers []*mondoov1.AWSEventPatternInput
+
+ if m.InstanceStateChangeTrigger.ValueBool() && m.ConsoleSignInTrigger.ValueBool() {
+ eventScanTriggers = append(eventScanTriggers, &mondoov1.AWSEventPatternInput{
+ ScanType: mondoov1.String("ALL"),
+ EventSource: mondoov1.String("aws.signin"),
+ EventDetailType: mondoov1.String("AWS Console Sign In via CloudTrail"),
+ })
+ eventScanTriggers = append(eventScanTriggers, &mondoov1.AWSEventPatternInput{
+ ScanType: mondoov1.String("ALL"),
+ EventSource: mondoov1.String("aws.ec2"),
+ EventDetailType: mondoov1.String("EC2 Instance State-change Notification"),
+ })
+ } else if m.ConsoleSignInTrigger.ValueBool() && !m.InstanceStateChangeTrigger.ValueBool() {
+ eventScanTriggers = append(eventScanTriggers, &mondoov1.AWSEventPatternInput{
+ ScanType: mondoov1.String("ALL"),
+ EventSource: mondoov1.String("aws.signin"),
+ EventDetailType: mondoov1.String("AWS Console Sign In via CloudTrail"),
+ })
+ } else if m.InstanceStateChangeTrigger.ValueBool() && !m.ConsoleSignInTrigger.ValueBool() {
+ eventScanTriggers = append(eventScanTriggers, &mondoov1.AWSEventPatternInput{
+ ScanType: mondoov1.String("ALL"),
+ EventSource: mondoov1.String("aws.ec2"),
+ EventDetailType: mondoov1.String("EC2 Instance State-change Notification"),
+ })
+ }
+
+ var instanceIdsFilter []mondoov1.String
+ instanceIds, _ := m.ScanConfiguration.Ec2ScanOptions.InstanceIDsFilter.ToListValue(context.Background())
+ instanceIds.ElementsAs(context.Background(), &instanceIdsFilter, true)
+
+ var RegionsFilter []mondoov1.String
+ regions, _ := m.ScanConfiguration.Ec2ScanOptions.RegionsFilter.ToListValue(context.Background())
+ regions.ElementsAs(context.Background(), &RegionsFilter, true)
+
+ var tagsFilter mondoov1.Map
+ tags, _ := m.ScanConfiguration.Ec2ScanOptions.TagsFilter.ToMapValue(context.Background())
+ tags.ElementsAs(context.Background(), &tagsFilter, true)
+
+ var accountIDs []mondoov1.String
+ accountIds, _ := m.AccountIDs.ToListValue(context.Background())
+ accountIds.ElementsAs(context.Background(), &accountIDs, true)
+
+ opts = &mondoov1.AWSConfigurationOptionsInput{
+ Region: mondoov1.String(m.Region.ValueString()),
+ IsOrganization: mondoov1.NewBooleanPtr(mondoov1.Boolean(m.IsOrganization.ValueBool())),
+ AccountIDs: &accountIDs,
+ ScanConfiguration: mondoov1.ScanConfigurationInput{
+ Ec2Scan: mondoov1.NewBooleanPtr(mondoov1.Boolean(m.ScanConfiguration.Ec2Scan.ValueBool())),
+ EcrScan: mondoov1.NewBooleanPtr(mondoov1.Boolean(m.ScanConfiguration.EcrScan.ValueBool())),
+ EcsScan: mondoov1.NewBooleanPtr(mondoov1.Boolean(m.ScanConfiguration.EcsScan.ValueBool())),
+ CronScaninHours: mondoov1.NewIntPtr(mondoov1.Int(m.ScanConfiguration.CronScaninHours.ValueInt64())),
+ EventScanTriggers: &eventScanTriggers,
+ Ec2ScanOptions: &mondoov1.Ec2ScanOptionsInput{
+ Ssm: mondoov1.NewBooleanPtr(mondoov1.Boolean(m.ScanConfiguration.Ec2ScanOptions.Ssm.ValueBool())),
+ InstanceIDsFilter: &instanceIdsFilter,
+ RegionsFilter: &RegionsFilter,
+ TagsFilter: &tagsFilter,
+ EbsVolumeScan: mondoov1.NewBooleanPtr(mondoov1.Boolean(m.ScanConfiguration.Ec2ScanOptions.EbsVolumeScan.ValueBool())),
+ EbsScanOptions: &mondoov1.EbsScanOptionsInput{
+ TargetInstancesPerScanner: mondoov1.NewIntPtr(mondoov1.Int(m.ScanConfiguration.Ec2ScanOptions.EbsScanOptions.TargetInstancesPerScanner.ValueInt64())),
+ MaxAsgInstances: mondoov1.NewIntPtr(mondoov1.Int(m.ScanConfiguration.Ec2ScanOptions.EbsScanOptions.MaxAsgInstances.ValueInt64())),
+ },
+ InstanceConnect: mondoov1.NewBooleanPtr(mondoov1.Boolean(m.ScanConfiguration.Ec2ScanOptions.InstanceConnect.ValueBool())),
+ },
+ },
+ }
+
+ return opts
+}
+
+func (r *integrationAwsServerlessResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_integration_aws_serverless"
+}
+
+func (r *integrationAwsServerlessResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
+ resp.Schema = schema.Schema{
+ MarkdownDescription: `Continuously scan AWS organization and accounts for misconfigurations and vulnerabilities.`,
+ Attributes: map[string]schema.Attribute{
+ "space_id": schema.StringAttribute{
+ MarkdownDescription: "Mondoo Space Identifier.",
+ Required: true,
+ },
+ "mrn": schema.StringAttribute{
+ Computed: true,
+ MarkdownDescription: "Integration identifier",
+ PlanModifiers: []planmodifier.String{
+ stringplanmodifier.UseStateForUnknown(),
+ },
+ },
+ "token": schema.StringAttribute{
+ Computed: true,
+ MarkdownDescription: "Integration token",
+ PlanModifiers: []planmodifier.String{
+ stringplanmodifier.UseStateForUnknown(),
+ },
+ },
+ "name": schema.StringAttribute{
+ MarkdownDescription: "Name of the integration.",
+ Required: true,
+ },
+ "region": schema.StringAttribute{
+ MarkdownDescription: "AWS region.",
+ Required: true,
+ },
+ "console_sign_in_trigger": schema.BoolAttribute{
+ MarkdownDescription: "Enable console sign in trigger.",
+ Optional: true,
+ },
+ "instance_state_change_trigger": schema.BoolAttribute{
+ MarkdownDescription: "Enable instance state change trigger.",
+ Optional: true,
+ },
+ "scan_configuration": schema.SingleNestedAttribute{
+ Required: true,
+ Attributes: map[string]schema.Attribute{
+ "ec2_scan": schema.BoolAttribute{
+ MarkdownDescription: "Enable EC2 scan.",
+ Optional: true,
+ },
+ "ecr_scan": schema.BoolAttribute{
+ MarkdownDescription: "Enable ECR scan.",
+ Optional: true,
+ },
+ "ecs_scan": schema.BoolAttribute{
+ MarkdownDescription: "Enable ECS scan.",
+ Optional: true,
+ },
+ "cron_scan_in_hours": schema.Int64Attribute{
+ MarkdownDescription: "Cron scan in hours.",
+ Optional: true,
+ },
+ "ec2_scan_options": schema.SingleNestedAttribute{
+ Required: true,
+ Attributes: map[string]schema.Attribute{
+ "ssm": schema.BoolAttribute{
+ MarkdownDescription: "Enable SSM.",
+ Optional: true,
+ },
+ "instance_ids_filter": schema.ListAttribute{
+ MarkdownDescription: "List of instance IDs filter.",
+ Optional: true,
+ ElementType: types.StringType,
+ },
+ "regions_filter": schema.ListAttribute{
+ MarkdownDescription: "List of regions filter.",
+ Optional: true,
+ ElementType: types.StringType,
+ },
+ "tags_filter": schema.MapAttribute{
+ MarkdownDescription: "Tags filter.",
+ Optional: true,
+ ElementType: types.StringType,
+ },
+ "ebs_volume_scan": schema.BoolAttribute{
+ MarkdownDescription: "Enable EBS volume scan.",
+ Optional: true,
+ },
+ "ebs_scan_options": schema.SingleNestedAttribute{
+ Required: true,
+ Attributes: map[string]schema.Attribute{
+ "target_instances_per_scanner": schema.Int64Attribute{
+ MarkdownDescription: "Target instances per scanner.",
+ Optional: true,
+ },
+ "max_asg_instances": schema.Int64Attribute{
+ MarkdownDescription: "Max ASG instances.",
+ Optional: true,
+ },
+ },
+ },
+ "instance_connect": schema.BoolAttribute{
+ MarkdownDescription: "Enable instance connect.",
+ Optional: true,
+ },
+ },
+ },
+ "event_scan_triggers": schema.SingleNestedAttribute{
+ Optional: true,
+ Attributes: map[string]schema.Attribute{
+ "scan_type": schema.StringAttribute{
+ MarkdownDescription: "Scan type.",
+ Optional: true,
+ },
+ "event_source": schema.StringAttribute{
+ MarkdownDescription: "Event source.",
+ Optional: true,
+ },
+ "event_detail_type": schema.StringAttribute{
+ MarkdownDescription: "Event detail type.",
+ Optional: true,
+ },
+ },
+ },
+ },
+ },
+ "account_ids": schema.ListAttribute{
+ MarkdownDescription: "List of AWS account IDs.",
+ Optional: true,
+ ElementType: types.StringType,
+ },
+ "is_organization": schema.BoolAttribute{
+ MarkdownDescription: "Is organization.",
+ Optional: true,
+ },
+ },
+ }
+}
+
+func (r *integrationAwsServerlessResource) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) {
+ // Prevent panic if the provider has not been configured.
+ if req.ProviderData == nil {
+ return
+ }
+
+ client, ok := req.ProviderData.(*mondoov1.Client)
+
+ if !ok {
+ resp.Diagnostics.AddError(
+ "Unexpected Resource Configure Type",
+ fmt.Sprintf("Expected *http.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData),
+ )
+
+ return
+ }
+
+ r.client = &ExtendedGqlClient{client}
+}
+
+func (r *integrationAwsServerlessResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
+ var data integrationAwsServerlessResourceModel
+
+ // Read Terraform plan data into the model
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
+
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ // Do GraphQL request to API to create the resource.
+ spaceMrn := ""
+ if data.SpaceId.ValueString() != "" {
+ spaceMrn = spacePrefix + data.SpaceId.ValueString()
+ }
+
+ var accountIDs []mondoov1.String
+ accountIds, _ := data.AccountIDs.ToListValue(context.Background())
+ accountIds.ElementsAs(context.Background(), &accountIDs, true)
+
+ // Check if both whitelist and blacklist are provided
+ if len(accountIDs) > 0 && data.IsOrganization.ValueBool() {
+ resp.Diagnostics.AddError("ConflictingAttributesError", "Cannot install CloudFormation Stack to both AWS organization and accounts.")
+ return
+ }
+
+ integration, err := r.client.CreateIntegration(ctx,
+ spaceMrn,
+ data.Name.ValueString(),
+ mondoov1.ClientIntegrationTypeAws,
+ mondoov1.ClientIntegrationConfigurationInput{
+ AwsConfigurationOptions: data.GetConfigurationOptions(),
+ })
+ if err != nil {
+ resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to create AWS integration, got error: %s", err))
+ return
+ }
+
+ // Save space mrn into the Terraform state.
+ data.Mrn = types.StringValue(string(integration.Mrn))
+ data.Name = types.StringValue(string(integration.Name))
+ data.SpaceId = types.StringValue(data.SpaceId.ValueString())
+ data.Token = types.StringValue(string(integration.Token))
+
+ // Save data into Terraform state
+ resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
+}
+
+func (r *integrationAwsServerlessResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
+ var data integrationAwsServerlessResourceModel
+
+ // Read Terraform prior state data into the model
+ resp.Diagnostics.Append(req.State.Get(ctx, &data)...)
+
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ // Read API call logic
+
+ // Save updated data into Terraform state
+ resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
+}
+
+func (r *integrationAwsServerlessResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
+ var data integrationAwsServerlessResourceModel
+
+ // Read Terraform plan data into the model
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
+
+ var accountIDs []mondoov1.String
+ accountIds, _ := data.AccountIDs.ToListValue(context.Background())
+ accountIds.ElementsAs(context.Background(), &accountIDs, true)
+
+ // Check if both whitelist and blacklist are provided
+ if len(accountIDs) > 0 && data.IsOrganization.ValueBool() {
+ resp.Diagnostics.AddError("ConflictingAttributesError", "Cannot install CloudFormation Stack to both AWS organization and accounts.")
+ return
+ }
+
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ // Do GraphQL request to API to update the resource.
+ opts := mondoov1.ClientIntegrationConfigurationInput{
+ AwsConfigurationOptions: data.GetConfigurationOptions(),
+ }
+
+ _, err := r.client.UpdateIntegration(ctx, data.Mrn.ValueString(), data.Name.ValueString(), mondoov1.ClientIntegrationTypeAws, opts)
+ if err != nil {
+ resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to update AWS integration, got error: %s", err))
+ return
+ }
+
+ // Save updated data into Terraform state
+ resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
+}
+
+func (r *integrationAwsServerlessResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
+ var data integrationAwsServerlessResourceModel
+
+ // Read Terraform prior state data into the model
+ resp.Diagnostics.Append(req.State.Get(ctx, &data)...)
+
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ // Delete API call logic
+}
+
+func (r *integrationAwsServerlessResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
+ resource.ImportStatePassthroughID(ctx, path.Root("mrn"), req, resp)
+}
diff --git a/internal/provider/provider.go b/internal/provider/provider.go
index d0e4143..91440f1 100644
--- a/internal/provider/provider.go
+++ b/internal/provider/provider.go
@@ -164,6 +164,7 @@ func (p *MondooProvider) Resources(ctx context.Context) []func() resource.Resour
NewScimGroupMappingResource,
NewIntegrationAzureResource,
NewIntegrationAwsResource,
+ NewIntegrationAwsServerlessResource,
NewIntegrationDomainResource,
NewIntegrationGcpResource,
NewIntegrationOciTenantResource,