mirror of
https://github.com/hanzokms/terraform-provider.git
synced 2026-10-30 20:29:45 +00:00
247 lines
11 KiB
Go
247 lines
11 KiB
Go
package resource
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
kmsclient "github.com/hanzokms/terraform-provider/internal/client"
|
|
|
|
"github.com/hashicorp/terraform-plugin-framework/attr"
|
|
"github.com/hashicorp/terraform-plugin-framework/diag"
|
|
"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-plugin-framework/types/basetypes"
|
|
)
|
|
|
|
// ExternalKmsAwsCredentialsModel describes the credentials data model.
|
|
type ExternalKmsAwsCredentialsModel struct {
|
|
AccessKeyId types.String `tfsdk:"access_key_id"`
|
|
SecretAccessKey types.String `tfsdk:"secret_access_key"`
|
|
RoleARN types.String `tfsdk:"role_arn"`
|
|
RoleExternalId types.String `tfsdk:"role_external_id"`
|
|
}
|
|
|
|
// ExternalKmsAwsConfigurationModel describes the configuration data model.
|
|
type ExternalKmsAwsConfigurationModel struct {
|
|
AwsRegion types.String `tfsdk:"aws_region"`
|
|
Type types.String `tfsdk:"type"`
|
|
Credential ExternalKmsAwsCredentialsModel `tfsdk:"credential"`
|
|
AwsKmsKeyId types.String `tfsdk:"aws_kms_key_id"`
|
|
}
|
|
|
|
const AwsExternalKmsAccessKeyType = "access-key"
|
|
const AwsExternalKmsAssumeRoleType = "assume-role"
|
|
|
|
func NewExternalKmsAwsResource() resource.Resource {
|
|
return &ExternalKmsBaseResource{
|
|
Provider: kmsclient.ExternalKmsProviderAWS,
|
|
ExternalKmsProviderName: "AWS",
|
|
ResourceTypeName: "_external_kms_aws",
|
|
ConfigurationAttributes: map[string]schema.Attribute{
|
|
"aws_region": schema.StringAttribute{
|
|
Required: true,
|
|
Description: "The AWS region where the KMS key is located",
|
|
},
|
|
"aws_kms_key_id": schema.StringAttribute{
|
|
Required: true,
|
|
Description: "The AWS KMS key ID to use for the external KMS. For more details, refer to the documentation here https://hanzo.ai/docs/documentation/platform/kms-configuration/aws-kms#param-aws-kms-key-id",
|
|
},
|
|
"type": schema.StringAttribute{
|
|
Required: true,
|
|
Description: fmt.Sprintf("The Authentication Type to use. Must be %s or %s", AwsExternalKmsAccessKeyType, AwsExternalKmsAssumeRoleType),
|
|
},
|
|
"credential": schema.SingleNestedAttribute{
|
|
Required: true,
|
|
Description: "The AWS credentials for the external KMS",
|
|
Attributes: map[string]schema.Attribute{
|
|
"access_key_id": schema.StringAttribute{
|
|
Optional: true,
|
|
Description: "The AWS Access Key ID used to authenticate requests to AWS services. Required for access-key type. For more details, refer to the documentation here https://hanzo.ai/docs/documentation/platform/kms-configuration/aws-kms#param-access-key-id",
|
|
Sensitive: true,
|
|
},
|
|
"secret_access_key": schema.StringAttribute{
|
|
Optional: true,
|
|
Description: "The AWS Secret Access Key associated with the Access Key ID to authenticate requests to AWS services. Required for access-key type. For more details, refer to the documentation here https://hanzo.ai/docs/documentation/platform/kms-configuration/aws-kms#param-secret-access-key",
|
|
Sensitive: true,
|
|
},
|
|
"role_external_id": schema.StringAttribute{
|
|
Optional: true,
|
|
Description: "The external ID of the role to assume for performing operations. Required for assume-role type. For more details, refer to the documentation here https://hanzo.ai/docs/documentation/platform/kms-configuration/aws-kms#param-assume-role-external-id",
|
|
Sensitive: true,
|
|
},
|
|
"role_arn": schema.StringAttribute{
|
|
Optional: true,
|
|
Description: "The Amazon Resource Name (ARN) of the IAM role to assume for performing operations. Kms will assume this role using AWS Security Token Service (STS). Required for assume-role type. For more details, refer to the documentation here https://hanzo.ai/docs/documentation/platform/kms-configuration/aws-kms#param-iam-role-arn-for-role-assumption",
|
|
Sensitive: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ReadConfigurationForCreateFromPlan: func(ctx context.Context, plan ExternalKmsBaseResourceModel) (map[string]any, diag.Diagnostics) {
|
|
configurationMap := make(map[string]any)
|
|
var diags diag.Diagnostics
|
|
|
|
var configuration ExternalKmsAwsConfigurationModel
|
|
diags = plan.Configuration.As(ctx, &configuration, basetypes.ObjectAsOptions{})
|
|
if diags.HasError() {
|
|
return nil, diags
|
|
}
|
|
|
|
credentialData := make(map[string]string)
|
|
|
|
if configuration.Type.ValueString() == AwsExternalKmsAccessKeyType {
|
|
if configuration.Credential.AccessKeyId.IsNull() || configuration.Credential.AccessKeyId.ValueString() == "" {
|
|
diags.AddError("Unable to create AWS external KMS", "Access key id field must be defined in access-key type")
|
|
return nil, diags
|
|
}
|
|
|
|
if configuration.Credential.SecretAccessKey.IsNull() || configuration.Credential.SecretAccessKey.ValueString() == "" {
|
|
diags.AddError("Unable to create AWS external KMS", "Secret access key field must be defined in access-key type")
|
|
return nil, diags
|
|
}
|
|
|
|
credentialData["accessKey"] = configuration.Credential.AccessKeyId.ValueString()
|
|
credentialData["secretKey"] = configuration.Credential.SecretAccessKey.ValueString()
|
|
} else if configuration.Type.ValueString() == AwsExternalKmsAssumeRoleType {
|
|
if configuration.Credential.RoleExternalId.IsNull() || configuration.Credential.RoleExternalId.ValueString() == "" {
|
|
diags.AddError("Unable to create AWS external KMS", "Role external id field must be defined in assume-role type")
|
|
return nil, diags
|
|
}
|
|
|
|
if configuration.Credential.RoleARN.IsNull() || configuration.Credential.RoleARN.ValueString() == "" {
|
|
diags.AddError("Unable to create AWS external KMS", "Role arn field must be defined in assume-role type")
|
|
return nil, diags
|
|
}
|
|
|
|
credentialData["assumeRoleArn"] = configuration.Credential.RoleARN.ValueString()
|
|
credentialData["externalId"] = configuration.Credential.RoleExternalId.ValueString()
|
|
} else {
|
|
diags.AddError("Invalid Authentication Type", "The 'type' attribute must be 'access-key' or 'assume-role'")
|
|
return nil, diags
|
|
}
|
|
|
|
configurationMap["credential"] = map[string]any{
|
|
"type": configuration.Type.ValueString(),
|
|
"data": credentialData,
|
|
}
|
|
configurationMap["awsRegion"] = configuration.AwsRegion.ValueString()
|
|
configurationMap["kmsKeyId"] = configuration.AwsKmsKeyId.ValueString()
|
|
|
|
return configurationMap, diags
|
|
},
|
|
ReadConfigurationForUpdateFromPlan: func(ctx context.Context, plan ExternalKmsBaseResourceModel, state ExternalKmsBaseResourceModel) (map[string]any, diag.Diagnostics) {
|
|
configurationMap := make(map[string]any)
|
|
|
|
var configurationFromPlan ExternalKmsAwsConfigurationModel
|
|
diags := plan.Configuration.As(ctx, &configurationFromPlan, basetypes.ObjectAsOptions{})
|
|
if diags.HasError() {
|
|
return nil, diags
|
|
}
|
|
|
|
var configurationFromState ExternalKmsAwsConfigurationModel
|
|
diags = state.Configuration.As(ctx, &configurationFromState, basetypes.ObjectAsOptions{})
|
|
if diags.HasError() {
|
|
return nil, diags
|
|
}
|
|
|
|
credentialData := make(map[string]string)
|
|
|
|
if configurationFromPlan.Type.ValueString() == AwsExternalKmsAccessKeyType {
|
|
accessKeyId := configurationFromPlan.Credential.AccessKeyId
|
|
if configurationFromPlan.Credential.AccessKeyId.IsUnknown() {
|
|
accessKeyId = configurationFromState.Credential.AccessKeyId
|
|
}
|
|
|
|
secretAccessKey := configurationFromPlan.Credential.SecretAccessKey
|
|
if configurationFromPlan.Credential.SecretAccessKey.IsUnknown() {
|
|
secretAccessKey = configurationFromState.Credential.SecretAccessKey
|
|
}
|
|
|
|
if accessKeyId.IsNull() || accessKeyId.ValueString() == "" {
|
|
diags.AddError("Unable to update AWS external KMS", "Access key id field must be defined in access-key type")
|
|
return nil, diags
|
|
}
|
|
|
|
if secretAccessKey.IsNull() || secretAccessKey.ValueString() == "" {
|
|
diags.AddError("Unable to update AWS external KMS", "Secret access key field must be defined in access-key type")
|
|
return nil, diags
|
|
}
|
|
|
|
credentialData["accessKey"] = accessKeyId.ValueString()
|
|
credentialData["secretKey"] = secretAccessKey.ValueString()
|
|
} else if configurationFromPlan.Type.ValueString() == AwsExternalKmsAssumeRoleType {
|
|
roleExternalId := configurationFromPlan.Credential.RoleExternalId
|
|
if configurationFromPlan.Credential.RoleExternalId.IsUnknown() {
|
|
roleExternalId = configurationFromState.Credential.RoleExternalId
|
|
}
|
|
|
|
roleArn := configurationFromPlan.Credential.RoleARN
|
|
if configurationFromPlan.Credential.RoleARN.IsUnknown() {
|
|
roleArn = configurationFromState.Credential.RoleARN
|
|
}
|
|
|
|
if roleExternalId.IsNull() || roleExternalId.ValueString() == "" {
|
|
diags.AddError("Unable to update AWS external KMS", "Role external id field must be defined in assume-role type")
|
|
return nil, diags
|
|
}
|
|
|
|
if roleArn.IsNull() || roleArn.ValueString() == "" {
|
|
diags.AddError("Unable to update AWS external KMS", "Role arn field must be defined in assume-role type")
|
|
return nil, diags
|
|
}
|
|
|
|
credentialData["assumeRoleArn"] = roleArn.ValueString()
|
|
credentialData["externalId"] = roleExternalId.ValueString()
|
|
} else {
|
|
diags.AddError("Invalid Authentication Type", "The 'type' attribute must be 'access-key' or 'assume-role'")
|
|
return nil, diags
|
|
}
|
|
configurationMap["credential"] = map[string]any{
|
|
"type": configurationFromPlan.Type.ValueString(),
|
|
"data": credentialData,
|
|
}
|
|
configurationMap["awsRegion"] = configurationFromPlan.AwsRegion.ValueString()
|
|
configurationMap["kmsKeyId"] = configurationFromPlan.AwsKmsKeyId.ValueString()
|
|
|
|
return configurationMap, diags
|
|
},
|
|
OverwriteConfigurationFields: func(state *ExternalKmsBaseResourceModel) diag.Diagnostics {
|
|
var diags diag.Diagnostics
|
|
|
|
configAttrs := state.Configuration.Attributes()
|
|
|
|
credentialTypes := map[string]attr.Type{
|
|
"access_key_id": types.StringType,
|
|
"secret_access_key": types.StringType,
|
|
"role_arn": types.StringType,
|
|
"role_external_id": types.StringType,
|
|
}
|
|
|
|
credentialConfig := map[string]attr.Value{
|
|
"access_key_id": types.StringNull(),
|
|
"secret_access_key": types.StringNull(),
|
|
"role_arn": types.StringNull(),
|
|
"role_external_id": types.StringNull(),
|
|
}
|
|
|
|
configAttrs["credential"] = types.ObjectValueMust(
|
|
credentialTypes,
|
|
credentialConfig,
|
|
)
|
|
|
|
configTypes := map[string]attr.Type{
|
|
"aws_region": types.StringType,
|
|
"aws_kms_key_id": types.StringType,
|
|
"type": types.StringType,
|
|
"credential": types.ObjectType{
|
|
AttrTypes: credentialTypes,
|
|
},
|
|
}
|
|
|
|
state.Configuration, diags = types.ObjectValue(configTypes, configAttrs)
|
|
|
|
return diags
|
|
},
|
|
}
|
|
}
|