diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 0000000..73bb4d3
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,15 @@
+# See GitHub's documentation for more information on this file:
+# https://docs.github.com/en/code-security/supply-chain-security/keeping-your-dependencies-updated-automatically/configuration-options-for-dependency-updates
+version: 2
+updates:
+ - package-ecosystem: "gomod"
+ directory: "/"
+ schedule:
+ interval: "daily"
+ - package-ecosystem: "github-actions"
+ directory: "/"
+ schedule:
+ interval: "daily"
+ # TODO: Dependabot only updates hashicorp GHAs in the template repository, the following lines can be removed for consumers of this template
+ allow:
+ - dependency-name: "hashicorp/*"
diff --git a/.github/workflows/issue-comment-triage.yml b/.github/workflows/issue-comment-triage.yml
new file mode 100644
index 0000000..00017cd
--- /dev/null
+++ b/.github/workflows/issue-comment-triage.yml
@@ -0,0 +1,21 @@
+# DO NOT EDIT - This GitHub Workflow is managed by automation
+# https://github.com/hashicorp/terraform-devex-repos
+name: Issue Comment Triage
+
+on:
+ issue_comment:
+ types: [created]
+
+jobs:
+ issue_comment_triage:
+ runs-on: ubuntu-latest
+ env:
+ # issue_comment events are triggered by comments on issues and pull requests. Checking the
+ # value of github.event.issue.pull_request tells us whether the issue is an issue or is
+ # actually a pull request, allowing us to dynamically set the gh subcommand:
+ # https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#issue_comment-on-issues-only-or-pull-requests-only
+ COMMAND: ${{ github.event.issue.pull_request && 'pr' || 'issue' }}
+ GH_TOKEN: ${{ github.token }}
+ steps:
+ - name: 'Remove waiting-response on comment'
+ run: gh ${{ env.COMMAND }} edit ${{ github.event.issue.html_url }} --remove-label waiting-response
diff --git a/.github/workflows/lock.yml b/.github/workflows/lock.yml
new file mode 100644
index 0000000..358aed1
--- /dev/null
+++ b/.github/workflows/lock.yml
@@ -0,0 +1,21 @@
+# DO NOT EDIT - This GitHub Workflow is managed by automation
+# https://github.com/hashicorp/terraform-devex-repos
+name: 'Lock Threads'
+
+on:
+ schedule:
+ - cron: '43 20 * * *'
+
+jobs:
+ lock:
+ runs-on: ubuntu-latest
+ steps:
+ # NOTE: When TSCCR updates the GitHub action version, update the template workflow file to avoid drift:
+ # https://github.com/hashicorp/terraform-devex-repos/blob/main/modules/repo/workflows/lock.tftpl
+ - uses: dessant/lock-threads@1bf7ec25051fe7c00bdd17e6a7cf3d7bfb7dc771 # v5.0.1
+ with:
+ github-token: ${{ github.token }}
+ issue-inactive-days: '30'
+ issue-lock-reason: resolved
+ pr-inactive-days: '30'
+ pr-lock-reason: resolved
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 0000000..d38fd88
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,41 @@
+# Terraform Provider release workflow.
+name: Release
+
+# This GitHub action creates a release when a tag that matches the pattern
+# "v*" (e.g. v0.1.0) is created.
+on:
+ push:
+ tags:
+ - 'v*'
+
+# Releases need permissions to read and write the repository contents.
+# GitHub considers creating releases and uploading assets as writing contents.
+permissions:
+ contents: write
+
+jobs:
+ goreleaser:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+ with:
+ # Allow goreleaser to access older tag information.
+ fetch-depth: 0
+ - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2
+ with:
+ go-version-file: 'go.mod'
+ cache: true
+ - name: Import GPG key
+ uses: crazy-max/ghaction-import-gpg@01dd5d3ca463c7f10f7f4f7b4f177225ac661ee4 # v6.1.0
+ id: import_gpg
+ with:
+ gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
+ passphrase: ${{ secrets.PASSPHRASE }}
+ - name: Run GoReleaser
+ uses: goreleaser/goreleaser-action@286f3b13b1b49da4ac219696163fb8c1c93e1200 # v6.0.0
+ with:
+ args: release --clean
+ env:
+ # GitHub sets the GITHUB_TOKEN secret automatically.
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }}
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
new file mode 100644
index 0000000..adfcbd9
--- /dev/null
+++ b/.github/workflows/test.yml
@@ -0,0 +1,87 @@
+# Terraform Provider testing workflow.
+name: Tests
+
+# This GitHub action runs your tests for each pull request and push.
+# Optionally, you can turn it on using a schedule for regular testing.
+on:
+ pull_request:
+ paths-ignore:
+ - 'README.md'
+ push:
+ paths-ignore:
+ - 'README.md'
+
+# Testing only needs permissions to read the repository contents.
+permissions:
+ contents: read
+
+jobs:
+ # Ensure project builds before running testing matrix
+ build:
+ name: Build
+ runs-on: ubuntu-latest
+ timeout-minutes: 5
+ steps:
+ - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+ - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2
+ with:
+ go-version-file: 'go.mod'
+ cache: true
+ - run: go mod download
+ - run: go build -v .
+ - name: Run linters
+ uses: golangci/golangci-lint-action@aaa42aa0628b4ae2578232a66b541047968fac86 # v6.1.0
+ with:
+ version: latest
+
+ generate:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+ - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2
+ with:
+ go-version-file: 'go.mod'
+ cache: true
+ # Temporarily download Terraform 1.8 prerelease for function documentation support.
+ # When Terraform 1.8.0 final is released, this can be removed.
+ - uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3.1.2
+ with:
+ terraform_version: '1.8.0-alpha20240216'
+ terraform_wrapper: false
+ - run: go generate ./...
+ - name: git diff
+ run: |
+ git diff --compact-summary --exit-code || \
+ (echo; echo "Unexpected difference in directories after code generation. Run 'go generate ./...' command and commit."; exit 1)
+
+ # Run acceptance tests in a matrix with Terraform CLI versions
+ test:
+ name: Terraform Provider Acceptance Tests
+ needs: build
+ runs-on: ubuntu-latest
+ timeout-minutes: 15
+ strategy:
+ fail-fast: false
+ matrix:
+ # list whatever Terraform versions here you would like to support
+ terraform:
+ - '1.0.*'
+ - '1.1.*'
+ - '1.2.*'
+ - '1.3.*'
+ - '1.4.*'
+ steps:
+ - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+ - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2
+ with:
+ go-version-file: 'go.mod'
+ cache: true
+ - uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3.1.2
+ with:
+ terraform_version: ${{ matrix.terraform }}
+ terraform_wrapper: false
+ - run: go mod download
+ - env:
+ TF_ACC: "1"
+ run: go test -v -cover ./internal/provider/
+ timeout-minutes: 10
diff --git a/.gitignore b/.gitignore
index 6f72f89..74fa3e3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,11 @@
# If you prefer the allow list template instead of the deny list, see community template:
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
#
+
+# IDEs
+.idea/
+.vscode/
+
# Binaries for programs and plugins
*.exe
*.exe~
@@ -15,7 +20,7 @@
*.out
# Dependency directories (remove the comment below to include it)
-# vendor/
+vendor/
# Go workspace file
go.work
diff --git a/.golangci.yml b/.golangci.yml
new file mode 100644
index 0000000..66a3313
--- /dev/null
+++ b/.golangci.yml
@@ -0,0 +1,27 @@
+# Visit https://golangci-lint.run/ for usage documentation
+# and information on other useful linters
+issues:
+ max-per-linter: 0
+ max-same-issues: 0
+
+linters:
+ disable-all: true
+ enable:
+ - durationcheck
+ - errcheck
+ - exportloopref
+ - forcetypeassert
+ - godot
+ - gofmt
+ - gosimple
+ - ineffassign
+ - makezero
+ - misspell
+ - nilerr
+ - predeclared
+ - staticcheck
+ - tenv
+ - unconvert
+ - unparam
+ - unused
+ - govet
diff --git a/.goreleaser.yml b/.goreleaser.yml
new file mode 100644
index 0000000..150ddfa
--- /dev/null
+++ b/.goreleaser.yml
@@ -0,0 +1,61 @@
+# Visit https://goreleaser.com for documentation on how to customize this
+# behavior.
+version: 2
+before:
+ hooks:
+ # this is just an example and not a requirement for provider building/publishing
+ - go mod tidy
+builds:
+- env:
+ # goreleaser does not work with CGO, it could also complicate
+ # usage by users in CI/CD systems like HCP Terraform where
+ # they are unable to install libraries.
+ - CGO_ENABLED=0
+ mod_timestamp: '{{ .CommitTimestamp }}'
+ flags:
+ - -trimpath
+ ldflags:
+ - '-s -w -X main.version={{.Version}} -X main.commit={{.Commit}}'
+ goos:
+ - freebsd
+ - windows
+ - linux
+ - darwin
+ goarch:
+ - amd64
+ - '386'
+ - arm
+ - arm64
+ ignore:
+ - goos: darwin
+ goarch: '386'
+ binary: '{{ .ProjectName }}_v{{ .Version }}'
+archives:
+- format: zip
+ name_template: '{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}'
+checksum:
+ extra_files:
+ - glob: 'terraform-registry-manifest.json'
+ name_template: '{{ .ProjectName }}_{{ .Version }}_manifest.json'
+ name_template: '{{ .ProjectName }}_{{ .Version }}_SHA256SUMS'
+ algorithm: sha256
+signs:
+ - artifacts: checksum
+ args:
+ # if you are using this in a GitHub action or some other automated pipeline, you
+ # need to pass the batch flag to indicate its not interactive.
+ - "--batch"
+ - "--local-user"
+ - "{{ .Env.GPG_FINGERPRINT }}" # set this environment variable for your signing key
+ - "--output"
+ - "${signature}"
+ - "--detach-sign"
+ - "${artifact}"
+release:
+ extra_files:
+ - glob: 'terraform-registry-manifest.json'
+ name_template: '{{ .ProjectName }}_{{ .Version }}_manifest.json'
+ # If you want to manually examine the release before its live, uncomment this line:
+ # draft: true
+changelog:
+ disable: true
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..b76e247
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,3 @@
+## 0.1.0 (Unreleased)
+
+FEATURES:
diff --git a/GNUmakefile b/GNUmakefile
new file mode 100644
index 0000000..7771cd6
--- /dev/null
+++ b/GNUmakefile
@@ -0,0 +1,6 @@
+default: testacc
+
+# Run acceptance tests
+.PHONY: testacc
+testacc:
+ TF_ACC=1 go test ./... -v $(TESTARGS) -timeout 120m
diff --git a/README.md b/README.md
index 6c30324..64aa694 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,9 @@
-# terraform-provider-awsex
-A Terraform provider to extend the functionality of the AWS provider
+# Terraform AWS (Extensions) Provider
+
+This is a Terraform provider to extend the functionality of the [AWS Provider](https://registry.terraform.io/providers/hashicorp/aws/latest/docs).
+
+At time of creation, Hashicorp had few review resources dedicated to the provider.
+As a result, there are over 400 open pull requests, many older than 4 years.
+
+The purpose of this provider is to rapidly augment the official provider.
+This can also be used to rapidly experiment with new resources.
diff --git a/docs/index.md b/docs/index.md
new file mode 100644
index 0000000..26f5b66
--- /dev/null
+++ b/docs/index.md
@@ -0,0 +1,71 @@
+---
+# generated by https://github.com/hashicorp/terraform-plugin-docs
+page_title: "awsex Provider"
+subcategory: ""
+description: |-
+
+---
+
+# awsex Provider
+
+
+
+
+
+
+## Schema
+
+### Optional
+
+- `access_key` (String) The access key for API operations. You can retrieve this
+from the 'Security & Credentials' section of the AWS console.
+- `assume_role` (Attributes) (see [below for nested schema](#nestedatt--assume_role))
+- `assume_role_with_web_identity` (Attributes) (see [below for nested schema](#nestedatt--assume_role_with_web_identity))
+- `custom_ca_bundle` (String) File containing custom root and intermediate certificates. Can also be configured using the `AWS_CA_BUNDLE` environment variable. (Setting `ca_bundle` in the shared config file is not supported.)
+- `http_proxy` (String) URL of a proxy to use for HTTP requests when accessing the AWS API. Can also be set using the `HTTP_PROXY` or `http_proxy` environment variables.
+- `https_proxy` (String) URL of a proxy to use for HTTPS requests when accessing the AWS API. Can also be set using the `HTTPS_PROXY` or `https_proxy` environment variables.
+- `insecure` (Boolean) Explicitly allow the provider to perform "insecure" SSL requests. If omitted, default value is `false`
+- `max_retries` (Number) The maximum number of times an AWS API request is
+being executed. If the API request still fails, an error is
+thrown.
+- `no_proxy` (String) Comma-separated list of hosts that should not use HTTP or HTTPS proxies. Can also be set using the `NO_PROXY` or `no_proxy` environment variables.
+- `profile` (String) The profile for API operations. If not set, the default profile
+created with `aws configure` will be used.
+- `region` (String) The region where AWS operations will take place. Examples
+are us-east-1, us-west-2, etc.
+- `retry_mode` (String) Specifies how retries are attempted. Valid values are `standard` and `adaptive`. Can also be configured using the `AWS_RETRY_MODE` environment variable.
+- `secret_key` (String) The secret key for API operations. You can retrieve this
+from the 'Security & Credentials' section of the AWS console.
+- `shared_config_files` (List of String) List of paths to shared config files. If not set, defaults to [~/.aws/config].
+- `shared_credentials_files` (List of String) List of paths to shared credentials files. If not set, defaults to [~/.aws/credentials].
+- `token` (String) session token. A session token is only required if you are
+using temporary security credentials.
+
+
+### Nested Schema for `assume_role`
+
+Optional:
+
+- `duration` (String) The duration, between 15 minutes and 12 hours, of the role session. Valid time units are ns, us (or µs), ms, s, h, or m.
+- `external_id` (String) A unique identifier that might be required when you assume a role in another account.
+- `policy` (String) IAM Policy JSON describing further restricting permissions for the IAM Role being assumed.
+- `policy_arns` (Set of String) Amazon Resource Names (ARNs) of IAM Policies describing further restricting permissions for the IAM Role being assumed.
+- `role_arn` (String) Amazon Resource Name (ARN) of an IAM Role to assume prior to making API calls.
+- `session_name` (String) An identifier for the assumed role session.
+- `source_identity` (String) Source identity specified by the principal assuming the role.
+- `tags` (Map of String) Assume role session tags.
+- `transitive_tag_keys` (Set of String) Assume role session tag keys to pass to any subsequent sessions.
+
+
+
+### Nested Schema for `assume_role_with_web_identity`
+
+Optional:
+
+- `duration` (String) The duration, between 15 minutes and 12 hours, of the role session. Valid time units are ns, us (or µs), ms, s, h, or m.
+- `policy` (String) IAM Policy JSON describing further restricting permissions for the IAM Role being assumed.
+- `policy_arns` (Set of String) Amazon Resource Names (ARNs) of IAM Policies describing further restricting permissions for the IAM Role being assumed.
+- `role_arn` (String) Amazon Resource Name (ARN) of an IAM Role to assume prior to making API calls.
+- `session_name` (String) An identifier for the assumed role session.
+- `web_identity_token` (String)
+- `web_identity_token_file` (String)
diff --git a/docs/resources/cloudfront_distribution_invalidation.md b/docs/resources/cloudfront_distribution_invalidation.md
new file mode 100644
index 0000000..02838c6
--- /dev/null
+++ b/docs/resources/cloudfront_distribution_invalidation.md
@@ -0,0 +1,38 @@
+---
+# generated by https://github.com/hashicorp/terraform-plugin-docs
+page_title: "awsex_cloudfront_distribution_invalidation Resource - awsex"
+subcategory: ""
+description: |-
+
+---
+
+# awsex_cloudfront_distribution_invalidation (Resource)
+
+
+
+
+
+
+## Schema
+
+### Required
+
+- `distribution_id` (String) The Cloudfront Distribution ID where an invalidation should be created.
+- `paths` (Set of String) A list of paths to invalidate. Each path *must* start with `/`.
+
+### Optional
+
+- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
+- `triggers` (Map of String) A map of triggers that, when changed, will force Terraform to create a new invalidation.
+
+### Read-Only
+
+- `id` (String) The ID of the invalidation.
+- `status` (String) The status of the invalidation.
+
+
+### Nested Schema for `timeouts`
+
+Optional:
+
+- `create` (String) A string that can be [parsed as a duration](https://pkg.go.dev/time#ParseDuration) consisting of numbers and unit suffixes, such as "30s" or "2h45m". Valid time units are "s" (seconds), "m" (minutes), "h" (hours).
diff --git a/examples/README.md b/examples/README.md
new file mode 100644
index 0000000..026c42c
--- /dev/null
+++ b/examples/README.md
@@ -0,0 +1,9 @@
+# Examples
+
+This directory contains examples that are mostly used for documentation, but can also be run/tested manually via the Terraform CLI.
+
+The document generation tool looks for files in the following locations by default. All other *.tf files besides the ones mentioned below are ignored by the documentation tool. This is useful for creating examples that can run and/or ar testable even if some parts are not relevant for the documentation.
+
+* **provider/provider.tf** example file for the provider index page
+* **data-sources/`full data source name`/data-source.tf** example file for the named data source page
+* **resources/`full resource name`/resource.tf** example file for the named data source page
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..0af3338
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,121 @@
+module github.com/hashicorp/terraform-provider-awsex
+
+go 1.22.7
+
+require (
+ github.com/aws/aws-sdk-go-v2 v1.30.5
+ github.com/aws/aws-sdk-go-v2/service/cloudfront v1.38.7
+ github.com/hashicorp/aws-sdk-go-base/v2 v2.0.0-beta.56
+ github.com/hashicorp/terraform-plugin-docs v0.19.4
+ github.com/hashicorp/terraform-plugin-framework v1.11.0
+ github.com/hashicorp/terraform-plugin-framework-jsontypes v0.2.0
+ github.com/hashicorp/terraform-plugin-framework-timeouts v0.4.1
+ github.com/hashicorp/terraform-plugin-framework-timetypes v0.5.0
+ github.com/hashicorp/terraform-plugin-framework-validators v0.13.0
+ github.com/hashicorp/terraform-plugin-go v0.23.0
+ github.com/hashicorp/terraform-plugin-log v0.9.0
+ github.com/hashicorp/terraform-plugin-testing v1.10.0
+)
+
+require (
+ github.com/BurntSushi/toml v1.2.1 // indirect
+ github.com/Kunde21/markdownfmt/v3 v3.1.0 // indirect
+ github.com/Masterminds/goutils v1.1.1 // indirect
+ github.com/Masterminds/semver/v3 v3.2.0 // indirect
+ github.com/Masterminds/sprig/v3 v3.2.3 // indirect
+ github.com/ProtonMail/go-crypto v1.1.0-alpha.2 // indirect
+ github.com/agext/levenshtein v1.2.2 // indirect
+ github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
+ github.com/armon/go-radix v1.0.0 // indirect
+ github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.4 // indirect
+ github.com/aws/aws-sdk-go-v2/config v1.27.33 // indirect
+ github.com/aws/aws-sdk-go-v2/credentials v1.17.32 // indirect
+ github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.13 // indirect
+ github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.17 // indirect
+ github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.17 // indirect
+ github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect
+ github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.17 // indirect
+ github.com/aws/aws-sdk-go-v2/service/dynamodb v1.34.9 // indirect
+ github.com/aws/aws-sdk-go-v2/service/iam v1.35.2 // indirect
+ github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4 // indirect
+ github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.19 // indirect
+ github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.9.18 // indirect
+ github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.19 // indirect
+ github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.17 // indirect
+ github.com/aws/aws-sdk-go-v2/service/s3 v1.61.2 // indirect
+ github.com/aws/aws-sdk-go-v2/service/sqs v1.34.8 // indirect
+ github.com/aws/aws-sdk-go-v2/service/sso v1.22.7 // indirect
+ github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.7 // indirect
+ github.com/aws/aws-sdk-go-v2/service/sts v1.30.7 // indirect
+ github.com/aws/smithy-go v1.20.4 // indirect
+ github.com/bgentry/speakeasy v0.1.0 // indirect
+ github.com/bmatcuk/doublestar/v4 v4.6.1 // indirect
+ github.com/cloudflare/circl v1.3.7 // indirect
+ github.com/fatih/color v1.17.0 // indirect
+ github.com/go-logr/logr v1.4.2 // indirect
+ github.com/go-logr/stdr v1.2.2 // indirect
+ github.com/golang/protobuf v1.5.4 // indirect
+ github.com/google/go-cmp v0.6.0 // indirect
+ github.com/google/uuid v1.6.0 // indirect
+ github.com/hashicorp/cli v1.1.6 // indirect
+ github.com/hashicorp/errwrap v1.1.0 // indirect
+ github.com/hashicorp/go-checkpoint v0.5.0 // indirect
+ github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
+ github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 // indirect
+ github.com/hashicorp/go-hclog v1.6.3 // indirect
+ github.com/hashicorp/go-multierror v1.1.1 // indirect
+ github.com/hashicorp/go-plugin v1.6.0 // indirect
+ github.com/hashicorp/go-retryablehttp v0.7.7 // indirect
+ github.com/hashicorp/go-uuid v1.0.3 // indirect
+ github.com/hashicorp/go-version v1.7.0 // indirect
+ github.com/hashicorp/hc-install v0.8.0 // indirect
+ github.com/hashicorp/hcl/v2 v2.21.0 // indirect
+ github.com/hashicorp/logutils v1.0.0 // indirect
+ github.com/hashicorp/terraform-exec v0.21.0 // indirect
+ github.com/hashicorp/terraform-json v0.22.1 // indirect
+ github.com/hashicorp/terraform-plugin-sdk/v2 v2.34.0 // indirect
+ github.com/hashicorp/terraform-registry-address v0.2.3 // indirect
+ github.com/hashicorp/terraform-svchost v0.1.1 // indirect
+ github.com/hashicorp/yamux v0.1.1 // indirect
+ github.com/huandu/xstrings v1.3.3 // indirect
+ github.com/imdario/mergo v0.3.15 // indirect
+ github.com/jmespath/go-jmespath v0.4.0 // indirect
+ github.com/mattn/go-colorable v0.1.13 // indirect
+ github.com/mattn/go-isatty v0.0.20 // indirect
+ github.com/mattn/go-runewidth v0.0.9 // indirect
+ github.com/mitchellh/copystructure v1.2.0 // indirect
+ github.com/mitchellh/go-homedir v1.1.0 // indirect
+ github.com/mitchellh/go-testing-interface v1.14.1 // indirect
+ github.com/mitchellh/go-wordwrap v1.0.0 // indirect
+ github.com/mitchellh/mapstructure v1.5.0 // indirect
+ github.com/mitchellh/reflectwalk v1.0.2 // indirect
+ github.com/oklog/run v1.0.0 // indirect
+ github.com/posener/complete v1.2.3 // indirect
+ github.com/shopspring/decimal v1.3.1 // indirect
+ github.com/spf13/cast v1.5.0 // indirect
+ github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect
+ github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
+ github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
+ github.com/yuin/goldmark v1.7.1 // indirect
+ github.com/yuin/goldmark-meta v1.1.0 // indirect
+ github.com/zclconf/go-cty v1.15.0 // indirect
+ go.abhg.dev/goldmark/frontmatter v0.2.0 // indirect
+ go.opentelemetry.io/contrib/instrumentation/github.com/aws/aws-sdk-go-v2/otelaws v0.54.0 // indirect
+ go.opentelemetry.io/otel v1.30.0 // indirect
+ go.opentelemetry.io/otel/metric v1.30.0 // indirect
+ go.opentelemetry.io/otel/trace v1.30.0 // indirect
+ golang.org/x/crypto v0.27.0 // indirect
+ golang.org/x/exp v0.0.0-20230809150735-7b3493d9a819 // indirect
+ golang.org/x/mod v0.19.0 // indirect
+ golang.org/x/net v0.29.0 // indirect
+ golang.org/x/sync v0.8.0 // indirect
+ golang.org/x/sys v0.25.0 // indirect
+ golang.org/x/text v0.18.0 // indirect
+ golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
+ google.golang.org/appengine v1.6.8 // indirect
+ google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de // indirect
+ google.golang.org/grpc v1.63.2 // indirect
+ google.golang.org/protobuf v1.34.0 // indirect
+ gopkg.in/yaml.v2 v2.4.0 // indirect
+ gopkg.in/yaml.v3 v3.0.1 // indirect
+)
diff --git a/go.sum b/go.sum
new file mode 100644
index 0000000..989c6f2
--- /dev/null
+++ b/go.sum
@@ -0,0 +1,360 @@
+dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
+dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
+github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak=
+github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
+github.com/Kunde21/markdownfmt/v3 v3.1.0 h1:KiZu9LKs+wFFBQKhrZJrFZwtLnCCWJahL+S+E/3VnM0=
+github.com/Kunde21/markdownfmt/v3 v3.1.0/go.mod h1:tPXN1RTyOzJwhfHoon9wUr4HGYmWgVxSQN6VBJDkrVc=
+github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
+github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
+github.com/Masterminds/semver/v3 v3.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7YgDP83g=
+github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
+github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA=
+github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM=
+github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
+github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
+github.com/ProtonMail/go-crypto v1.1.0-alpha.2 h1:bkyFVUP+ROOARdgCiJzNQo2V2kiB97LyUpzH9P6Hrlg=
+github.com/ProtonMail/go-crypto v1.1.0-alpha.2/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE=
+github.com/agext/levenshtein v1.2.2 h1:0S/Yg6LYmFJ5stwQeRp6EeOcCbj7xiqQSdNelsXvaqE=
+github.com/agext/levenshtein v1.2.2/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
+github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec=
+github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY=
+github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4=
+github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI=
+github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
+github.com/aws/aws-sdk-go-v2 v1.30.5 h1:mWSRTwQAb0aLE17dSzztCVJWI9+cRMgqebndjwDyK0g=
+github.com/aws/aws-sdk-go-v2 v1.30.5/go.mod h1:CT+ZPWXbYrci8chcARI3OmI/qgd+f6WtuLOoaIA8PR0=
+github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.4 h1:70PVAiL15/aBMh5LThwgXdSQorVr91L127ttckI9QQU=
+github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.4/go.mod h1:/MQxMqci8tlqDH+pjmoLu1i0tbWCUP1hhyMRuFxpQCw=
+github.com/aws/aws-sdk-go-v2/config v1.27.33 h1:Nof9o/MsmH4oa0s2q9a0k7tMz5x/Yj5k06lDODWz3BU=
+github.com/aws/aws-sdk-go-v2/config v1.27.33/go.mod h1:kEqdYzRb8dd8Sy2pOdEbExTTF5v7ozEXX0McgPE7xks=
+github.com/aws/aws-sdk-go-v2/credentials v1.17.32 h1:7Cxhp/BnT2RcGy4VisJ9miUPecY+lyE9I8JvcZofn9I=
+github.com/aws/aws-sdk-go-v2/credentials v1.17.32/go.mod h1:P5/QMF3/DCHbXGEGkdbilXHsyTBX5D3HSwcrSc9p20I=
+github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.13 h1:pfQ2sqNpMVK6xz2RbqLEL0GH87JOwSxPV2rzm8Zsb74=
+github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.13/go.mod h1:NG7RXPUlqfsCLLFfi0+IpKN4sCB9D9fw/qTaSB+xRoU=
+github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.17 h1:pI7Bzt0BJtYA0N/JEC6B8fJ4RBrEMi1LBrkMdFYNSnQ=
+github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.17/go.mod h1:Dh5zzJYMtxfIjYW+/evjQ8uj2OyR/ve2KROHGHlSFqE=
+github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.17 h1:Mqr/V5gvrhA2gvgnF42Zh5iMiQNcOYthFYwCyrnuWlc=
+github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.17/go.mod h1:aLJpZlCmjE+V+KtN1q1uyZkfnUWpQGpbsn89XPKyzfU=
+github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ=
+github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc=
+github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.17 h1:Roo69qTpfu8OlJ2Tb7pAYVuF0CpuUMB0IYWwYP/4DZM=
+github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.17/go.mod h1:NcWPxQzGM1USQggaTVwz6VpqMZPX1CvDJLDh6jnOCa4=
+github.com/aws/aws-sdk-go-v2/service/cloudfront v1.38.7 h1:XAIxPw6FUxGv2xCB+7GapxB/H1LxfUogdzHbL6Pn3kI=
+github.com/aws/aws-sdk-go-v2/service/cloudfront v1.38.7/go.mod h1:R7mWBZ2a/EnExUNP+vkBBQGTz7+ZCcT16Mm6a9XZ/0A=
+github.com/aws/aws-sdk-go-v2/service/dynamodb v1.34.9 h1:jbqgtdKfAXebx2/l2UhDEe/jmmCIhaCO3HFK71M7VzM=
+github.com/aws/aws-sdk-go-v2/service/dynamodb v1.34.9/go.mod h1:N3YdUYxyxhiuAelUgCpSVBuBI1klobJxZrDtL+olu10=
+github.com/aws/aws-sdk-go-v2/service/iam v1.35.2 h1:CK5cIZTxza9ki/4eghMeLk32/UeVcPgyDBNiFfbcG0U=
+github.com/aws/aws-sdk-go-v2/service/iam v1.35.2/go.mod h1:PpmEOH3ZTQlDAezieBVdFMjPO1jovUMNPA4OpCtnwbY=
+github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4 h1:KypMCbLPPHEmf9DgMGw51jMj77VfGPAN2Kv4cfhlfgI=
+github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4/go.mod h1:Vz1JQXliGcQktFTN/LN6uGppAIRoLBR2bMvIMP0gOjc=
+github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.19 h1:FLMkfEiRjhgeDTCjjLoc3URo/TBkgeQbocA78lfkzSI=
+github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.19/go.mod h1:Vx+GucNSsdhaxs3aZIKfSUjKVGsxN25nX2SRcdhuw08=
+github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.9.18 h1:GACdEPdpBE59I7pbfvu0/Mw1wzstlP3QtPHklUxybFE=
+github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.9.18/go.mod h1:K+xV06+Wni4TSaOOJ1Y35e5tYOCUBYbebLKmJQQa8yY=
+github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.19 h1:rfprUlsdzgl7ZL2KlXiUAoJnI/VxfHCvDFr2QDFj6u4=
+github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.19/go.mod h1:SCWkEdRq8/7EK60NcvvQ6NXKuTcchAD4ROAsC37VEZE=
+github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.17 h1:u+EfGmksnJc/x5tq3A+OD7LrMbSSR/5TrKLvkdy/fhY=
+github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.17/go.mod h1:VaMx6302JHax2vHJWgRo+5n9zvbacs3bLU/23DNQrTY=
+github.com/aws/aws-sdk-go-v2/service/s3 v1.61.2 h1:Kp6PWAlXwP1UvIflkIP6MFZYBNDCa4mFCGtxrpICVOg=
+github.com/aws/aws-sdk-go-v2/service/s3 v1.61.2/go.mod h1:5FmD/Dqq57gP+XwaUnd5WFPipAuzrf0HmupX27Gvjvc=
+github.com/aws/aws-sdk-go-v2/service/sqs v1.34.8 h1:t3TzmBX0lpDNtLhl7vY97VMvLtxp/KTvjjj2X3s6SUQ=
+github.com/aws/aws-sdk-go-v2/service/sqs v1.34.8/go.mod h1:zn0Oy7oNni7XIGoAd6bHBTVtX06OrnpvT1kww8jxyi8=
+github.com/aws/aws-sdk-go-v2/service/sso v1.22.7 h1:pIaGg+08llrP7Q5aiz9ICWbY8cqhTkyy+0SHvfzQpTc=
+github.com/aws/aws-sdk-go-v2/service/sso v1.22.7/go.mod h1:eEygMHnTKH/3kNp9Jr1n3PdejuSNcgwLe1dWgQtO0VQ=
+github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.7 h1:/Cfdu0XV3mONYKaOt1Gr0k1KvQzkzPyiKUdlWJqy+J4=
+github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.7/go.mod h1:bCbAxKDqNvkHxRaIMnyVPXPo+OaPRwvmgzMxbz1VKSA=
+github.com/aws/aws-sdk-go-v2/service/sts v1.30.7 h1:NKTa1eqZYw8tiHSRGpP0VtTdub/8KNk8sDkNPFaOKDE=
+github.com/aws/aws-sdk-go-v2/service/sts v1.30.7/go.mod h1:NXi1dIAGteSaRLqYgarlhP/Ij0cFT+qmCwiJqWh/U5o=
+github.com/aws/smithy-go v1.20.4 h1:2HK1zBdPgRbjFOHlfeQZfpC4r72MOb9bZkiFwggKO+4=
+github.com/aws/smithy-go v1.20.4/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg=
+github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY=
+github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
+github.com/bmatcuk/doublestar/v4 v4.6.1 h1:FH9SifrbvJhnlQpztAx++wlkk70QBf0iBWDwNy7PA4I=
+github.com/bmatcuk/doublestar/v4 v4.6.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
+github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA=
+github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8=
+github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU=
+github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA=
+github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
+github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
+github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
+github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
+github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4=
+github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI=
+github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=
+github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps=
+github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=
+github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=
+github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU=
+github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow=
+github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZtys=
+github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXYjuz9i5OEY=
+github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
+github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
+github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
+github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
+github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
+github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
+github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
+github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
+github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
+github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
+github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
+github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
+github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
+github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
+github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/hashicorp/aws-sdk-go-base/v2 v2.0.0-beta.56 h1:Ox8WdpEBNU9YbEjbJvbGU5NqT3TQxICAvhUEGSgyldM=
+github.com/hashicorp/aws-sdk-go-base/v2 v2.0.0-beta.56/go.mod h1:cr1HCixlKU5P/sXAluEaAEFpL/Kh43MVNSj3nHSYyo8=
+github.com/hashicorp/cli v1.1.6 h1:CMOV+/LJfL1tXCOKrgAX0uRKnzjj/mpmqNXloRSy2K8=
+github.com/hashicorp/cli v1.1.6/go.mod h1:MPon5QYlgjjo0BSoAiN0ESeT5fRzDjVRp+uioJ0piz4=
+github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
+github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
+github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
+github.com/hashicorp/go-checkpoint v0.5.0 h1:MFYpPZCnQqQTE18jFwSII6eUQrD/oxMFp3mlgcqk5mU=
+github.com/hashicorp/go-checkpoint v0.5.0/go.mod h1:7nfLNL10NsxqO4iWuW6tWW0HjZuDrwkBuEQsVcpCOgg=
+github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
+github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
+github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
+github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 h1:1/D3zfFHttUKaCaGKZ/dR2roBXv0vKbSCnssIldfQdI=
+github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320/go.mod h1:EiZBMaudVLy8fmjf9Npq1dq9RalhveqZG5w/yz3mHWs=
+github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k=
+github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
+github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
+github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
+github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
+github.com/hashicorp/go-plugin v1.6.0 h1:wgd4KxHJTVGGqWBq4QPB1i5BZNEx9BR8+OFmHDmTk8A=
+github.com/hashicorp/go-plugin v1.6.0/go.mod h1:lBS5MtSSBZk0SHc66KACcjjlU6WzEVP/8pwz68aMkCI=
+github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU=
+github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk=
+github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
+github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
+github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
+github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY=
+github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
+github.com/hashicorp/hc-install v0.8.0 h1:LdpZeXkZYMQhoKPCecJHlKvUkQFixN/nvyR1CdfOLjI=
+github.com/hashicorp/hc-install v0.8.0/go.mod h1:+MwJYjDfCruSD/udvBmRB22Nlkwwkwf5sAB6uTIhSaU=
+github.com/hashicorp/hcl/v2 v2.21.0 h1:lve4q/o/2rqwYOgUg3y3V2YPyD1/zkCLGjIV74Jit14=
+github.com/hashicorp/hcl/v2 v2.21.0/go.mod h1:62ZYHrXgPoX8xBnzl8QzbWq4dyDsDtfCRgIq1rbJEvA=
+github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y=
+github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
+github.com/hashicorp/terraform-exec v0.21.0 h1:uNkLAe95ey5Uux6KJdua6+cv8asgILFVWkd/RG0D2XQ=
+github.com/hashicorp/terraform-exec v0.21.0/go.mod h1:1PPeMYou+KDUSSeRE9szMZ/oHf4fYUmB923Wzbq1ICg=
+github.com/hashicorp/terraform-json v0.22.1 h1:xft84GZR0QzjPVWs4lRUwvTcPnegqlyS7orfb5Ltvec=
+github.com/hashicorp/terraform-json v0.22.1/go.mod h1:JbWSQCLFSXFFhg42T7l9iJwdGXBYV8fmmD6o/ML4p3A=
+github.com/hashicorp/terraform-plugin-docs v0.19.4 h1:G3Bgo7J22OMtegIgn8Cd/CaSeyEljqjH3G39w28JK4c=
+github.com/hashicorp/terraform-plugin-docs v0.19.4/go.mod h1:4pLASsatTmRynVzsjEhbXZ6s7xBlUw/2Kt0zfrq8HxA=
+github.com/hashicorp/terraform-plugin-framework v1.11.0 h1:M7+9zBArexHFXDx/pKTxjE6n/2UCXY6b8FIq9ZYhwfE=
+github.com/hashicorp/terraform-plugin-framework v1.11.0/go.mod h1:qBXLDn69kM97NNVi/MQ9qgd1uWWsVftGSnygYG1tImM=
+github.com/hashicorp/terraform-plugin-framework-jsontypes v0.2.0 h1:SJXL5FfJJm17554Kpt9jFXngdM6fXbnUnZ6iT2IeiYA=
+github.com/hashicorp/terraform-plugin-framework-jsontypes v0.2.0/go.mod h1:p0phD0IYhsu9bR4+6OetVvvH59I6LwjXGnTVEr8ox6E=
+github.com/hashicorp/terraform-plugin-framework-timeouts v0.4.1 h1:gm5b1kHgFFhaKFhm4h2TgvMUlNzFAtUqlcOWnWPm+9E=
+github.com/hashicorp/terraform-plugin-framework-timeouts v0.4.1/go.mod h1:MsjL1sQ9L7wGwzJ5RjcI6FzEMdyoBnw+XK8ZnOvQOLY=
+github.com/hashicorp/terraform-plugin-framework-timetypes v0.5.0 h1:v3DapR8gsp3EM8fKMh6up9cJUFQ2iRaFsYLP8UJnCco=
+github.com/hashicorp/terraform-plugin-framework-timetypes v0.5.0/go.mod h1:c3PnGE9pHBDfdEVG9t1S1C9ia5LW+gkFR0CygXlM8ak=
+github.com/hashicorp/terraform-plugin-framework-validators v0.13.0 h1:bxZfGo9DIUoLLtHMElsu+zwqI4IsMZQBRRy4iLzZJ8E=
+github.com/hashicorp/terraform-plugin-framework-validators v0.13.0/go.mod h1:wGeI02gEhj9nPANU62F2jCaHjXulejm/X+af4PdZaNo=
+github.com/hashicorp/terraform-plugin-go v0.23.0 h1:AALVuU1gD1kPb48aPQUjug9Ir/125t+AAurhqphJ2Co=
+github.com/hashicorp/terraform-plugin-go v0.23.0/go.mod h1:1E3Cr9h2vMlahWMbsSEcNrOCxovCZhOOIXjFHbjc/lQ=
+github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0=
+github.com/hashicorp/terraform-plugin-log v0.9.0/go.mod h1:rKL8egZQ/eXSyDqzLUuwUYLVdlYeamldAHSxjUFADow=
+github.com/hashicorp/terraform-plugin-sdk/v2 v2.34.0 h1:kJiWGx2kiQVo97Y5IOGR4EMcZ8DtMswHhUuFibsCQQE=
+github.com/hashicorp/terraform-plugin-sdk/v2 v2.34.0/go.mod h1:sl/UoabMc37HA6ICVMmGO+/0wofkVIRxf+BMb/dnoIg=
+github.com/hashicorp/terraform-plugin-testing v1.10.0 h1:2+tmRNhvnfE4Bs8rB6v58S/VpqzGC6RCh9Y8ujdn+aw=
+github.com/hashicorp/terraform-plugin-testing v1.10.0/go.mod h1:iWRW3+loP33WMch2P/TEyCxxct/ZEcCGMquSLSCVsrc=
+github.com/hashicorp/terraform-registry-address v0.2.3 h1:2TAiKJ1A3MAkZlH1YI/aTVcLZRu7JseiXNRHbOAyoTI=
+github.com/hashicorp/terraform-registry-address v0.2.3/go.mod h1:lFHA76T8jfQteVfT7caREqguFrW3c4MFSPhZB7HHgUM=
+github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ=
+github.com/hashicorp/terraform-svchost v0.1.1/go.mod h1:mNsjQfZyf/Jhz35v6/0LWcv26+X7JPS+buii2c9/ctc=
+github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE=
+github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
+github.com/huandu/xstrings v1.3.3 h1:/Gcsuc1x8JVbJ9/rlye4xZnVAbEkGauT8lbebqcQws4=
+github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
+github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
+github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM=
+github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
+github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
+github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
+github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c=
+github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo=
+github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
+github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
+github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
+github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
+github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
+github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
+github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
+github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
+github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
+github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
+github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
+github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
+github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
+github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
+github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
+github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
+github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
+github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
+github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
+github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
+github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
+github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
+github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
+github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
+github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
+github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU=
+github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8=
+github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4=
+github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
+github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
+github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
+github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
+github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
+github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
+github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw=
+github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
+github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4=
+github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/posener/complete v1.2.3 h1:NP0eAhjcjImqslEwo/1hq7gpajME0fTLTezBKDqfXqo=
+github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=
+github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
+github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
+github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8=
+github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
+github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
+github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
+github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
+github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L3A=
+github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo=
+github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
+github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
+github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
+github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
+github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
+github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
+github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
+github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI=
+github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
+github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8=
+github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok=
+github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
+github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
+github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
+github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
+github.com/yuin/goldmark v1.7.1 h1:3bajkSilaCbjdKVsKdZjZCLBNPL9pYzrCakKaf4U49U=
+github.com/yuin/goldmark v1.7.1/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E=
+github.com/yuin/goldmark-meta v1.1.0 h1:pWw+JLHGZe8Rk0EGsMVssiNb/AaPMHfSRszZeUeiOUc=
+github.com/yuin/goldmark-meta v1.1.0/go.mod h1:U4spWENafuA7Zyg+Lj5RqK/MF+ovMYtBvXi1lBb2VP0=
+github.com/zclconf/go-cty v1.15.0 h1:tTCRWxsexYUmtt/wVxgDClUe+uQusuI443uL6e+5sXQ=
+github.com/zclconf/go-cty v1.15.0/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE=
+github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940 h1:4r45xpDWB6ZMSMNJFMOjqrGHynW3DIBuR2H9j0ug+Mo=
+github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940/go.mod h1:CmBdvvj3nqzfzJ6nTCIwDTPZ56aVGvDrmztiO5g3qrM=
+go.abhg.dev/goldmark/frontmatter v0.2.0 h1:P8kPG0YkL12+aYk2yU3xHv4tcXzeVnN+gU0tJ5JnxRw=
+go.abhg.dev/goldmark/frontmatter v0.2.0/go.mod h1:XqrEkZuM57djk7zrlRUB02x8I5J0px76YjkOzhB4YlU=
+go.opentelemetry.io/contrib/instrumentation/github.com/aws/aws-sdk-go-v2/otelaws v0.54.0 h1:By10h8DrrjRcZjy10wBEkRdwhe4kOFuNTfprm8RXQQk=
+go.opentelemetry.io/contrib/instrumentation/github.com/aws/aws-sdk-go-v2/otelaws v0.54.0/go.mod h1:EtfcBqee4PFJSl+TXvfhg8ADvLWGFXwwX7SYNHG/VGM=
+go.opentelemetry.io/otel v1.30.0 h1:F2t8sK4qf1fAmY9ua4ohFS/K+FUuOPemHUIXHtktrts=
+go.opentelemetry.io/otel v1.30.0/go.mod h1:tFw4Br9b7fOS+uEao81PJjVMjW/5fvNCbpsDIXqP0pc=
+go.opentelemetry.io/otel/metric v1.30.0 h1:4xNulvn9gjzo4hjg+wzIKG7iNFEaBMX00Qd4QIZs7+w=
+go.opentelemetry.io/otel/metric v1.30.0/go.mod h1:aXTfST94tswhWEb+5QjlSqG+cZlmyXy/u8jFpor3WqQ=
+go.opentelemetry.io/otel/trace v1.30.0 h1:7UBkkYzeg3C7kQX8VAidWh2biiQbtAKjyIML8dQ9wmc=
+go.opentelemetry.io/otel/trace v1.30.0/go.mod h1:5EyKqTzzmyqB9bwtCCq6pDLktPK6fmGf/Dph+8VI02o=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
+golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
+golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
+golang.org/x/exp v0.0.0-20230809150735-7b3493d9a819 h1:EDuYyU/MkFXllv9QF9819VlI9a4tzGuCbhG0ExK9o1U=
+golang.org/x/exp v0.0.0-20230809150735-7b3493d9a819/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
+golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8=
+golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
+golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=
+golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
+golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
+golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
+golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
+golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg=
+golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
+google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
+google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de h1:cZGRis4/ot9uVm639a+rHCUaG0JJHEsdyzSQTMX+suY=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:H4O17MA/PE9BsGx3w+a+W2VOLLD1Qf7oJneAoU6WktY=
+google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM=
+google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA=
+google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
+google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
+google.golang.org/protobuf v1.34.0 h1:Qo/qEd2RZPCf2nKuorzksSknv0d3ERwp1vFG38gSmH4=
+google.golang.org/protobuf v1.34.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
+gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
+gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/internal/conns/client.go b/internal/conns/client.go
new file mode 100644
index 0000000..5d54c41
--- /dev/null
+++ b/internal/conns/client.go
@@ -0,0 +1,14 @@
+package conns
+
+import (
+ "github.com/aws/aws-sdk-go-v2/aws"
+ "github.com/aws/aws-sdk-go-v2/service/cloudfront"
+)
+
+type Client struct {
+ Config aws.Config
+}
+
+func (c *Client) Cloudfront() *cloudfront.Client {
+ return cloudfront.NewFromConfig(c.Config)
+}
diff --git a/internal/provider/arn.go b/internal/provider/arn.go
new file mode 100644
index 0000000..c68c40c
--- /dev/null
+++ b/internal/provider/arn.go
@@ -0,0 +1,81 @@
+package provider
+
+import (
+ "context"
+ "fmt"
+ "github.com/aws/aws-sdk-go-v2/aws/arn"
+ "github.com/hashicorp/terraform-plugin-framework/diag"
+ "github.com/hashicorp/terraform-plugin-framework/schema/validator"
+ "regexp"
+)
+
+var (
+ _ validator.String = ArnValidator{}
+)
+
+var (
+ accountIDRegexp = regexp.MustCompile(`^(aws|aws-managed|third-party|\d{12}|cw.{10})$`)
+ partitionRegexp = regexp.MustCompile(`^aws(-[a-z]+)*$`)
+ regionRegexp = regexp.MustCompile(`^[a-z]{2}(-[a-z]+)+-\d$`)
+)
+
+// ArnValidator validates that a string value matches an ARN format with additional validation on the parsed ARN value
+// It must:
+// * Be parseable as an ARN
+// * Have a valid partition
+// * Have a valid region
+// * Have either an empty or valid account ID
+// * Have a non-empty resource part
+// * Pass the supplied checks
+type ArnValidator struct {
+}
+
+func (v ArnValidator) Description(ctx context.Context) string {
+ return fmt.Sprintf("string must be a valid ARN")
+}
+
+func (v ArnValidator) MarkdownDescription(ctx context.Context) string {
+ return v.Description(ctx)
+}
+
+func (v ArnValidator) ValidateString(ctx context.Context, request validator.StringRequest, response *validator.StringResponse) {
+ if request.ConfigValue.IsNull() || request.ConfigValue.IsUnknown() {
+ return
+ }
+ value := request.ConfigValue.ValueString()
+ if value == "" {
+ return
+ }
+ errs := v.validate(request.Path.String(), value)
+ for _, err := range errs {
+ response.Diagnostics.Append(diag.NewErrorDiagnostic(err.Error(), ""))
+ }
+}
+
+func (v ArnValidator) validate(path, value string) []error {
+ parsedARN, err := arn.Parse(value)
+ if err != nil {
+ return []error{fmt.Errorf("%q (%s) is an invalid ARN: %s", path, value, err.Error())}
+ }
+
+ errs := make([]error, 0)
+ if parsedARN.Partition == "" {
+ errs = append(errs, fmt.Errorf("%q (%s) is an invalid ARN: missing partition value", path, value))
+ } else if !partitionRegexp.MatchString(parsedARN.Partition) {
+ errs = append(errs, fmt.Errorf("%q (%s) is an invalid ARN: invalid partition value (expecting to match regular expression: %s)", path, value, partitionRegexp))
+ }
+
+ if parsedARN.Region != "" && !regionRegexp.MatchString(parsedARN.Region) {
+ errs = append(errs, fmt.Errorf("%q (%s) is an invalid ARN: invalid region value (expecting to match regular expression: %s)", path, value, regionRegexp))
+ }
+
+ if parsedARN.AccountID != "" && !accountIDRegexp.MatchString(parsedARN.AccountID) {
+ errs = append(errs, fmt.Errorf("%q (%s) is an invalid ARN: invalid account ID value (expecting to match regular expression: %s)", path, value, accountIDRegexp))
+ }
+
+ if parsedARN.Resource == "" {
+ errs = append(errs, fmt.Errorf("%q (%s) is an invalid ARN: missing resource value", path, value))
+ }
+
+ return errs
+}
diff --git a/internal/provider/assume_role.go b/internal/provider/assume_role.go
new file mode 100644
index 0000000..d1355d3
--- /dev/null
+++ b/internal/provider/assume_role.go
@@ -0,0 +1,189 @@
+package provider
+
+import (
+ "context"
+ "fmt"
+ "github.com/hashicorp/terraform-plugin-framework-jsontypes/jsontypes"
+ "github.com/hashicorp/terraform-plugin-framework-timetypes/timetypes"
+ "github.com/hashicorp/terraform-plugin-framework-validators/setvalidator"
+ "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
+ "github.com/hashicorp/terraform-plugin-framework/path"
+ "github.com/hashicorp/terraform-plugin-framework/provider/schema"
+ "github.com/hashicorp/terraform-plugin-framework/schema/validator"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+ "regexp"
+ "time"
+)
+
+func assumeRoleSchema() schema.Attribute {
+ return schema.SingleNestedAttribute{
+ Optional: true,
+ Attributes: map[string]schema.Attribute{
+ "duration": schema.StringAttribute{
+ CustomType: timetypes.GoDurationType{},
+ Optional: true,
+ Description: "The duration, between 15 minutes and 12 hours, of the role session. Valid time units are ns, us (or µs), ms, s, h, or m.",
+ Validators: []validator.String{validAssumeRoleDuration{}},
+ },
+ "external_id": schema.StringAttribute{
+ Optional: true,
+ Description: "A unique identifier that might be required when you assume a role in another account.",
+ Validators: []validator.String{
+ stringvalidator.All(
+ stringvalidator.LengthBetween(2, 1224),
+ stringvalidator.RegexMatches(regexp.MustCompile(`[\w+=,.@:\/\-]*`), ""),
+ ),
+ },
+ },
+ "policy": schema.StringAttribute{
+ CustomType: jsontypes.NormalizedType{},
+ Optional: true,
+ Description: "IAM Policy JSON describing further restricting permissions for the IAM Role being assumed.",
+ },
+ "policy_arns": schema.SetAttribute{
+ Optional: true,
+ ElementType: types.StringType,
+ Description: "Amazon Resource Names (ARNs) of IAM Policies describing further restricting permissions for the IAM Role being assumed.",
+ Validators: []validator.Set{
+ setvalidator.ValueStringsAre(
+ ArnValidator{},
+ ),
+ },
+ },
+ "role_arn": schema.StringAttribute{
+ Optional: true,
+ Description: "Amazon Resource Name (ARN) of an IAM Role to assume prior to making API calls.",
+ Validators: []validator.String{
+ ArnValidator{},
+ },
+ },
+ "session_name": schema.StringAttribute{
+ Optional: true,
+ Description: "An identifier for the assumed role session.",
+ Validators: []validator.String{
+ stringvalidator.All(
+ stringvalidator.LengthBetween(2, 64),
+ stringvalidator.RegexMatches(regexp.MustCompile(`[\w+=,.@\-]*`), ""),
+ ),
+ },
+ },
+ "source_identity": schema.StringAttribute{
+ Optional: true,
+ Description: "Source identity specified by the principal assuming the role.",
+ Validators: []validator.String{
+ stringvalidator.All(
+ stringvalidator.LengthBetween(2, 64),
+ stringvalidator.RegexMatches(regexp.MustCompile(`[\w+=,.@\-]*`), ""),
+ ),
+ },
+ },
+ "tags": schema.MapAttribute{
+ Optional: true,
+ ElementType: types.StringType,
+ Description: "Assume role session tags.",
+ },
+ "transitive_tag_keys": schema.SetAttribute{
+ Optional: true,
+ ElementType: types.StringType,
+ Description: "Assume role session tag keys to pass to any subsequent sessions.",
+ },
+ },
+ }
+}
+
+func assumeRoleWithWebIdentitySchema() schema.Attribute {
+ return schema.SingleNestedAttribute{
+ Optional: true,
+ Attributes: map[string]schema.Attribute{
+ "duration": schema.StringAttribute{
+ CustomType: timetypes.GoDurationType{},
+ Optional: true,
+ Description: "The duration, between 15 minutes and 12 hours, of the role session. Valid time units are ns, us (or µs), ms, s, h, or m.",
+ Validators: []validator.String{validAssumeRoleDuration{}},
+ },
+ "policy": schema.StringAttribute{
+ CustomType: jsontypes.NormalizedType{},
+ Optional: true,
+ Description: "IAM Policy JSON describing further restricting permissions for the IAM Role being assumed.",
+ },
+ "policy_arns": schema.SetAttribute{
+ Optional: true,
+ Description: "Amazon Resource Names (ARNs) of IAM Policies describing further restricting permissions for the IAM Role being assumed.",
+ ElementType: types.StringType,
+ Validators: []validator.Set{
+ setvalidator.ValueStringsAre(ArnValidator{}),
+ },
+ },
+ "role_arn": schema.StringAttribute{
+ Optional: true,
+ Description: "Amazon Resource Name (ARN) of an IAM Role to assume prior to making API calls.",
+ Validators: []validator.String{ArnValidator{}},
+ },
+ "session_name": schema.StringAttribute{
+ Optional: true,
+ Description: "An identifier for the assumed role session.",
+ Validators: []validator.String{
+ stringvalidator.All(
+ stringvalidator.LengthBetween(2, 64),
+ stringvalidator.RegexMatches(regexp.MustCompile(`[\w+=,.@\-]*`), ""),
+ ),
+ },
+ },
+ "web_identity_token": schema.StringAttribute{
+ Optional: true,
+ Validators: []validator.String{
+ stringvalidator.All(
+ stringvalidator.LengthBetween(4, 20000),
+ stringvalidator.ConflictsWith(
+ path.MatchRoot("assume_role_with_web_identity.0.web_identity_token"),
+ path.MatchRoot("assume_role_with_web_identity.0.web_identity_token_file"),
+ ),
+ ),
+ },
+ },
+ "web_identity_token_file": schema.StringAttribute{
+ Optional: true,
+ Validators: []validator.String{
+ stringvalidator.ConflictsWith(
+ path.MatchRoot("assume_role_with_web_identity.0.web_identity_token"),
+ path.MatchRoot("assume_role_with_web_identity.0.web_identity_token_file"),
+ ),
+ },
+ },
+ },
+ }
+}
+
+var (
+ _ validator.String = validAssumeRoleDuration{}
+)
+
+type validAssumeRoleDuration struct{}
+
+func (v validAssumeRoleDuration) Description(ctx context.Context) string {
+ return "string must be a valid duration"
+}
+
+func (v validAssumeRoleDuration) MarkdownDescription(ctx context.Context) string {
+ return v.Description(ctx)
+}
+
+func (v validAssumeRoleDuration) ValidateString(ctx context.Context, request validator.StringRequest, response *validator.StringResponse) {
+ if request.ConfigValue.IsNull() || request.ConfigValue.IsUnknown() {
+ return
+ }
+ value := request.ConfigValue.ValueString()
+ if value == "" {
+ return
+ }
+
+ duration, err := time.ParseDuration(value)
+ if err != nil {
+ response.Diagnostics.AddError(fmt.Sprintf("%q cannot be parsed as a duration: %s", request.Path, err), "")
+ return
+ }
+
+ if duration.Minutes() > 15 || duration.Hours() > 12 {
+ response.Diagnostics.AddError(fmt.Sprintf("duration %q must be between 15 minutes (15m) and 12 hours (12h), inclusive", request.Path), "")
+ }
+}
diff --git a/internal/provider/cloudfront_distribution_invalidation.go b/internal/provider/cloudfront_distribution_invalidation.go
new file mode 100644
index 0000000..137b335
--- /dev/null
+++ b/internal/provider/cloudfront_distribution_invalidation.go
@@ -0,0 +1,249 @@
+package provider
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "github.com/aws/aws-sdk-go-v2/aws"
+ "github.com/aws/aws-sdk-go-v2/service/cloudfront"
+ cftypes "github.com/aws/aws-sdk-go-v2/service/cloudfront/types"
+ "github.com/hashicorp/terraform-plugin-framework-timeouts/resource/timeouts"
+ "github.com/hashicorp/terraform-plugin-framework-validators/setvalidator"
+ "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
+ "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/resource/schema/mapplanmodifier"
+ "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
+ "github.com/hashicorp/terraform-plugin-framework/resource/schema/setplanmodifier"
+ "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
+ "github.com/hashicorp/terraform-plugin-framework/schema/validator"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+ "github.com/hashicorp/terraform-plugin-log/tflog"
+ "github.com/hashicorp/terraform-provider-awsex/internal/conns"
+ "regexp"
+ "time"
+)
+
+var _ resource.Resource = &CloudfrontDistributionInvalidationResource{}
+
+type CloudfrontDistributionInvalidationResource struct {
+ client *conns.Client
+}
+
+func NewCloudfrontDistributionInvalidationResource() resource.Resource {
+ return &CloudfrontDistributionInvalidationResource{}
+}
+
+type CloudfrontDistributionInvalidationModel struct {
+ Id types.String `tfsdk:"id"`
+ DistributionId types.String `tfsdk:"distribution_id"`
+ Paths types.Set `tfsdk:"paths"`
+ Status types.String `tfsdk:"status"`
+ Triggers types.Map `tfsdk:"triggers"`
+ Timeouts timeouts.Value `tfsdk:"timeouts"`
+}
+
+func (r *CloudfrontDistributionInvalidationResource) Metadata(ctx context.Context, request resource.MetadataRequest, response *resource.MetadataResponse) {
+ response.TypeName = request.ProviderTypeName + "_cloudfront_distribution_invalidation"
+}
+
+func (r *CloudfrontDistributionInvalidationResource) Schema(ctx context.Context, request resource.SchemaRequest, response *resource.SchemaResponse) {
+ response.Schema = schema.Schema{
+ MarkdownDescription: "",
+
+ Attributes: map[string]schema.Attribute{
+ "distribution_id": schema.StringAttribute{
+ MarkdownDescription: "The Cloudfront Distribution ID where an invalidation should be created.",
+ Required: true,
+ PlanModifiers: []planmodifier.String{
+ stringplanmodifier.RequiresReplace(),
+ },
+ },
+ "paths": schema.SetAttribute{
+ ElementType: types.StringType,
+ MarkdownDescription: "A list of paths to invalidate. Each path *must* start with `/`.",
+ Required: true,
+ PlanModifiers: []planmodifier.Set{
+ setplanmodifier.RequiresReplace(),
+ },
+ Validators: []validator.Set{
+ setvalidator.ValueStringsAre(stringvalidator.RegexMatches(regexp.MustCompile(`^/`), "")),
+ },
+ },
+ "status": schema.StringAttribute{
+ Description: "The status of the invalidation.",
+ Computed: true,
+ PlanModifiers: []planmodifier.String{
+ stringplanmodifier.UseStateForUnknown(),
+ },
+ },
+ "triggers": schema.MapAttribute{
+ ElementType: types.StringType,
+ MarkdownDescription: "A map of triggers that, when changed, will force Terraform to create a new invalidation.",
+ Optional: true,
+ Computed: true,
+ PlanModifiers: []planmodifier.Map{
+ mapplanmodifier.RequiresReplace(),
+ mapplanmodifier.UseStateForUnknown(),
+ },
+ },
+ "id": schema.StringAttribute{
+ MarkdownDescription: "The ID of the invalidation.",
+ Computed: true,
+ PlanModifiers: []planmodifier.String{
+ stringplanmodifier.UseStateForUnknown(),
+ },
+ },
+ },
+ Blocks: map[string]schema.Block{
+ "timeouts": timeouts.Block(ctx, timeouts.Opts{
+ Create: true,
+ }),
+ },
+ }
+}
+
+func (r *CloudfrontDistributionInvalidationResource) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) {
+ if req.ProviderData == nil {
+ return
+ }
+
+ client, ok := req.ProviderData.(*conns.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 = client
+}
+
+func (r *CloudfrontDistributionInvalidationResource) Create(ctx context.Context, request resource.CreateRequest, response *resource.CreateResponse) {
+ var data CloudfrontDistributionInvalidationModel
+ response.Diagnostics.Append(request.Plan.Get(ctx, &data)...)
+ if response.Diagnostics.HasError() {
+ return
+ }
+
+ data, diags := r.createInvalidation(ctx, data)
+ response.Diagnostics.Append(diags...)
+ if response.Diagnostics.HasError() {
+ return
+ }
+
+ if data.Triggers.IsUnknown() {
+ data.Triggers = types.MapNull(types.StringType)
+ }
+
+ response.Diagnostics.Append(response.State.Set(ctx, &data)...)
+}
+
+func (r *CloudfrontDistributionInvalidationResource) Read(ctx context.Context, request resource.ReadRequest, response *resource.ReadResponse) {
+ var data CloudfrontDistributionInvalidationModel
+ response.Diagnostics.Append(request.State.Get(ctx, &data)...)
+ if response.Diagnostics.HasError() {
+ return
+ }
+
+ inval, diags := r.findInvalidation(ctx, data)
+ response.Diagnostics.Append(diags...)
+ if response.Diagnostics.HasError() {
+ return
+ }
+
+ if inval == nil {
+ response.State.RemoveResource(ctx)
+ } else {
+ data.Id = types.StringPointerValue(inval.Id)
+ data.Status = types.StringPointerValue(inval.Status)
+ }
+
+ response.Diagnostics.Append(response.State.Set(ctx, &data)...)
+}
+
+func (r *CloudfrontDistributionInvalidationResource) Update(ctx context.Context, request resource.UpdateRequest, response *resource.UpdateResponse) {
+}
+
+func (r *CloudfrontDistributionInvalidationResource) Delete(ctx context.Context, request resource.DeleteRequest, response *resource.DeleteResponse) {
+}
+
+func (r *CloudfrontDistributionInvalidationResource) createInvalidation(ctx context.Context, data CloudfrontDistributionInvalidationModel) (CloudfrontDistributionInvalidationModel, diag.Diagnostics) {
+ var diags diag.Diagnostics
+
+ distributionId := data.DistributionId.ValueString()
+
+ paths := make([]string, 0)
+ diags = append(diags, data.Paths.ElementsAs(ctx, &paths, false)...)
+ if diags.HasError() {
+ return data, diags
+ }
+
+ input := &cloudfront.CreateInvalidationInput{
+ DistributionId: &distributionId,
+ InvalidationBatch: &cftypes.InvalidationBatch{
+ CallerReference: aws.String("terraform-provider-awsex"),
+ Paths: &cftypes.Paths{
+ Quantity: aws.Int32(int32(len(paths))),
+ Items: paths,
+ },
+ },
+ }
+ client := r.client.Cloudfront()
+ out, err := client.CreateInvalidation(ctx, input)
+ if err != nil {
+ diags.AddError("Error creating AWS Cloudfront Invalidation", err.Error())
+ return data, diags
+ }
+ if out != nil && out.Invalidation != nil && out.Invalidation.Id != nil {
+ data.Id = types.StringValue(*out.Invalidation.Id)
+ tflog.Trace(ctx, "Created Cloudfront Invalidation")
+ } else {
+ diags.AddWarning("Unable to create AWS Cloudfront Invalidation.", "AWS did not create an invalidation and gave no reason")
+ }
+
+ createTimeout, diags := data.Timeouts.Create(ctx, 30*time.Minute)
+ if diags.HasError() {
+ return data, diags
+ }
+
+ waiter := cloudfront.NewInvalidationCompletedWaiter(client)
+ res, err := waiter.WaitForOutput(ctx, &cloudfront.GetInvalidationInput{
+ DistributionId: aws.String(distributionId),
+ Id: out.Invalidation.Id,
+ }, createTimeout)
+ if err != nil {
+ diags.AddError("Error waiting for creation of AWS Cloudfront Invalidation", err.Error())
+ return data, diags
+ } else if res.Invalidation != nil {
+ data.Status = types.StringPointerValue(res.Invalidation.Status)
+ }
+
+ return data, diags
+}
+
+func (r *CloudfrontDistributionInvalidationResource) findInvalidation(ctx context.Context, data CloudfrontDistributionInvalidationModel) (*cftypes.Invalidation, diag.Diagnostics) {
+ var diags diag.Diagnostics
+ var inval *cftypes.Invalidation
+
+ input := &cloudfront.GetInvalidationInput{
+ DistributionId: data.DistributionId.ValueStringPointer(),
+ Id: data.Id.ValueStringPointer(),
+ }
+ client := r.client.Cloudfront()
+ out, err := client.GetInvalidation(ctx, input)
+ if err != nil {
+ var nsi *cftypes.NoSuchInvalidation
+ if !errors.As(err, &nsi) {
+ diags.AddError("error getting AWS Invalidation", err.Error())
+ }
+ }
+ if out != nil && out.Invalidation != nil {
+ inval = out.Invalidation
+ }
+ return inval, diags
+}
diff --git a/internal/provider/cloudfront_distribution_invalidation_test.go b/internal/provider/cloudfront_distribution_invalidation_test.go
new file mode 100644
index 0000000..34c3182
--- /dev/null
+++ b/internal/provider/cloudfront_distribution_invalidation_test.go
@@ -0,0 +1,122 @@
+package provider
+
+import (
+ "context"
+ "fmt"
+ "github.com/aws/aws-sdk-go-v2/aws"
+ "github.com/aws/aws-sdk-go-v2/config"
+ "github.com/aws/aws-sdk-go-v2/service/cloudfront"
+ cftypes "github.com/aws/aws-sdk-go-v2/service/cloudfront/types"
+ "github.com/hashicorp/terraform-plugin-testing/helper/resource"
+ "testing"
+)
+
+const (
+ providerConfig = `
+provider "awsex" {
+}
+`
+)
+
+func TestAccDistributionInvalidation(t *testing.T) {
+ if testing.Short() {
+ t.Skip("skipping long-running test in short mode")
+ }
+
+ cdnId := testAccCreateCdn(t)
+ config1 := providerConfig + fmt.Sprintf(`
+resource "awsex_cloudfront_distribution_invalidation" "test" {
+ distribution_id = %[1]q
+ paths = ["/*"]
+}
+`, cdnId)
+
+ resource.Test(t, resource.TestCase{
+ PreCheck: func() { testAccPreCheck(t) },
+ ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
+ Steps: []resource.TestStep{
+ {
+ Config: config1,
+ Check: resource.ComposeAggregateTestCheckFunc(
+ resource.TestCheckResourceAttrSet("awsex_cloudfront_distribution_invalidation.test", "id"),
+ resource.TestCheckResourceAttr("awsex_cloudfront_distribution_invalidation.test", "status", "Completed"),
+ ),
+ },
+ },
+ })
+}
+
+func testAccCreateCdn(t *testing.T) string {
+ ctx := context.Background()
+ cfg, err := config.LoadDefaultConfig(ctx)
+ if err != nil {
+ t.Fatal(err.Error())
+ }
+ client := cloudfront.NewFromConfig(cfg)
+ input := &cloudfront.CreateDistributionInput{
+ DistributionConfig: &cftypes.DistributionConfig{
+ Enabled: aws.Bool(false),
+ DefaultCacheBehavior: &cftypes.DefaultCacheBehavior{
+ AllowedMethods: &cftypes.AllowedMethods{
+ Items: []cftypes.Method{cftypes.MethodGet, cftypes.MethodHead},
+ Quantity: aws.Int32(2),
+ CachedMethods: &cftypes.CachedMethods{
+ Items: []cftypes.Method{cftypes.MethodGet, cftypes.MethodHead},
+ Quantity: aws.Int32(2),
+ },
+ },
+ TargetOriginId: aws.String("test"),
+ ViewerProtocolPolicy: "allow-all",
+ MinTTL: aws.Int64(0),
+ ForwardedValues: &cftypes.ForwardedValues{
+ QueryString: aws.Bool(false),
+ Cookies: &cftypes.CookiePreference{Forward: cftypes.ItemSelectionAll},
+ },
+ },
+ Restrictions: &cftypes.Restrictions{
+ GeoRestriction: &cftypes.GeoRestriction{
+ RestrictionType: "none",
+ Quantity: aws.Int32(0),
+ },
+ },
+ Origins: &cftypes.Origins{
+ Quantity: aws.Int32(1),
+ Items: []cftypes.Origin{
+ {
+ DomainName: aws.String("www.example.com"),
+ Id: aws.String("test"),
+ CustomOriginConfig: &cftypes.CustomOriginConfig{
+ HTTPPort: aws.Int32(80),
+ HTTPSPort: aws.Int32(443),
+ OriginProtocolPolicy: "https-only",
+ OriginSslProtocols: &cftypes.OriginSslProtocols{
+ Quantity: aws.Int32(1),
+ Items: []cftypes.SslProtocol{cftypes.SslProtocolTLSv12},
+ },
+ },
+ },
+ },
+ },
+ CallerReference: aws.String("terraform-provider-awsex"),
+ Comment: aws.String("Test Distribution for terraform-provider-awsex"),
+ ViewerCertificate: &cftypes.ViewerCertificate{
+ CloudFrontDefaultCertificate: aws.Bool(true),
+ },
+ },
+ }
+ out, err := client.CreateDistribution(ctx, input)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if out == nil {
+ t.Fatal("create distribution had a nil result")
+ }
+
+ t.Cleanup(func() {
+ client.DeleteDistribution(ctx, &cloudfront.DeleteDistributionInput{
+ Id: out.Distribution.Id,
+ })
+ })
+
+ return *out.Distribution.Id
+}
diff --git a/internal/provider/provider.go b/internal/provider/provider.go
new file mode 100644
index 0000000..8b7d2a0
--- /dev/null
+++ b/internal/provider/provider.go
@@ -0,0 +1,168 @@
+package provider
+
+import (
+ "context"
+ awsbase "github.com/hashicorp/aws-sdk-go-base/v2"
+ "github.com/hashicorp/terraform-plugin-framework/datasource"
+ "github.com/hashicorp/terraform-plugin-framework/diag"
+ "github.com/hashicorp/terraform-plugin-framework/function"
+ "github.com/hashicorp/terraform-plugin-framework/provider"
+ "github.com/hashicorp/terraform-plugin-framework/provider/schema"
+ "github.com/hashicorp/terraform-plugin-framework/resource"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+ "github.com/hashicorp/terraform-plugin-log/tflog"
+ "github.com/hashicorp/terraform-provider-awsex/internal/conns"
+)
+
+// Ensure AwsexProvider satisfies various provider interfaces.
+
+var (
+ _ provider.ProviderWithValidateConfig = &AwsexProvider{}
+ _ provider.ProviderWithFunctions = &AwsexProvider{}
+)
+
+// AwsexProvider defines the provider implementation.
+type AwsexProvider struct {
+ // version is set to the provider version on release, "dev" when the
+ // provider is built and ran locally, and "test" when running acceptance
+ // testing.
+ version string
+}
+
+func (p *AwsexProvider) Metadata(ctx context.Context, req provider.MetadataRequest, resp *provider.MetadataResponse) {
+ resp.TypeName = "awsex"
+ resp.Version = p.version
+}
+
+func (p *AwsexProvider) Schema(ctx context.Context, req provider.SchemaRequest, resp *provider.SchemaResponse) {
+ resp.Schema = schema.Schema{
+ Attributes: map[string]schema.Attribute{
+ "access_key": schema.StringAttribute{
+ Optional: true,
+ Description: "The access key for API operations. You can retrieve this\n" +
+ "from the 'Security & Credentials' section of the AWS console.",
+ },
+ "assume_role": assumeRoleSchema(),
+ "assume_role_with_web_identity": assumeRoleWithWebIdentitySchema(),
+ "custom_ca_bundle": schema.StringAttribute{
+ Optional: true,
+ Description: "File containing custom root and intermediate certificates. " +
+ "Can also be configured using the `AWS_CA_BUNDLE` environment variable. " +
+ "(Setting `ca_bundle` in the shared config file is not supported.)",
+ },
+ "http_proxy": schema.StringAttribute{
+ Optional: true,
+ Description: "URL of a proxy to use for HTTP requests when accessing the AWS API. " +
+ "Can also be set using the `HTTP_PROXY` or `http_proxy` environment variables.",
+ },
+ "https_proxy": schema.StringAttribute{
+ Optional: true,
+ Description: "URL of a proxy to use for HTTPS requests when accessing the AWS API. " +
+ "Can also be set using the `HTTPS_PROXY` or `https_proxy` environment variables.",
+ },
+ "insecure": schema.BoolAttribute{
+ Optional: true,
+ Description: "Explicitly allow the provider to perform \"insecure\" SSL requests. If omitted, " +
+ "default value is `false`",
+ },
+ "max_retries": schema.Int32Attribute{
+ Optional: true,
+ Description: "The maximum number of times an AWS API request is\n" +
+ "being executed. If the API request still fails, an error is\n" +
+ "thrown.",
+ },
+ "no_proxy": schema.StringAttribute{
+ Optional: true,
+ Description: "Comma-separated list of hosts that should not use HTTP or HTTPS proxies. " +
+ "Can also be set using the `NO_PROXY` or `no_proxy` environment variables.",
+ },
+ "profile": schema.StringAttribute{
+ Optional: true,
+ Description: "The profile for API operations. If not set, the default profile\n" +
+ "created with `aws configure` will be used.",
+ },
+ "region": schema.StringAttribute{
+ Optional: true,
+ Description: "The region where AWS operations will take place. Examples\n" +
+ "are us-east-1, us-west-2, etc.", // lintignore:AWSAT003,
+ },
+ "retry_mode": schema.StringAttribute{
+ Optional: true,
+ Description: "Specifies how retries are attempted. Valid values are `standard` and `adaptive`. " +
+ "Can also be configured using the `AWS_RETRY_MODE` environment variable.",
+ },
+ "secret_key": schema.StringAttribute{
+ Optional: true,
+ Description: "The secret key for API operations. You can retrieve this\n" +
+ "from the 'Security & Credentials' section of the AWS console.",
+ },
+ "shared_config_files": schema.ListAttribute{
+ Optional: true,
+ Description: "List of paths to shared config files. If not set, defaults to [~/.aws/config].",
+ ElementType: types.StringType,
+ },
+ "shared_credentials_files": schema.ListAttribute{
+ Optional: true,
+ Description: "List of paths to shared credentials files. If not set, defaults to [~/.aws/credentials].",
+ ElementType: types.StringType,
+ },
+ "token": schema.StringAttribute{
+ Optional: true,
+ Description: "session token. A session token is only required if you are\n" +
+ "using temporary security credentials.",
+ },
+ },
+ }
+}
+
+func (p *AwsexProvider) Configure(ctx context.Context, req provider.ConfigureRequest, resp *provider.ConfigureResponse) {
+ var model AwsexProviderModel
+ resp.Diagnostics.Append(req.Config.Get(ctx, &model)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ tflog.Debug(ctx, "Configuring Terraform AWS Provider")
+ awsbaseConfig := model.GetAwsBaseConfig(p.version, req.TerraformVersion)
+ ctx, cfg, basediags := awsbase.GetAwsConfig(ctx, &awsbaseConfig)
+ for _, d := range basediags {
+ switch int(d.Severity()) {
+ case int(diag.SeverityError):
+ resp.Diagnostics.AddError(d.Summary(), d.Detail())
+ case int(diag.SeverityWarning):
+ resp.Diagnostics.AddWarning(d.Summary(), d.Detail())
+ }
+ }
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ client := &conns.Client{Config: cfg}
+ resp.DataSourceData = client
+ resp.ResourceData = client
+}
+
+func (p *AwsexProvider) ValidateConfig(ctx context.Context, request provider.ValidateConfigRequest, response *provider.ValidateConfigResponse) {
+}
+
+func (p *AwsexProvider) Resources(ctx context.Context) []func() resource.Resource {
+ return []func() resource.Resource{
+ NewCloudfrontDistributionInvalidationResource,
+ }
+}
+
+func (p *AwsexProvider) DataSources(ctx context.Context) []func() datasource.DataSource {
+ return []func() datasource.DataSource{}
+}
+
+func (p *AwsexProvider) Functions(ctx context.Context) []func() function.Function {
+ return []func() function.Function{}
+}
+
+func New(version string) func() provider.Provider {
+ return func() provider.Provider {
+ return &AwsexProvider{
+ version: version,
+ }
+ }
+}
diff --git a/internal/provider/provider_model.go b/internal/provider/provider_model.go
new file mode 100644
index 0000000..0fd52dd
--- /dev/null
+++ b/internal/provider/provider_model.go
@@ -0,0 +1,174 @@
+package provider
+
+import (
+ "github.com/aws/aws-sdk-go-v2/aws"
+ awsbase "github.com/hashicorp/aws-sdk-go-base/v2"
+ "github.com/hashicorp/terraform-plugin-framework-jsontypes/jsontypes"
+ "github.com/hashicorp/terraform-plugin-framework-timetypes/timetypes"
+)
+
+type AwsexProviderModel struct {
+ // AccessKey
+ // The access key for API operations. You can retrieve this from the 'Security & Credentials' section of the AWS console.
+ AccessKey *string `tfsdk:"access_key"`
+ AssumeRole *AwsexAssumeRoleModel `tfsdk:"assume_role"`
+ AssumeRoleWithWebIdentity *AwsexAssumeRoleWithWebIdentityModel `tfsdk:"assume_role_with_web_identity"`
+ // CustomCaBundle
+ // File containing custom root and intermediate certificates.
+ // Can also be configured using the `AWS_CA_BUNDLE` environment variable.
+ // (Setting `ca_bundle` in the shared config file is not supported.)
+ CustomCaBundle *string `tfsdk:"custom_ca_bundle"`
+ // HttpProxy
+ // URL of a proxy to use for HTTP requests when accessing the AWS API.
+ // Can also be set using the `HTTP_PROXY` or `http_proxy` environment variables.
+ HttpProxy *string `tfsdk:"http_proxy"`
+ // HttpsProxy
+ // URL of a proxy to use for HTTPS requests when accessing the AWS API.
+ // Can also be set using the `HTTPS_PROXY` or `https_proxy` environment variables.
+ HttpsProxy *string `tfsdk:"https_proxy"`
+ // Insecure
+ // Explicitly allow the provider to perform "insecure" SSL requests.
+ // If omitted, default value is `false`
+ Insecure *bool `tfsdk:"insecure"`
+ // MaxRetries
+ // The maximum number of times an AWS API request is being executed.
+ // If the API request still fails, an error is thrown.
+ MaxRetries *int `tfsdk:"max_retries"`
+ // NoProxy
+ // Comma-separated list of hosts that should not use HTTP or HTTPS proxies.
+ // Can also be set using the `NO_PROXY` or `no_proxy` environment variables.
+ NoProxy *string `tfsdk:"no_proxy"`
+ // Profile
+ // The profile for API operations. If not set, the default profile created with `aws configure` will be used.
+ Profile *string `tfsdk:"profile"`
+ // Region
+ // The region where AWS operations will take place.
+ // Examples are us-east-1, us-west-2, etc.
+ Region *string `tfsdk:"region"`
+ // RetryMode
+ // Specifies how retries are attempted. Valid values are `standard` and `adaptive`.
+ // Can also be configured using the `AWS_RETRY_MODE` environment variable.
+ RetryMode *string `tfsdk:"retry_mode"`
+ // SecretKey
+ // The secret key for API operations. You can retrieve this from the 'Security & Credentials' section of the AWS console.
+ SecretKey *string `tfsdk:"secret_key"`
+ // SharedConfigFiles
+ // List of paths to shared config files. If not set, defaults to [~/.aws/config].
+ SharedConfigFiles []string `tfsdk:"shared_config_files"`
+ // SharedCredentialsFiles
+ // List of paths to shared credentials files. If not set, defaults to [~/.aws/credentials].
+ SharedCredentialsFiles []string `tfsdk:"shared_credentials_files"`
+ // Token
+ // session token. A session token is only required if you are using temporary security credentials.
+ Token *string `tfsdk:"token"`
+}
+
+func (m AwsexProviderModel) GetAwsBaseConfig(providerVersion, terraformVersion string) awsbase.Config {
+ awsbaseConfig := awsbase.Config{
+ AccessKey: unptr(m.AccessKey),
+ APNInfo: &awsbase.APNInfo{
+ PartnerName: "Nullstone",
+ Products: []awsbase.UserAgentProduct{
+ {Name: "Terraform", Version: terraformVersion, Comment: "+https://www.terraform.io"},
+ {Name: "terraform-provider-awsex", Version: providerVersion, Comment: "+https://registry.terraform.io/providers/nullstone-io/awsex"},
+ },
+ },
+ //Backoff: &v1CompatibleBackoff{maxRetryDelay: maxBackoff},
+ CallerDocumentationURL: "https://registry.terraform.io/providers/hashicorp/aws",
+ CallerName: "Terraform AWS Provider",
+ //EC2MetadataServiceEnableState: m.EC2MetadataServiceEnableState,
+ Insecure: unptr(m.Insecure),
+ //HTTPClient: client.HTTPClient(ctx),
+ HTTPProxy: m.HttpProxy,
+ HTTPSProxy: m.HttpsProxy,
+ HTTPProxyMode: awsbase.HTTPProxyModeLegacy,
+ //Logger: logger,
+ //MaxBackoff: maxBackoff,
+ MaxRetries: unptr(m.MaxRetries),
+ NoProxy: unptr(m.NoProxy),
+ Profile: unptr(m.Profile),
+ Region: unptr(m.Region),
+ RetryMode: aws.RetryMode(unptr(m.RetryMode)),
+ SecretKey: unptr(m.SecretKey),
+ Token: unptr(m.Token),
+ }
+ m.AssumeRole.Configure(&awsbaseConfig)
+ m.AssumeRoleWithWebIdentity.Configure(&awsbaseConfig)
+ if len(m.SharedConfigFiles) != 0 {
+ awsbaseConfig.SharedConfigFiles = m.SharedConfigFiles
+ }
+ if len(m.SharedCredentialsFiles) != 0 {
+ awsbaseConfig.SharedCredentialsFiles = m.SharedCredentialsFiles
+ }
+ return awsbaseConfig
+}
+
+type AwsexAssumeRoleModel struct {
+ Duration timetypes.GoDuration `tfsdk:"duration"`
+ ExternalId string `tfsdk:"external_id"`
+ Policy jsontypes.Normalized `tfsdk:"policy"`
+ PolicyArns []string `tfsdk:"policy_arns"`
+ RoleArn string `tfsdk:"role_arn"`
+ SessionName string `tfsdk:"session_name"`
+ SourceIdentity string `tfsdk:"source_identity"`
+ Tags map[string]string `tfsdk:"tags"`
+ TransitiveTagKeys []string `tfsdk:"transitive_tag_keys"`
+}
+
+func (m *AwsexAssumeRoleModel) Configure(cfg *awsbase.Config) {
+ if m == nil || m.RoleArn == "" {
+ return
+ }
+
+ // Validation will catch errors from this conversion
+ duration, _ := m.Duration.ValueGoDuration()
+
+ cfg.AssumeRole = append(cfg.AssumeRole, awsbase.AssumeRole{
+ RoleARN: m.RoleArn,
+ Duration: duration,
+ ExternalID: m.ExternalId,
+ Policy: m.Policy.ValueString(),
+ PolicyARNs: m.PolicyArns,
+ SessionName: m.SessionName,
+ SourceIdentity: m.SourceIdentity,
+ Tags: m.Tags,
+ TransitiveTagKeys: m.TransitiveTagKeys,
+ })
+}
+
+type AwsexAssumeRoleWithWebIdentityModel struct {
+ Duration timetypes.GoDuration `tfsdk:"duration"`
+ Policy jsontypes.Normalized `tfsdk:"policy"`
+ PolicyArns []string `tfsdk:"policy_arns"`
+ RoleArn string `tfsdk:"role_arn"`
+ SessionName string `tfsdk:"session_name"`
+ WebIdentityToken string `tfsdk:"web_identity_token"`
+ WebIdentityTokenFile string `tfsdk:"web_identity_token_file"`
+}
+
+func (m *AwsexAssumeRoleWithWebIdentityModel) Configure(cfg *awsbase.Config) {
+ if m == nil || m.RoleArn == "" {
+ return
+ }
+
+ // Validation will catch errors from this conversion
+ duration, _ := m.Duration.ValueGoDuration()
+
+ cfg.AssumeRoleWithWebIdentity = &awsbase.AssumeRoleWithWebIdentity{
+ RoleARN: m.RoleArn,
+ Duration: duration,
+ Policy: m.Policy.ValueString(),
+ PolicyARNs: m.PolicyArns,
+ SessionName: m.SessionName,
+ WebIdentityToken: m.WebIdentityToken,
+ WebIdentityTokenFile: m.WebIdentityTokenFile,
+ }
+}
+
+func unptr[T any](val *T) T {
+ var t T
+ if val != nil {
+ return *val
+ }
+ return t
+}
diff --git a/internal/provider/provider_test.go b/internal/provider/provider_test.go
new file mode 100644
index 0000000..f5ee88b
--- /dev/null
+++ b/internal/provider/provider_test.go
@@ -0,0 +1,21 @@
+package provider
+
+import (
+ "github.com/hashicorp/terraform-plugin-framework/providerserver"
+ "github.com/hashicorp/terraform-plugin-go/tfprotov6"
+ "testing"
+)
+
+// testAccProtoV6ProviderFactories are used to instantiate a provider during
+// acceptance testing. The factory function will be invoked for every Terraform
+// CLI command executed to create a provider server to which the CLI can
+// reattach.
+var testAccProtoV6ProviderFactories = map[string]func() (tfprotov6.ProviderServer, error){
+ "awsex": providerserver.NewProtocol6WithError(New("test")()),
+}
+
+func testAccPreCheck(t *testing.T) {
+ // You can add code here to run prior to any test case execution, for example assertions
+ // about the appropriate environment variables being set are common to see in a pre-check
+ // function.
+}
diff --git a/main.go b/main.go
new file mode 100644
index 0000000..423fca4
--- /dev/null
+++ b/main.go
@@ -0,0 +1,47 @@
+package main
+
+import (
+ "context"
+ "flag"
+ "log"
+
+ "github.com/hashicorp/terraform-plugin-framework/providerserver"
+ "github.com/hashicorp/terraform-provider-awsex/internal/provider"
+)
+
+// Run "go generate" to format example terraform files and generate the docs for the registry/website
+
+// If you do not have terraform installed, you can remove the formatting command, but it's suggested to
+// ensure the documentation is formatted properly.
+//go:generate terraform fmt -recursive ./examples/
+
+// Run the docs generation tool, check its repository for more information on how it works and how docs
+// can be customized.
+//go:generate go run github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs generate -provider-name awsex
+
+var (
+ // these will be set by the goreleaser configuration
+ // to appropriate values for the compiled binary.
+ version string = "dev"
+
+ // goreleaser can pass other information to the main package, such as the specific commit
+ // https://goreleaser.com/cookbooks/using-main.version/
+)
+
+func main() {
+ var debug bool
+
+ flag.BoolVar(&debug, "debug", false, "set to true to run the provider with support for debuggers like delve")
+ flag.Parse()
+
+ opts := providerserver.ServeOpts{
+ Address: "registry.terraform.io/nullstone-io/awsex",
+ Debug: debug,
+ }
+
+ err := providerserver.Serve(context.Background(), provider.New(version), opts)
+
+ if err != nil {
+ log.Fatal(err.Error())
+ }
+}
diff --git a/terraform-registry-manifest.json b/terraform-registry-manifest.json
new file mode 100644
index 0000000..fec2a56
--- /dev/null
+++ b/terraform-registry-manifest.json
@@ -0,0 +1,6 @@
+{
+ "version": 1,
+ "metadata": {
+ "protocol_versions": ["6.0"]
+ }
+}
diff --git a/tools/tools.go b/tools/tools.go
new file mode 100644
index 0000000..2c4f8fb
--- /dev/null
+++ b/tools/tools.go
@@ -0,0 +1,8 @@
+//go:build tools
+
+package tools
+
+import (
+ // Documentation generation
+ _ "github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs"
+)