Skip to content

Commit

Permalink
Merge pull request #28314 from hashicorp/f-aws_auditmanager_account_r…
Browse files Browse the repository at this point in the history
…egistration

New Resource: `aws_auditmanager_account_registration`
  • Loading branch information
jar-b authored Dec 14, 2022
2 parents 6b50b56 + c7c2ad0 commit 9dc81df
Show file tree
Hide file tree
Showing 6 changed files with 453 additions and 2 deletions.
3 changes: 3 additions & 0 deletions .changelog/28314.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:new-resource
aws_auditmanager_account_registration
```
1 change: 1 addition & 0 deletions docs/acc-test-environment-variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ Environment variables (beyond standard AWS Go SDK ones) used by acceptance testi
| `APNS_VOIP_TOKEN_KEY` | Token key file content (.p8 format) for VOIP Apple Push Notification Service in Pinpoint testing. |
| `APNS_VOIP_TOKEN_KEY_ID` | Identifier for VOIP Apple Push Notification Service Token Key in Pinpoint testing. |
| `APPRUNNER_CUSTOM_DOMAIN` | A custom domain endpoint (root domain, subdomain, or wildcard) for AppRunner Custom Domain Association testing. |
| `AUDITMANAGER_DEREGISTER_ACCOUNT_ON_DESTROY` | Flag to execute tests that will disable AuditManager in the account upon destruction. |
| `AWS_ALTERNATE_ACCESS_KEY_ID` | AWS access key ID with access to a secondary AWS account for tests requiring multiple accounts. Requires `AWS_ALTERNATE_SECRET_ACCESS_KEY`. Conflicts with `AWS_ALTERNATE_PROFILE`. |
| `AWS_ALTERNATE_SECRET_ACCESS_KEY` | AWS secret access key with access to a secondary AWS account for tests requiring multiple accounts. Requires `AWS_ALTERNATE_ACCESS_KEY_ID`. Conflicts with `AWS_ALTERNATE_PROFILE`. |
| `AWS_ALTERNATE_PROFILE` | AWS profile with access to a secondary AWS account for tests requiring multiple accounts. Conflicts with `AWS_ALTERNATE_ACCESS_KEY_ID` and `AWS_ALTERNATE_SECRET_ACCESS_KEY`. |
Expand Down
191 changes: 191 additions & 0 deletions internal/service/auditmanager/account_registration.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
package auditmanager

import (
"context"

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/auditmanager"
awstypes "github.com/aws/aws-sdk-go-v2/service/auditmanager/types"
"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/types"
"github.com/hashicorp/terraform-provider-aws/internal/create"
"github.com/hashicorp/terraform-provider-aws/internal/flex"
"github.com/hashicorp/terraform-provider-aws/internal/framework"
"github.com/hashicorp/terraform-provider-aws/names"
)

func init() {
registerFrameworkResourceFactory(newResourceAccountRegistration)
}

func newResourceAccountRegistration(_ context.Context) (resource.ResourceWithConfigure, error) {
return &resourceAccountRegistration{}, nil
}

const (
ResNameAccountRegistration = "AccountRegistration"
)

type resourceAccountRegistration struct {
framework.ResourceWithConfigure
}

func (r *resourceAccountRegistration) Metadata(_ context.Context, request resource.MetadataRequest, response *resource.MetadataResponse) {
response.TypeName = "aws_auditmanager_account_registration"
}

func (r *resourceAccountRegistration) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
resp.Schema = schema.Schema{
Attributes: map[string]schema.Attribute{
"delegated_admin_account": schema.StringAttribute{
Optional: true,
},
"deregister_on_destroy": schema.BoolAttribute{
Optional: true,
},
"kms_key": schema.StringAttribute{
Optional: true,
},
"id": framework.IDAttribute(),
"status": schema.StringAttribute{
Computed: true,
},
},
}
}

func (r *resourceAccountRegistration) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
conn := r.Meta().AuditManagerClient
// Registration is applied per region, so use this as the ID
id := r.Meta().Region

var plan resourceAccountRegistrationData
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
if resp.Diagnostics.HasError() {
return
}

in := auditmanager.RegisterAccountInput{}
if !plan.DelegatedAdminAccount.IsNull() {
in.DelegatedAdminAccount = aws.String(plan.DelegatedAdminAccount.ValueString())
}
if !plan.KmsKey.IsNull() {
in.KmsKey = aws.String(plan.KmsKey.ValueString())
}
out, err := conn.RegisterAccount(ctx, &in)
if err != nil {
resp.Diagnostics.AddError(
create.ProblemStandardMessage(names.AuditManager, create.ErrActionCreating, ResNameAccountRegistration, id, nil),
err.Error(),
)
return
}

state := plan
state.ID = types.StringValue(id)
state.Status = flex.StringValueToFramework(ctx, out.Status)
resp.Diagnostics.Append(resp.State.Set(ctx, state)...)
}

func (r *resourceAccountRegistration) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
conn := r.Meta().AuditManagerClient

var state resourceAccountRegistrationData
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
if resp.Diagnostics.HasError() {
return
}

// There is no API to get account registration attributes like delegated admin account
// and KMS key. Read will instead call the GetAccountStatus API to confirm an active
// account status.
out, err := conn.GetAccountStatus(ctx, &auditmanager.GetAccountStatusInput{})
if err != nil {
resp.Diagnostics.AddError(
create.ProblemStandardMessage(names.AuditManager, create.ErrActionReading, ResNameAccountRegistration, state.ID.String(), nil),
err.Error(),
)
return
}
if out.Status == awstypes.AccountStatusInactive {
resp.State.RemoveResource(ctx)
return
}

state.Status = flex.StringValueToFramework(ctx, out.Status)
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
}

func (r *resourceAccountRegistration) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
conn := r.Meta().AuditManagerClient

var plan, state resourceAccountRegistrationData
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
if resp.Diagnostics.HasError() {
return
}

if !plan.DelegatedAdminAccount.Equal(state.DelegatedAdminAccount) ||
!plan.KmsKey.Equal(state.KmsKey) {
in := auditmanager.RegisterAccountInput{}
if !plan.DelegatedAdminAccount.IsNull() {
in.DelegatedAdminAccount = aws.String(plan.DelegatedAdminAccount.ValueString())
}
if !plan.KmsKey.IsNull() {
in.KmsKey = aws.String(plan.KmsKey.ValueString())
}
out, err := conn.RegisterAccount(ctx, &in)
if err != nil {
resp.Diagnostics.AddError(
create.ProblemStandardMessage(names.AuditManager, create.ErrActionUpdating, ResNameAccountRegistration, state.ID.String(), nil),
err.Error(),
)
return
}

state.DelegatedAdminAccount = plan.DelegatedAdminAccount
state.KmsKey = plan.KmsKey
state.Status = flex.StringValueToFramework(ctx, out.Status)
}

if !plan.DeregisterOnDestroy.Equal(state.DeregisterOnDestroy) {
state.DeregisterOnDestroy = plan.DeregisterOnDestroy
}

resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
}

func (r *resourceAccountRegistration) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
conn := r.Meta().AuditManagerClient

var state resourceAccountRegistrationData
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
if resp.Diagnostics.HasError() {
return
}

if state.DeregisterOnDestroy.ValueBool() {
_, err := conn.DeregisterAccount(ctx, &auditmanager.DeregisterAccountInput{})
if err != nil {
resp.Diagnostics.AddError(
create.ProblemStandardMessage(names.AuditManager, create.ErrActionDeleting, ResNameAccountRegistration, state.ID.String(), nil),
err.Error(),
)
}
}
}

func (r *resourceAccountRegistration) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp)
}

type resourceAccountRegistrationData struct {
DelegatedAdminAccount types.String `tfsdk:"delegated_admin_account"`
DeregisterOnDestroy types.Bool `tfsdk:"deregister_on_destroy"`
KmsKey types.String `tfsdk:"kms_key"`
ID types.String `tfsdk:"id"`
Status types.String `tfsdk:"status"`
}
Loading

0 comments on commit 9dc81df

Please sign in to comment.