From dc6aeab7ce42c8ec699075a6d1d2a221a6590733 Mon Sep 17 00:00:00 2001 From: Adam Tyler Date: Wed, 10 Aug 2022 12:32:30 -0400 Subject: [PATCH] feat: Add support for resource groups (#1396) --- client/client.go | 3 + client/mocks/mock_resourcegroups.go | 116 +++++++++++++ client/services.go | 9 + .../aws_resourcegroups_resource_groups.md | 14 ++ go.mod | 1 + go.sum | 2 + resources/provider/provider.go | 2 + resources/services/resourcegroups/gen.hcl | 54 ++++++ .../resourcegroups/resource_groups.go | 155 ++++++++++++++++++ .../resource_groups_mock_test.go | 61 +++++++ terraform/resourcegroups/local/main.tf | 5 + terraform/resourcegroups/local/variables.tf | 9 + .../resourcegroups/modules/test/provider.tf | 4 + .../modules/test/resourcegroups.tf | 20 +++ .../resourcegroups/modules/test/terraform.tf | 10 ++ .../resourcegroups/modules/test/variables.tf | 16 ++ 16 files changed, 481 insertions(+) create mode 100644 client/mocks/mock_resourcegroups.go create mode 100644 docs/tables/aws_resourcegroups_resource_groups.md create mode 100644 resources/services/resourcegroups/gen.hcl create mode 100644 resources/services/resourcegroups/resource_groups.go create mode 100644 resources/services/resourcegroups/resource_groups_mock_test.go create mode 100644 terraform/resourcegroups/local/main.tf create mode 100644 terraform/resourcegroups/local/variables.tf create mode 100644 terraform/resourcegroups/modules/test/provider.tf create mode 100644 terraform/resourcegroups/modules/test/resourcegroups.tf create mode 100644 terraform/resourcegroups/modules/test/terraform.tf create mode 100644 terraform/resourcegroups/modules/test/variables.tf diff --git a/client/client.go b/client/client.go index a1fcfcab9..34c26389a 100644 --- a/client/client.go +++ b/client/client.go @@ -61,6 +61,7 @@ import ( "github.com/aws/aws-sdk-go-v2/service/qldb" "github.com/aws/aws-sdk-go-v2/service/rds" "github.com/aws/aws-sdk-go-v2/service/redshift" + "github.com/aws/aws-sdk-go-v2/service/resourcegroups" "github.com/aws/aws-sdk-go-v2/service/route53" "github.com/aws/aws-sdk-go-v2/service/route53domains" "github.com/aws/aws-sdk-go-v2/service/s3" @@ -168,6 +169,7 @@ type Services struct { QLDB QLDBClient RDS RdsClient Redshift RedshiftClient + ResourceGroups ResourceGroupsClient Route53 Route53Client Route53Domains Route53DomainsClient S3 S3Client @@ -667,6 +669,7 @@ func initServices(region string, c aws.Config) Services { Organizations: organizations.NewFromConfig(awsCfg), QLDB: qldb.NewFromConfig(awsCfg), RDS: rds.NewFromConfig(awsCfg), + ResourceGroups: resourcegroups.NewFromConfig(awsCfg), Redshift: redshift.NewFromConfig(awsCfg), Route53: route53.NewFromConfig(awsCfg), Route53Domains: route53domains.NewFromConfig(awsCfg), diff --git a/client/mocks/mock_resourcegroups.go b/client/mocks/mock_resourcegroups.go new file mode 100644 index 000000000..70b913f99 --- /dev/null +++ b/client/mocks/mock_resourcegroups.go @@ -0,0 +1,116 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/cloudquery/cq-provider-aws/client (interfaces: ResourceGroupsClient) + +// Package mocks is a generated GoMock package. +package mocks + +import ( + context "context" + reflect "reflect" + + resourcegroups "github.com/aws/aws-sdk-go-v2/service/resourcegroups" + gomock "github.com/golang/mock/gomock" +) + +// MockResourceGroupsClient is a mock of ResourceGroupsClient interface. +type MockResourceGroupsClient struct { + ctrl *gomock.Controller + recorder *MockResourceGroupsClientMockRecorder +} + +// MockResourceGroupsClientMockRecorder is the mock recorder for MockResourceGroupsClient. +type MockResourceGroupsClientMockRecorder struct { + mock *MockResourceGroupsClient +} + +// NewMockResourceGroupsClient creates a new mock instance. +func NewMockResourceGroupsClient(ctrl *gomock.Controller) *MockResourceGroupsClient { + mock := &MockResourceGroupsClient{ctrl: ctrl} + mock.recorder = &MockResourceGroupsClientMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockResourceGroupsClient) EXPECT() *MockResourceGroupsClientMockRecorder { + return m.recorder +} + +// GetGroup mocks base method. +func (m *MockResourceGroupsClient) GetGroup(arg0 context.Context, arg1 *resourcegroups.GetGroupInput, arg2 ...func(*resourcegroups.Options)) (*resourcegroups.GetGroupOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetGroup", varargs...) + ret0, _ := ret[0].(*resourcegroups.GetGroupOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetGroup indicates an expected call of GetGroup. +func (mr *MockResourceGroupsClientMockRecorder) GetGroup(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetGroup", reflect.TypeOf((*MockResourceGroupsClient)(nil).GetGroup), varargs...) +} + +// GetGroupQuery mocks base method. +func (m *MockResourceGroupsClient) GetGroupQuery(arg0 context.Context, arg1 *resourcegroups.GetGroupQueryInput, arg2 ...func(*resourcegroups.Options)) (*resourcegroups.GetGroupQueryOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetGroupQuery", varargs...) + ret0, _ := ret[0].(*resourcegroups.GetGroupQueryOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetGroupQuery indicates an expected call of GetGroupQuery. +func (mr *MockResourceGroupsClientMockRecorder) GetGroupQuery(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetGroupQuery", reflect.TypeOf((*MockResourceGroupsClient)(nil).GetGroupQuery), varargs...) +} + +// GetTags mocks base method. +func (m *MockResourceGroupsClient) GetTags(arg0 context.Context, arg1 *resourcegroups.GetTagsInput, arg2 ...func(*resourcegroups.Options)) (*resourcegroups.GetTagsOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetTags", varargs...) + ret0, _ := ret[0].(*resourcegroups.GetTagsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetTags indicates an expected call of GetTags. +func (mr *MockResourceGroupsClientMockRecorder) GetTags(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTags", reflect.TypeOf((*MockResourceGroupsClient)(nil).GetTags), varargs...) +} + +// ListGroups mocks base method. +func (m *MockResourceGroupsClient) ListGroups(arg0 context.Context, arg1 *resourcegroups.ListGroupsInput, arg2 ...func(*resourcegroups.Options)) (*resourcegroups.ListGroupsOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListGroups", varargs...) + ret0, _ := ret[0].(*resourcegroups.ListGroupsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListGroups indicates an expected call of ListGroups. +func (mr *MockResourceGroupsClientMockRecorder) ListGroups(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListGroups", reflect.TypeOf((*MockResourceGroupsClient)(nil).ListGroups), varargs...) +} diff --git a/client/services.go b/client/services.go index afd3a1303..29ec7923f 100644 --- a/client/services.go +++ b/client/services.go @@ -51,6 +51,7 @@ import ( "github.com/aws/aws-sdk-go-v2/service/qldb" "github.com/aws/aws-sdk-go-v2/service/rds" "github.com/aws/aws-sdk-go-v2/service/redshift" + "github.com/aws/aws-sdk-go-v2/service/resourcegroups" "github.com/aws/aws-sdk-go-v2/service/route53" "github.com/aws/aws-sdk-go-v2/service/route53domains" "github.com/aws/aws-sdk-go-v2/service/s3" @@ -796,3 +797,11 @@ type KinesisClient interface { ListStreams(ctx context.Context, params *kinesis.ListStreamsInput, optFns ...func(*kinesis.Options)) (*kinesis.ListStreamsOutput, error) ListTagsForStream(ctx context.Context, params *kinesis.ListTagsForStreamInput, optFns ...func(*kinesis.Options)) (*kinesis.ListTagsForStreamOutput, error) } + +//go:generate mockgen -package=mocks -destination=./mocks/mock_resourcegroups.go . ResourceGroupsClient +type ResourceGroupsClient interface { + GetGroup(ctx context.Context, params *resourcegroups.GetGroupInput, optFns ...func(*resourcegroups.Options)) (*resourcegroups.GetGroupOutput, error) + GetGroupQuery(ctx context.Context, params *resourcegroups.GetGroupQueryInput, optFns ...func(*resourcegroups.Options)) (*resourcegroups.GetGroupQueryOutput, error) + GetTags(ctx context.Context, params *resourcegroups.GetTagsInput, optFns ...func(*resourcegroups.Options)) (*resourcegroups.GetTagsOutput, error) + ListGroups(ctx context.Context, params *resourcegroups.ListGroupsInput, optFns ...func(*resourcegroups.Options)) (*resourcegroups.ListGroupsOutput, error) +} diff --git a/docs/tables/aws_resourcegroups_resource_groups.md b/docs/tables/aws_resourcegroups_resource_groups.md new file mode 100644 index 000000000..8baf9534f --- /dev/null +++ b/docs/tables/aws_resourcegroups_resource_groups.md @@ -0,0 +1,14 @@ + +# Table: aws_resourcegroups_resource_groups + +## Columns +| Name | Type | Description | +| ------------- | ------------- | ----- | +|account_id|text|The AWS Account ID of the resource.| +|region|text|The AWS Region of the resource.| +|tags|jsonb|| +|arn|text|The ARN of the resource group| +|group|text|The name of the resource group| +|group_description|text|The description of the resource group| +|resource_query|text|The query that defines a group or a search| +|resource_query_type|text|The type of the query| diff --git a/go.mod b/go.mod index b2a8cbdee..74efbafc7 100644 --- a/go.mod +++ b/go.mod @@ -52,6 +52,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/qldb v1.14.8 github.com/aws/aws-sdk-go-v2/service/rds v1.21.5 github.com/aws/aws-sdk-go-v2/service/redshift v1.25.1 + github.com/aws/aws-sdk-go-v2/service/resourcegroups v1.12.9 github.com/aws/aws-sdk-go-v2/service/route53 v1.21.2 github.com/aws/aws-sdk-go-v2/service/route53domains v1.12.7 github.com/aws/aws-sdk-go-v2/service/s3 v1.27.1 diff --git a/go.sum b/go.sum index 03acd7b7c..febad0030 100644 --- a/go.sum +++ b/go.sum @@ -188,6 +188,8 @@ github.com/aws/aws-sdk-go-v2/service/rds v1.21.5 h1:FxgP8Ty+UMcnFfLDYATBxBBwNqxd github.com/aws/aws-sdk-go-v2/service/rds v1.21.5/go.mod h1:CETZ4xhuVW6rXcYVl9UIDaRPF1RDSjbr5IfTTCHswDM= github.com/aws/aws-sdk-go-v2/service/redshift v1.25.1 h1:pt62Je9eCVqDdlfB25LF9bnsuW24jyHqlpwpdQ4AEio= github.com/aws/aws-sdk-go-v2/service/redshift v1.25.1/go.mod h1:hb7YE8ERBjqEn3FV+xx4TVA1i/qX9aazglk+KBZK5lc= +github.com/aws/aws-sdk-go-v2/service/resourcegroups v1.12.9 h1:kz3eatV1DyQs28XMufhi7/Gk98F86pJm7liA430CiOA= +github.com/aws/aws-sdk-go-v2/service/resourcegroups v1.12.9/go.mod h1:kawkSDK0FqSCkzy89C6WQ+CsDixssVsPGe/Guh69N94= github.com/aws/aws-sdk-go-v2/service/route53 v1.21.2 h1:t7yn/jSMOVFAlCpJqFzivixMRPI/MySAcD0LhXdjbf4= github.com/aws/aws-sdk-go-v2/service/route53 v1.21.2/go.mod h1:ZBOkwr2JviKbUwZjhaUjQFaIbSx9XL0pQxNHaCqlMAU= github.com/aws/aws-sdk-go-v2/service/route53domains v1.12.7 h1:myfNXFwvCde6JZAfy6YoI9VMKhefNDjhMQTVGQWJ3nY= diff --git a/resources/provider/provider.go b/resources/provider/provider.go index 40144285c..d37141522 100644 --- a/resources/provider/provider.go +++ b/resources/provider/provider.go @@ -51,6 +51,7 @@ import ( "github.com/cloudquery/cq-provider-aws/resources/services/qldb" "github.com/cloudquery/cq-provider-aws/resources/services/rds" "github.com/cloudquery/cq-provider-aws/resources/services/redshift" + "github.com/cloudquery/cq-provider-aws/resources/services/resourcegroups" "github.com/cloudquery/cq-provider-aws/resources/services/route53" "github.com/cloudquery/cq-provider-aws/resources/services/s3" "github.com/cloudquery/cq-provider-aws/resources/services/sagemaker" @@ -238,6 +239,7 @@ func Provider() *provider.Provider { "redshift.clusters": redshift.RedshiftClusters(), "redshift.event_subscriptions": redshift.EventSubscriptions(), "redshift.subnet_groups": redshift.RedshiftSubnetGroups(), + "resourcegroups.resource_groups": resourcegroups.ResourceGroups(), "route53.domains": route53.Route53Domains(), "route53.health_checks": route53.Route53HealthChecks(), "route53.hosted_zones": route53.Route53HostedZones(), diff --git a/resources/services/resourcegroups/gen.hcl b/resources/services/resourcegroups/gen.hcl new file mode 100644 index 000000000..19bdc064d --- /dev/null +++ b/resources/services/resourcegroups/gen.hcl @@ -0,0 +1,54 @@ +//check-for-changes +service = "aws" +output_directory = "." +add_generate = true + +description_modifier "remove_read_only" { + words = [" This member is required."] +} + +resource "aws" "resourcegroups" "resource_groups" { + path = "../resourcegroups.ResourceGroupWrapper" + + ignoreError "IgnoreCommonErrors" { + path = "github.com/cloudquery/cq-provider-aws/client.IgnoreCommonErrors" + } + multiplex "AwsAccountRegion" { + path = "github.com/cloudquery/cq-provider-aws/client.ServiceAccountRegionMultiplexer" + params = ["resource-groups"] + } + deleteFilter "AccountRegionFilter" { + path = "github.com/cloudquery/cq-provider-aws/client.DeleteAccountRegionFilter" + } + + options { + primary_keys = ["arn"] + } + + column "group_arn" { + rename = "arn" + } + + column "group_name" { + rename = "group" + } + + userDefinedColumn "account_id" { + type = "string" + description = "The AWS Account ID of the resource." + resolver "resolveAWSAccount" { + path = "github.com/cloudquery/cq-provider-aws/client.ResolveAWSAccount" + } + } + userDefinedColumn "region" { + type = "string" + description = "The AWS Region of the resource." + resolver "resolveAWSRegion" { + path = "github.com/cloudquery/cq-provider-aws/client.ResolveAWSRegion" + } + } + userDefinedColumn "tags" { + type = "json" + generate_resolver = true + } +} diff --git a/resources/services/resourcegroups/resource_groups.go b/resources/services/resourcegroups/resource_groups.go new file mode 100644 index 000000000..27dde9c55 --- /dev/null +++ b/resources/services/resourcegroups/resource_groups.go @@ -0,0 +1,155 @@ +package resourcegroups + +import ( + "context" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/resourcegroups" + "github.com/aws/aws-sdk-go-v2/service/resourcegroups/types" + "github.com/cloudquery/cq-provider-aws/client" + "github.com/cloudquery/cq-provider-sdk/provider/diag" + "github.com/cloudquery/cq-provider-sdk/provider/schema" +) + +//go:generate cq-gen --resource resource_groups --config gen.hcl --output . +func ResourceGroups() *schema.Table { + return &schema.Table{ + Name: "aws_resourcegroups_resource_groups", + Resolver: fetchResourcegroupsResourceGroups, + Multiplex: client.ServiceAccountRegionMultiplexer("resource-groups"), + IgnoreError: client.IgnoreCommonErrors, + DeleteFilter: client.DeleteAccountRegionFilter, + Options: schema.TableCreationOptions{PrimaryKeys: []string{"arn"}}, + Columns: []schema.Column{ + { + Name: "account_id", + Description: "The AWS Account ID of the resource.", + Type: schema.TypeString, + Resolver: client.ResolveAWSAccount, + }, + { + Name: "region", + Description: "The AWS Region of the resource.", + Type: schema.TypeString, + Resolver: client.ResolveAWSRegion, + }, + { + Name: "tags", + Type: schema.TypeJSON, + Resolver: resolveResourcegroupsResourceGroupTags, + }, + { + Name: "arn", + Description: "The ARN of the resource group", + Type: schema.TypeString, + Resolver: schema.PathResolver("Group.GroupArn"), + }, + { + Name: "group", + Description: "The name of the resource group", + Type: schema.TypeString, + Resolver: schema.PathResolver("Group.Name"), + }, + { + Name: "group_description", + Description: "The description of the resource group", + Type: schema.TypeString, + Resolver: schema.PathResolver("Group.Description"), + }, + { + Name: "resource_query", + Description: "The query that defines a group or a search", + Type: schema.TypeString, + Resolver: schema.PathResolver("ResourceQuery.Query"), + }, + { + Name: "resource_query_type", + Description: "The type of the query", + Type: schema.TypeString, + Resolver: schema.PathResolver("ResourceQuery.Type"), + }, + }, + } +} + +// ==================================================================================================================== +// Table Resolver Functions +// ==================================================================================================================== + +func fetchResourcegroupsResourceGroups(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- interface{}) error { + return diag.WrapError(client.ListAndDetailResolver(ctx, meta, res, listResourceGroups, resourceGroupDetail)) +} +func resolveResourcegroupsResourceGroupTags(ctx context.Context, meta schema.ClientMeta, resource *schema.Resource, c schema.Column) error { + cl := meta.(*client.Client) + svc := cl.Services().ResourceGroups + group := resource.Item.(ResourceGroupWrapper) + input := resourcegroups.GetTagsInput{ + Arn: group.GroupArn, + } + output, err := svc.GetTags(ctx, &input, func(options *resourcegroups.Options) { + options.Region = cl.Region + }) + if err != nil { + return diag.WrapError(err) + } + return diag.WrapError(resource.Set(c.Name, output.Tags)) +} + +// ==================================================================================================================== +// User Defined Helpers +// ==================================================================================================================== + +type ResourceGroupWrapper struct { + *types.Group + *types.ResourceQuery +} + +func listResourceGroups(ctx context.Context, meta schema.ClientMeta, detailChan chan<- interface{}) error { + var config resourcegroups.ListGroupsInput + c := meta.(*client.Client) + svc := c.Services().ResourceGroups + for { + output, err := svc.ListGroups(ctx, &config, func(options *resourcegroups.Options) { + options.Region = c.Region + }) + if err != nil { + return diag.WrapError(err) + } + for _, item := range output.GroupIdentifiers { + detailChan <- item.GroupArn + } + if aws.ToString(output.NextToken) == "" { + break + } + config.NextToken = output.NextToken + } + return nil +} +func resourceGroupDetail(ctx context.Context, meta schema.ClientMeta, resultsChan chan<- interface{}, errorChan chan<- error, listInfo interface{}) { + c := meta.(*client.Client) + groupArn := listInfo.(*string) + svc := c.Services().ResourceGroups + groupResponse, err := svc.GetGroup(ctx, &resourcegroups.GetGroupInput{ + Group: groupArn, + }) + if err != nil { + if c.IsNotFoundError(err) { + return + } + errorChan <- diag.WrapError(err) + return + } + + input := resourcegroups.GetGroupQueryInput{ + Group: groupResponse.Group.GroupArn, + } + output, err := svc.GetGroupQuery(ctx, &input) + if err != nil { + errorChan <- diag.WrapError(err) + return + } + resultsChan <- ResourceGroupWrapper{ + groupResponse.Group, + output.GroupQuery.ResourceQuery, + } +} diff --git a/resources/services/resourcegroups/resource_groups_mock_test.go b/resources/services/resourcegroups/resource_groups_mock_test.go new file mode 100644 index 000000000..cdb4cde7e --- /dev/null +++ b/resources/services/resourcegroups/resource_groups_mock_test.go @@ -0,0 +1,61 @@ +package resourcegroups + +import ( + "testing" + + "github.com/aws/aws-sdk-go-v2/service/resourcegroups" + "github.com/aws/aws-sdk-go-v2/service/resourcegroups/types" + "github.com/cloudquery/cq-provider-aws/client" + "github.com/cloudquery/cq-provider-aws/client/mocks" + "github.com/cloudquery/faker/v3" + "github.com/golang/mock/gomock" +) + +func buildResourceGroupsMock(t *testing.T, ctrl *gomock.Controller) client.Services { + m := mocks.NewMockResourceGroupsClient(ctrl) + gId := types.GroupIdentifier{} + err := faker.FakeData(&gId) + if err != nil { + t.Fatal(err) + } + + groupResponse := types.Group{} + err = faker.FakeData(&groupResponse) + if err != nil { + t.Fatal(err) + } + + tagsResponse := resourcegroups.GetTagsOutput{} + err = faker.FakeData(&tagsResponse) + if err != nil { + t.Fatal(err) + } + + query := types.GroupQuery{} + err = faker.FakeData(&query) + if err != nil { + t.Fatal(err) + } + + m.EXPECT().ListGroups(gomock.Any(), gomock.Any(), gomock.Any()).Return( + &resourcegroups.ListGroupsOutput{ + GroupIdentifiers: []types.GroupIdentifier{gId}, + }, nil) + m.EXPECT().GetGroup(gomock.Any(), gomock.Any(), gomock.Any()).Return( + &resourcegroups.GetGroupOutput{ + Group: &groupResponse, + }, nil) + m.EXPECT().GetTags(gomock.Any(), gomock.Any(), gomock.Any()).Return(&tagsResponse, nil) + m.EXPECT().GetGroupQuery(gomock.Any(), gomock.Any(), gomock.Any()).Return( + &resourcegroups.GetGroupQueryOutput{ + GroupQuery: &query, + }, nil) + + return client.Services{ + ResourceGroups: m, + } +} + +func TestResourceGroups(t *testing.T) { + client.AwsMockTestHelper(t, ResourceGroups(), buildResourceGroupsMock, client.TestOptions{}) +} diff --git a/terraform/resourcegroups/local/main.tf b/terraform/resourcegroups/local/main.tf new file mode 100644 index 000000000..e150ecb98 --- /dev/null +++ b/terraform/resourcegroups/local/main.tf @@ -0,0 +1,5 @@ +module "demo" { + source = "../modules/test" + prefix = var.prefix + } + \ No newline at end of file diff --git a/terraform/resourcegroups/local/variables.tf b/terraform/resourcegroups/local/variables.tf new file mode 100644 index 000000000..096015333 --- /dev/null +++ b/terraform/resourcegroups/local/variables.tf @@ -0,0 +1,9 @@ +variable "prefix" { + description = "Prefix to use for all name resources" + type = string + validation { + condition = length(var.prefix) == 2 + error_message = "The prefix should be exactly two characters." + } + } + \ No newline at end of file diff --git a/terraform/resourcegroups/modules/test/provider.tf b/terraform/resourcegroups/modules/test/provider.tf new file mode 100644 index 000000000..319a068db --- /dev/null +++ b/terraform/resourcegroups/modules/test/provider.tf @@ -0,0 +1,4 @@ +provider "aws" { + region = "us-east-1" + } + \ No newline at end of file diff --git a/terraform/resourcegroups/modules/test/resourcegroups.tf b/terraform/resourcegroups/modules/test/resourcegroups.tf new file mode 100644 index 000000000..7f5e41971 --- /dev/null +++ b/terraform/resourcegroups/modules/test/resourcegroups.tf @@ -0,0 +1,20 @@ +resource "aws_resourcegroups_group" "test" { + name = "${var.prefix}-group" + description = "Test resource group" + + resource_query { + query = <