Skip to content

Commit

Permalink
Merge branch 'main' into daniel/databricks-integration
Browse files Browse the repository at this point in the history
  • Loading branch information
DanielHougaard authored Nov 14, 2024
2 parents d0c54c9 + 3afbc04 commit addab2e
Show file tree
Hide file tree
Showing 9 changed files with 168 additions and 30 deletions.
12 changes: 9 additions & 3 deletions docs/resources/integration_aws_parameter_store.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,14 @@ resource "infisical_integration_aws_parameter_store" "parameter-store-integratio
secret_path = "<infisical-secrets-path>" // example, /folder, or /
parameter_store_path = "/example/secrets"
aws_region = "<aws-region>" // example, us-east-2
aws_region = "<aws-region>" // example, us-east-2
# AWS Authentication
access_key_id = "<aws-access-key-id>"
secret_access_key = "<aws-secret-access-key>"
# OR
assume_role_arn = "arn:aws:iam::<aws-account-id>:role/<role-name>"
// Optional
options = {
Expand All @@ -58,17 +63,18 @@ resource "infisical_integration_aws_parameter_store" "parameter-store-integratio

### Required

- `access_key_id` (String, Sensitive) The AWS access key ID. Used to authenticate with AWS Secrets Manager.
- `aws_region` (String) The AWS region to sync secrets to. (us-east-1, us-east-2, etc)
- `environment` (String) The slug of the environment to sync to AWS Parameter Store (prod, dev, staging, etc).
- `parameter_store_path` (String) The path in AWS Parameter Store to sync secrets to.
- `project_id` (String) The ID of your Infisical project.
- `secret_access_key` (String, Sensitive) The AWS secret access key. Used to authenticate with AWS Secrets Manager.
- `secret_path` (String) The secret path in Infisical to sync secrets from.

### Optional

- `access_key_id` (String, Sensitive) The AWS access key ID. Used to authenticate with AWS Parameter Store. You must either set secret_access_key and access_key_id, or set assume_role_arn to assume a role.
- `assume_role_arn` (String) The ARN of the role to assume when syncing secrets to AWS Parameter Store. You must either set secret_access_key and access_key_id, or set assume_role_arn to assume a role.
- `options` (Attributes) Integration options (see [below for nested schema](#nestedatt--options))
- `secret_access_key` (String, Sensitive) The AWS secret access key. Used to authenticate with AWS Parameter Store. You must either set secret_access_key and access_key_id, or set assume_role_arn to assume a role.

### Read-Only

Expand Down
8 changes: 6 additions & 2 deletions docs/resources/integration_aws_secrets_manager.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,11 @@ resource "infisical_integration_aws_secrets_manager" "secrets-manager-integratio
secrets_manager_path = "/example/secrets" # Only required if mapping_behavior is one-to-one
mapping_behavior = "one-to-one" # Optional, default is many-to-one
# AWS Authentication
access_key_id = "<aws-access-key-id>"
secret_access_key = "<aws-secret-access-key>"
# OR
assume_role_arn = "arn:aws:iam::<aws-account-id>:role/<role-name>"
options = {
secret_prefix = "<optional-prefix>"
Expand All @@ -58,17 +61,18 @@ resource "infisical_integration_aws_secrets_manager" "secrets-manager-integratio

### Required

- `access_key_id` (String, Sensitive) The AWS access key ID. Used to authenticate with AWS Secrets Manager.
- `aws_region` (String) The AWS region to sync secrets to. (us-east-1, us-east-2, etc)
- `environment` (String) The slug of the environment to sync to AWS Secrets Manager (prod, dev, staging, etc).
- `project_id` (String) The ID of your Infisical project.
- `secret_access_key` (String, Sensitive) The AWS secret access key. Used to authenticate with AWS Secrets Manager.
- `secret_path` (String) The secret path in Infisical to sync secrets from.

### Optional

- `access_key_id` (String, Sensitive) The AWS access key ID. Used to authenticate with AWS Secrets Manager. You must either set secret_access_key and access_key_id, or set assume_role_arn to assume a role.
- `assume_role_arn` (String) The ARN of the role to assume when syncing secrets to AWS Secrets Manager. You must either set secret_access_key and access_key_id, or set assume_role_arn to assume a role.
- `mapping_behavior` (String) The behavior of the mapping. Can be 'many-to-one' or 'one-to-one'. Many to One: All Infisical secrets will be mapped to a single AWS secret. One to One: Each Infisical secret will be mapped to its own AWS secret.
- `options` (Attributes) Integration options (see [below for nested schema](#nestedatt--options))
- `secret_access_key` (String, Sensitive) The AWS secret access key. Used to authenticate with AWS Secrets Manager. You must either set secret_access_key and access_key_id, or set assume_role_arn to assume a role.
- `secrets_manager_path` (String) The path in AWS Secrets Manager to sync secrets to. This is required if mapping_behavior is 'many-to-one'.

### Read-Only
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,14 @@ resource "infisical_integration_aws_parameter_store" "parameter-store-integratio
secret_path = "<infisical-secrets-path>" // example, /folder, or /
parameter_store_path = "/example/secrets"

aws_region = "<aws-region>" // example, us-east-2
aws_region = "<aws-region>" // example, us-east-2

# AWS Authentication
access_key_id = "<aws-access-key-id>"
secret_access_key = "<aws-secret-access-key>"
# OR
assume_role_arn = "arn:aws:iam::<aws-account-id>:role/<role-name>"


// Optional
options = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,11 @@ resource "infisical_integration_aws_secrets_manager" "secrets-manager-integratio
secrets_manager_path = "/example/secrets" # Only required if mapping_behavior is one-to-one
mapping_behavior = "one-to-one" # Optional, default is many-to-one

# AWS Authentication
access_key_id = "<aws-access-key-id>"
secret_access_key = "<aws-secret-access-key>"
# OR
assume_role_arn = "arn:aws:iam::<aws-account-id>:role/<role-name>"

options = {
secret_prefix = "<optional-prefix>"
Expand Down
11 changes: 6 additions & 5 deletions internal/client/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -1543,11 +1543,12 @@ type RevokeIdentityKubernetesAuthResponse struct {
}

type CreateIntegrationAuthRequest struct {
AccessId string `json:"accessId"`
AccessToken string `json:"accessToken"`
RefreshToken string `json:"refreshToken"`
ProjectID string `json:"workspaceId"`
Integration IntegrationAuthType `json:"integration"`
AccessId string `json:"accessId,omitempty"`
AccessToken string `json:"accessToken,omitempty"`
AWSAssumeIamRoleArn string `json:"awsAssumeIamRoleArn,omitempty"`
RefreshToken string `json:"refreshToken,omitempty"`
ProjectID string `json:"workspaceId"`
Integration IntegrationAuthType `json:"integration"`
URL string `json:"url"`
}

Expand Down
17 changes: 17 additions & 0 deletions internal/pkg/input/model.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package pkg

type AwsAuthenticationMethod string

const (
AwsAuthMethodAccessKey AwsAuthenticationMethod = "access_key"
AwsAuthMethodAssumeRole AwsAuthenticationMethod = "assume_role"
)

type AwsAccessKeyCredentials struct {
AccessKeyId string
SecretAccessKey string
}

type AwsAssumeRoleCredentials struct {
AssumeRoleArn string
}
31 changes: 31 additions & 0 deletions internal/pkg/input/validate-aws.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package pkg

import (
"fmt"

"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
)

func ValidateAwsInputCredentials(accessKeyId basetypes.StringValue, secretAccessKey basetypes.StringValue, assumeRoleArn basetypes.StringValue) (AwsAuthenticationMethod, error) {

// No credentials provided at all
if assumeRoleArn.ValueString() == "" && (accessKeyId.ValueString() == "" && secretAccessKey.ValueString() == "") {
return "", fmt.Errorf("No credentials provided. Either set access_key_id and secret_access_key, or assume_role_arn.")
}

if accessKeyId.ValueString() != "" && secretAccessKey.ValueString() != "" && assumeRoleArn.ValueString() != "" {
return "", fmt.Errorf("Both access_key_id and secret_access_key, and assume_role_arn are provided. Only one set of credentials can be used. Either set access_key_id and secret_access_key, or assume_role_arn.")
}

// Access key and secret key provided
if accessKeyId.ValueString() != "" && secretAccessKey.ValueString() != "" {
return AwsAuthMethodAccessKey, nil
}

// Assume role provided
if assumeRoleArn.ValueString() != "" {
return AwsAuthMethodAssumeRole, nil
}

return "", fmt.Errorf("Invalid credentials provided. Either set access_key_id and secret_access_key, or assume_role_arn.")
}
53 changes: 44 additions & 9 deletions internal/provider/resource/integration_aws_parameter_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"fmt"
infisical "terraform-provider-infisical/internal/client"
pkg "terraform-provider-infisical/internal/pkg/input"

"github.com/hashicorp/terraform-plugin-framework/attr"
"github.com/hashicorp/terraform-plugin-framework/resource"
Expand Down Expand Up @@ -45,6 +46,7 @@ type AwsParameterStoreOptions struct {
type IntegrationAWSParameterStoreResourceModel struct {
AccessKeyID types.String `tfsdk:"access_key_id"`
SecretAccessKey types.String `tfsdk:"secret_access_key"`
AssumeRoleArn types.String `tfsdk:"assume_role_arn"`
ProjectID types.String `tfsdk:"project_id"`

IntegrationAuthID types.String `tfsdk:"integration_auth_id"`
Expand Down Expand Up @@ -130,15 +132,21 @@ func (r *IntegrationAWSParameterStoreResource) Schema(_ context.Context, _ resou

"access_key_id": schema.StringAttribute{
Sensitive: true,
Required: true,
Description: "The AWS access key ID. Used to authenticate with AWS Secrets Manager.",
Optional: true,
Description: "The AWS access key ID. Used to authenticate with AWS Parameter Store. You must either set secret_access_key and access_key_id, or set assume_role_arn to assume a role.",
PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()},
},

"secret_access_key": schema.StringAttribute{
Sensitive: true,
Required: true,
Description: "The AWS secret access key. Used to authenticate with AWS Secrets Manager.",
Optional: true,
Description: "The AWS secret access key. Used to authenticate with AWS Parameter Store. You must either set secret_access_key and access_key_id, or set assume_role_arn to assume a role.",
PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()},
},

"assume_role_arn": schema.StringAttribute{
Optional: true,
Description: "The ARN of the role to assume when syncing secrets to AWS Parameter Store. You must either set secret_access_key and access_key_id, or set assume_role_arn to assume a role.",
PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()},
},

Expand Down Expand Up @@ -205,13 +213,30 @@ func (r *IntegrationAWSParameterStoreResource) Create(ctx context.Context, req r
return
}

// Create integration auth first
auth, err := r.client.CreateIntegrationAuth(infisical.CreateIntegrationAuthRequest{
AccessId: plan.AccessKeyID.ValueString(),
AccessToken: plan.SecretAccessKey.ValueString(),
authMethod, err := pkg.ValidateAwsInputCredentials(plan.AccessKeyID, plan.SecretAccessKey, plan.AssumeRoleArn)

if err != nil {
resp.Diagnostics.AddError(
"Error validating AWS credentials",
err.Error(),
)
return
}

createIntegrationAuthRequest := infisical.CreateIntegrationAuthRequest{
ProjectID: plan.ProjectID.ValueString(),
Integration: infisical.IntegrationAuthTypeAwsParameterStore,
})
}

if authMethod == pkg.AwsAuthMethodAccessKey {
createIntegrationAuthRequest.AccessId = plan.AccessKeyID.ValueString()
createIntegrationAuthRequest.AccessToken = plan.SecretAccessKey.ValueString()
} else if authMethod == pkg.AwsAuthMethodAssumeRole {
createIntegrationAuthRequest.AWSAssumeIamRoleArn = plan.AssumeRoleArn.ValueString()
}

// Create integration auth first
auth, err := r.client.CreateIntegrationAuth(createIntegrationAuthRequest)

if err != nil {
resp.Diagnostics.AddError(
Expand Down Expand Up @@ -367,6 +392,16 @@ func (r *IntegrationAWSParameterStoreResource) Update(ctx context.Context, req r
return
}

_, err := pkg.ValidateAwsInputCredentials(plan.AccessKeyID, plan.SecretAccessKey, plan.AssumeRoleArn)

if err != nil {
resp.Diagnostics.AddError(
"Error validating AWS credentials",
err.Error(),
)
return
}

var planOptions AwsParameterStoreOptions

if !plan.Options.IsNull() {
Expand Down
56 changes: 46 additions & 10 deletions internal/provider/resource/integration_aws_secrets_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"fmt"
infisical "terraform-provider-infisical/internal/client"
pkg "terraform-provider-infisical/internal/pkg/input"

"github.com/hashicorp/terraform-plugin-framework/attr"
"github.com/hashicorp/terraform-plugin-framework/resource"
Expand Down Expand Up @@ -45,7 +46,9 @@ type AwsSecretsManagerOptions struct {
type IntegrationAWSSecretsManagerResourceModel struct {
AccessKeyID types.String `tfsdk:"access_key_id"`
SecretAccessKey types.String `tfsdk:"secret_access_key"`
ProjectID types.String `tfsdk:"project_id"`
AssumeRoleArn types.String `tfsdk:"assume_role_arn"`

ProjectID types.String `tfsdk:"project_id"`

IntegrationAuthID types.String `tfsdk:"integration_auth_id"`
IntegrationID types.String `tfsdk:"integration_id"`
Expand Down Expand Up @@ -134,15 +137,21 @@ func (r *IntegrationAWSSecretsManagerResource) Schema(_ context.Context, _ resou

"access_key_id": schema.StringAttribute{
Sensitive: true,
Required: true,
Description: "The AWS access key ID. Used to authenticate with AWS Secrets Manager.",
Optional: true,
Description: "The AWS access key ID. Used to authenticate with AWS Secrets Manager. You must either set secret_access_key and access_key_id, or set assume_role_arn to assume a role.",
PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()},
},

"secret_access_key": schema.StringAttribute{
Sensitive: true,
Required: true,
Description: "The AWS secret access key. Used to authenticate with AWS Secrets Manager.",
Optional: true,
Description: "The AWS secret access key. Used to authenticate with AWS Secrets Manager. You must either set secret_access_key and access_key_id, or set assume_role_arn to assume a role.",
PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()},
},

"assume_role_arn": schema.StringAttribute{
Optional: true,
Description: "The ARN of the role to assume when syncing secrets to AWS Secrets Manager. You must either set secret_access_key and access_key_id, or set assume_role_arn to assume a role.",
PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()},
},

Expand Down Expand Up @@ -232,13 +241,30 @@ func (r *IntegrationAWSSecretsManagerResource) Create(ctx context.Context, req r
return
}

// Create integration auth first
auth, err := r.client.CreateIntegrationAuth(infisical.CreateIntegrationAuthRequest{
AccessId: plan.AccessKeyID.ValueString(),
AccessToken: plan.SecretAccessKey.ValueString(),
authMethod, err := pkg.ValidateAwsInputCredentials(plan.AccessKeyID, plan.SecretAccessKey, plan.AssumeRoleArn)

if err != nil {
resp.Diagnostics.AddError(
"Error validating AWS credentials",
err.Error(),
)
return
}

createIntegrationAuthRequest := infisical.CreateIntegrationAuthRequest{
ProjectID: plan.ProjectID.ValueString(),
Integration: infisical.IntegrationAuthTypeAwsSecretsManager,
})
}

if authMethod == pkg.AwsAuthMethodAccessKey {
createIntegrationAuthRequest.AccessId = plan.AccessKeyID.ValueString()
createIntegrationAuthRequest.AccessToken = plan.SecretAccessKey.ValueString()
} else if authMethod == pkg.AwsAuthMethodAssumeRole {
createIntegrationAuthRequest.AWSAssumeIamRoleArn = plan.AssumeRoleArn.ValueString()
}

// Create integration auth first
auth, err := r.client.CreateIntegrationAuth(createIntegrationAuthRequest)

if err != nil {
resp.Diagnostics.AddError(
Expand Down Expand Up @@ -408,6 +434,16 @@ func (r *IntegrationAWSSecretsManagerResource) Update(ctx context.Context, req r
return
}

_, err := pkg.ValidateAwsInputCredentials(plan.AccessKeyID, plan.SecretAccessKey, plan.AssumeRoleArn)

if err != nil {
resp.Diagnostics.AddError(
"Error validating AWS credentials",
err.Error(),
)
return
}

var planOptions AwsSecretsManagerOptions

if !plan.Options.IsNull() {
Expand Down

0 comments on commit addab2e

Please sign in to comment.