diff --git a/.changelog/45073.txt b/.changelog/45073.txt new file mode 100644 index 000000000000..ad0dc989854a --- /dev/null +++ b/.changelog/45073.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/aws_msk_cluster: Add `rebalancing` configuration block to support intelligent rebalancing for Express broker clusters +``` diff --git a/.changelog/45097.txt b/.changelog/45097.txt new file mode 100644 index 000000000000..d9d1e0cdf867 --- /dev/null +++ b/.changelog/45097.txt @@ -0,0 +1,3 @@ +```release-note:new-resource +aws_billing_view +``` \ No newline at end of file diff --git a/.changelog/45104.txt b/.changelog/45104.txt new file mode 100644 index 000000000000..a1003d9e8cb0 --- /dev/null +++ b/.changelog/45104.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/aws_bedrock_guardrail: Add `input_action`, `input_enabled`, `input_modalities`, `output_action`, `output_enabled`, and `output_modalities` arguments to the `content_policy_config.filters_config` block +``` \ No newline at end of file diff --git a/.changelog/45143.txt b/.changelog/45143.txt new file mode 100644 index 000000000000..254473ff6cc7 --- /dev/null +++ b/.changelog/45143.txt @@ -0,0 +1,6 @@ +```release-note:new-guide +Tag Policy Compliance +``` +```release-note:enhancement +provider: Add support for enforcing tag policy compliance. This opt-in feature can be enabled via the new `tag_policy_compliance` provider argument, or the `TF_AWS_TAG_POLICY_COMPLIANCE` environment variable. When enabled, the principal executing Terraform must have the `tags:ListRequiredTags` IAM permission. +``` diff --git a/.changelog/45159.txt b/.changelog/45159.txt new file mode 100644 index 000000000000..59cdee5fceb3 --- /dev/null +++ b/.changelog/45159.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/aws_fsx_openzfs_file_system: Support `INTELLIGENT_TIERING` storage type and add `read_cache_configuration` argument +``` diff --git a/.changelog/45170.txt b/.changelog/45170.txt new file mode 100644 index 000000000000..fc0c3644c521 --- /dev/null +++ b/.changelog/45170.txt @@ -0,0 +1,19 @@ +```release-note:enhancement +resource/aws_lambda_function: Add `tenancy_config` argument +``` + +```release-note:enhancement +data-source/aws_lambda_function: Add `tenancy_config` attribute +``` + +```release-note:enhancement +resource/aws_lambda_invocation: Add `tenant_id` argument +``` + +```release-note:enhancement +data-source/aws_lambda_invocation: Add `tenant_id` argument +``` + +```release-note:enhancement +action/aws_lambda_invoke: Add `tenant_id` argument +``` \ No newline at end of file diff --git a/.changelog/45201.txt b/.changelog/45201.txt new file mode 100644 index 000000000000..73a58e0602d1 --- /dev/null +++ b/.changelog/45201.txt @@ -0,0 +1,6 @@ +```release-note:bug +provider: Fix early return logic in the required tag validation interceptor. This addresses a performance regression introduced in [v6.22.0](https://github.com/hashicorp/terraform-provider-aws/blob/main/CHANGELOG.md#6220-november-20-2025). +``` +```release-note:bug +provider: Fix crash in required tag validation interceptor when tag values are unknown. This addresses a regression introduced in [v6.22.0](https://github.com/hashicorp/terraform-provider-aws/blob/main/CHANGELOG.md#6220-november-20-2025). +``` diff --git a/.changelog/45202.txt b/.changelog/45202.txt new file mode 100644 index 000000000000..c8fdf41e3a98 --- /dev/null +++ b/.changelog/45202.txt @@ -0,0 +1,3 @@ +```release-note:bug +resource/aws_accessanalyzer_analyzer: Fix `interface conversion: interface {} is nil, not map[string]interface {}` panics when `configuration.unused_access.analysis_rule.exclusion.resource_tags` contains `null` values +``` \ No newline at end of file diff --git a/.changelog/45205.txt b/.changelog/45205.txt new file mode 100644 index 000000000000..3db6869e7008 --- /dev/null +++ b/.changelog/45205.txt @@ -0,0 +1,3 @@ +```release-note:bug +resource/aws_odb_cloud_vm_cluster: Fix incorrect validation error when arguments are configured using variables. This addresses a regression introduced in [v6.22.0](https://github.com/hashicorp/terraform-provider-aws/blob/main/CHANGELOG.md#6220-november-20-2025) +``` \ No newline at end of file diff --git a/.ci/providerlint/go.mod b/.ci/providerlint/go.mod index 134d539eb632..6c9f165fb572 100644 --- a/.ci/providerlint/go.mod +++ b/.ci/providerlint/go.mod @@ -53,7 +53,7 @@ require ( github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect github.com/zclconf/go-cty v1.17.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.38.0 // indirect - golang.org/x/crypto v0.44.0 // indirect + golang.org/x/crypto v0.45.0 // indirect golang.org/x/mod v0.30.0 // indirect golang.org/x/net v0.47.0 // indirect golang.org/x/sync v0.18.0 // indirect diff --git a/.ci/providerlint/go.sum b/.ci/providerlint/go.sum index 130c5a681158..43441b2b339b 100644 --- a/.ci/providerlint/go.sum +++ b/.ci/providerlint/go.sum @@ -178,8 +178,8 @@ go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42s golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.44.0 h1:A97SsFvM3AIwEEmTBiaxPPTYpDC47w720rdiiUvgoAU= -golang.org/x/crypto v0.44.0/go.mod h1:013i+Nw79BMiQiMsOPcVCB5ZIJbYkerPrGnOa00tvmc= +golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= +golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk= diff --git a/.ci/tools/go.mod b/.ci/tools/go.mod index 8298a5b0c094..137d44a518d0 100644 --- a/.ci/tools/go.mod +++ b/.ci/tools/go.mod @@ -10,7 +10,7 @@ require ( github.com/hashicorp/go-changelog v0.0.0-20250127101332-effe3832fb0b github.com/katbyte/terrafmt v0.5.5 github.com/pavius/impi v0.0.3 - github.com/rhysd/actionlint v1.7.8 + github.com/rhysd/actionlint v1.7.9 github.com/terraform-linters/tflint v0.58.1 golang.org/x/tools v0.39.0 mvdan.cc/gofumpt v0.9.2 @@ -375,8 +375,8 @@ require ( go.uber.org/automaxprocs v1.6.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - go.yaml.in/yaml/v4 v4.0.0-rc.2 // indirect - golang.org/x/crypto v0.44.0 // indirect + go.yaml.in/yaml/v4 v4.0.0-rc.3 // indirect + golang.org/x/crypto v0.45.0 // indirect golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect golang.org/x/exp/typeparams v0.0.0-20251023183803-a4bb9ffd2546 // indirect golang.org/x/mod v0.30.0 // indirect diff --git a/.ci/tools/go.sum b/.ci/tools/go.sum index 63bc05181fc6..f3f03d4490d2 100644 --- a/.ci/tools/go.sum +++ b/.ci/tools/go.sum @@ -1734,8 +1734,8 @@ github.com/raeperd/recvcheck v0.2.0 h1:GnU+NsbiCqdC2XX5+vMZzP+jAJC5fht7rcVTAhX74 github.com/raeperd/recvcheck v0.2.0/go.mod h1:n04eYkwIR0JbgD73wT8wL4JjPC3wm0nFtzBnWNocnYU= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/rhnvrm/simples3 v0.6.1/go.mod h1:Y+3vYm2V7Y4VijFoJHHTrja6OgPrJ2cBti8dPGkC3sA= -github.com/rhysd/actionlint v1.7.8 h1:3d+N9ourgAxVYG4z2IFxFIk/YiT6V+VnKASfXGwT60E= -github.com/rhysd/actionlint v1.7.8/go.mod h1:3kiS6egcbXG+vQsJIhFxTz+UKaF1JprsE0SKrpCZKvU= +github.com/rhysd/actionlint v1.7.9 h1:oq4uFwcW6pRTk8BhAS4+RhYoUddUkbvRMcqndja0CT0= +github.com/rhysd/actionlint v1.7.9/go.mod h1:H3q8YpD2es7K4c+mibw3OhTXGQQ7HkZX1u+DXaHLwfE= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= @@ -2035,8 +2035,8 @@ go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -go.yaml.in/yaml/v4 v4.0.0-rc.2 h1:/FrI8D64VSr4HtGIlUtlFMGsm7H7pWTbj6vOLVZcA6s= -go.yaml.in/yaml/v4 v4.0.0-rc.2/go.mod h1:aZqd9kCMsGL7AuUv/m/PvWLdg5sjJsZ4oHDEnfPPfY0= +go.yaml.in/yaml/v4 v4.0.0-rc.3 h1:3h1fjsh1CTAPjW7q/EMe+C8shx5d8ctzZTrLcs/j8Go= +go.yaml.in/yaml/v4 v4.0.0-rc.3/go.mod h1:aZqd9kCMsGL7AuUv/m/PvWLdg5sjJsZ4oHDEnfPPfY0= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -2062,8 +2062,8 @@ golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= -golang.org/x/crypto v0.44.0 h1:A97SsFvM3AIwEEmTBiaxPPTYpDC47w720rdiiUvgoAU= -golang.org/x/crypto v0.44.0/go.mod h1:013i+Nw79BMiQiMsOPcVCB5ZIJbYkerPrGnOa00tvmc= +golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= +golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= diff --git a/.github/workflows/acctest-terraform-embedded-lint.yml b/.github/workflows/acctest-terraform-embedded-lint.yml index 03a75ff555c6..0ce65155b6b1 100644 --- a/.github/workflows/acctest-terraform-embedded-lint.yml +++ b/.github/workflows/acctest-terraform-embedded-lint.yml @@ -24,7 +24,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 - - uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 + - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 with: go-version-file: go.mod - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 @@ -52,7 +52,7 @@ jobs: steps: - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 - - uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 + - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 with: go-version-file: go.mod - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 diff --git a/.github/workflows/acctest-terraform-lint.yml b/.github/workflows/acctest-terraform-lint.yml index 5b8377575feb..add27218740f 100644 --- a/.github/workflows/acctest-terraform-lint.yml +++ b/.github/workflows/acctest-terraform-lint.yml @@ -23,7 +23,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 - - uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 + - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 with: go-version-file: go.mod - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 @@ -42,7 +42,7 @@ jobs: steps: - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 - - uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 + - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 with: go-version-file: go.mod - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3d32b97b64f7..714a33cac04d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -29,7 +29,7 @@ jobs: go-version: ${{ steps.get-go-version.outputs.go-version }} steps: - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 - - uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 + - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 with: go-version-file: 'go.mod' - name: Detect Go version diff --git a/.github/workflows/changelog_misspell.yml b/.github/workflows/changelog_misspell.yml index ef983981a41d..14aaa6fb38fc 100644 --- a/.github/workflows/changelog_misspell.yml +++ b/.github/workflows/changelog_misspell.yml @@ -21,7 +21,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 - - uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 + - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 with: go-version-file: go.mod - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 diff --git a/.github/workflows/copyright.yml b/.github/workflows/copyright.yml index 450823f65b64..69bf076acc75 100644 --- a/.github/workflows/copyright.yml +++ b/.github/workflows/copyright.yml @@ -25,7 +25,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 - - uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 + - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 with: go-version-file: go.mod # See also: https://github.com/actions/setup-go/issues/54 diff --git a/.github/workflows/dependencies.yml b/.github/workflows/dependencies.yml index aec60ee9c2c0..c32f02bc12fe 100644 --- a/.github/workflows/dependencies.yml +++ b/.github/workflows/dependencies.yml @@ -41,7 +41,7 @@ jobs: with: fetch-depth: 0 - name: Setup Go - uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 + uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 with: go-version-file: go.mod - name: go env diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index b89e0229e652..b294709d38da 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -44,7 +44,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 - - uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 + - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 with: go-version-file: go.mod - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 diff --git a/.github/workflows/examples.yml b/.github/workflows/examples.yml index f7d43b9bbf2f..0434f258799e 100644 --- a/.github/workflows/examples.yml +++ b/.github/workflows/examples.yml @@ -31,7 +31,7 @@ jobs: with: path: ~/go/pkg/mod key: ${{ runner.os }}-go-pkg-mod-${{ hashFiles('go.sum') }} - - uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 + - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 with: go-version-file: go.mod @@ -68,7 +68,7 @@ jobs: with: path: ~/go/pkg/mod key: ${{ runner.os }}-go-pkg-mod-${{ hashFiles('go.sum') }} - - uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 + - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 with: go-version-file: go.mod - name: go build diff --git a/.github/workflows/generate_changelog.yml b/.github/workflows/generate_changelog.yml index 672e867474bc..e28d5e154e3f 100644 --- a/.github/workflows/generate_changelog.yml +++ b/.github/workflows/generate_changelog.yml @@ -17,7 +17,7 @@ jobs: with: fetch-depth: 0 token: ${{ steps.app-token.outputs.token }} - - uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 + - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 with: go-version-file: .ci/tools/go.mod - run: cd .ci/tools && go install github.com/hashicorp/go-changelog/cmd/changelog-build diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml index a821ff103c44..4154fedd551c 100644 --- a/.github/workflows/golangci-lint.yml +++ b/.github/workflows/golangci-lint.yml @@ -28,7 +28,7 @@ jobs: runs-on: custom-ubuntu-22.04-large steps: - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 - - uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 + - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 with: go-version-file: go.mod cache: false @@ -51,7 +51,7 @@ jobs: runs-on: custom-ubuntu-22.04-xl steps: - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 - - uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 + - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 with: go-version-file: go.mod cache: false @@ -79,7 +79,7 @@ jobs: runs-on: custom-ubuntu-22.04-xl steps: - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 - - uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 + - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 with: go-version-file: go.mod cache: false @@ -107,7 +107,7 @@ jobs: runs-on: custom-ubuntu-22.04-xl steps: - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 - - uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 + - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 with: go-version-file: go.mod cache: false @@ -135,7 +135,7 @@ jobs: runs-on: custom-ubuntu-22.04-xl steps: - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 - - uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 + - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 with: go-version-file: go.mod cache: false diff --git a/.github/workflows/modern_go.yml b/.github/workflows/modern_go.yml index 90d1d48e7617..167784c1efe3 100644 --- a/.github/workflows/modern_go.yml +++ b/.github/workflows/modern_go.yml @@ -22,7 +22,7 @@ jobs: runs-on: custom-ubuntu-22.04-medium steps: - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 - - uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 + - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 with: go-version-file: go.mod # See also: https://github.com/actions/setup-go/issues/54 diff --git a/.github/workflows/provider.yml b/.github/workflows/provider.yml index 92ac4109f36f..f2f59d7c12ed 100644 --- a/.github/workflows/provider.yml +++ b/.github/workflows/provider.yml @@ -38,7 +38,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 - - uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 + - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 with: go-version-file: go.mod - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 @@ -65,7 +65,7 @@ jobs: path: terraform-plugin-dir key: ${{ runner.os }}-terraform-plugin-dir-${{ hashFiles('go.sum') }}-${{ hashFiles('internal/**') }} - if: steps.cache-terraform-plugin-dir.outputs.cache-hit != 'true' || steps.cache-terraform-plugin-dir.outcome == 'failure' - uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 + uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 with: go-version-file: go.mod # See also: https://github.com/actions/setup-go/issues/54 @@ -93,7 +93,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 - - uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 + - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 with: go-version-file: go.mod # See also: https://github.com/actions/setup-go/issues/54 @@ -128,7 +128,7 @@ jobs: - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: fetch-depth: 0 - - uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 + - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 with: go-version-file: go.mod # See also: https://github.com/actions/setup-go/issues/54 @@ -155,7 +155,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 - - uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 + - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 with: go-version-file: go.mod # See also: https://github.com/actions/setup-go/issues/54 @@ -188,7 +188,7 @@ jobs: - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: fetch-depth: 0 - - uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 + - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 with: go-version-file: go.mod # See also: https://github.com/actions/setup-go/issues/54 @@ -279,7 +279,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 - - uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 + - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 with: go-version-file: go.mod - uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd @@ -316,7 +316,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 - - uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 + - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 with: go-version-file: go.mod - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 diff --git a/.github/workflows/providerlint.yml b/.github/workflows/providerlint.yml index 55eb2275c60a..cb9314f4a95d 100644 --- a/.github/workflows/providerlint.yml +++ b/.github/workflows/providerlint.yml @@ -24,7 +24,7 @@ jobs: runs-on: custom-ubuntu-22.04-medium steps: - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 - - uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 + - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 with: go-version-file: go.mod - name: go env diff --git a/.github/workflows/pull_request_target.yml b/.github/workflows/pull_request_target.yml index 4fe096c62b6b..583aa40a1c72 100644 --- a/.github/workflows/pull_request_target.yml +++ b/.github/workflows/pull_request_target.yml @@ -33,7 +33,7 @@ jobs: with: fetch-depth: 0 - name: Setup Go - uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 + uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 with: go-version-file: go.mod - name: go env diff --git a/.github/workflows/skaff.yml b/.github/workflows/skaff.yml index a53c1bff6204..6c710f6ca10d 100644 --- a/.github/workflows/skaff.yml +++ b/.github/workflows/skaff.yml @@ -24,7 +24,7 @@ jobs: - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: fetch-depth: 0 - - uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 + - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 with: go-version-file: skaff/go.mod # See also: https://github.com/actions/setup-go/issues/54 diff --git a/.github/workflows/smarterr.yml b/.github/workflows/smarterr.yml index 827ceab80877..142462d55e90 100644 --- a/.github/workflows/smarterr.yml +++ b/.github/workflows/smarterr.yml @@ -22,7 +22,7 @@ jobs: runs-on: custom-ubuntu-22.04-medium steps: - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 - - uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 + - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 with: go-version-file: go.mod # See also: https://github.com/actions/setup-go/issues/54 diff --git a/.github/workflows/website.yml b/.github/workflows/website.yml index d79ed34975c9..5a45d7e2b182 100644 --- a/.github/workflows/website.yml +++ b/.github/workflows/website.yml @@ -87,7 +87,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 - - uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 + - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 with: go-version-file: .ci/tools/go.mod - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 @@ -103,7 +103,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 - - uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 + - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 with: go-version-file: .ci/tools/go.mod - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 @@ -121,7 +121,7 @@ jobs: - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: fetch-depth: 0 - - uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 + - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 with: go-version-file: .ci/tools/go.mod - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 diff --git a/.github/workflows/workflow-lint.yml b/.github/workflows/workflow-lint.yml index e4ac6590abc1..6bac023f1fac 100644 --- a/.github/workflows/workflow-lint.yml +++ b/.github/workflows/workflow-lint.yml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 - - uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 + - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 with: go-version-file: .ci/tools/go.mod - name: Install actionlint diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ef19eedb880..70a8cc157d99 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,20 @@ -## 6.22.0 (Unreleased) +## 6.23.0 (Unreleased) + +## 6.22.1 (November 21, 2025) + +ENHANCEMENTS: + +* resource/aws_fsx_openzfs_file_system: Support `INTELLIGENT_TIERING` storage type and add `read_cache_configuration` argument ([#45159](https://github.com/hashicorp/terraform-provider-aws/issues/45159)) +* resource/aws_msk_cluster: Add `rebalancing` configuration block to support intelligent rebalancing for Express broker clusters ([#45073](https://github.com/hashicorp/terraform-provider-aws/issues/45073)) + +BUG FIXES: + +* provider: Fix crash in required tag validation interceptor when tag values are unknown. This addresses a regression introduced in [v6.22.0](https://github.com/hashicorp/terraform-provider-aws/blob/main/CHANGELOG.md#6220-november-20-2025). ([#45201](https://github.com/hashicorp/terraform-provider-aws/issues/45201)) +* provider: Fix early return logic in the required tag validation interceptor. This addresses a performance regression introduced in [v6.22.0](https://github.com/hashicorp/terraform-provider-aws/blob/main/CHANGELOG.md#6220-november-20-2025). ([#45201](https://github.com/hashicorp/terraform-provider-aws/issues/45201)) +* resource/aws_accessanalyzer_analyzer: Fix `interface conversion: interface {} is nil, not map[string]interface {}` panics when `configuration.unused_access.analysis_rule.exclusion.resource_tags` contains `null` values ([#45202](https://github.com/hashicorp/terraform-provider-aws/issues/45202)) +* resource/aws_odb_cloud_vm_cluster: Fix incorrect validation error when arguments are configured using variables. This addresses a regression introduced in [v6.22.0](https://github.com/hashicorp/terraform-provider-aws/blob/main/CHANGELOG.md#6220-november-20-2025) ([#45205](https://github.com/hashicorp/terraform-provider-aws/issues/45205)) + +## 6.22.0 (November 20, 2025) NOTES: @@ -7,6 +23,8 @@ NOTES: FEATURES: * **New Ephemeral Resource:** `aws_ecr_authorization_token` ([#44949](https://github.com/hashicorp/terraform-provider-aws/issues/44949)) +* **New Guide:** `Tag Policy Compliance` ([#45143](https://github.com/hashicorp/terraform-provider-aws/issues/45143)) +* **New Resource:** `aws_billing_view` ([#45097](https://github.com/hashicorp/terraform-provider-aws/issues/45097)) * **New Resource:** `aws_vpclattice_domain_verification` ([#45085](https://github.com/hashicorp/terraform-provider-aws/issues/45085)) ENHANCEMENTS: @@ -14,7 +32,9 @@ ENHANCEMENTS: * data-source/aws_lb_listener: Add `default_action.jwt_validation` attribute ([#45089](https://github.com/hashicorp/terraform-provider-aws/issues/45089)) * data-source/aws_lb_listener_rule: Add `action.jwt_validation` attribute ([#45089](https://github.com/hashicorp/terraform-provider-aws/issues/45089)) * data-source/aws_route53_zone: Support filtering by `tags` only or by `vpc_id` only ([#39671](https://github.com/hashicorp/terraform-provider-aws/issues/39671)) +* provider: Add support for enforcing tag policy compliance. This opt-in feature can be enabled via the new `tag_policy_compliance` provider argument, or the `TF_AWS_TAG_POLICY_COMPLIANCE` environment variable. When enabled, the principal executing Terraform must have the `tags:ListRequiredTags` IAM permission. ([#45143](https://github.com/hashicorp/terraform-provider-aws/issues/45143)) * resource/aws_backup_logically_air_gapped_vault: Add `encryption_key_arn` argument ([#45020](https://github.com/hashicorp/terraform-provider-aws/issues/45020)) +* resource/aws_bedrock_guardrail: Add `input_action`, `input_enabled`, `input_modalities`, `output_action`, `output_enabled`, and `output_modalities` arguments to the `content_policy_config.filters_config` block ([#45104](https://github.com/hashicorp/terraform-provider-aws/issues/45104)) * resource/aws_bedrockagent_knowledge_base: Add `storage_configuration.rds_configuration.field_mapping.custom_metadata_field` argument ([#45075](https://github.com/hashicorp/terraform-provider-aws/issues/45075)) * resource/aws_bedrockagentcore_agent_runtime: Add `agent_runtime_artifact.code_configuration` block ([#45091](https://github.com/hashicorp/terraform-provider-aws/issues/45091)) * resource/aws_bedrockagentcore_agent_runtime: Make `agent_runtime_artifact.container_configuration` block optional ([#45091](https://github.com/hashicorp/terraform-provider-aws/issues/45091)) diff --git a/docs/acc-test-environment-variables.md b/docs/acc-test-environment-variables.md index 093f27dbb070..e282f75d07a9 100644 --- a/docs/acc-test-environment-variables.md +++ b/docs/acc-test-environment-variables.md @@ -85,6 +85,7 @@ Environment variables (beyond standard AWS Go SDK ones) used by acceptance testi | `GRAFANA_SSO_GROUP_ID` | AWS SSO group ID for Grafana testing. | | `GRAFANA_SSO_USER_ID` | AWS SSO user ID for Grafana testing. | | `MACIE_MEMBER_ACCOUNT_ID` | Identifier of AWS Account for Macie Member testing. **DEPRECATED:** Should be replaced with standard alternate account handling for tests. | +| `MSK_EXPRESS_BROKER_ENABLED` | Enables MSK Express broker testing. | | `QUICKSIGHT_NAMESPACE` | QuickSight namespace name for testing. | | `QUICKSIGHT_ATHENA_TESTING_ENABLED` | Enable QuickSight tests dependent on Amazon Athena resources. | | `ROUTE53DOMAINS_DOMAIN_NAME` | Registered domain for Route 53 Domains testing. | @@ -100,6 +101,7 @@ Environment variables (beyond standard AWS Go SDK ones) used by acceptance testi | `TEST_AWS_SES_VERIFIED_EMAIL_ARN` | Verified SES Email Identity for use in Cognito User Pool testing. | | `TF_ACC` | Enables Go tests containing `resource.Test()` and `resource.ParallelTest()`. | | `TF_ACC_ASSUME_ROLE_ARN` | Amazon Resource Name of existing IAM Role to use for limited permissions acceptance testing. | +| `TF_ACC_REQUIRED_TAG_KEY` | Name of the tag key required for the resource being tested as defined in the organizational tagging policy | | `TF_AWS_BEDROCK_OSS_COLLECTION_NAME` | Name of the OpenSearch Serverless collection to be used with an Amazon Bedrock Knowledge Base. | | `TF_AWS_CONTROLTOWER_CONTROL_OU_NAME` | Organizational unit name to be targeted by the Control Tower control. | | `TF_AWS_CONTROLTOWER_BASELINE_ENABLE_BASELINE_ARN` | Enable baseline ARN. | diff --git a/go.mod b/go.mod index 47fd7521dbcc..4a4d3fb3ed97 100644 --- a/go.mod +++ b/go.mod @@ -11,268 +11,268 @@ require ( github.com/YakDriver/go-version v0.1.0 github.com/YakDriver/regexache v0.25.0 github.com/YakDriver/smarterr v0.8.0 - github.com/aws/aws-sdk-go-v2 v1.39.6 - github.com/aws/aws-sdk-go-v2/config v1.31.21 - github.com/aws/aws-sdk-go-v2/credentials v1.18.25 - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.13 - github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.20.8 - github.com/aws/aws-sdk-go-v2/service/accessanalyzer v1.45.2 - github.com/aws/aws-sdk-go-v2/service/account v1.29.4 - github.com/aws/aws-sdk-go-v2/service/acm v1.37.13 - github.com/aws/aws-sdk-go-v2/service/acmpca v1.46.2 - github.com/aws/aws-sdk-go-v2/service/amp v1.42.0 - github.com/aws/aws-sdk-go-v2/service/amplify v1.38.5 - github.com/aws/aws-sdk-go-v2/service/apigateway v1.37.0 - github.com/aws/aws-sdk-go-v2/service/apigatewayv2 v1.33.0 - github.com/aws/aws-sdk-go-v2/service/appconfig v1.43.3 - github.com/aws/aws-sdk-go-v2/service/appfabric v1.16.12 - github.com/aws/aws-sdk-go-v2/service/appflow v1.51.3 - github.com/aws/aws-sdk-go-v2/service/appintegrations v1.36.12 - github.com/aws/aws-sdk-go-v2/service/applicationautoscaling v1.41.4 - github.com/aws/aws-sdk-go-v2/service/applicationinsights v1.34.11 - github.com/aws/aws-sdk-go-v2/service/applicationsignals v1.17.4 - github.com/aws/aws-sdk-go-v2/service/appmesh v1.35.3 - github.com/aws/aws-sdk-go-v2/service/apprunner v1.39.5 - github.com/aws/aws-sdk-go-v2/service/appstream v1.52.1 - github.com/aws/aws-sdk-go-v2/service/appsync v1.52.3 - github.com/aws/aws-sdk-go-v2/service/arcregionswitch v1.2.14 - github.com/aws/aws-sdk-go-v2/service/athena v1.55.12 - github.com/aws/aws-sdk-go-v2/service/auditmanager v1.46.3 - github.com/aws/aws-sdk-go-v2/service/autoscaling v1.61.0 - github.com/aws/aws-sdk-go-v2/service/autoscalingplans v1.30.5 - github.com/aws/aws-sdk-go-v2/service/backup v1.54.0 - github.com/aws/aws-sdk-go-v2/service/batch v1.58.6 - github.com/aws/aws-sdk-go-v2/service/bcmdataexports v1.12.5 - github.com/aws/aws-sdk-go-v2/service/bedrock v1.49.1 - github.com/aws/aws-sdk-go-v2/service/bedrockagent v1.51.3 - github.com/aws/aws-sdk-go-v2/service/bedrockagentcorecontrol v1.13.3 - github.com/aws/aws-sdk-go-v2/service/billing v1.9.0 - github.com/aws/aws-sdk-go-v2/service/budgets v1.41.3 - github.com/aws/aws-sdk-go-v2/service/chatbot v1.14.12 - github.com/aws/aws-sdk-go-v2/service/chime v1.41.3 - github.com/aws/aws-sdk-go-v2/service/chimesdkmediapipelines v1.26.12 - github.com/aws/aws-sdk-go-v2/service/chimesdkvoice v1.28.4 - github.com/aws/aws-sdk-go-v2/service/cleanrooms v1.37.3 - github.com/aws/aws-sdk-go-v2/service/cloud9 v1.33.11 - github.com/aws/aws-sdk-go-v2/service/cloudcontrol v1.29.3 - github.com/aws/aws-sdk-go-v2/service/cloudformation v1.70.0 - github.com/aws/aws-sdk-go-v2/service/cloudfront v1.56.2 - github.com/aws/aws-sdk-go-v2/service/cloudfrontkeyvaluestore v1.12.14 - github.com/aws/aws-sdk-go-v2/service/cloudhsmv2 v1.34.11 - github.com/aws/aws-sdk-go-v2/service/cloudsearch v1.32.3 - github.com/aws/aws-sdk-go-v2/service/cloudtrail v1.54.0 - github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.52.3 - github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.60.0 - github.com/aws/aws-sdk-go-v2/service/codeartifact v1.38.12 - github.com/aws/aws-sdk-go-v2/service/codebuild v1.68.4 - github.com/aws/aws-sdk-go-v2/service/codecatalyst v1.21.3 - github.com/aws/aws-sdk-go-v2/service/codecommit v1.33.3 - github.com/aws/aws-sdk-go-v2/service/codeconnections v1.10.11 - github.com/aws/aws-sdk-go-v2/service/codedeploy v1.35.3 - github.com/aws/aws-sdk-go-v2/service/codeguruprofiler v1.29.11 - github.com/aws/aws-sdk-go-v2/service/codegurureviewer v1.34.11 - github.com/aws/aws-sdk-go-v2/service/codepipeline v1.46.12 - github.com/aws/aws-sdk-go-v2/service/codestarconnections v1.35.4 - github.com/aws/aws-sdk-go-v2/service/codestarnotifications v1.31.12 - github.com/aws/aws-sdk-go-v2/service/cognitoidentity v1.33.12 - github.com/aws/aws-sdk-go-v2/service/cognitoidentityprovider v1.57.13 - github.com/aws/aws-sdk-go-v2/service/comprehend v1.40.12 - github.com/aws/aws-sdk-go-v2/service/computeoptimizer v1.48.3 - github.com/aws/aws-sdk-go-v2/service/configservice v1.59.4 - github.com/aws/aws-sdk-go-v2/service/connect v1.146.0 - github.com/aws/aws-sdk-go-v2/service/connectcases v1.34.3 - github.com/aws/aws-sdk-go-v2/service/controltower v1.27.2 - github.com/aws/aws-sdk-go-v2/service/costandusagereportservice v1.34.4 - github.com/aws/aws-sdk-go-v2/service/costexplorer v1.60.0 - github.com/aws/aws-sdk-go-v2/service/costoptimizationhub v1.21.0 - github.com/aws/aws-sdk-go-v2/service/customerprofiles v1.54.5 - github.com/aws/aws-sdk-go-v2/service/databasemigrationservice v1.60.0 - github.com/aws/aws-sdk-go-v2/service/databrew v1.39.5 - github.com/aws/aws-sdk-go-v2/service/dataexchange v1.40.5 - github.com/aws/aws-sdk-go-v2/service/datapipeline v1.30.11 - github.com/aws/aws-sdk-go-v2/service/datasync v1.55.6 - github.com/aws/aws-sdk-go-v2/service/datazone v1.48.0 - github.com/aws/aws-sdk-go-v2/service/dax v1.29.7 - github.com/aws/aws-sdk-go-v2/service/detective v1.38.4 - github.com/aws/aws-sdk-go-v2/service/devicefarm v1.37.0 - github.com/aws/aws-sdk-go-v2/service/devopsguru v1.40.3 - github.com/aws/aws-sdk-go-v2/service/directconnect v1.38.5 - github.com/aws/aws-sdk-go-v2/service/directoryservice v1.38.6 - github.com/aws/aws-sdk-go-v2/service/dlm v1.35.6 - github.com/aws/aws-sdk-go-v2/service/docdb v1.48.3 - github.com/aws/aws-sdk-go-v2/service/docdbelastic v1.20.4 - github.com/aws/aws-sdk-go-v2/service/drs v1.36.4 - github.com/aws/aws-sdk-go-v2/service/dsql v1.11.2 - github.com/aws/aws-sdk-go-v2/service/dynamodb v1.53.0 - github.com/aws/aws-sdk-go-v2/service/ec2 v1.272.0 - github.com/aws/aws-sdk-go-v2/service/ecr v1.53.0 - github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.38.4 - github.com/aws/aws-sdk-go-v2/service/ecs v1.68.0 - github.com/aws/aws-sdk-go-v2/service/efs v1.41.4 - github.com/aws/aws-sdk-go-v2/service/eks v1.74.9 - github.com/aws/aws-sdk-go-v2/service/elasticache v1.51.3 - github.com/aws/aws-sdk-go-v2/service/elasticbeanstalk v1.33.13 - github.com/aws/aws-sdk-go-v2/service/elasticloadbalancing v1.33.13 - github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 v1.53.0 - github.com/aws/aws-sdk-go-v2/service/elasticsearchservice v1.37.13 - github.com/aws/aws-sdk-go-v2/service/elastictranscoder v1.32.12 - github.com/aws/aws-sdk-go-v2/service/emr v1.56.0 - github.com/aws/aws-sdk-go-v2/service/emrcontainers v1.40.8 - github.com/aws/aws-sdk-go-v2/service/emrserverless v1.37.3 - github.com/aws/aws-sdk-go-v2/service/eventbridge v1.45.12 - github.com/aws/aws-sdk-go-v2/service/evidently v1.28.11 - github.com/aws/aws-sdk-go-v2/service/evs v1.5.8 - github.com/aws/aws-sdk-go-v2/service/finspace v1.33.12 - github.com/aws/aws-sdk-go-v2/service/firehose v1.42.3 - github.com/aws/aws-sdk-go-v2/service/fis v1.37.11 - github.com/aws/aws-sdk-go-v2/service/fms v1.44.12 - github.com/aws/aws-sdk-go-v2/service/fsx v1.64.0 - github.com/aws/aws-sdk-go-v2/service/gamelift v1.48.2 - github.com/aws/aws-sdk-go-v2/service/glacier v1.31.12 - github.com/aws/aws-sdk-go-v2/service/globalaccelerator v1.35.5 - github.com/aws/aws-sdk-go-v2/service/glue v1.133.0 - github.com/aws/aws-sdk-go-v2/service/grafana v1.32.5 - github.com/aws/aws-sdk-go-v2/service/greengrass v1.32.12 - github.com/aws/aws-sdk-go-v2/service/groundstation v1.39.2 - github.com/aws/aws-sdk-go-v2/service/guardduty v1.68.0 - github.com/aws/aws-sdk-go-v2/service/healthlake v1.36.4 - github.com/aws/aws-sdk-go-v2/service/iam v1.52.0 - github.com/aws/aws-sdk-go-v2/service/identitystore v1.34.2 - github.com/aws/aws-sdk-go-v2/service/imagebuilder v1.49.0 - github.com/aws/aws-sdk-go-v2/service/inspector v1.30.11 - github.com/aws/aws-sdk-go-v2/service/inspector2 v1.45.0 - github.com/aws/aws-sdk-go-v2/service/internetmonitor v1.26.4 - github.com/aws/aws-sdk-go-v2/service/invoicing v1.8.0 - github.com/aws/aws-sdk-go-v2/service/iot v1.69.11 - github.com/aws/aws-sdk-go-v2/service/ivs v1.48.5 - github.com/aws/aws-sdk-go-v2/service/ivschat v1.21.11 - github.com/aws/aws-sdk-go-v2/service/kafka v1.46.0 - github.com/aws/aws-sdk-go-v2/service/kafkaconnect v1.27.12 - github.com/aws/aws-sdk-go-v2/service/kendra v1.60.12 - github.com/aws/aws-sdk-go-v2/service/keyspaces v1.24.5 - github.com/aws/aws-sdk-go-v2/service/kinesis v1.42.3 - github.com/aws/aws-sdk-go-v2/service/kinesisanalytics v1.30.12 - github.com/aws/aws-sdk-go-v2/service/kinesisanalyticsv2 v1.36.13 - github.com/aws/aws-sdk-go-v2/service/kinesisvideo v1.32.11 - github.com/aws/aws-sdk-go-v2/service/kms v1.48.2 - github.com/aws/aws-sdk-go-v2/service/lakeformation v1.45.11 - github.com/aws/aws-sdk-go-v2/service/lambda v1.82.0 - github.com/aws/aws-sdk-go-v2/service/launchwizard v1.13.12 - github.com/aws/aws-sdk-go-v2/service/lexmodelbuildingservice v1.34.5 - github.com/aws/aws-sdk-go-v2/service/lexmodelsv2 v1.57.0 - github.com/aws/aws-sdk-go-v2/service/licensemanager v1.36.12 - github.com/aws/aws-sdk-go-v2/service/lightsail v1.50.6 - github.com/aws/aws-sdk-go-v2/service/location v1.50.4 + github.com/aws/aws-sdk-go-v2 v1.40.0 + github.com/aws/aws-sdk-go-v2/config v1.32.0 + github.com/aws/aws-sdk-go-v2/credentials v1.19.0 + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.14 + github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.20.10 + github.com/aws/aws-sdk-go-v2/service/accessanalyzer v1.45.3 + github.com/aws/aws-sdk-go-v2/service/account v1.29.5 + github.com/aws/aws-sdk-go-v2/service/acm v1.37.14 + github.com/aws/aws-sdk-go-v2/service/acmpca v1.46.3 + github.com/aws/aws-sdk-go-v2/service/amp v1.42.1 + github.com/aws/aws-sdk-go-v2/service/amplify v1.38.6 + github.com/aws/aws-sdk-go-v2/service/apigateway v1.37.1 + github.com/aws/aws-sdk-go-v2/service/apigatewayv2 v1.33.1 + github.com/aws/aws-sdk-go-v2/service/appconfig v1.43.4 + github.com/aws/aws-sdk-go-v2/service/appfabric v1.16.13 + github.com/aws/aws-sdk-go-v2/service/appflow v1.51.4 + github.com/aws/aws-sdk-go-v2/service/appintegrations v1.36.13 + github.com/aws/aws-sdk-go-v2/service/applicationautoscaling v1.41.5 + github.com/aws/aws-sdk-go-v2/service/applicationinsights v1.34.12 + github.com/aws/aws-sdk-go-v2/service/applicationsignals v1.18.0 + github.com/aws/aws-sdk-go-v2/service/appmesh v1.35.4 + github.com/aws/aws-sdk-go-v2/service/apprunner v1.39.6 + github.com/aws/aws-sdk-go-v2/service/appstream v1.52.2 + github.com/aws/aws-sdk-go-v2/service/appsync v1.52.4 + github.com/aws/aws-sdk-go-v2/service/arcregionswitch v1.2.15 + github.com/aws/aws-sdk-go-v2/service/athena v1.55.13 + github.com/aws/aws-sdk-go-v2/service/auditmanager v1.46.4 + github.com/aws/aws-sdk-go-v2/service/autoscaling v1.62.0 + github.com/aws/aws-sdk-go-v2/service/autoscalingplans v1.30.6 + github.com/aws/aws-sdk-go-v2/service/backup v1.54.1 + github.com/aws/aws-sdk-go-v2/service/batch v1.58.7 + github.com/aws/aws-sdk-go-v2/service/bcmdataexports v1.12.6 + github.com/aws/aws-sdk-go-v2/service/bedrock v1.49.3 + github.com/aws/aws-sdk-go-v2/service/bedrockagent v1.51.4 + github.com/aws/aws-sdk-go-v2/service/bedrockagentcorecontrol v1.13.4 + github.com/aws/aws-sdk-go-v2/service/billing v1.9.1 + github.com/aws/aws-sdk-go-v2/service/budgets v1.42.0 + github.com/aws/aws-sdk-go-v2/service/chatbot v1.14.13 + github.com/aws/aws-sdk-go-v2/service/chime v1.41.4 + github.com/aws/aws-sdk-go-v2/service/chimesdkmediapipelines v1.26.13 + github.com/aws/aws-sdk-go-v2/service/chimesdkvoice v1.28.5 + github.com/aws/aws-sdk-go-v2/service/cleanrooms v1.37.4 + github.com/aws/aws-sdk-go-v2/service/cloud9 v1.33.12 + github.com/aws/aws-sdk-go-v2/service/cloudcontrol v1.29.4 + github.com/aws/aws-sdk-go-v2/service/cloudformation v1.70.1 + github.com/aws/aws-sdk-go-v2/service/cloudfront v1.57.0 + github.com/aws/aws-sdk-go-v2/service/cloudfrontkeyvaluestore v1.12.15 + github.com/aws/aws-sdk-go-v2/service/cloudhsmv2 v1.34.12 + github.com/aws/aws-sdk-go-v2/service/cloudsearch v1.32.4 + github.com/aws/aws-sdk-go-v2/service/cloudtrail v1.55.0 + github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.52.4 + github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.60.1 + github.com/aws/aws-sdk-go-v2/service/codeartifact v1.38.13 + github.com/aws/aws-sdk-go-v2/service/codebuild v1.68.5 + github.com/aws/aws-sdk-go-v2/service/codecatalyst v1.21.4 + github.com/aws/aws-sdk-go-v2/service/codecommit v1.33.4 + github.com/aws/aws-sdk-go-v2/service/codeconnections v1.10.12 + github.com/aws/aws-sdk-go-v2/service/codedeploy v1.35.4 + github.com/aws/aws-sdk-go-v2/service/codeguruprofiler v1.29.12 + github.com/aws/aws-sdk-go-v2/service/codegurureviewer v1.34.12 + github.com/aws/aws-sdk-go-v2/service/codepipeline v1.46.13 + github.com/aws/aws-sdk-go-v2/service/codestarconnections v1.35.5 + github.com/aws/aws-sdk-go-v2/service/codestarnotifications v1.31.13 + github.com/aws/aws-sdk-go-v2/service/cognitoidentity v1.33.13 + github.com/aws/aws-sdk-go-v2/service/cognitoidentityprovider v1.57.14 + github.com/aws/aws-sdk-go-v2/service/comprehend v1.40.13 + github.com/aws/aws-sdk-go-v2/service/computeoptimizer v1.48.4 + github.com/aws/aws-sdk-go-v2/service/configservice v1.59.5 + github.com/aws/aws-sdk-go-v2/service/connect v1.147.0 + github.com/aws/aws-sdk-go-v2/service/connectcases v1.34.4 + github.com/aws/aws-sdk-go-v2/service/controltower v1.27.3 + github.com/aws/aws-sdk-go-v2/service/costandusagereportservice v1.34.5 + github.com/aws/aws-sdk-go-v2/service/costexplorer v1.60.1 + github.com/aws/aws-sdk-go-v2/service/costoptimizationhub v1.21.1 + github.com/aws/aws-sdk-go-v2/service/customerprofiles v1.54.6 + github.com/aws/aws-sdk-go-v2/service/databasemigrationservice v1.61.0 + github.com/aws/aws-sdk-go-v2/service/databrew v1.39.6 + github.com/aws/aws-sdk-go-v2/service/dataexchange v1.40.6 + github.com/aws/aws-sdk-go-v2/service/datapipeline v1.30.12 + github.com/aws/aws-sdk-go-v2/service/datasync v1.56.0 + github.com/aws/aws-sdk-go-v2/service/datazone v1.48.1 + github.com/aws/aws-sdk-go-v2/service/dax v1.29.8 + github.com/aws/aws-sdk-go-v2/service/detective v1.38.5 + github.com/aws/aws-sdk-go-v2/service/devicefarm v1.38.0 + github.com/aws/aws-sdk-go-v2/service/devopsguru v1.40.4 + github.com/aws/aws-sdk-go-v2/service/directconnect v1.38.6 + github.com/aws/aws-sdk-go-v2/service/directoryservice v1.38.7 + github.com/aws/aws-sdk-go-v2/service/dlm v1.35.7 + github.com/aws/aws-sdk-go-v2/service/docdb v1.48.4 + github.com/aws/aws-sdk-go-v2/service/docdbelastic v1.20.5 + github.com/aws/aws-sdk-go-v2/service/drs v1.36.5 + github.com/aws/aws-sdk-go-v2/service/dsql v1.12.0 + github.com/aws/aws-sdk-go-v2/service/dynamodb v1.53.1 + github.com/aws/aws-sdk-go-v2/service/ec2 v1.273.0 + github.com/aws/aws-sdk-go-v2/service/ecr v1.53.1 + github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.38.5 + github.com/aws/aws-sdk-go-v2/service/ecs v1.69.0 + github.com/aws/aws-sdk-go-v2/service/efs v1.41.5 + github.com/aws/aws-sdk-go-v2/service/eks v1.74.10 + github.com/aws/aws-sdk-go-v2/service/elasticache v1.51.4 + github.com/aws/aws-sdk-go-v2/service/elasticbeanstalk v1.33.14 + github.com/aws/aws-sdk-go-v2/service/elasticloadbalancing v1.33.14 + github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 v1.54.0 + github.com/aws/aws-sdk-go-v2/service/elasticsearchservice v1.37.14 + github.com/aws/aws-sdk-go-v2/service/elastictranscoder v1.32.13 + github.com/aws/aws-sdk-go-v2/service/emr v1.57.0 + github.com/aws/aws-sdk-go-v2/service/emrcontainers v1.40.9 + github.com/aws/aws-sdk-go-v2/service/emrserverless v1.37.4 + github.com/aws/aws-sdk-go-v2/service/eventbridge v1.45.13 + github.com/aws/aws-sdk-go-v2/service/evidently v1.28.12 + github.com/aws/aws-sdk-go-v2/service/evs v1.5.9 + github.com/aws/aws-sdk-go-v2/service/finspace v1.33.13 + github.com/aws/aws-sdk-go-v2/service/firehose v1.42.4 + github.com/aws/aws-sdk-go-v2/service/fis v1.37.12 + github.com/aws/aws-sdk-go-v2/service/fms v1.44.13 + github.com/aws/aws-sdk-go-v2/service/fsx v1.64.1 + github.com/aws/aws-sdk-go-v2/service/gamelift v1.48.3 + github.com/aws/aws-sdk-go-v2/service/glacier v1.31.13 + github.com/aws/aws-sdk-go-v2/service/globalaccelerator v1.35.6 + github.com/aws/aws-sdk-go-v2/service/glue v1.134.0 + github.com/aws/aws-sdk-go-v2/service/grafana v1.32.6 + github.com/aws/aws-sdk-go-v2/service/greengrass v1.32.13 + github.com/aws/aws-sdk-go-v2/service/groundstation v1.39.3 + github.com/aws/aws-sdk-go-v2/service/guardduty v1.68.1 + github.com/aws/aws-sdk-go-v2/service/healthlake v1.36.5 + github.com/aws/aws-sdk-go-v2/service/iam v1.52.1 + github.com/aws/aws-sdk-go-v2/service/identitystore v1.34.4 + github.com/aws/aws-sdk-go-v2/service/imagebuilder v1.50.0 + github.com/aws/aws-sdk-go-v2/service/inspector v1.30.12 + github.com/aws/aws-sdk-go-v2/service/inspector2 v1.45.1 + github.com/aws/aws-sdk-go-v2/service/internetmonitor v1.26.5 + github.com/aws/aws-sdk-go-v2/service/invoicing v1.8.1 + github.com/aws/aws-sdk-go-v2/service/iot v1.69.12 + github.com/aws/aws-sdk-go-v2/service/ivs v1.48.6 + github.com/aws/aws-sdk-go-v2/service/ivschat v1.21.12 + github.com/aws/aws-sdk-go-v2/service/kafka v1.46.1 + github.com/aws/aws-sdk-go-v2/service/kafkaconnect v1.27.13 + github.com/aws/aws-sdk-go-v2/service/kendra v1.60.13 + github.com/aws/aws-sdk-go-v2/service/keyspaces v1.24.6 + github.com/aws/aws-sdk-go-v2/service/kinesis v1.42.5 + github.com/aws/aws-sdk-go-v2/service/kinesisanalytics v1.30.13 + github.com/aws/aws-sdk-go-v2/service/kinesisanalyticsv2 v1.36.14 + github.com/aws/aws-sdk-go-v2/service/kinesisvideo v1.32.12 + github.com/aws/aws-sdk-go-v2/service/kms v1.48.3 + github.com/aws/aws-sdk-go-v2/service/lakeformation v1.46.0 + github.com/aws/aws-sdk-go-v2/service/lambda v1.82.1 + github.com/aws/aws-sdk-go-v2/service/launchwizard v1.13.13 + github.com/aws/aws-sdk-go-v2/service/lexmodelbuildingservice v1.34.6 + github.com/aws/aws-sdk-go-v2/service/lexmodelsv2 v1.57.1 + github.com/aws/aws-sdk-go-v2/service/licensemanager v1.37.0 + github.com/aws/aws-sdk-go-v2/service/lightsail v1.50.7 + github.com/aws/aws-sdk-go-v2/service/location v1.50.5 github.com/aws/aws-sdk-go-v2/service/lookoutmetrics v1.37.2 - github.com/aws/aws-sdk-go-v2/service/m2 v1.26.5 - github.com/aws/aws-sdk-go-v2/service/macie2 v1.50.4 - github.com/aws/aws-sdk-go-v2/service/mediaconnect v1.46.0 - github.com/aws/aws-sdk-go-v2/service/mediaconvert v1.85.0 - github.com/aws/aws-sdk-go-v2/service/medialive v1.87.0 - github.com/aws/aws-sdk-go-v2/service/mediapackage v1.39.12 - github.com/aws/aws-sdk-go-v2/service/mediapackagev2 v1.33.0 - github.com/aws/aws-sdk-go-v2/service/mediapackagevod v1.39.12 - github.com/aws/aws-sdk-go-v2/service/mediastore v1.29.12 - github.com/aws/aws-sdk-go-v2/service/memorydb v1.33.5 - github.com/aws/aws-sdk-go-v2/service/mgn v1.38.4 - github.com/aws/aws-sdk-go-v2/service/mq v1.34.10 - github.com/aws/aws-sdk-go-v2/service/mwaa v1.39.12 - github.com/aws/aws-sdk-go-v2/service/neptune v1.43.3 - github.com/aws/aws-sdk-go-v2/service/neptunegraph v1.21.11 - github.com/aws/aws-sdk-go-v2/service/networkfirewall v1.58.0 - github.com/aws/aws-sdk-go-v2/service/networkflowmonitor v1.11.0 - github.com/aws/aws-sdk-go-v2/service/networkmanager v1.40.5 - github.com/aws/aws-sdk-go-v2/service/networkmonitor v1.13.4 - github.com/aws/aws-sdk-go-v2/service/notifications v1.7.10 - github.com/aws/aws-sdk-go-v2/service/notificationscontacts v1.5.14 - github.com/aws/aws-sdk-go-v2/service/oam v1.23.5 - github.com/aws/aws-sdk-go-v2/service/observabilityadmin v1.8.6 - github.com/aws/aws-sdk-go-v2/service/odb v1.5.6 - github.com/aws/aws-sdk-go-v2/service/opensearch v1.54.0 - github.com/aws/aws-sdk-go-v2/service/opensearchserverless v1.27.4 - github.com/aws/aws-sdk-go-v2/service/organizations v1.46.4 - github.com/aws/aws-sdk-go-v2/service/osis v1.21.5 - github.com/aws/aws-sdk-go-v2/service/outposts v1.57.6 - github.com/aws/aws-sdk-go-v2/service/paymentcryptography v1.26.3 - github.com/aws/aws-sdk-go-v2/service/pcaconnectorad v1.15.12 - github.com/aws/aws-sdk-go-v2/service/pcs v1.15.0 - github.com/aws/aws-sdk-go-v2/service/pinpoint v1.39.12 - github.com/aws/aws-sdk-go-v2/service/pinpointsmsvoicev2 v1.26.2 - github.com/aws/aws-sdk-go-v2/service/pipes v1.23.11 - github.com/aws/aws-sdk-go-v2/service/polly v1.54.5 - github.com/aws/aws-sdk-go-v2/service/pricing v1.40.5 - github.com/aws/aws-sdk-go-v2/service/qbusiness v1.33.12 + github.com/aws/aws-sdk-go-v2/service/m2 v1.26.6 + github.com/aws/aws-sdk-go-v2/service/macie2 v1.50.5 + github.com/aws/aws-sdk-go-v2/service/mediaconnect v1.46.1 + github.com/aws/aws-sdk-go-v2/service/mediaconvert v1.85.1 + github.com/aws/aws-sdk-go-v2/service/medialive v1.87.1 + github.com/aws/aws-sdk-go-v2/service/mediapackage v1.39.13 + github.com/aws/aws-sdk-go-v2/service/mediapackagev2 v1.33.1 + github.com/aws/aws-sdk-go-v2/service/mediapackagevod v1.39.13 + github.com/aws/aws-sdk-go-v2/service/mediastore v1.29.13 + github.com/aws/aws-sdk-go-v2/service/memorydb v1.33.6 + github.com/aws/aws-sdk-go-v2/service/mgn v1.38.5 + github.com/aws/aws-sdk-go-v2/service/mq v1.34.11 + github.com/aws/aws-sdk-go-v2/service/mwaa v1.39.13 + github.com/aws/aws-sdk-go-v2/service/neptune v1.43.4 + github.com/aws/aws-sdk-go-v2/service/neptunegraph v1.21.12 + github.com/aws/aws-sdk-go-v2/service/networkfirewall v1.58.1 + github.com/aws/aws-sdk-go-v2/service/networkflowmonitor v1.11.1 + github.com/aws/aws-sdk-go-v2/service/networkmanager v1.41.0 + github.com/aws/aws-sdk-go-v2/service/networkmonitor v1.13.5 + github.com/aws/aws-sdk-go-v2/service/notifications v1.7.11 + github.com/aws/aws-sdk-go-v2/service/notificationscontacts v1.5.15 + github.com/aws/aws-sdk-go-v2/service/oam v1.23.6 + github.com/aws/aws-sdk-go-v2/service/observabilityadmin v1.8.7 + github.com/aws/aws-sdk-go-v2/service/odb v1.5.7 + github.com/aws/aws-sdk-go-v2/service/opensearch v1.54.1 + github.com/aws/aws-sdk-go-v2/service/opensearchserverless v1.27.5 + github.com/aws/aws-sdk-go-v2/service/organizations v1.47.0 + github.com/aws/aws-sdk-go-v2/service/osis v1.21.6 + github.com/aws/aws-sdk-go-v2/service/outposts v1.57.7 + github.com/aws/aws-sdk-go-v2/service/paymentcryptography v1.26.4 + github.com/aws/aws-sdk-go-v2/service/pcaconnectorad v1.15.13 + github.com/aws/aws-sdk-go-v2/service/pcs v1.15.1 + github.com/aws/aws-sdk-go-v2/service/pinpoint v1.39.13 + github.com/aws/aws-sdk-go-v2/service/pinpointsmsvoicev2 v1.26.3 + github.com/aws/aws-sdk-go-v2/service/pipes v1.23.12 + github.com/aws/aws-sdk-go-v2/service/polly v1.54.6 + github.com/aws/aws-sdk-go-v2/service/pricing v1.40.6 + github.com/aws/aws-sdk-go-v2/service/qbusiness v1.33.13 github.com/aws/aws-sdk-go-v2/service/qldb v1.32.2 - github.com/aws/aws-sdk-go-v2/service/quicksight v1.96.2 - github.com/aws/aws-sdk-go-v2/service/ram v1.34.13 - github.com/aws/aws-sdk-go-v2/service/rbin v1.26.13 - github.com/aws/aws-sdk-go-v2/service/rds v1.109.0 - github.com/aws/aws-sdk-go-v2/service/redshift v1.60.0 - github.com/aws/aws-sdk-go-v2/service/redshiftdata v1.37.12 - github.com/aws/aws-sdk-go-v2/service/redshiftserverless v1.31.15 - github.com/aws/aws-sdk-go-v2/service/rekognition v1.51.11 - github.com/aws/aws-sdk-go-v2/service/resiliencehub v1.35.4 - github.com/aws/aws-sdk-go-v2/service/resourceexplorer2 v1.22.6 - github.com/aws/aws-sdk-go-v2/service/resourcegroups v1.33.14 - github.com/aws/aws-sdk-go-v2/service/resourcegroupstaggingapi v1.31.0 - github.com/aws/aws-sdk-go-v2/service/rolesanywhere v1.21.12 - github.com/aws/aws-sdk-go-v2/service/route53 v1.60.0 - github.com/aws/aws-sdk-go-v2/service/route53domains v1.34.10 - github.com/aws/aws-sdk-go-v2/service/route53profiles v1.9.12 - github.com/aws/aws-sdk-go-v2/service/route53recoverycontrolconfig v1.32.5 - github.com/aws/aws-sdk-go-v2/service/route53recoveryreadiness v1.26.12 - github.com/aws/aws-sdk-go-v2/service/route53resolver v1.41.0 - github.com/aws/aws-sdk-go-v2/service/rum v1.30.0 - github.com/aws/aws-sdk-go-v2/service/s3 v1.91.0 - github.com/aws/aws-sdk-go-v2/service/s3control v1.66.9 - github.com/aws/aws-sdk-go-v2/service/s3outposts v1.34.3 - github.com/aws/aws-sdk-go-v2/service/s3tables v1.12.0 - github.com/aws/aws-sdk-go-v2/service/s3vectors v1.5.2 - github.com/aws/aws-sdk-go-v2/service/sagemaker v1.224.0 - github.com/aws/aws-sdk-go-v2/service/scheduler v1.17.12 - github.com/aws/aws-sdk-go-v2/service/schemas v1.34.3 - github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.40.0 - github.com/aws/aws-sdk-go-v2/service/securityhub v1.65.4 - github.com/aws/aws-sdk-go-v2/service/securitylake v1.25.4 - github.com/aws/aws-sdk-go-v2/service/serverlessapplicationrepository v1.30.3 - github.com/aws/aws-sdk-go-v2/service/servicecatalog v1.39.3 - github.com/aws/aws-sdk-go-v2/service/servicecatalogappregistry v1.35.12 - github.com/aws/aws-sdk-go-v2/service/servicediscovery v1.39.16 - github.com/aws/aws-sdk-go-v2/service/servicequotas v1.33.7 - github.com/aws/aws-sdk-go-v2/service/ses v1.34.11 - github.com/aws/aws-sdk-go-v2/service/sesv2 v1.54.4 - github.com/aws/aws-sdk-go-v2/service/sfn v1.40.0 - github.com/aws/aws-sdk-go-v2/service/shield v1.34.12 - github.com/aws/aws-sdk-go-v2/service/signer v1.31.12 - github.com/aws/aws-sdk-go-v2/service/sns v1.39.5 - github.com/aws/aws-sdk-go-v2/service/sqs v1.42.15 - github.com/aws/aws-sdk-go-v2/service/ssm v1.67.2 - github.com/aws/aws-sdk-go-v2/service/ssmcontacts v1.31.5 - github.com/aws/aws-sdk-go-v2/service/ssmincidents v1.39.11 - github.com/aws/aws-sdk-go-v2/service/ssmquicksetup v1.8.12 - github.com/aws/aws-sdk-go-v2/service/ssmsap v1.25.11 - github.com/aws/aws-sdk-go-v2/service/sso v1.30.3 - github.com/aws/aws-sdk-go-v2/service/ssoadmin v1.36.8 - github.com/aws/aws-sdk-go-v2/service/storagegateway v1.43.4 - github.com/aws/aws-sdk-go-v2/service/sts v1.41.0 - github.com/aws/aws-sdk-go-v2/service/swf v1.33.6 - github.com/aws/aws-sdk-go-v2/service/synthetics v1.42.4 - github.com/aws/aws-sdk-go-v2/service/taxsettings v1.16.12 - github.com/aws/aws-sdk-go-v2/service/timestreaminfluxdb v1.17.6 - github.com/aws/aws-sdk-go-v2/service/timestreamquery v1.36.5 - github.com/aws/aws-sdk-go-v2/service/timestreamwrite v1.35.11 - github.com/aws/aws-sdk-go-v2/service/transcribe v1.53.6 - github.com/aws/aws-sdk-go-v2/service/transfer v1.67.6 - github.com/aws/aws-sdk-go-v2/service/verifiedpermissions v1.30.2 - github.com/aws/aws-sdk-go-v2/service/vpclattice v1.20.2 - github.com/aws/aws-sdk-go-v2/service/waf v1.30.11 - github.com/aws/aws-sdk-go-v2/service/wafregional v1.30.12 - github.com/aws/aws-sdk-go-v2/service/wafv2 v1.70.0 - github.com/aws/aws-sdk-go-v2/service/wellarchitected v1.39.12 - github.com/aws/aws-sdk-go-v2/service/workmail v1.36.10 - github.com/aws/aws-sdk-go-v2/service/workspaces v1.64.4 - github.com/aws/aws-sdk-go-v2/service/workspacesweb v1.34.0 - github.com/aws/aws-sdk-go-v2/service/xray v1.36.11 + github.com/aws/aws-sdk-go-v2/service/quicksight v1.97.0 + github.com/aws/aws-sdk-go-v2/service/ram v1.34.14 + github.com/aws/aws-sdk-go-v2/service/rbin v1.27.0 + github.com/aws/aws-sdk-go-v2/service/rds v1.110.0 + github.com/aws/aws-sdk-go-v2/service/redshift v1.60.1 + github.com/aws/aws-sdk-go-v2/service/redshiftdata v1.38.0 + github.com/aws/aws-sdk-go-v2/service/redshiftserverless v1.31.16 + github.com/aws/aws-sdk-go-v2/service/rekognition v1.51.12 + github.com/aws/aws-sdk-go-v2/service/resiliencehub v1.35.5 + github.com/aws/aws-sdk-go-v2/service/resourceexplorer2 v1.22.7 + github.com/aws/aws-sdk-go-v2/service/resourcegroups v1.33.15 + github.com/aws/aws-sdk-go-v2/service/resourcegroupstaggingapi v1.31.1 + github.com/aws/aws-sdk-go-v2/service/rolesanywhere v1.21.13 + github.com/aws/aws-sdk-go-v2/service/route53 v1.60.1 + github.com/aws/aws-sdk-go-v2/service/route53domains v1.34.11 + github.com/aws/aws-sdk-go-v2/service/route53profiles v1.9.13 + github.com/aws/aws-sdk-go-v2/service/route53recoverycontrolconfig v1.32.6 + github.com/aws/aws-sdk-go-v2/service/route53recoveryreadiness v1.26.13 + github.com/aws/aws-sdk-go-v2/service/route53resolver v1.41.1 + github.com/aws/aws-sdk-go-v2/service/rum v1.30.1 + github.com/aws/aws-sdk-go-v2/service/s3 v1.92.0 + github.com/aws/aws-sdk-go-v2/service/s3control v1.66.10 + github.com/aws/aws-sdk-go-v2/service/s3outposts v1.34.4 + github.com/aws/aws-sdk-go-v2/service/s3tables v1.12.1 + github.com/aws/aws-sdk-go-v2/service/s3vectors v1.5.3 + github.com/aws/aws-sdk-go-v2/service/sagemaker v1.225.0 + github.com/aws/aws-sdk-go-v2/service/scheduler v1.17.13 + github.com/aws/aws-sdk-go-v2/service/schemas v1.34.4 + github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.40.1 + github.com/aws/aws-sdk-go-v2/service/securityhub v1.66.0 + github.com/aws/aws-sdk-go-v2/service/securitylake v1.25.5 + github.com/aws/aws-sdk-go-v2/service/serverlessapplicationrepository v1.30.4 + github.com/aws/aws-sdk-go-v2/service/servicecatalog v1.39.4 + github.com/aws/aws-sdk-go-v2/service/servicecatalogappregistry v1.35.13 + github.com/aws/aws-sdk-go-v2/service/servicediscovery v1.39.17 + github.com/aws/aws-sdk-go-v2/service/servicequotas v1.33.8 + github.com/aws/aws-sdk-go-v2/service/ses v1.34.12 + github.com/aws/aws-sdk-go-v2/service/sesv2 v1.54.5 + github.com/aws/aws-sdk-go-v2/service/sfn v1.40.1 + github.com/aws/aws-sdk-go-v2/service/shield v1.34.13 + github.com/aws/aws-sdk-go-v2/service/signer v1.31.13 + github.com/aws/aws-sdk-go-v2/service/sns v1.39.6 + github.com/aws/aws-sdk-go-v2/service/sqs v1.42.16 + github.com/aws/aws-sdk-go-v2/service/ssm v1.67.3 + github.com/aws/aws-sdk-go-v2/service/ssmcontacts v1.31.6 + github.com/aws/aws-sdk-go-v2/service/ssmincidents v1.39.12 + github.com/aws/aws-sdk-go-v2/service/ssmquicksetup v1.8.13 + github.com/aws/aws-sdk-go-v2/service/ssmsap v1.25.12 + github.com/aws/aws-sdk-go-v2/service/sso v1.30.4 + github.com/aws/aws-sdk-go-v2/service/ssoadmin v1.36.9 + github.com/aws/aws-sdk-go-v2/service/storagegateway v1.43.5 + github.com/aws/aws-sdk-go-v2/service/sts v1.41.1 + github.com/aws/aws-sdk-go-v2/service/swf v1.33.7 + github.com/aws/aws-sdk-go-v2/service/synthetics v1.42.5 + github.com/aws/aws-sdk-go-v2/service/taxsettings v1.16.13 + github.com/aws/aws-sdk-go-v2/service/timestreaminfluxdb v1.17.7 + github.com/aws/aws-sdk-go-v2/service/timestreamquery v1.36.6 + github.com/aws/aws-sdk-go-v2/service/timestreamwrite v1.35.12 + github.com/aws/aws-sdk-go-v2/service/transcribe v1.53.7 + github.com/aws/aws-sdk-go-v2/service/transfer v1.67.7 + github.com/aws/aws-sdk-go-v2/service/verifiedpermissions v1.30.3 + github.com/aws/aws-sdk-go-v2/service/vpclattice v1.20.3 + github.com/aws/aws-sdk-go-v2/service/waf v1.30.12 + github.com/aws/aws-sdk-go-v2/service/wafregional v1.30.13 + github.com/aws/aws-sdk-go-v2/service/wafv2 v1.70.1 + github.com/aws/aws-sdk-go-v2/service/wellarchitected v1.39.13 + github.com/aws/aws-sdk-go-v2/service/workmail v1.36.11 + github.com/aws/aws-sdk-go-v2/service/workspaces v1.64.5 + github.com/aws/aws-sdk-go-v2/service/workspacesweb v1.34.1 + github.com/aws/aws-sdk-go-v2/service/xray v1.36.12 github.com/aws/smithy-go v1.23.2 github.com/beevik/etree v1.6.0 github.com/cedar-policy/cedar-go v1.3.0 @@ -315,7 +315,7 @@ require ( github.com/shopspring/decimal v1.4.0 go.opentelemetry.io/contrib/instrumentation/github.com/aws/aws-sdk-go-v2/otelaws v0.63.0 go.opentelemetry.io/otel v1.38.0 - golang.org/x/crypto v0.44.0 + golang.org/x/crypto v0.45.0 golang.org/x/text v0.31.0 golang.org/x/tools v0.39.0 gopkg.in/dnaeon/go-vcr.v4 v4.0.5 @@ -329,16 +329,17 @@ require ( 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.7.3 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.13 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.13 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.14 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.14 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 // indirect - github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.13 // indirect + github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.14 // indirect github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.3 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.4 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.11.13 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.13 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.13 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.7 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.5 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.11.14 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.14 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.14 // indirect + github.com/aws/aws-sdk-go-v2/service/signin v1.0.1 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.8 // indirect github.com/bgentry/speakeasy v0.1.0 // indirect github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect github.com/cloudflare/circl v1.6.1 // indirect diff --git a/go.sum b/go.sum index 62dada21806f..717cf94c80ee 100644 --- a/go.sum +++ b/go.sum @@ -23,552 +23,554 @@ github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew 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.39.6 h1:2JrPCVgWJm7bm83BDwY5z8ietmeJUbh3O2ACnn+Xsqk= -github.com/aws/aws-sdk-go-v2 v1.39.6/go.mod h1:c9pm7VwuW0UPxAEYGyTmyurVcNrbF6Rt/wixFqDhcjE= +github.com/aws/aws-sdk-go-v2 v1.40.0 h1:/WMUA0kjhZExjOQN2z3oLALDREea1A7TobfuiBrKlwc= +github.com/aws/aws-sdk-go-v2 v1.40.0/go.mod h1:c9pm7VwuW0UPxAEYGyTmyurVcNrbF6Rt/wixFqDhcjE= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.3 h1:DHctwEM8P8iTXFxC/QK0MRjwEpWQeM9yzidCRjldUz0= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.3/go.mod h1:xdCzcZEtnSTKVDOmUZs4l/j3pSV6rpo1WXl5ugNsL8Y= -github.com/aws/aws-sdk-go-v2/config v1.31.21 h1:gH/y+NphLGIVuNHXNkTQir3PmL44Efe8OpPAsbDms0o= -github.com/aws/aws-sdk-go-v2/config v1.31.21/go.mod h1:P6I8guuLej6F2++fKUlo9OIhI59LuEsyEZZMMmgqh/4= -github.com/aws/aws-sdk-go-v2/credentials v1.18.25 h1:MvtSN3ECsQbgEHcux1pZQhuMjZnShlsqcS0Pqlan4Vw= -github.com/aws/aws-sdk-go-v2/credentials v1.18.25/go.mod h1:YATyDPzlHucr1cxEE9rsZl7ZG3gQsxpjD6o5of/8qXE= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.13 h1:T1brd5dR3/fzNFAQch/iBKeX07/ffu/cLu+q+RuzEWk= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.13/go.mod h1:Peg/GBAQ6JDt+RoBf4meB1wylmAipb7Kg2ZFakZTlwk= -github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.20.8 h1:R1Ws+p6Gyk0mdVvMI8zruUFnqaFouKKKDOdadtKbHbI= -github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.20.8/go.mod h1:VPrEBa+zT9J2x+HHdeq5SwTMd7tbhcBQH3sYPiKORfY= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.13 h1:a+8/MLcWlIxo1lF9xaGt3J/u3yOZx+CdSveSNwjhD40= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.13/go.mod h1:oGnKwIYZ4XttyU2JWxFrwvhF6YKiK/9/wmE3v3Iu9K8= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.13 h1:HBSI2kDkMdWz4ZM7FjwE7e/pWDEZ+nR95x8Ztet1ooY= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.13/go.mod h1:YE94ZoDArI7awZqJzBAZ3PDD2zSfuP7w6P2knOzIn8M= +github.com/aws/aws-sdk-go-v2/config v1.32.0 h1:T5WWJYnam9SzBLbsVYDu2HscLDe+GU1AUJtfcDAc/vA= +github.com/aws/aws-sdk-go-v2/config v1.32.0/go.mod h1:pSRm/+D3TxBixGMXlgtX4+MPO9VNtEEtiFmNpxksoxw= +github.com/aws/aws-sdk-go-v2/credentials v1.19.0 h1:7zm+ez+qEqLaNsCSRaistkvJRJv8sByDOVuCnyHbP7M= +github.com/aws/aws-sdk-go-v2/credentials v1.19.0/go.mod h1:pHKPblrT7hqFGkNLxqoS3FlGoPrQg4hMIa+4asZzBfs= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.14 h1:WZVR5DbDgxzA0BJeudId89Kmgy6DIU4ORpxwsVHz0qA= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.14/go.mod h1:Dadl9QO0kHgbrH1GRqGiZdYtW5w+IXXaBNCHTIaheM4= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.20.10 h1:Zg7Sxr0IQQmKCzPxCAHQhekJYIIpykXlpq/EbLZGgcQ= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.20.10/go.mod h1:hR70agY0Gy52HSo/tsOfjfCfQcNg5PEMWLJz1f4yIcU= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.14 h1:PZHqQACxYb8mYgms4RZbhZG0a7dPW06xOjmaH0EJC/I= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.14/go.mod h1:VymhrMJUWs69D8u0/lZ7jSB6WgaG/NqHi3gX0aYf6U0= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.14 h1:bOS19y6zlJwagBfHxs0ESzr1XCOU2KXJCWcq3E2vfjY= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.14/go.mod h1:1ipeGBMAxZ0xcTm6y6paC2C/J6f6OO7LBODV9afuAyM= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 h1:WKuaxf++XKWlHWu9ECbMlha8WOEGm0OUEZqm4K/Gcfk= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4/go.mod h1:ZWy7j6v1vWGmPReu0iSGvRiise4YI5SkR3OHKTZ6Wuc= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.13 h1:eg/WYAa12vqTphzIdWMzqYRVKKnCboVPRlvaybNCqPA= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.13/go.mod h1:/FDdxWhz1486obGrKKC1HONd7krpk38LBt+dutLcN9k= -github.com/aws/aws-sdk-go-v2/service/accessanalyzer v1.45.2 h1:Ako32TEdYnL79+slzTDOFxdSKhltoWcjkNxPWz9X/M4= -github.com/aws/aws-sdk-go-v2/service/accessanalyzer v1.45.2/go.mod h1:iATSoxt/SEINLDvYHe5N9/UDnc45vngRxRJYr2MqGO0= -github.com/aws/aws-sdk-go-v2/service/account v1.29.4 h1:qrptW0Zqnc3O0fjjfmBDtJPRaNH+qY47txKwRhXQ67A= -github.com/aws/aws-sdk-go-v2/service/account v1.29.4/go.mod h1:3LbGl+sLnaiyCVp2LJXj0gEoeV2Uw0QOsDpP1gDMBVA= -github.com/aws/aws-sdk-go-v2/service/acm v1.37.13 h1:5AUX6KOEBF20wiIaiI4fKHvVkELEptyLtRTbWGpNQNY= -github.com/aws/aws-sdk-go-v2/service/acm v1.37.13/go.mod h1:v8E4cAu0qIxpS7IokQilQb60A8IODPxo82VxVtJ+Dgo= -github.com/aws/aws-sdk-go-v2/service/acmpca v1.46.2 h1:mBl0TQb13preknTDjHWbanhl1BveYfF1QES/YverKlQ= -github.com/aws/aws-sdk-go-v2/service/acmpca v1.46.2/go.mod h1:rpBWGq3UUlrgtAwNMy+I9ZoGgbiCoy30QetJZtI6+1A= -github.com/aws/aws-sdk-go-v2/service/amp v1.42.0 h1:eBxruXVqrfytiVJIqxGVW4kGlbxlsCasNa5GZgcTgZ4= -github.com/aws/aws-sdk-go-v2/service/amp v1.42.0/go.mod h1:uwNPmGivmh+4kJecS8OuYtMQTeZCGoBxdLLAGv+13r0= -github.com/aws/aws-sdk-go-v2/service/amplify v1.38.5 h1:uqG80MBs+aYwh6V2bpD3p4EAN3+23H9zDF+kyQNmbgo= -github.com/aws/aws-sdk-go-v2/service/amplify v1.38.5/go.mod h1:ieZIB8x+q5G3azy9SUtyGzGxXGHCVsTK4YvnADiCBZQ= -github.com/aws/aws-sdk-go-v2/service/apigateway v1.37.0 h1:yGW8ujCEpbex84kfx9KL6HkzfSC3pTiUOwNgrCB/Tek= -github.com/aws/aws-sdk-go-v2/service/apigateway v1.37.0/go.mod h1:9tT261wkl3uME2BWp/a3nzGNe9BM7jLWZdrXW1eX3BA= -github.com/aws/aws-sdk-go-v2/service/apigatewayv2 v1.33.0 h1:jFWRglDVLlQcANMwsdFp/lJ6RAsc/mFLopFlTw9IeXs= -github.com/aws/aws-sdk-go-v2/service/apigatewayv2 v1.33.0/go.mod h1:vr6hE/YGoQQa8PPwsB1uKt9wHjNZZcbXN+ww6lBXVhY= -github.com/aws/aws-sdk-go-v2/service/appconfig v1.43.3 h1:CiSitRcp8P68+JoA9cNuBL6H2cdDtNr1w1pkHyRXFKE= -github.com/aws/aws-sdk-go-v2/service/appconfig v1.43.3/go.mod h1:rvGHrN6a1lCypZrV0gDsJNPP5w51XIzr6manLptGnZg= -github.com/aws/aws-sdk-go-v2/service/appfabric v1.16.12 h1:CKuViUgkrDY63niR+Jg2UBylJOSOrMx83NbOFKT0I7o= -github.com/aws/aws-sdk-go-v2/service/appfabric v1.16.12/go.mod h1:EFrW9OOrllIDc/Rg/aUpaWnK81C2VVxhtFt9XUmM4kQ= -github.com/aws/aws-sdk-go-v2/service/appflow v1.51.3 h1:lmeUBk1pCMxqGNhlp1bpAMLzelZsqVh6YEQw5kJffMU= -github.com/aws/aws-sdk-go-v2/service/appflow v1.51.3/go.mod h1:bjux2H0bZSqK50RnMXHMr1eBi6Uw6gJmTeDOvFk7w14= -github.com/aws/aws-sdk-go-v2/service/appintegrations v1.36.12 h1:Mpl2kD1mBc6fegNiwcRzp8FjgDZ97fbaEafbDXF9xqk= -github.com/aws/aws-sdk-go-v2/service/appintegrations v1.36.12/go.mod h1:FrNhRSko1IPmuXPB8ldLs3nRkjjONG3E7ZE5nnV0snE= -github.com/aws/aws-sdk-go-v2/service/applicationautoscaling v1.41.4 h1:YjpBB2PGZSl6WRhmgzLMMdvY5FIpWPQ/oVThQd6uX3M= -github.com/aws/aws-sdk-go-v2/service/applicationautoscaling v1.41.4/go.mod h1:BDzrZs53Hsb5MyAICN2dmtFWaeLONzMaseXyF9Bagt0= -github.com/aws/aws-sdk-go-v2/service/applicationinsights v1.34.11 h1:EcnZjQKet6JnsXwj2tw1gfvesNmnfGfvwuzWMZIxTfM= -github.com/aws/aws-sdk-go-v2/service/applicationinsights v1.34.11/go.mod h1:2Sln2mubGkQTNc86N2eobz6KhGrHatsr4lVoIkUwrhQ= -github.com/aws/aws-sdk-go-v2/service/applicationsignals v1.17.4 h1:t4DkpLlx64Dyv5ttJNfjuQCtXA4jwygnPic3u6SHeqg= -github.com/aws/aws-sdk-go-v2/service/applicationsignals v1.17.4/go.mod h1:5Il7eB5oblkNf9V8ugOpPwA6ZARgTzld7otDTumO2w4= -github.com/aws/aws-sdk-go-v2/service/appmesh v1.35.3 h1:IsdFy0YkFhSo1nPjw9WcPpm3joGCEH1pLnXuLkAV2X0= -github.com/aws/aws-sdk-go-v2/service/appmesh v1.35.3/go.mod h1:xcEbbUjLqajeslIydrSJhESXNlGMtfXmu7MLY6ONlzY= -github.com/aws/aws-sdk-go-v2/service/apprunner v1.39.5 h1:+fyOW8hT7uLzKQgkmKeqyq6Z8Y4+qiGsAOvbXYXmpdQ= -github.com/aws/aws-sdk-go-v2/service/apprunner v1.39.5/go.mod h1:rI1byQGgb9tUXBvo3uLFrRXRzaCJayw+CiqAnDgYSKw= -github.com/aws/aws-sdk-go-v2/service/appstream v1.52.1 h1:wP/OGyNS8YMeNf1nqNMl3zPkyl3Vp2UJ171ykt2Vkvc= -github.com/aws/aws-sdk-go-v2/service/appstream v1.52.1/go.mod h1:flCm0TnAjuMbHs8YaGjVjQjUUsa5EP5O6nC4Zpt080E= -github.com/aws/aws-sdk-go-v2/service/appsync v1.52.3 h1:ANP9cl/DMLE1BewJU7eg25Ipq2gdrBtzd3k7nIcfq3A= -github.com/aws/aws-sdk-go-v2/service/appsync v1.52.3/go.mod h1:uCcHMGXa27Gp8b/hlAI0JbqmXeZp16E2FDWNz5nX0cQ= -github.com/aws/aws-sdk-go-v2/service/arcregionswitch v1.2.14 h1:wRm3ZJkjRHNiTRFGPLR9xTzXpAG8l1h5ywGY9b5tN5I= -github.com/aws/aws-sdk-go-v2/service/arcregionswitch v1.2.14/go.mod h1:PyPhpvZGkGYZTeuYRlPwZTgBx93EUYtHdpPbiIlY7Q8= -github.com/aws/aws-sdk-go-v2/service/athena v1.55.12 h1:upjiOGrCbvVk/kgSvE8oRE5SwzuaayRsBoMs2dnVlvY= -github.com/aws/aws-sdk-go-v2/service/athena v1.55.12/go.mod h1:1bY3ff3w7nTDnyGgOAOEZpO7e7bUiG2iDM2tXbCzxjg= -github.com/aws/aws-sdk-go-v2/service/auditmanager v1.46.3 h1:gus+gJbIngKvaL6Q3PH7e2tjO1Isx+kp+ldWIvysiY0= -github.com/aws/aws-sdk-go-v2/service/auditmanager v1.46.3/go.mod h1:6U6XFWocDXxVtEZsjDajhNtAxNJzZRs9k7CJHuTMJCY= -github.com/aws/aws-sdk-go-v2/service/autoscaling v1.61.0 h1:L4+Ts9JbR5Bb92eyQunFFAB6TfTobcfFne8+fNPGFX0= -github.com/aws/aws-sdk-go-v2/service/autoscaling v1.61.0/go.mod h1:6E1AiecbY52kVBl8lKkdaO759rbGK3TBBBNnfxJezTM= -github.com/aws/aws-sdk-go-v2/service/autoscalingplans v1.30.5 h1:/Gf9lbM1ce3h5SswLp0dCzWz3Lb8wHdlQvD9okQFnKs= -github.com/aws/aws-sdk-go-v2/service/autoscalingplans v1.30.5/go.mod h1:NkStIqURmzgUVyoB3YkmU1HUtIPECrExIastd5QbXIk= -github.com/aws/aws-sdk-go-v2/service/backup v1.54.0 h1:irUsF+2pK8u1YfiH1SC265XCRR81txSLGOca1s8Dh88= -github.com/aws/aws-sdk-go-v2/service/backup v1.54.0/go.mod h1:Sqiqu5Ws64P9IYY+0mQ4OafDKK1LK6sRWQqw89dZZYA= -github.com/aws/aws-sdk-go-v2/service/batch v1.58.6 h1:/SWr0iPuPFm90sbJwTowOCD63ZtbdFYmp67XlXygwxo= -github.com/aws/aws-sdk-go-v2/service/batch v1.58.6/go.mod h1:zaUBHLEVy5UjLlFt996XZMXLza3teA7f0IhAoV7+3mg= -github.com/aws/aws-sdk-go-v2/service/bcmdataexports v1.12.5 h1:otJvRakif5zPNVJ2sRcayQFqYh8QMj3ukVNred28uTw= -github.com/aws/aws-sdk-go-v2/service/bcmdataexports v1.12.5/go.mod h1:PJ5iWye10CA9cYAeVL4RUSkZvAwVK/WrOnTSHLztNAI= -github.com/aws/aws-sdk-go-v2/service/bedrock v1.49.1 h1:Da6sk9ZLlC2PXBWRPENz9msEkn5fYE6MOSWKPTjoMRg= -github.com/aws/aws-sdk-go-v2/service/bedrock v1.49.1/go.mod h1:xJ84P+JCcEkzkMjqBKmImWl/zlwEwBmbjc9QR+tcACQ= -github.com/aws/aws-sdk-go-v2/service/bedrockagent v1.51.3 h1:UArcFWYHtdk5QWOTteqRZwF/tAoaYx+ArreUakHx8K0= -github.com/aws/aws-sdk-go-v2/service/bedrockagent v1.51.3/go.mod h1:R5jkUdemrZt6+90gq4JFyxHKldEMH88F6wdxquDLa4Q= -github.com/aws/aws-sdk-go-v2/service/bedrockagentcorecontrol v1.13.3 h1:lskoaAo1V+KpDYgS6lWMGvnxGhA0eX/bUQ6Xm7TEJM8= -github.com/aws/aws-sdk-go-v2/service/bedrockagentcorecontrol v1.13.3/go.mod h1:MvhjtEWL5RO1w6AMrt4d9k//kZxZUsLrTSipRM9Q0/8= -github.com/aws/aws-sdk-go-v2/service/billing v1.9.0 h1:xbdlsW9TVa7AVpqB8CzaX6cM4qQQ/9RLrx6GGuBoSHE= -github.com/aws/aws-sdk-go-v2/service/billing v1.9.0/go.mod h1:7WI9oHeKA76HgGtTaUeKToGO/rRH9/fx7WLCw1QLJt4= -github.com/aws/aws-sdk-go-v2/service/budgets v1.41.3 h1:9cQXqYwHzp4fcKCHOAlHeMm/m/K+dcZS2D5SB+4ZA9s= -github.com/aws/aws-sdk-go-v2/service/budgets v1.41.3/go.mod h1:wjQL1whunmAT3ZhqQGZq0lPGNmU27Uu8RjGmT12wLNg= -github.com/aws/aws-sdk-go-v2/service/chatbot v1.14.12 h1:WAVCaNagdhnjzFUUsrYADbR6NF1RVG9LAZj2+oY8gAg= -github.com/aws/aws-sdk-go-v2/service/chatbot v1.14.12/go.mod h1:H9eUeKMZNHJnd/zKD3Ga0xyk6da+LDSFMZfOw2Wz45E= -github.com/aws/aws-sdk-go-v2/service/chime v1.41.3 h1:8Dt3NnfOF1ErL1xUxi6+fu5p/3Ezee6RZaCxH8YzL8g= -github.com/aws/aws-sdk-go-v2/service/chime v1.41.3/go.mod h1:NL5o86salGH/wxYiFkrzG6K8/GGPGdUNYXS00LCoNr4= -github.com/aws/aws-sdk-go-v2/service/chimesdkmediapipelines v1.26.12 h1:f6OT810gyz9/vYCGh99l8e2bSIqGO2B8HeSEsFwKy7w= -github.com/aws/aws-sdk-go-v2/service/chimesdkmediapipelines v1.26.12/go.mod h1:ykYGKe/rWysRsTmMJcq5VvqFzViL4XqsHke2UMh4ok0= -github.com/aws/aws-sdk-go-v2/service/chimesdkvoice v1.28.4 h1:0W88faK7py65Xgpi/SPpK4HxF4nrHi0SG20ZTDdGQ1A= -github.com/aws/aws-sdk-go-v2/service/chimesdkvoice v1.28.4/go.mod h1:xjd2Oeftl4VNXrNTaEBSpwu4cKUDo82FQL9eHunFDqU= -github.com/aws/aws-sdk-go-v2/service/cleanrooms v1.37.3 h1:158UOfGTmbAijrcMpR72d7UWaA8VtpyRDSQtiGB2Gd8= -github.com/aws/aws-sdk-go-v2/service/cleanrooms v1.37.3/go.mod h1:q9yJkMo4u5vpFAExN0Vtw+ChYDwq0hsSrD9DDE5Sd8w= -github.com/aws/aws-sdk-go-v2/service/cloud9 v1.33.11 h1:iR8n4gvDdN2hrUjXgETp76p/ILPbLFPuNbOi68B4CfE= -github.com/aws/aws-sdk-go-v2/service/cloud9 v1.33.11/go.mod h1:kyuiuFhvDWwqLGNWmwbIr/amPIFQWrA7KkbxRQvP0JU= -github.com/aws/aws-sdk-go-v2/service/cloudcontrol v1.29.3 h1:6ZTiyJCqVLE5CjuCZ6h9kKEbWOTbFxlBFXZ0fvTZK+s= -github.com/aws/aws-sdk-go-v2/service/cloudcontrol v1.29.3/go.mod h1:6kx+wmHMUP1fQBUpXN2N9xRt2sQUlloxwyF5cMIvDOc= -github.com/aws/aws-sdk-go-v2/service/cloudformation v1.70.0 h1:w9Yx0QWNhU2615kugQRIYSSR27GpZHkyRVdEHGi5PIY= -github.com/aws/aws-sdk-go-v2/service/cloudformation v1.70.0/go.mod h1:llucikq1Q6I1Ps8rNV3St0bOY5RQMxYh1lpCaskyhPw= -github.com/aws/aws-sdk-go-v2/service/cloudfront v1.56.2 h1:1Ipv5nooFuWg3iPGQPeh1WkUSJ96QFTqZQKMHPw9WHc= -github.com/aws/aws-sdk-go-v2/service/cloudfront v1.56.2/go.mod h1:UtP1sSXq2FHHO7Lvn4mNplFS4x7oP4+uMIJIQ8+3JyY= -github.com/aws/aws-sdk-go-v2/service/cloudfrontkeyvaluestore v1.12.14 h1:AfC0uaSoMsz32lAOMkTjyfSX1PZRYniqzyt6pJmf+00= -github.com/aws/aws-sdk-go-v2/service/cloudfrontkeyvaluestore v1.12.14/go.mod h1:yFxrWxlbxnTilFCsiViY+x3qnKqi1CGdSPfEWYnwh6Q= -github.com/aws/aws-sdk-go-v2/service/cloudhsmv2 v1.34.11 h1:w+afQ/tvYUVdTiX1LhIm/vSNvaNiOyy3QoYGz3GfhuI= -github.com/aws/aws-sdk-go-v2/service/cloudhsmv2 v1.34.11/go.mod h1:w13K+4E6mjE6m5w3tDBZCs+S0zUiAse7M3qZg5ugecw= -github.com/aws/aws-sdk-go-v2/service/cloudsearch v1.32.3 h1:AUYRw6eRXp6MjvKpTGRbNBmlfVRY7kEuClnMGv/zQQI= -github.com/aws/aws-sdk-go-v2/service/cloudsearch v1.32.3/go.mod h1:6hxErkN8bbEtojNMVdGQPpL7j9+A/QKL+eDljfRIKMM= -github.com/aws/aws-sdk-go-v2/service/cloudtrail v1.54.0 h1:dbSrsAKSNOOwNd1rtaZwiRSzjc6U9yIRMfymrEeCM9g= -github.com/aws/aws-sdk-go-v2/service/cloudtrail v1.54.0/go.mod h1:yPef5Em35Sb/89IIHAOarpsld8EuxyxuDVDlHj32LVA= -github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.52.3 h1:fD9/X9n4O6fauKLp9BE848I3JcXVEliwlgliernxUhs= -github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.52.3/go.mod h1:KSWhI1V5x80r8NUqs8QDkOazDolFqFUAjsyE5nYjKro= -github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.60.0 h1:jqF36cdImXcEo63d52Wpdi2qTXOLTZSJF/71h9MP5jo= -github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.60.0/go.mod h1:9/Q0/HtqBTLMksFse42wZjUq0jJrUuo4XlnXy/uSoeg= -github.com/aws/aws-sdk-go-v2/service/codeartifact v1.38.12 h1:j75xPdSialz4ipsvOpCtKl2VFb/ugc2PMgOfVvWjt6o= -github.com/aws/aws-sdk-go-v2/service/codeartifact v1.38.12/go.mod h1:9R9pEHnoKOjLs5dDREGyV1Ui2kWZgPPKz0VZd3juZhY= -github.com/aws/aws-sdk-go-v2/service/codebuild v1.68.4 h1:rp7p7dTLS1qix2pVRT168GfZevumq0HoiytyrRG5e9o= -github.com/aws/aws-sdk-go-v2/service/codebuild v1.68.4/go.mod h1:LAT1SFMRPN1z4wewG4PHazKs2xL+J59saaAJQfZj8rc= -github.com/aws/aws-sdk-go-v2/service/codecatalyst v1.21.3 h1:jusavOo6R3Cx7dF90etnt4fSU1KWM1NSwENFsdPPqVQ= -github.com/aws/aws-sdk-go-v2/service/codecatalyst v1.21.3/go.mod h1:160q+ylvlYKq6c8wufCHYeX4Qei0IC509n4hxlh8oVA= -github.com/aws/aws-sdk-go-v2/service/codecommit v1.33.3 h1:D0CCIRXUefKZX30AyyG7QZby5+tVzP3Z+M66HoZVI4g= -github.com/aws/aws-sdk-go-v2/service/codecommit v1.33.3/go.mod h1:jZuIO2m8qmy6VFTQgB/8bTb72o+X4zLRfnu1PubtriM= -github.com/aws/aws-sdk-go-v2/service/codeconnections v1.10.11 h1:UjRTTd2hwOv/bzqqaDlemhOqBK+J/tjTdv6PRJSvCxg= -github.com/aws/aws-sdk-go-v2/service/codeconnections v1.10.11/go.mod h1:MMDcKcUGX6vTU6iI4+JFF486CGygY/COEldYNSdQDFQ= -github.com/aws/aws-sdk-go-v2/service/codedeploy v1.35.3 h1:K6u1VZc2SmFqWaBELcIfowpH4livshEk3Iwg/Kuvd9g= -github.com/aws/aws-sdk-go-v2/service/codedeploy v1.35.3/go.mod h1:t9VTnwqOH9QaIWz+NXLMpV68Q983qdWH+ol+4pXATI8= -github.com/aws/aws-sdk-go-v2/service/codeguruprofiler v1.29.11 h1:2+4r5Z7FE6bFMOfMt9b26xVwNwOn9DSS/gDTQSZVcuU= -github.com/aws/aws-sdk-go-v2/service/codeguruprofiler v1.29.11/go.mod h1:TTz1x8GSLqG2xw5I6ZPs0nm9Ro8W/D44MyeffDYxXnE= -github.com/aws/aws-sdk-go-v2/service/codegurureviewer v1.34.11 h1:SEaA8Sl/YGV7nrjySKWTncQo4Zj0Xcbjr2+jb8LFrtU= -github.com/aws/aws-sdk-go-v2/service/codegurureviewer v1.34.11/go.mod h1:KysZ41BGS0TjTmMIu6v0jIOKSlmhACK+7NnZOytrqC4= -github.com/aws/aws-sdk-go-v2/service/codepipeline v1.46.12 h1:OhbU8xlrNQt2qNHX8kKB8/WaONKPadiaSRXpyPYkCFY= -github.com/aws/aws-sdk-go-v2/service/codepipeline v1.46.12/go.mod h1:COTp2TtxyTD6Pm7H6mKieN+Q0TmccQhJnfxD6//JPtg= -github.com/aws/aws-sdk-go-v2/service/codestarconnections v1.35.4 h1:we8Y0b2KcnY65saLrF9YXtFfK9BrpMY/qlx7QysALqI= -github.com/aws/aws-sdk-go-v2/service/codestarconnections v1.35.4/go.mod h1:QOzDyBkE0ODl/dOuwpcSdMDz/8mz2i+KbwE8hSTUxKo= -github.com/aws/aws-sdk-go-v2/service/codestarnotifications v1.31.12 h1:6YR4J0bwBwLRwZ7OFm8gpA8BBVoTsbjfMBWNOuRkOBE= -github.com/aws/aws-sdk-go-v2/service/codestarnotifications v1.31.12/go.mod h1:9+D52LzbRUGdyzwB/AMLPi4ydjtSeFkCSloB6Tw7bq0= -github.com/aws/aws-sdk-go-v2/service/cognitoidentity v1.33.12 h1:lS0WkuQQ13PmBN5Aab3GajJA15BeTGOeFCYQlAmROfw= -github.com/aws/aws-sdk-go-v2/service/cognitoidentity v1.33.12/go.mod h1:ahZYJFutez0db6zWQyLWNddBtDDGovvOShiUTnOYPPw= -github.com/aws/aws-sdk-go-v2/service/cognitoidentityprovider v1.57.13 h1:gUchSsfXNg3xDlGKTCOx/ZvFk/CbsiQ6pHgSzAAvNUo= -github.com/aws/aws-sdk-go-v2/service/cognitoidentityprovider v1.57.13/go.mod h1:NLRVISwN4NcFEWz8WN5kySbgN1g8hjYPR2cZD9Of3Rg= -github.com/aws/aws-sdk-go-v2/service/comprehend v1.40.12 h1:OUq9z5ZMhZn87/QKG9xxWeyEmf8HKC4aiNnpLy36lc8= -github.com/aws/aws-sdk-go-v2/service/comprehend v1.40.12/go.mod h1:QY56Tp8KUNsipLdUdWGTwNg76WXpos4Q4Bbw51i2KS0= -github.com/aws/aws-sdk-go-v2/service/computeoptimizer v1.48.3 h1:0oum8CeAFRcovMsI+a8R3op5Z1ngJVLgi9ffWYt3xkQ= -github.com/aws/aws-sdk-go-v2/service/computeoptimizer v1.48.3/go.mod h1:PzK50LObvBt9Mb2YxwsocMuck07wSMSR+eVU9CiV05M= -github.com/aws/aws-sdk-go-v2/service/configservice v1.59.4 h1:dY6ktQ8OfUkI6fTs0R9/3mAbYC6N1wEbjsGq2PLFms4= -github.com/aws/aws-sdk-go-v2/service/configservice v1.59.4/go.mod h1:8pBCQK4k6Qpff8QKM6gcCt2ZsluQFsNtNaa8ouEZLFc= -github.com/aws/aws-sdk-go-v2/service/connect v1.146.0 h1:fL4XXNHdfBmVWSGgsBzoezErUf7knnLK5cCUe1F3eoQ= -github.com/aws/aws-sdk-go-v2/service/connect v1.146.0/go.mod h1:4S/3f30iB9LArrLNHVRw/IWyGEGturV5Z5DF1rp3NsE= -github.com/aws/aws-sdk-go-v2/service/connectcases v1.34.3 h1:ZcrD31NLG/brevUHw8XSn74VHShleHUm5xy8uJC/1ek= -github.com/aws/aws-sdk-go-v2/service/connectcases v1.34.3/go.mod h1:g0V7qnDiTliogqzfAiJrhrOAEKnY+XY3u7/FJ8sZEYU= -github.com/aws/aws-sdk-go-v2/service/controltower v1.27.2 h1:D5zM7WP5IWp4DMbtY8NdTemanN/MxGyp2vm8Eis0gQE= -github.com/aws/aws-sdk-go-v2/service/controltower v1.27.2/go.mod h1:ZQuFo9/qnryEiHaDdXGo0pgsC+uHYHheHzGq+Vem8xM= -github.com/aws/aws-sdk-go-v2/service/costandusagereportservice v1.34.4 h1:aCPRvahOg+fH79Sk9wOZslIrQVAAPgC1JpGzj1s5ZBo= -github.com/aws/aws-sdk-go-v2/service/costandusagereportservice v1.34.4/go.mod h1:z4Y8J/t7ktcqMxLtf4korP74Tg42Ov97FjuTDyFfJKw= -github.com/aws/aws-sdk-go-v2/service/costexplorer v1.60.0 h1:nZrsl4tViAlW9+xkUpc4GXa9t0p3RIzGz9csmRrXR/s= -github.com/aws/aws-sdk-go-v2/service/costexplorer v1.60.0/go.mod h1:sP89eC3imDzTgMk/N+gDwDqjeQgLLEt0PuU5NMBHBCo= -github.com/aws/aws-sdk-go-v2/service/costoptimizationhub v1.21.0 h1:8oTOAr895uaekGOozHzfH1zHGfBhSHZwpardvitnaCI= -github.com/aws/aws-sdk-go-v2/service/costoptimizationhub v1.21.0/go.mod h1:Ouo0lXAlK9jTlJeMt6LTL+G6kKOfoK7xks0TT5AwdlQ= -github.com/aws/aws-sdk-go-v2/service/customerprofiles v1.54.5 h1:XJUCroqsUAG80W0jVK/Rb4QPF/YbZu/oVtmiGvF8gjI= -github.com/aws/aws-sdk-go-v2/service/customerprofiles v1.54.5/go.mod h1:86sgcd46latOOSvQKbctenNsiEHnow3vip0OnwSqC54= -github.com/aws/aws-sdk-go-v2/service/databasemigrationservice v1.60.0 h1:cJZPHHPjft5N0BNv9X0bsUdDNGGbTQiT2b7jiN+NYv4= -github.com/aws/aws-sdk-go-v2/service/databasemigrationservice v1.60.0/go.mod h1:Sc22CT1GPF61n0yJdqquFNvqoyfnQCZ+WS7Uz8daW8c= -github.com/aws/aws-sdk-go-v2/service/databrew v1.39.5 h1:gQDXbDgv5AW3treUAsfQGEeU3+ZmSEfb1TTpiDD7Gc8= -github.com/aws/aws-sdk-go-v2/service/databrew v1.39.5/go.mod h1:hu5s2BoJ9fqmyMoVVvYbAtTFOFg8lsr4TzgJnK58n2Q= -github.com/aws/aws-sdk-go-v2/service/dataexchange v1.40.5 h1:P9xrOXwbBxBzq30eiCFUlVE8lUUe6YnHs8j9dQx4YEM= -github.com/aws/aws-sdk-go-v2/service/dataexchange v1.40.5/go.mod h1:rwA2QoV4mz3TSrr4QirNyAndfs3EmwbVrGx5nMtTdz0= -github.com/aws/aws-sdk-go-v2/service/datapipeline v1.30.11 h1:ZmEqPDpJsiqkVqsRD7pi5SLO0VMyDavr9vlhF2R9iVM= -github.com/aws/aws-sdk-go-v2/service/datapipeline v1.30.11/go.mod h1:WZjvFO/jWbSRaxdkTmbL5GZu1HmPV2+DrDFmUCH0BKk= -github.com/aws/aws-sdk-go-v2/service/datasync v1.55.6 h1:pxK2rp4xZ073UMj7KUIX3Bwao02V6P+GXwvhOJW2Qkg= -github.com/aws/aws-sdk-go-v2/service/datasync v1.55.6/go.mod h1:35IO7OkYfIGQJeJ8IOFN7dPrregYgMMxBlSGpR0dEj8= -github.com/aws/aws-sdk-go-v2/service/datazone v1.48.0 h1:ON4CIIi/LgvXPKl+9FcuHI6evqfbFWbKvpngpS2IqvY= -github.com/aws/aws-sdk-go-v2/service/datazone v1.48.0/go.mod h1:ELpY+QIvAO5sH048NMmxDNMDuAKWbRmHCl0rrNR4V5s= -github.com/aws/aws-sdk-go-v2/service/dax v1.29.7 h1:d+Iq53DFhoJ4m+PKRCCosIodRTuWvlsh+LAWuOe7zWE= -github.com/aws/aws-sdk-go-v2/service/dax v1.29.7/go.mod h1:LqCHisA88LmdWAT7R/FsvLksZZs7ghdIUwZsZSu0xKs= -github.com/aws/aws-sdk-go-v2/service/detective v1.38.4 h1:iR9Cjiohq4R9veZr6DadbXEbKj1FADofRNJZ3hEjuwY= -github.com/aws/aws-sdk-go-v2/service/detective v1.38.4/go.mod h1:cOhEIcmxoL4V4Uavp0LRUV30gYNTGiTd2G0/ECJlIls= -github.com/aws/aws-sdk-go-v2/service/devicefarm v1.37.0 h1:VdU+oiTksNqUwRw5xv6AkoVKq6RecX6HrZmWGm/7lpY= -github.com/aws/aws-sdk-go-v2/service/devicefarm v1.37.0/go.mod h1:DOlSchQTITKhdLgShZBymT+x+kX6jSJx8ArGf2jvFVs= -github.com/aws/aws-sdk-go-v2/service/devopsguru v1.40.3 h1:pyh8Q7gwaW9mKsPG52ql7tarNkBn7jiYKmhXwzOAEO0= -github.com/aws/aws-sdk-go-v2/service/devopsguru v1.40.3/go.mod h1:pOx5GDFaf6hXYuvqq18r+Op5BCfuMuZKX2ZJgacqWNk= -github.com/aws/aws-sdk-go-v2/service/directconnect v1.38.5 h1:XLpifFvzfFmQ0i4EX/xosiSt/yYEN7Wtw1LqffT3o0c= -github.com/aws/aws-sdk-go-v2/service/directconnect v1.38.5/go.mod h1:ozhPmvMQlk6trPDKahoaHUUEzmgiRxuHjXMWqdBy/Is= -github.com/aws/aws-sdk-go-v2/service/directoryservice v1.38.6 h1:33I5jbO/kG0WEg/U4GyMYR1RfOfEk+hRQhUmiBOrFBE= -github.com/aws/aws-sdk-go-v2/service/directoryservice v1.38.6/go.mod h1:yv/LQu/I+t1HsDl5wBlBxhnFDmLe8sk+6EkFW1WTb10= -github.com/aws/aws-sdk-go-v2/service/dlm v1.35.6 h1:D7GyrH7x87n6IwM4sdujnhYdm+tRR3M6j9Q/uZV6GEI= -github.com/aws/aws-sdk-go-v2/service/dlm v1.35.6/go.mod h1:rP4rq5uek/rreEV2CzUzGPNcD36+ZLDeh9HzyxePFnE= -github.com/aws/aws-sdk-go-v2/service/docdb v1.48.3 h1:4VZq8ExlKiUtoFswYkkA36jHO4DwMHJe+EINHAbtVnc= -github.com/aws/aws-sdk-go-v2/service/docdb v1.48.3/go.mod h1:13D9OjKPmSXbWE+20zVYaesIuFSUtx1pEouI2hu8yp0= -github.com/aws/aws-sdk-go-v2/service/docdbelastic v1.20.4 h1:0BkoVJIQfd3qMdianq8AUXcOxY9325OVroccwV3MGg4= -github.com/aws/aws-sdk-go-v2/service/docdbelastic v1.20.4/go.mod h1:GXVZTuVYCRQvfLiT+fKmnXLYap5xGTfz+UD47bxJEKE= -github.com/aws/aws-sdk-go-v2/service/drs v1.36.4 h1:HH+yOVt1hVdw3q5OyG6dYjMi5mg+pGC7aza93j0sMNw= -github.com/aws/aws-sdk-go-v2/service/drs v1.36.4/go.mod h1:qO9+wcb7meZj7R8VQd8QnHb+ZPRWdODsexKGr3ru7cA= -github.com/aws/aws-sdk-go-v2/service/dsql v1.11.2 h1:+dLCcQdBv+JiLDp25/cDm5GiK2vKg5+y1n+Lm+ve3zY= -github.com/aws/aws-sdk-go-v2/service/dsql v1.11.2/go.mod h1:qAIMlh9aATA3n6dbs3aHQD7MOCAN8km548KABpaxqUs= -github.com/aws/aws-sdk-go-v2/service/dynamodb v1.53.0 h1:oyaZ6mvMgqy3Vm2RMD6ni2sQi4G9T6ntOXP5/PFtnVs= -github.com/aws/aws-sdk-go-v2/service/dynamodb v1.53.0/go.mod h1:6eUUnWOJ8sucL5Uk8rPkFo8FYioM0CTNGHga8hwzXVc= -github.com/aws/aws-sdk-go-v2/service/ec2 v1.272.0 h1:zWYlsIUX88ZSDiKQR4603gVjPLR7Wn1+/hv76lsrMvA= -github.com/aws/aws-sdk-go-v2/service/ec2 v1.272.0/go.mod h1:NDdDLLW5PtLLXN661gKcvJvqAH5OBXsfhMlmKVu1/pY= -github.com/aws/aws-sdk-go-v2/service/ecr v1.53.0 h1:ReOAhAmW/8c2yLfr7fuLeD6WgXrp12yL27CCQMP6eQM= -github.com/aws/aws-sdk-go-v2/service/ecr v1.53.0/go.mod h1:1NVD1KuMjH2GqnPwMotPndQaT/MreKkWpjkF12d6oKU= -github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.38.4 h1:0rqbFeBlrTHNEIdrcH9g1yW0QjBOaCrGcTQ6sLcsH9w= -github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.38.4/go.mod h1:x7gU4CAyAz4BsM9hlRkhHiYw2GIr1QCmN45uwQw9l/E= -github.com/aws/aws-sdk-go-v2/service/ecs v1.68.0 h1:eKgxT+0Aj9zkdw2qcfCP9FyfrQlQwsfH7lQyeqwODmY= -github.com/aws/aws-sdk-go-v2/service/ecs v1.68.0/go.mod h1:rrhqfkXfa2DSNq0RyFhnnFEAyI+yJB4+2QlZKeJvMjs= -github.com/aws/aws-sdk-go-v2/service/efs v1.41.4 h1:Uk/tvWjdaeVQxmKTjleCJ05SPoXL5Upgq+rffBcolZI= -github.com/aws/aws-sdk-go-v2/service/efs v1.41.4/go.mod h1:ddWcpZJhvKugMHfwzBsq3dtaBLH7PsTgtAyiL3BEdxo= -github.com/aws/aws-sdk-go-v2/service/eks v1.74.9 h1:ugqH9Vu52QlUhpTbW75rsv0WA9k704DEwOCoxWsLy+4= -github.com/aws/aws-sdk-go-v2/service/eks v1.74.9/go.mod h1:xHVz3A2oEVl3UzjCOSEz/fBeBoFrS6FJ3cc/jo0WLyM= -github.com/aws/aws-sdk-go-v2/service/elasticache v1.51.3 h1:a7jZ0M15w4FAGi7VsRvNSfUZk6ozGiFNz/eJ7DySiiE= -github.com/aws/aws-sdk-go-v2/service/elasticache v1.51.3/go.mod h1:m21nBoJHIHVbICAgJgvaZuO2AEfamKO53hl05xQ1ZUQ= -github.com/aws/aws-sdk-go-v2/service/elasticbeanstalk v1.33.13 h1:l4FFXPDGzjr3bXU3tamm1cAmz4c7OWOiHPSekTdRllg= -github.com/aws/aws-sdk-go-v2/service/elasticbeanstalk v1.33.13/go.mod h1:V3Yl2vXro/+nzAmexAXOc1GdkTmEE+UHp0YMuTn5G5k= -github.com/aws/aws-sdk-go-v2/service/elasticloadbalancing v1.33.13 h1:VygvbUZq3ancO3iutKRr5zsdVR3X5wQPFoYMD1P8hhg= -github.com/aws/aws-sdk-go-v2/service/elasticloadbalancing v1.33.13/go.mod h1:ImGbJ8W4fb8KZekLSWCnuuabYN5WusCD7cnW4Nz7i14= -github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 v1.53.0 h1:FW40Wq7eYkzoBc/7X4Ds7OLKXv+CM5w7n1mMN+qxSRI= -github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 v1.53.0/go.mod h1:Uyo8wjqYyZaHVqoe+APHe4+THRGv4pctJzItYYnRe5Q= -github.com/aws/aws-sdk-go-v2/service/elasticsearchservice v1.37.13 h1:hqyzd5cRYxvjVLa9FmmR39IM76hSNf+ROudLUpZviSE= -github.com/aws/aws-sdk-go-v2/service/elasticsearchservice v1.37.13/go.mod h1:GXyWYhCWYQQhGzxzNDU6CRL++zIsBgguWJFTa/iTOqI= -github.com/aws/aws-sdk-go-v2/service/elastictranscoder v1.32.12 h1:Aqvjf0SzPHFEq7stD7515Osa/l8dXxnkdZiwjTrGE6c= -github.com/aws/aws-sdk-go-v2/service/elastictranscoder v1.32.12/go.mod h1:hV8KFAz+flqQ0eHBEJYGU4NWzTqQBtrRyqVwfm3Gi2Q= -github.com/aws/aws-sdk-go-v2/service/emr v1.56.0 h1:g185SYMRcklpYhul88jlO00EMsuOpfAwcXoys9KaeNk= -github.com/aws/aws-sdk-go-v2/service/emr v1.56.0/go.mod h1:NZatCe1XK65DogTuEG2emmEN3NIZtwLsXtJzWpkqSx0= -github.com/aws/aws-sdk-go-v2/service/emrcontainers v1.40.8 h1:h4R+o2xRhtn4SPIao+6aU1TVTYBk0CfoLd9bhXZ3OTw= -github.com/aws/aws-sdk-go-v2/service/emrcontainers v1.40.8/go.mod h1:ncWhqV69Tim5BrNp98qdJfLvlD/WwCs5X3lBPgV62rs= -github.com/aws/aws-sdk-go-v2/service/emrserverless v1.37.3 h1:axxXrvkaQcqcmEfNoIhU5oRLX7ufI2sAX+2a1j8xN1k= -github.com/aws/aws-sdk-go-v2/service/emrserverless v1.37.3/go.mod h1:osVEDevOxiptmGI1/Q3CCm0FFIRf0MhwnWoL8Br0Pso= -github.com/aws/aws-sdk-go-v2/service/eventbridge v1.45.12 h1:KsjKcIasbPhVthcDQcAJAyouihkQq5ZS5UJDMwx7yMM= -github.com/aws/aws-sdk-go-v2/service/eventbridge v1.45.12/go.mod h1:WVMQLFJTxCpu7h7eKnItFtVWitmVRJLsHTbZFYOmkTs= -github.com/aws/aws-sdk-go-v2/service/evidently v1.28.11 h1:Gz7BrxUHRme9DZt145R0WhRk6Kc4a8W5Wdl6Mw7oDp0= -github.com/aws/aws-sdk-go-v2/service/evidently v1.28.11/go.mod h1:3Dt+ChkPyMq1eJTpXmBu4AUtsXN0oqfYph09KNICC6Q= -github.com/aws/aws-sdk-go-v2/service/evs v1.5.8 h1:DBvUxll31Wr0ZiahXp+xzR4cuFmO1eFXXk41FopsAl4= -github.com/aws/aws-sdk-go-v2/service/evs v1.5.8/go.mod h1:/IUqdRVJhNRM7OjN7cdlxnM2j+nuf8b1C6j20YzKTeg= -github.com/aws/aws-sdk-go-v2/service/finspace v1.33.12 h1:f88cDjxWDscEu/9pLvTEn+xISRibEuceOFpX4xwoOxw= -github.com/aws/aws-sdk-go-v2/service/finspace v1.33.12/go.mod h1:L9hrtvHZKfvGwvP3rZcNgaZhhH0QWarqvcuw66JUqR8= -github.com/aws/aws-sdk-go-v2/service/firehose v1.42.3 h1:EwlA0X8pv8N6/sVK4r0A4JlZyib7nos8yU9YJSaiKV8= -github.com/aws/aws-sdk-go-v2/service/firehose v1.42.3/go.mod h1:tHbE62j5gxIYxqmus+zqDQEZama0aWmglUnAk5+lAUs= -github.com/aws/aws-sdk-go-v2/service/fis v1.37.11 h1:Z0sI7NcI76E0ok3s29O5TVM0ye2Qi4YGeeRGr7qDP9A= -github.com/aws/aws-sdk-go-v2/service/fis v1.37.11/go.mod h1:Ja2eowkEbK8dfjWqxg96k4lkVjnf7YTUpEtQKHflynQ= -github.com/aws/aws-sdk-go-v2/service/fms v1.44.12 h1:wqtKrEUifaZHVItsMfgAcHzHce8UUQfOvP6vDb2XqpY= -github.com/aws/aws-sdk-go-v2/service/fms v1.44.12/go.mod h1:qKGD0P+Hxcbq4w6Q6PUrDDLd0C2PcgwLtIS2BT6+2yo= -github.com/aws/aws-sdk-go-v2/service/fsx v1.64.0 h1:pIzBzYXgK8naqPgQ0H7VDd6hEi05rZG6DCrAxsn9f2Q= -github.com/aws/aws-sdk-go-v2/service/fsx v1.64.0/go.mod h1:MCyHv+eBeciHOldY/pOKwp7j02Jo2HS1cpvThq2hSqs= -github.com/aws/aws-sdk-go-v2/service/gamelift v1.48.2 h1:cdqUPiNlaSdNumcrBGIag7Qpi6rHwLZHxBvjP08LDBs= -github.com/aws/aws-sdk-go-v2/service/gamelift v1.48.2/go.mod h1:dcVPaAeS/WE1PQeOldz0EuPud1gttdoQXajAKhNf0rE= -github.com/aws/aws-sdk-go-v2/service/glacier v1.31.12 h1:8Az5fIk1L9pRU81KubxXn8QzUZJbticx8KBbTrc+s5c= -github.com/aws/aws-sdk-go-v2/service/glacier v1.31.12/go.mod h1:qkG1pn5qsa79Ovau5ZJ3DpYa9Ar534RyQU8PjjMalCM= -github.com/aws/aws-sdk-go-v2/service/globalaccelerator v1.35.5 h1:h80nAJssBG0S3yD8ZHoigFjmVFJIiL6jfx5FTUihdwo= -github.com/aws/aws-sdk-go-v2/service/globalaccelerator v1.35.5/go.mod h1:La9wJnRUasTkBLOLqH2JVrApk1WG0vui4MVyr+rGS8Y= -github.com/aws/aws-sdk-go-v2/service/glue v1.133.0 h1:bIzOBSUg62ENeRK0t7p8TjdXDhGgVZppSVrSNYSzSgQ= -github.com/aws/aws-sdk-go-v2/service/glue v1.133.0/go.mod h1:KBo/tKQu4KUTMQ88jWZR79PNgEeDCD8QrO8oMmAq8ng= -github.com/aws/aws-sdk-go-v2/service/grafana v1.32.5 h1:eTAfP6KrOmbUK4at7wlX8vG7qc8Ao110th4/Lw7xxI4= -github.com/aws/aws-sdk-go-v2/service/grafana v1.32.5/go.mod h1:6tjVI48fzvjSAKY486cvKQPNeuIcV5YULNlFyAPZ+UU= -github.com/aws/aws-sdk-go-v2/service/greengrass v1.32.12 h1:0OhsswAs8h4vSCyGYx283pH+3Ks4Qngui0/g/KOhUYc= -github.com/aws/aws-sdk-go-v2/service/greengrass v1.32.12/go.mod h1:wXnnE8KHU07d8VHPGTibk+Kx2TXFaCsL92wJoPPvCvM= -github.com/aws/aws-sdk-go-v2/service/groundstation v1.39.2 h1:BsyqAKq5RduYyz1muDRvvsKwXHd6yG/C+9TpdD+8O/o= -github.com/aws/aws-sdk-go-v2/service/groundstation v1.39.2/go.mod h1:mg5Mut9Q671xNH+VvfaPBVvS4U9vLw1R5wz4bJvPjd4= -github.com/aws/aws-sdk-go-v2/service/guardduty v1.68.0 h1:CMWFVQQDypdxhS1d4V19fP/Y3XNB72WLyteyafQMCsI= -github.com/aws/aws-sdk-go-v2/service/guardduty v1.68.0/go.mod h1:U8kxZNr/dDtSqvr9L8e+fyqVmU/BNyI9fKWAatpu1CE= -github.com/aws/aws-sdk-go-v2/service/healthlake v1.36.4 h1:Dt34+Yu6fRgiZgSMoO6J65IMKawDGjJn7BkPvjrI0ns= -github.com/aws/aws-sdk-go-v2/service/healthlake v1.36.4/go.mod h1:1GUJHZK3s9RIYhn/cLwh5/08/EfcnpCllSHWeJ23nVg= -github.com/aws/aws-sdk-go-v2/service/iam v1.52.0 h1:tXH4OrcRq053tqoWcmk9V3yfeedhgoa8o1J04S5JeYc= -github.com/aws/aws-sdk-go-v2/service/iam v1.52.0/go.mod h1:cuEMbL1mNtO1sUyT+DYDNIA8Y7aJG1oIdgHqUk29Uzk= -github.com/aws/aws-sdk-go-v2/service/identitystore v1.34.2 h1:Ch+EIqM8RIEtVQqQl14XazfYBCzzxiZ1f7jbrOJ5D+8= -github.com/aws/aws-sdk-go-v2/service/identitystore v1.34.2/go.mod h1:uuQmaV23i5w+5Jy2XFnquY0Z41iR6oDDdu+Sqz6bsNg= -github.com/aws/aws-sdk-go-v2/service/imagebuilder v1.49.0 h1:VTKPR2R1q0o7N7T0ilqSajWWTlKNjsSzxvu319pLitc= -github.com/aws/aws-sdk-go-v2/service/imagebuilder v1.49.0/go.mod h1:VD7bLCk88KQgyRB+yIQH9BNmtmSpwgRQ0Q7Wp1bsCuk= -github.com/aws/aws-sdk-go-v2/service/inspector v1.30.11 h1:I2WBSlw0rFVTTMDdg+7a77/kQFNKxJh1lJDZyI77ZTc= -github.com/aws/aws-sdk-go-v2/service/inspector v1.30.11/go.mod h1:Ce8Iac726mzXgIOgFkMllAZsgb5XTOjzC5og1vPkHu0= -github.com/aws/aws-sdk-go-v2/service/inspector2 v1.45.0 h1:gQW64ZGON3XG+UX2hDSHEXyRGd0YRxEqnyAYQRBK8tQ= -github.com/aws/aws-sdk-go-v2/service/inspector2 v1.45.0/go.mod h1:btzexzBLvYxamIptsxWMmHhXXx/FFmdKGgH96IM6HE8= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.14 h1:ITi7qiDSv/mSGDSWNpZ4k4Ve0DQR6Ug2SJQ8zEHoDXg= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.14/go.mod h1:k1xtME53H1b6YpZt74YmwlONMWf4ecM+lut1WQLAF/U= +github.com/aws/aws-sdk-go-v2/service/accessanalyzer v1.45.3 h1:k7JN/XRVcIU5+8Wx6bTfrxSH7XTNvMicP6TWZtT4WO4= +github.com/aws/aws-sdk-go-v2/service/accessanalyzer v1.45.3/go.mod h1:ysJZ4K/YfV0rht959xPdE1uzTGROMHatQTrdtORLdV8= +github.com/aws/aws-sdk-go-v2/service/account v1.29.5 h1:ykS4Q5ASR6tZQSLblydQjIAfC2N6QM1rlAaJtGAcO0k= +github.com/aws/aws-sdk-go-v2/service/account v1.29.5/go.mod h1:6D0qKm5OkfoJMN20c05fZl1OJXZl+pMu4Zg4jdmhXKg= +github.com/aws/aws-sdk-go-v2/service/acm v1.37.14 h1:jfO+N0WaKSsl8/3F6l8nr44EWpYQGGBxawEpjUfX2VU= +github.com/aws/aws-sdk-go-v2/service/acm v1.37.14/go.mod h1:Bmnx9GINL2vPDrVqZDVKtukAOmuovly5IGzXJH2dOA8= +github.com/aws/aws-sdk-go-v2/service/acmpca v1.46.3 h1:7Q4vEw+bXCc53tnO1tkINb7RF0st7BZAfxXr0DwZt6c= +github.com/aws/aws-sdk-go-v2/service/acmpca v1.46.3/go.mod h1:78KpefA7OS+q+jVCjqILswjfKERqMJqiCOFKRLgLAtg= +github.com/aws/aws-sdk-go-v2/service/amp v1.42.1 h1:fJorvFIiVlizskYTlQUtckFmb21hjkgT1PUSvH8cq/U= +github.com/aws/aws-sdk-go-v2/service/amp v1.42.1/go.mod h1:P4J8uc2Id/r3Lo+LmVV8yoz9Pdmihj7AJ5lxWU9rJJA= +github.com/aws/aws-sdk-go-v2/service/amplify v1.38.6 h1:Uu/4eG1yT44J9Tqrk+E6xgyVhPqmsrQdJRGjzWyKAO8= +github.com/aws/aws-sdk-go-v2/service/amplify v1.38.6/go.mod h1:IRLsCWM1rNJ86cDEFp/ulTKdWlKVe87qSxerPEMXA1w= +github.com/aws/aws-sdk-go-v2/service/apigateway v1.37.1 h1:KrbKXPlNuytK5KAaQFX8xf15ZpKrvgAUuHkt7mhIdGA= +github.com/aws/aws-sdk-go-v2/service/apigateway v1.37.1/go.mod h1:/HnZROWxpp+MMou2NI80NiDSzosdrx2/9Rvg56culQQ= +github.com/aws/aws-sdk-go-v2/service/apigatewayv2 v1.33.1 h1:/3PwsCVinZ9vep6rU3OQd0nubfnshxHxwy1xLzqstSQ= +github.com/aws/aws-sdk-go-v2/service/apigatewayv2 v1.33.1/go.mod h1:wjcTbvMGit508yYd5nXdFC404E6YR04VE4FZ6jHvO8Y= +github.com/aws/aws-sdk-go-v2/service/appconfig v1.43.4 h1:mbw2jTXGgTQJcZMGJSp2iMknNQs0T1mBW9KZaRUnoMs= +github.com/aws/aws-sdk-go-v2/service/appconfig v1.43.4/go.mod h1:/m+9B/urzrVtarnXvzN+kd+HIcsmZ4pyqA9VeUhr420= +github.com/aws/aws-sdk-go-v2/service/appfabric v1.16.13 h1:KYRX3my0ktlrZrInVyW+GLnv7Mit796jt56hN9XOfxw= +github.com/aws/aws-sdk-go-v2/service/appfabric v1.16.13/go.mod h1:OBJ1A8d1pkpk1kjT8mMOlqZCleNSee98ccmS/v2voMQ= +github.com/aws/aws-sdk-go-v2/service/appflow v1.51.4 h1:Ji3k+Ar1fewvMLd0ke9LApMQFmGFBVor+GxhKbk6AmM= +github.com/aws/aws-sdk-go-v2/service/appflow v1.51.4/go.mod h1:wmuyUniTVcz8dqJUKWjTvM5HmmtqmF6wDhv2q/tce34= +github.com/aws/aws-sdk-go-v2/service/appintegrations v1.36.13 h1:/0XT7noLtnbUM6ExxQhL/zhi7/m4B/6d2IO8eJ5Ny6I= +github.com/aws/aws-sdk-go-v2/service/appintegrations v1.36.13/go.mod h1:9u8qolAYZaeuc1QBe72BvVVG7W59z6NW0x+Et3UoOak= +github.com/aws/aws-sdk-go-v2/service/applicationautoscaling v1.41.5 h1:Dmn3fRcmDplaCLgTeGvD4ftiVUYmhxwCaE9sQZaTRPI= +github.com/aws/aws-sdk-go-v2/service/applicationautoscaling v1.41.5/go.mod h1:qAe2ND6y3dp1DgpO1Yi/YnLSXpdxzhlgpPDteD4k+Vo= +github.com/aws/aws-sdk-go-v2/service/applicationinsights v1.34.12 h1:fUdSTKcfoPiKR1nYfVMeh+b1+Lj7zYtdScCAluzeKtg= +github.com/aws/aws-sdk-go-v2/service/applicationinsights v1.34.12/go.mod h1:pFgvo2beLgB+KAlbEaiDorB0tpMZQYUZJgPDBrGTPow= +github.com/aws/aws-sdk-go-v2/service/applicationsignals v1.18.0 h1:XgDt53l4YAKv8nMtpUAA+6M9j3+u3BhK8wgoVQf2sKc= +github.com/aws/aws-sdk-go-v2/service/applicationsignals v1.18.0/go.mod h1:JiP8NIeL2VIOI3EIIpepj3ga9X3M7+na32lGqxEapo4= +github.com/aws/aws-sdk-go-v2/service/appmesh v1.35.4 h1:SS9WmDDzBXx1GtHvrGHbH0nD6Chovd/e31K9NMuilMg= +github.com/aws/aws-sdk-go-v2/service/appmesh v1.35.4/go.mod h1:zHvyRFwphYyvGE1FO55940bsRsJppGeSJkVJhiQHykk= +github.com/aws/aws-sdk-go-v2/service/apprunner v1.39.6 h1:Elcq1H9O6erkFp36kTcWVDLLcnj9/+ofH0gZcQ5d3Xo= +github.com/aws/aws-sdk-go-v2/service/apprunner v1.39.6/go.mod h1:4ZOqpxGgZG94Pe0EEBymCj+ljWKRVeyU0vmfuDoyq78= +github.com/aws/aws-sdk-go-v2/service/appstream v1.52.2 h1:k+vEEAJOCXC7qOBpXIQYlQEh+pNBozjAokUN8Sh9YmY= +github.com/aws/aws-sdk-go-v2/service/appstream v1.52.2/go.mod h1:1CrfXbbxbeVA2IA5ZP+U8kgE5fThA1pAOQ+U7S8sMOI= +github.com/aws/aws-sdk-go-v2/service/appsync v1.52.4 h1:px1BM7U1B1meU672xe/fFiAMBc7Du9rBZWgdpo0t8Kg= +github.com/aws/aws-sdk-go-v2/service/appsync v1.52.4/go.mod h1:O+8BFtV0hVUON/mjQzIkxS8rZcUgdvew5a5vYQxUrc4= +github.com/aws/aws-sdk-go-v2/service/arcregionswitch v1.2.15 h1:VtSIOfOJzouZ0WmCcL5RrVkohNLe33IOqJqPNlHmlQo= +github.com/aws/aws-sdk-go-v2/service/arcregionswitch v1.2.15/go.mod h1:TiGkbaifAXAyXcvB7gD6wqocmtxGwt3ELHQN+POyr6M= +github.com/aws/aws-sdk-go-v2/service/athena v1.55.13 h1:98pxyd9WZm1xLTF+fz2e8K3chrTWTOGnnIKE8G11r24= +github.com/aws/aws-sdk-go-v2/service/athena v1.55.13/go.mod h1:4A0RedsMl3WXKVbYHL9eXnyfi1ZYajDjQz7FxGJIVJk= +github.com/aws/aws-sdk-go-v2/service/auditmanager v1.46.4 h1:qAl3PFavOdDrkAhwQJw4DlVJswUyU2UL4UeZaFrF9Eg= +github.com/aws/aws-sdk-go-v2/service/auditmanager v1.46.4/go.mod h1:hXTso1pRe6MtH3nxxT3EY34fqXtZG4rfbR10ozUKurU= +github.com/aws/aws-sdk-go-v2/service/autoscaling v1.62.0 h1:cYsffsQcIls7mqvMQ3+SkaUXgz/CvxBQgJFrKCLj64k= +github.com/aws/aws-sdk-go-v2/service/autoscaling v1.62.0/go.mod h1:6q/I1pH386VpPfB6FE62X/MOs6NW/oCsY9FXU33YXOU= +github.com/aws/aws-sdk-go-v2/service/autoscalingplans v1.30.6 h1:sPg/pDjwZmtPbHmfIz9khR2b3U/VCJAUfmO0l+NXWfE= +github.com/aws/aws-sdk-go-v2/service/autoscalingplans v1.30.6/go.mod h1:CHaY8BE6Hxfo6HJx7d3WauQbZzFloOEEXOt+4m98YVc= +github.com/aws/aws-sdk-go-v2/service/backup v1.54.1 h1:IZMjxKACs2nGUcT1IUhaDdtkGLE/6QcM+1Eaq6aa9YA= +github.com/aws/aws-sdk-go-v2/service/backup v1.54.1/go.mod h1:jPKoVknYePQQIuFqYb9MJQrUmokCl+oqFD1Nz6Ly4F8= +github.com/aws/aws-sdk-go-v2/service/batch v1.58.7 h1:vbYYWl1qg31I8Smezhkzv0JzW7jfF5C0jQLQJGgeqss= +github.com/aws/aws-sdk-go-v2/service/batch v1.58.7/go.mod h1:jPR/hL+ncTdOo6ovJpbHVrCtc6fcXqSKedlBflV0ci0= +github.com/aws/aws-sdk-go-v2/service/bcmdataexports v1.12.6 h1:r1WfnIm1l2j+r8B97xSfTTBWtcUbRmLVk0dKe1z0oWE= +github.com/aws/aws-sdk-go-v2/service/bcmdataexports v1.12.6/go.mod h1:irnQ+bwBP8QTNMxJuknd2QNeduTii8OR4vJHZVyLVqg= +github.com/aws/aws-sdk-go-v2/service/bedrock v1.49.3 h1:qF3XggiU18L8QBLU/LVH+I/Sl1qyZMpuUR+h6+gYFhQ= +github.com/aws/aws-sdk-go-v2/service/bedrock v1.49.3/go.mod h1:hXxa/UTPE5uLWb/vquqMxVmS+IFUHeVf4gKeLSuiKqE= +github.com/aws/aws-sdk-go-v2/service/bedrockagent v1.51.4 h1:w4fU0VFfdjEGqAAQuw/BIdrRnj/vSOa+lCQOzMnFEjA= +github.com/aws/aws-sdk-go-v2/service/bedrockagent v1.51.4/go.mod h1:W5wiJ+7Z3Thx/TlvvNeQgeJFY1ghO7Gpcay12WO/Zd4= +github.com/aws/aws-sdk-go-v2/service/bedrockagentcorecontrol v1.13.4 h1:h4Mgd6FliaOK5ornhLIvP42ko9k62g7r5LK92ss80VM= +github.com/aws/aws-sdk-go-v2/service/bedrockagentcorecontrol v1.13.4/go.mod h1:rSP65Gc7ucwUaO12JTPl8o835CZlN8d3qUFcdT/6dHE= +github.com/aws/aws-sdk-go-v2/service/billing v1.9.1 h1:yza2j5Myi2jRxHUe4q0Is+r9VkJ7HZGxJZasVjYhOYo= +github.com/aws/aws-sdk-go-v2/service/billing v1.9.1/go.mod h1:xJnUORWEM7RAHY+bzFl1la8IFxfyAbccbdSr25vJUS0= +github.com/aws/aws-sdk-go-v2/service/budgets v1.42.0 h1:4nlp0fWGDKyTFgAG+CkVpCcLlTH1XqiEFebbz+4IfjI= +github.com/aws/aws-sdk-go-v2/service/budgets v1.42.0/go.mod h1:DW69mROaOTaFFNE5DViFTfugWTJG2Zw/NniLQblAmbk= +github.com/aws/aws-sdk-go-v2/service/chatbot v1.14.13 h1:go4oq2X7vgf4XbjjJEvrwW/Xr62gnYMMbRsYmY9gLOQ= +github.com/aws/aws-sdk-go-v2/service/chatbot v1.14.13/go.mod h1:SefM/lOvvt0B3DOzA7QVtLycPJniHJ8Kht6BMPmASFU= +github.com/aws/aws-sdk-go-v2/service/chime v1.41.4 h1:hdQFK7C+LbNBLZXbMR3E7F4MWpiQ5njudxEQ4CefGfc= +github.com/aws/aws-sdk-go-v2/service/chime v1.41.4/go.mod h1:BQrHRnlutIKk0F+J8DDMucwT2HgqQZLM948jOzveQzo= +github.com/aws/aws-sdk-go-v2/service/chimesdkmediapipelines v1.26.13 h1:iPpWibzdfbuV4Sv0BP0SSDp9IZMskkn6BsxpAaxaCyQ= +github.com/aws/aws-sdk-go-v2/service/chimesdkmediapipelines v1.26.13/go.mod h1:XcUYZ46XzmzbkC6v2HA5yvQ7BLxxUvnf08hCqx/0pj0= +github.com/aws/aws-sdk-go-v2/service/chimesdkvoice v1.28.5 h1:cPEX42clexCeG0Go0eXHTXROeneXiZpENiDNl6+Lg8Y= +github.com/aws/aws-sdk-go-v2/service/chimesdkvoice v1.28.5/go.mod h1:6x+LIQMdqdAtkRRUkGNmShjrkRLJAEvIPMewwMGB164= +github.com/aws/aws-sdk-go-v2/service/cleanrooms v1.37.4 h1:T0BBPg8vH+6puyXgRv4Ga0JRnQWzmKaljUzh3BOOFT0= +github.com/aws/aws-sdk-go-v2/service/cleanrooms v1.37.4/go.mod h1:bRdFbDwBkz32R7ympGXrKne/Er4OlR7aabOs1kllhfY= +github.com/aws/aws-sdk-go-v2/service/cloud9 v1.33.12 h1:xEEqlbvCS0tEYKJ2/aColjiPjSeLJZn1mn1cYIc1bok= +github.com/aws/aws-sdk-go-v2/service/cloud9 v1.33.12/go.mod h1:Uv3v++wSBqiXMYhl/h17/knL3uIIsf5quqq13ZQuFuw= +github.com/aws/aws-sdk-go-v2/service/cloudcontrol v1.29.4 h1:GiSgorIElOwkVHjt9fraV7eecQgqLDA2nTVIRhw68AU= +github.com/aws/aws-sdk-go-v2/service/cloudcontrol v1.29.4/go.mod h1:XyQgviAJh0ix9AEoEQd1txAgMNWhjHwmH9GaPKRhpGg= +github.com/aws/aws-sdk-go-v2/service/cloudformation v1.70.1 h1:cAdsbsK6UsT29aVjpA/VcR/neSSZwq5FtwJLVzhO7bQ= +github.com/aws/aws-sdk-go-v2/service/cloudformation v1.70.1/go.mod h1:AIfiLeQfCO8suB3zxZp155Sv9KfiDhPyF+SSIRLEUYk= +github.com/aws/aws-sdk-go-v2/service/cloudfront v1.57.0 h1:e8fNhNWwv/qIGFjK4eV4TE2yrf56yFCDkZ9cSyuewnA= +github.com/aws/aws-sdk-go-v2/service/cloudfront v1.57.0/go.mod h1:BeF/zsF5v8suyEFqg9h230PtSBJAL2PWSCCULD4/H5g= +github.com/aws/aws-sdk-go-v2/service/cloudfrontkeyvaluestore v1.12.15 h1:ZyUTATfJJZi5cQ43t8lUaBVxye+fAtaMHKojWtNJcRA= +github.com/aws/aws-sdk-go-v2/service/cloudfrontkeyvaluestore v1.12.15/go.mod h1:AFWVoaDjzkPtx0y8CdSel9wjNoJCgdcL3E2b1f/iaxo= +github.com/aws/aws-sdk-go-v2/service/cloudhsmv2 v1.34.12 h1:SZlIVdXH6bALHm+S9E3A8AyusETBj6Ac8vhp8Rul90w= +github.com/aws/aws-sdk-go-v2/service/cloudhsmv2 v1.34.12/go.mod h1:u8d2bR9E7S8aCTb7VlXzgrUqL7OW6hgkGKVGOp3yquw= +github.com/aws/aws-sdk-go-v2/service/cloudsearch v1.32.4 h1:DQpaAyjX8GmXuWuyO6TkjaN4IJRqt/nKorRi19mQkJs= +github.com/aws/aws-sdk-go-v2/service/cloudsearch v1.32.4/go.mod h1:oacL8OCx2lpH8K4KtuSTMRdmwqw5cS0GGKm+UQFnwjY= +github.com/aws/aws-sdk-go-v2/service/cloudtrail v1.55.0 h1:6Sv/xMZqb4koEQQYF3OsqBc+v5+oTFCGOepEhKReyhs= +github.com/aws/aws-sdk-go-v2/service/cloudtrail v1.55.0/go.mod h1:XSNDmicqamWtX6yg5lisFAiFaf56PErQo/cMQvUQWX0= +github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.52.4 h1:ljiDPeMJhk9lvTHvmEk7mHOuk5rtdS618fdIr2vquSw= +github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.52.4/go.mod h1:vta+WQPKfEzTigLRCnlWbrsv8sLj3/imAQ2fjySEA4k= +github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.60.1 h1:ZVEs9ZPzCsX9n1/Pr+x+ms1f6UZOPjuj9evCmwHceA4= +github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.60.1/go.mod h1:WXcA3mYRgWVIzjD+kxzap0axltmt4zBVDZaRX0S86gk= +github.com/aws/aws-sdk-go-v2/service/codeartifact v1.38.13 h1:tBzK9wUdcAzJelHFFHZ3Zmq/xMYfreX4KL7dJenAAiM= +github.com/aws/aws-sdk-go-v2/service/codeartifact v1.38.13/go.mod h1:htMVJ4Hvxuzw3znlz/difZJ63D7qW7pj8qsvIaJy92k= +github.com/aws/aws-sdk-go-v2/service/codebuild v1.68.5 h1:T6YofQNDDRCRjrXGbISm7NAfWrkiTulVRJJvlRGxZZ8= +github.com/aws/aws-sdk-go-v2/service/codebuild v1.68.5/go.mod h1:6beJzOhsJ3eZZer/LZsc22MDwGBDB36JBkgyx6g3m0w= +github.com/aws/aws-sdk-go-v2/service/codecatalyst v1.21.4 h1:KKLd2otYauuDybA81T8Z+jjPBi0z9yvLgdVBldmUBXE= +github.com/aws/aws-sdk-go-v2/service/codecatalyst v1.21.4/go.mod h1:j4TcbQRWZQJpZqORVYHaV4lTpmrxVz+TT0kwF6EogTg= +github.com/aws/aws-sdk-go-v2/service/codecommit v1.33.4 h1:hcWOsME6nj9abHmBhXXEhsmuDigtJqLuVOF+2foCWeg= +github.com/aws/aws-sdk-go-v2/service/codecommit v1.33.4/go.mod h1:Apq9XzUs2Fpf4zGYSTT30AzyGpmQ5WdUQ9FB4Oo3VEY= +github.com/aws/aws-sdk-go-v2/service/codeconnections v1.10.12 h1:4j3wJdrlTpCkim5wPsoj10SqpmkRv0kE/4NVdu/qQcM= +github.com/aws/aws-sdk-go-v2/service/codeconnections v1.10.12/go.mod h1:QN0TcnmMfAz/VqxgxbiULvIlgQBFFR/eraAQGDhwukE= +github.com/aws/aws-sdk-go-v2/service/codedeploy v1.35.4 h1:E7La22cTAVR/JOqughhRLrsuu60vM/KyWT9lJX7kojk= +github.com/aws/aws-sdk-go-v2/service/codedeploy v1.35.4/go.mod h1:Gfi04+7zlmC/s+j1mn5ysisC7L6JeNXRXCa9HFFptII= +github.com/aws/aws-sdk-go-v2/service/codeguruprofiler v1.29.12 h1:zjPh0tOCA9nrlkdqTOISrHsecKBxVPrIAXOD4Q0Ye2g= +github.com/aws/aws-sdk-go-v2/service/codeguruprofiler v1.29.12/go.mod h1:8BgUjRLY22j/eaG36+xgcqD9UkUBk/QM4q/oDZ4cQo0= +github.com/aws/aws-sdk-go-v2/service/codegurureviewer v1.34.12 h1:oqn4v50SvbgM790LkfShIIiqNSVk2SZzkTl1iKeIp8Y= +github.com/aws/aws-sdk-go-v2/service/codegurureviewer v1.34.12/go.mod h1:Nld3gJ1kPAzMzySq1jqxauvQFWKwrELKyqylzjObKjM= +github.com/aws/aws-sdk-go-v2/service/codepipeline v1.46.13 h1:Kmp/z7F0BpjiRYeeo0y6AzUrMxN6Qas8SCudtwAa1ow= +github.com/aws/aws-sdk-go-v2/service/codepipeline v1.46.13/go.mod h1:1BCNGWCG70VC3WSBU6arF41A8uOCaXvHXJfEuc0BcE0= +github.com/aws/aws-sdk-go-v2/service/codestarconnections v1.35.5 h1:tJiiFrDkD12MYK3JkQk58G7aAFniAkbIZikwn+J2KJI= +github.com/aws/aws-sdk-go-v2/service/codestarconnections v1.35.5/go.mod h1:SwSe4micC5/bJGgCKSDUABd5jz21xhTSdSDmn/dKKUU= +github.com/aws/aws-sdk-go-v2/service/codestarnotifications v1.31.13 h1:jszJ3CqI/kpZ6UawSUMUJISAcGk1RCtSwthsmmTjOyQ= +github.com/aws/aws-sdk-go-v2/service/codestarnotifications v1.31.13/go.mod h1:bir4uZVKP85EGw4AtGrNYx+1ojTZHXiwmh9GBs9rmzA= +github.com/aws/aws-sdk-go-v2/service/cognitoidentity v1.33.13 h1:+/K5ZHJubNdQBSuX5NhJOTgmCnMOQ9iS2aX3EKis+jk= +github.com/aws/aws-sdk-go-v2/service/cognitoidentity v1.33.13/go.mod h1:Na4x4vWmhGhowGbS8CpEv8i2dy7LqMIDihGMnyYuWbU= +github.com/aws/aws-sdk-go-v2/service/cognitoidentityprovider v1.57.14 h1:5NblKxf/gIiOBfQg84/b24F4bB5HlP14jiOV/+1ItZ4= +github.com/aws/aws-sdk-go-v2/service/cognitoidentityprovider v1.57.14/go.mod h1:PXsFfhP2kOeVp5cc/3Ogyv7vJwx2wKg+7pH7/nAJ3YU= +github.com/aws/aws-sdk-go-v2/service/comprehend v1.40.13 h1:Iz10MriW+a6hh2Cbazq7b+mEyF81Ra2cIxxVw+pE4Qg= +github.com/aws/aws-sdk-go-v2/service/comprehend v1.40.13/go.mod h1:fp8KjsMghxMXHwpMswKhLlXzhBiboeiqRFfFio5uxik= +github.com/aws/aws-sdk-go-v2/service/computeoptimizer v1.48.4 h1:QIY4le+1uRnrOClfpWpVfG6+vtQqEO7sEDl6SuhswfI= +github.com/aws/aws-sdk-go-v2/service/computeoptimizer v1.48.4/go.mod h1:LomC95qThQQOln0G+5WJw36bEHj7Mr5Wunn5LbITBLk= +github.com/aws/aws-sdk-go-v2/service/configservice v1.59.5 h1:KJtaGTJQSMQogUsLcgmltqYYXWXzRsakPTOO/w+pLKU= +github.com/aws/aws-sdk-go-v2/service/configservice v1.59.5/go.mod h1:cXhjm6628GYAJVUcPXS2lmPWMDshtIryVKTIhKGse94= +github.com/aws/aws-sdk-go-v2/service/connect v1.147.0 h1:x7IEtha46ZlO3cL6Wy5hord+nBi9fRAVb0v+Yq94nAI= +github.com/aws/aws-sdk-go-v2/service/connect v1.147.0/go.mod h1:TMEEKB4pVRexhyblCXY/y0W6jW4+dpSyz8lBbikW8uw= +github.com/aws/aws-sdk-go-v2/service/connectcases v1.34.4 h1:6KX8jpNnTeAGqtF/Mimf0fs9eg+ztwL09PyNoRCUHnM= +github.com/aws/aws-sdk-go-v2/service/connectcases v1.34.4/go.mod h1:AuJ0PUhJ71jYKpu+6ZsbeflD1Ryfv/J+WQcHdlaSxfc= +github.com/aws/aws-sdk-go-v2/service/controltower v1.27.3 h1:tjuF2Q6uIsLFvhFR3fAKrOlNz4xhKxrFcbC8N8HZK6A= +github.com/aws/aws-sdk-go-v2/service/controltower v1.27.3/go.mod h1:G8s3hKQicUH1EnO/eBV+G9S4yQ0s85DJLN88Obqvj+w= +github.com/aws/aws-sdk-go-v2/service/costandusagereportservice v1.34.5 h1:Yvo/Hf1PyVTHzNxF5CjT+L7lwdZn2Ii+pjnFhgbQwpg= +github.com/aws/aws-sdk-go-v2/service/costandusagereportservice v1.34.5/go.mod h1:fDFeDhD0L0/lblD3vUjJ9JIkjMFFBDRvG9odyEpH+gI= +github.com/aws/aws-sdk-go-v2/service/costexplorer v1.60.1 h1:tq8HHHqO5lgRdptchQ38S5UYJi2//ZW5zu6Bpx/XMVk= +github.com/aws/aws-sdk-go-v2/service/costexplorer v1.60.1/go.mod h1:USNfCQdwGW7AAHQt/7uDrFI2zbeZsMXEqt4zSPu7xGM= +github.com/aws/aws-sdk-go-v2/service/costoptimizationhub v1.21.1 h1:GDy+qkGuLrChf5GbPzHWE6VJKmQPpcK+8lfLEPzQlYk= +github.com/aws/aws-sdk-go-v2/service/costoptimizationhub v1.21.1/go.mod h1:k2LgBKk/ZTzoK0xBS+CNVqHdUDrQRc7rJMzf5ANC7v4= +github.com/aws/aws-sdk-go-v2/service/customerprofiles v1.54.6 h1:LwZ8b5hvK+f7B94Psvid/DWEoCeWFI0/EQ1S2UNbfbA= +github.com/aws/aws-sdk-go-v2/service/customerprofiles v1.54.6/go.mod h1:8VNdSARzX/dUYbtwIQNLsMMf6MyBECT132AgF3YVXzk= +github.com/aws/aws-sdk-go-v2/service/databasemigrationservice v1.61.0 h1:2VKTALfefAO/w98dxPaVXUw1lh+DW+McLEUaXWd8w+I= +github.com/aws/aws-sdk-go-v2/service/databasemigrationservice v1.61.0/go.mod h1:fQ0qBdbGgAJ/Eu76l9sjlvnfu3HwGyMimXk0GLQz/u8= +github.com/aws/aws-sdk-go-v2/service/databrew v1.39.6 h1:LVHrDsYIw98nI9h7hflbiDAbaZWtfWnGqpKxuVMcmHQ= +github.com/aws/aws-sdk-go-v2/service/databrew v1.39.6/go.mod h1:4GeWnC4q32eYLx6LbwTpZ0KLEsNaBoRlf/N6QNhjRrw= +github.com/aws/aws-sdk-go-v2/service/dataexchange v1.40.6 h1:yGAmZOaZoO7pR7li1xAdTSoefPYU9w3dReJqHvu7Ytc= +github.com/aws/aws-sdk-go-v2/service/dataexchange v1.40.6/go.mod h1:JHAULA1ArMgCzvgVfQFksKJAa/8LBWiFc8I6UnJcLeA= +github.com/aws/aws-sdk-go-v2/service/datapipeline v1.30.12 h1:wnZTfexNWH+E1VMU1BqNME9rzNJcWt7mTZF5/ZOox6c= +github.com/aws/aws-sdk-go-v2/service/datapipeline v1.30.12/go.mod h1:7HuTZpaCATXeh9BgyOaGl+CsHWuenGnVOk/DzWqR6+0= +github.com/aws/aws-sdk-go-v2/service/datasync v1.56.0 h1:s2ThzC+XJ308Tq/w1BN17k0wxi7QU8OKFMuZfgo0RZ4= +github.com/aws/aws-sdk-go-v2/service/datasync v1.56.0/go.mod h1:LkXrU5qwiBROYW0LbZdKmYatLi3XtnDGI5MfFkDqgkM= +github.com/aws/aws-sdk-go-v2/service/datazone v1.48.1 h1:GDqYM/erfU6vxdPnqlR+RMA6Fq2BAqRoYKGsbPJAM5k= +github.com/aws/aws-sdk-go-v2/service/datazone v1.48.1/go.mod h1:tFgI26zrBCLvM+Y3KszrCV/llPXj3/AW7y+6X4+Ff1o= +github.com/aws/aws-sdk-go-v2/service/dax v1.29.8 h1:KAeUjl440e4O7uGoAywFQO91NdMAKdCmSG6x320TH5g= +github.com/aws/aws-sdk-go-v2/service/dax v1.29.8/go.mod h1:bUwIfe1DAC2Cevx2X5ewDFBdFuh9EqTqiOPNNvmIYyY= +github.com/aws/aws-sdk-go-v2/service/detective v1.38.5 h1:3Guq3ZYf31BQBZOn8PDtnOXsfPPaoHn51T2qrKKqo1M= +github.com/aws/aws-sdk-go-v2/service/detective v1.38.5/go.mod h1:HEwm5EWvX1lhb0oL2IZ4nfPTzCMSxGLZ/kpcM+4N5b0= +github.com/aws/aws-sdk-go-v2/service/devicefarm v1.38.0 h1:KsxS9mJYJMifuRadEt2GE5HNS/LQ/H7UifdBAaLOnlY= +github.com/aws/aws-sdk-go-v2/service/devicefarm v1.38.0/go.mod h1:o7c0JSwhdY6BrJSE4Ix304GGScromPtUORjcnSDyhQE= +github.com/aws/aws-sdk-go-v2/service/devopsguru v1.40.4 h1:fgbCO39te+Qh2l7C0eFrf7zBGfuVArZrQ3AhPZr/4ik= +github.com/aws/aws-sdk-go-v2/service/devopsguru v1.40.4/go.mod h1:wmVeu5tb+3SNeslOxukK5BifxkaL4KcbLtzfRuxMXjw= +github.com/aws/aws-sdk-go-v2/service/directconnect v1.38.6 h1:mIgSjHgWbm8QxTM6eohjAx2GRkyJP0PTAjWZPyYrhgA= +github.com/aws/aws-sdk-go-v2/service/directconnect v1.38.6/go.mod h1:S+im9xXqp0IB2fFvcOXgbFKzV+vL7d8ShTl9BNUXJdg= +github.com/aws/aws-sdk-go-v2/service/directoryservice v1.38.7 h1:Bo8b1qoLm5p06PUQ7MynI2Fg2/nAeXrSJTkmYZ+SFcw= +github.com/aws/aws-sdk-go-v2/service/directoryservice v1.38.7/go.mod h1:G6YzonR7wX5/pMGXX24c4SyUBVg4p1WwUNf/t2BBIIY= +github.com/aws/aws-sdk-go-v2/service/dlm v1.35.7 h1:ro1d6N2z8P9FYNc+mChGT1fMDC66AeAO7GTVOqdHHTQ= +github.com/aws/aws-sdk-go-v2/service/dlm v1.35.7/go.mod h1:TcDH6wSbs/z+0n4NY3QBb6gj6Qs2DhFg5yQ1s4RZkZY= +github.com/aws/aws-sdk-go-v2/service/docdb v1.48.4 h1:SmEHt6LweGc5ihaFFS79Kis/CwQGIsBlY2iUyg0EfiY= +github.com/aws/aws-sdk-go-v2/service/docdb v1.48.4/go.mod h1:+ZJ270JFyumo/nhCNLK5qFOPdXbQmS/ZcEznibSTPj0= +github.com/aws/aws-sdk-go-v2/service/docdbelastic v1.20.5 h1:pIme55gjYk3pB6odYiOTvVjduOmACSOrNPIbwzLbyI0= +github.com/aws/aws-sdk-go-v2/service/docdbelastic v1.20.5/go.mod h1:nXmJYIF39MD5YSUVnoCO1tsDxQJjuZXgF5Gnso7rqWg= +github.com/aws/aws-sdk-go-v2/service/drs v1.36.5 h1:cYpfwYpc4w39DZqi1kBmd4zlER4JWWRi13wylX4PQ/A= +github.com/aws/aws-sdk-go-v2/service/drs v1.36.5/go.mod h1:P1+6yT6SXEGn5in+7aGjosmdCfhlIDlknmUAYalfdAc= +github.com/aws/aws-sdk-go-v2/service/dsql v1.12.0 h1:cCsvLk5Ef7UpGoa91qQ/oypURIPYEqJQv8Qt1wcwFA8= +github.com/aws/aws-sdk-go-v2/service/dsql v1.12.0/go.mod h1:FNZYp895vM1Rw2x1RExcbAVmnlHo97OXZrwtKITRHGA= +github.com/aws/aws-sdk-go-v2/service/dynamodb v1.53.1 h1:94W5IklNYC4LSldDFfH9E+gQbczZjqRwEr6lN5wEpCM= +github.com/aws/aws-sdk-go-v2/service/dynamodb v1.53.1/go.mod h1:bz4cZH7uK5fLxQbj7hL4MFDL+pjReC9en/nM2Wfwxsk= +github.com/aws/aws-sdk-go-v2/service/ec2 v1.273.0 h1:lJZflraZ8ddloz8bA2dX9ukc4mkLQFoYwZlzG7GLgWk= +github.com/aws/aws-sdk-go-v2/service/ec2 v1.273.0/go.mod h1:QrV+/GjhSrJh6MRRuTO6ZEg4M2I0nwPakf0lZHSrE1o= +github.com/aws/aws-sdk-go-v2/service/ecr v1.53.1 h1:mLG+iEEtdrS1+DSNqt+nC/jWlXc/GRSpn1AUPhMYUwk= +github.com/aws/aws-sdk-go-v2/service/ecr v1.53.1/go.mod h1:gTUZahuPMDg0ySQRPFNIbxUzpqu9CSSzU2LVURbWi54= +github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.38.5 h1:1f7Ah71P6+IgmIFxmzOZP3j26jscVsvlqkIENjYCntY= +github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.38.5/go.mod h1:z7nn/sUdic8fCdTPhg+w6/9aCvb7BNCLlfifxKn0T2Y= +github.com/aws/aws-sdk-go-v2/service/ecs v1.69.0 h1:rAfTuGAMTqlmxwRcddooVLbwoVqZKNwgXGga7cTFmQY= +github.com/aws/aws-sdk-go-v2/service/ecs v1.69.0/go.mod h1:Tc2TICeWJQ4koMm6/39NK1ZIrSJh+5FF8EAm4WtdN+0= +github.com/aws/aws-sdk-go-v2/service/efs v1.41.5 h1:rDc7Vz41BIR4ju1V386OZ8ozzncWfzRk+ZMqemg8OXQ= +github.com/aws/aws-sdk-go-v2/service/efs v1.41.5/go.mod h1:SZ37SpJcrcW0J8EwoCkUWbz4eZ1+qCNCyu6e+0+8Oto= +github.com/aws/aws-sdk-go-v2/service/eks v1.74.10 h1:bkpRyAmbBYuMKx4ZfmVLRdTwewAXGy1S0LrvH1BFz2M= +github.com/aws/aws-sdk-go-v2/service/eks v1.74.10/go.mod h1:lrJRZkSj6nIXH/SN3gbGQp4i4AtNyha0wT7VgYZ3KDw= +github.com/aws/aws-sdk-go-v2/service/elasticache v1.51.4 h1:PrwDrZSKHstbo6Pbg3NfgM2yw0qgeRxgaiMR6xFuXHo= +github.com/aws/aws-sdk-go-v2/service/elasticache v1.51.4/go.mod h1:ApnhfqBJO/U4iwpAYBKWmGZFXR2de6UVjqhj/hGMaEk= +github.com/aws/aws-sdk-go-v2/service/elasticbeanstalk v1.33.14 h1:nCikYwZAXX2GclNZNLIx/jWqzrZO4OIBwG51/ZgTx+U= +github.com/aws/aws-sdk-go-v2/service/elasticbeanstalk v1.33.14/go.mod h1:CKE5puCItDiU+61TEnU0aeeIRf2VUO2zQyh4FH0ksRc= +github.com/aws/aws-sdk-go-v2/service/elasticloadbalancing v1.33.14 h1:MRXEhiJNnnNOck/FEaO0msVXJscCDUfNTuYe5RGgf/E= +github.com/aws/aws-sdk-go-v2/service/elasticloadbalancing v1.33.14/go.mod h1:QEbuU4eh8HGdv4uvld0Jth+KW8L0lOSYlyPcW6+JJo8= +github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 v1.54.0 h1:7Aa/utljEengXYcL+29baOrd6eRtP0JoX3UJwYNA83Y= +github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 v1.54.0/go.mod h1:DpGMmFhQwV/HH9zugLT5Ovf9HMKdQ+6ejfJybqEC9i4= +github.com/aws/aws-sdk-go-v2/service/elasticsearchservice v1.37.14 h1:xEDJsw2VcwxcB6ZaZ1eWl0YEKLgODqpHgBDxXECLUeQ= +github.com/aws/aws-sdk-go-v2/service/elasticsearchservice v1.37.14/go.mod h1:dyQBvnFiOLtFTRo5MiKZxqS1z0rXQ2+crUeXSmPAxNA= +github.com/aws/aws-sdk-go-v2/service/elastictranscoder v1.32.13 h1:3tXl5c+6sL7P9y8DMfTWKWPYLGavXcnSZbWUEzn/f0g= +github.com/aws/aws-sdk-go-v2/service/elastictranscoder v1.32.13/go.mod h1:8hd3XqGD2QPBzu16Ov1zb8nxDgwT9Jpzjdqc64llGOs= +github.com/aws/aws-sdk-go-v2/service/emr v1.57.0 h1:vxGu1za7EznI+b24fwJndJqkdPFn7zPh7wGPcWmujBw= +github.com/aws/aws-sdk-go-v2/service/emr v1.57.0/go.mod h1:jWn7UtQ6SKVdUEUW5tWpmsAoMTOofQNwICe0K3sCvo0= +github.com/aws/aws-sdk-go-v2/service/emrcontainers v1.40.9 h1:hBU9c9ke1xselOGxHY+qK1alU0BmoHI8dqliKv4KCo0= +github.com/aws/aws-sdk-go-v2/service/emrcontainers v1.40.9/go.mod h1:e8EC0ae1AGruG8d4Szh6+5JP/gIjIHeobeGsB7L0ay8= +github.com/aws/aws-sdk-go-v2/service/emrserverless v1.37.4 h1:9LVUn0oF+PT8vXIRMkoMKT65wXBtKDv13ndtgJxXSPU= +github.com/aws/aws-sdk-go-v2/service/emrserverless v1.37.4/go.mod h1:jp7WQ5Slmqwxm+gNdKJjq4O+ROa+GR3L4EizEaxRq7g= +github.com/aws/aws-sdk-go-v2/service/eventbridge v1.45.13 h1:xOu7mzsFNFtRNPHHKZy2WV4z4Mh9VuY8I0hAWD5lwuY= +github.com/aws/aws-sdk-go-v2/service/eventbridge v1.45.13/go.mod h1:zHeo4QChGlVJGqNVSl6LZpTJAGy0JwNlRcf1tV3tX4c= +github.com/aws/aws-sdk-go-v2/service/evidently v1.28.12 h1:Y2mIa0UIIA38cgAoeLRgauO3UCPk1xdGFcE9Xqje6IM= +github.com/aws/aws-sdk-go-v2/service/evidently v1.28.12/go.mod h1:FMSLELS9/DRL4uy1a4jSvI4rQTxB7D9lRRgfmIuSqxU= +github.com/aws/aws-sdk-go-v2/service/evs v1.5.9 h1:1BG7XfiSOxeQG6UYhEf54DR+0iqoyORTJzwrBnNYX2c= +github.com/aws/aws-sdk-go-v2/service/evs v1.5.9/go.mod h1:KMV65KgWYbLqjkKnYpxc6PacBmU2+dkpy989M09K8xo= +github.com/aws/aws-sdk-go-v2/service/finspace v1.33.13 h1:ZOeWDamg5pigakb0h3W8Js6Ghqk0icAF59b8RtH81Wk= +github.com/aws/aws-sdk-go-v2/service/finspace v1.33.13/go.mod h1:eg0D97fQmnYMYkBh5kT75+gD9jTj2BV7szBsJXl8T04= +github.com/aws/aws-sdk-go-v2/service/firehose v1.42.4 h1:GpbwE41nfQ9XOwwu7fBZVxhx/2l1zp/lk+h3CLSnfEY= +github.com/aws/aws-sdk-go-v2/service/firehose v1.42.4/go.mod h1:J8wd9RoLkzQ+uPZpgrqA6HwgCB8xxXAZbqLUlGPW2Fc= +github.com/aws/aws-sdk-go-v2/service/fis v1.37.12 h1:W16wWC7SzFrxbAlP2LLmb93Az4u4FlHUnmu7aC1b0cQ= +github.com/aws/aws-sdk-go-v2/service/fis v1.37.12/go.mod h1:yocavJz1pXxKsMm3/N9A35nSZQlqCKxadyCAMrivzBI= +github.com/aws/aws-sdk-go-v2/service/fms v1.44.13 h1:n/SrW3/f8+u6UuJfx8jaeHSyBBuJYo6mjtPprq8m8PM= +github.com/aws/aws-sdk-go-v2/service/fms v1.44.13/go.mod h1:3K77N22ju3vSRALJJhID5iB3dZnUsBEslLSSkROX3Xg= +github.com/aws/aws-sdk-go-v2/service/fsx v1.64.1 h1:BKdEn+ebwfpY9p9eAhQUSevRyTMuFtF/mL6FA7ApvN4= +github.com/aws/aws-sdk-go-v2/service/fsx v1.64.1/go.mod h1:NAXw//R84TyGhe6wKEgQ6Z5AbmvbVYyaY6m1rvPRDE8= +github.com/aws/aws-sdk-go-v2/service/gamelift v1.48.3 h1:zox0y5UpkJqYfyxjlLoIbB+TMUnOTbrLk+mgbnbGvUA= +github.com/aws/aws-sdk-go-v2/service/gamelift v1.48.3/go.mod h1:KTdjEd5V1BQkVbApMlgXMYLGFfGQvyJEfIIWxXiaiRg= +github.com/aws/aws-sdk-go-v2/service/glacier v1.31.13 h1:X7jZS1OP281MIBiV+D/K1m+HpyQ6SWQDkEsNN4n3FxE= +github.com/aws/aws-sdk-go-v2/service/glacier v1.31.13/go.mod h1:JAN67uxabv+RUAJc8eri9awt0AxZQDAiqLkqsN8NEGo= +github.com/aws/aws-sdk-go-v2/service/globalaccelerator v1.35.6 h1:d67UFEggPYsa2E8erOb+qkpbaJxe8pyQwUwBvX4Cqu4= +github.com/aws/aws-sdk-go-v2/service/globalaccelerator v1.35.6/go.mod h1:q6V0mPl64Zt6BSgnurs0XKRHT3v6JxMiyw9dAxUfJBM= +github.com/aws/aws-sdk-go-v2/service/glue v1.134.0 h1:visdVt0O75Z9g1b7ZsdXdw2eSeFM2p9LGP8VvoRQzFM= +github.com/aws/aws-sdk-go-v2/service/glue v1.134.0/go.mod h1:2yxIwUNUUoAcN7xlsrkAH4zcT79XFY6lcjc1V8i1ATg= +github.com/aws/aws-sdk-go-v2/service/grafana v1.32.6 h1:QOcgGXMEW+P4jiQhgN9x4bA/r2BSNmXphyuAJ1aSE7Q= +github.com/aws/aws-sdk-go-v2/service/grafana v1.32.6/go.mod h1:n4lKemL6oAceu5oaWqZey4Cz4nSBut3ZK3dVC0SzovQ= +github.com/aws/aws-sdk-go-v2/service/greengrass v1.32.13 h1:duELE5+UY+6vlQNrV3xIFWhuqdY47PsZCLgyeYMiWds= +github.com/aws/aws-sdk-go-v2/service/greengrass v1.32.13/go.mod h1:XpF2/heVBCD22v1vUc8cX4y6xpo/kjp5v867JuC8BS4= +github.com/aws/aws-sdk-go-v2/service/groundstation v1.39.3 h1:p3JszaARq/gKmVASh+Pm4ZNb9oqIHil/EqmcPoV6YOo= +github.com/aws/aws-sdk-go-v2/service/groundstation v1.39.3/go.mod h1:iXx78Xnkq6qA4hYrip8Xu/965so0ZTb4utAIVtVs3Ao= +github.com/aws/aws-sdk-go-v2/service/guardduty v1.68.1 h1:DURQ4QSqBgM0Hbi1eHG1YpTtcFIb+G41RtaONzmRQBc= +github.com/aws/aws-sdk-go-v2/service/guardduty v1.68.1/go.mod h1:JbKofzxmhlEPWyQr5DbIwqVZyrlzB+IBPb63+AXFkKI= +github.com/aws/aws-sdk-go-v2/service/healthlake v1.36.5 h1:dPrHo+N4GKABKun3m5z8vHg+yiO0SUXn8m76qcB6vew= +github.com/aws/aws-sdk-go-v2/service/healthlake v1.36.5/go.mod h1:DQJvwpAE4DV+KqlFy+0HZ6KPZWMybyxV3dJn8V3iOew= +github.com/aws/aws-sdk-go-v2/service/iam v1.52.1 h1:OYigTuTHayk1j11osOuJqIEuXSGAVndZYKH4aZYn8qk= +github.com/aws/aws-sdk-go-v2/service/iam v1.52.1/go.mod h1:PuHz5kGh1jtsNpjezdYhRp7xgn6DzCNJJfQt7O7U9Aw= +github.com/aws/aws-sdk-go-v2/service/identitystore v1.34.4 h1:8GuyU1gnYrYs3VajqWD/yrYvTUOUynakW3KKq/9EywI= +github.com/aws/aws-sdk-go-v2/service/identitystore v1.34.4/go.mod h1:iOVKxrQj2ZqWDLxIusqhVQX3YORti9qnSRIyHP/Ckdc= +github.com/aws/aws-sdk-go-v2/service/imagebuilder v1.50.0 h1:WrEoYNBS1xiEHZzeqat+rHqHm2d0U+phUbHQgD6d0YE= +github.com/aws/aws-sdk-go-v2/service/imagebuilder v1.50.0/go.mod h1:GFODe4NMmp8DDpuKfqiQ1IryOwfBKYCCMZ+GD42Xiig= +github.com/aws/aws-sdk-go-v2/service/inspector v1.30.12 h1:GPt9DrCgpqJTgm0DK0E4Dc4SswW3O0kNgdRLxqHcnhU= +github.com/aws/aws-sdk-go-v2/service/inspector v1.30.12/go.mod h1:R6F1r1OeVpZuEmMxCPDBSna0OWSuL1T5NyOOpXbxqYc= +github.com/aws/aws-sdk-go-v2/service/inspector2 v1.45.1 h1:M3I3Qz9+RsF9SAZAYo03GoKQPZwS+JzDXse4dcUCO4g= +github.com/aws/aws-sdk-go-v2/service/inspector2 v1.45.1/go.mod h1:KvmCGpfBw47nVEYjFMDV691cN8NSZXwTp+HgqTkxFgU= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.3 h1:x2Ibm/Af8Fi+BH+Hsn9TXGdT+hKbDd5XOTZxTMxDk7o= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.3/go.mod h1:IW1jwyrQgMdhisceG8fQLmQIydcT/jWY21rFhzgaKwo= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.4 h1:NvMjwvv8hpGUILarKw7Z4Q0w1H9anXKsesMxtw++MA4= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.4/go.mod h1:455WPHSwaGj2waRSpQp7TsnpOnBfw8iDfPfbwl7KPJE= -github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.11.13 h1:FScsqdRyKFkw3u2ysLeWC0dbaz9I+g0xJ1JlQpH6bPo= -github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.11.13/go.mod h1:wkhwIaGltEuG4SRwNzPiJmf/tDp+yL5ym55Lt4bheno= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.13 h1:kDqdFvMY4AtKoACfzIGD8A0+hbT41KTKF//gq7jITfM= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.13/go.mod h1:lmKuogqSU3HzQCwZ9ZtcqOc5XGMqtDK7OIc2+DxiUEg= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.13 h1:zhBJXdhWIFZ1acfDYIhu4+LCzdUS2Vbcum7D01dXlHQ= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.13/go.mod h1:JaaOeCE368qn2Hzi3sEzY6FgAZVCIYcC2nwbro2QCh8= -github.com/aws/aws-sdk-go-v2/service/internetmonitor v1.26.4 h1:i0+jLDeUbGVMnbM062bNuqXSRGvxChArs5Z/HcetByo= -github.com/aws/aws-sdk-go-v2/service/internetmonitor v1.26.4/go.mod h1:1J+jvIbqr9u7BwNyDWrriI1BsFBVMBEi6XP2T8QSAXw= -github.com/aws/aws-sdk-go-v2/service/invoicing v1.8.0 h1:GmwiBzG6DhuL9w4MgrbUUHE+GFCJ9diSxbTAX27zTdo= -github.com/aws/aws-sdk-go-v2/service/invoicing v1.8.0/go.mod h1:077SFzwNIDjtHm35vjTtBHkweLVXtd3ahiPqfxo9Jms= -github.com/aws/aws-sdk-go-v2/service/iot v1.69.11 h1:E1iadLmKaX8iqk4lIOenXnd52iORtxQItB5kOID2J48= -github.com/aws/aws-sdk-go-v2/service/iot v1.69.11/go.mod h1:Qsm1SgHzgKxy9TPqGfVBL+ULu/LW1iIOTn7kbsFhWE8= -github.com/aws/aws-sdk-go-v2/service/ivs v1.48.5 h1:S7hZ3yWMpTG7jDJIQhWoob0vjAbS7g8VMmqDs+Rr0v8= -github.com/aws/aws-sdk-go-v2/service/ivs v1.48.5/go.mod h1:LWpDgCXaAZgKF5EH2xincNziWa0GkknDhx+ig0pAWzo= -github.com/aws/aws-sdk-go-v2/service/ivschat v1.21.11 h1:3O57ECBVWgTITHZTmIsDdpaUUxGN2YULXDhBtea4A+Q= -github.com/aws/aws-sdk-go-v2/service/ivschat v1.21.11/go.mod h1:gHijQmBJujk/KV3Y+trzDPVZ16MS5JkITQX5MqO3wiA= -github.com/aws/aws-sdk-go-v2/service/kafka v1.46.0 h1:hOOY9fQ95Rfv/L6XRFiJTZlcf52dFQ5txxw49VbFT5k= -github.com/aws/aws-sdk-go-v2/service/kafka v1.46.0/go.mod h1:Duj0BV8XyPzvoVF2LYtLDTCoQkIJ+NU1ui7QyMyCM/Y= -github.com/aws/aws-sdk-go-v2/service/kafkaconnect v1.27.12 h1:7ZayGxzuj2qFwCTUUVGHYS6hxHb5Uly1W4Lbau4BTXs= -github.com/aws/aws-sdk-go-v2/service/kafkaconnect v1.27.12/go.mod h1:wnbOw77+1dcXjlDl1JhSQmsO0+r3np9nFxvaX4HgUQ0= -github.com/aws/aws-sdk-go-v2/service/kendra v1.60.12 h1:MSoRxnPxbIaotIGof/+4CCw1ftfVnvTfB0h+0xDuAJA= -github.com/aws/aws-sdk-go-v2/service/kendra v1.60.12/go.mod h1:KeQsf6zSp1LMwzIHnjOGuBzDWisc1sXHoJkLBFrsZ9c= -github.com/aws/aws-sdk-go-v2/service/keyspaces v1.24.5 h1:8xc7vsJS13R7ikYhbREO8XJrekgAzju/kUNML/mibqc= -github.com/aws/aws-sdk-go-v2/service/keyspaces v1.24.5/go.mod h1:W3i/Z8SlfqFwSoCNyYtKGd/LgR1vi08/35YQ1bxcEh8= -github.com/aws/aws-sdk-go-v2/service/kinesis v1.42.3 h1:A2HNxrABEFha5831yAU05G0mYNxaxYH4WG85FV6ZWIQ= -github.com/aws/aws-sdk-go-v2/service/kinesis v1.42.3/go.mod h1:jTDNZao/9uv/6JeaeDWEqA4s+l6c8+cqaDeYFpM+818= -github.com/aws/aws-sdk-go-v2/service/kinesisanalytics v1.30.12 h1:WAfQy/LSjjyAeWtCndtEkJA1tqADh7bqA3eEImVOsQo= -github.com/aws/aws-sdk-go-v2/service/kinesisanalytics v1.30.12/go.mod h1:LHFWG4nhpu6EEIU4ZReJbmDVVL/up6CVhgkUTacFVyM= -github.com/aws/aws-sdk-go-v2/service/kinesisanalyticsv2 v1.36.13 h1:m0QZX2HW98IKt/tS4DJFJwt/Qra46XXCfroHX/kvmA4= -github.com/aws/aws-sdk-go-v2/service/kinesisanalyticsv2 v1.36.13/go.mod h1:tzsKwzVe1LFyj0teoeHk5bMpNCUNaHwX76Fw0Tc7xZg= -github.com/aws/aws-sdk-go-v2/service/kinesisvideo v1.32.11 h1:P1mPzg4L38jehlGOWnZIc9kCV4OD2Fjk0sJqdDWutzg= -github.com/aws/aws-sdk-go-v2/service/kinesisvideo v1.32.11/go.mod h1:ml4xarTHw7hFk3uIw4wioNdFnATCJQhvlbGBHIMTRH0= -github.com/aws/aws-sdk-go-v2/service/kms v1.48.2 h1:aL8Y/AbB6I+uw0MjLbdo68NQ8t5lNs3CY3S848HpETk= -github.com/aws/aws-sdk-go-v2/service/kms v1.48.2/go.mod h1:VJcNH6BLr+3VJwinRKdotLOMglHO8mIKlD3ea5c7hbw= -github.com/aws/aws-sdk-go-v2/service/lakeformation v1.45.11 h1:hF1Qozl8Fh6C1bUeNaL0xLbTlsHaKmxHKFfA08q5mU8= -github.com/aws/aws-sdk-go-v2/service/lakeformation v1.45.11/go.mod h1:1oR3VqBIi345fZEqaBh7HbB/GKLZU5F1+nbXQV5csnY= -github.com/aws/aws-sdk-go-v2/service/lambda v1.82.0 h1:MrStO25Ef1TbXFzZr2pZPdwcFHyUgPxCX7MXz09Qk7k= -github.com/aws/aws-sdk-go-v2/service/lambda v1.82.0/go.mod h1:X9xD+03BeNMi9vA0zcJ0rL4jaGRaBpB/54ukKjhz6ik= -github.com/aws/aws-sdk-go-v2/service/launchwizard v1.13.12 h1:dN62fbhBm0z/WOjTqQm7+vRpAPrLjFQd08TIhjvOhlA= -github.com/aws/aws-sdk-go-v2/service/launchwizard v1.13.12/go.mod h1://3iRAUIqql/dPeYQI4lIv4JA8FiZzgIifX0EiX+9uU= -github.com/aws/aws-sdk-go-v2/service/lexmodelbuildingservice v1.34.5 h1:C/Qq1lPIUMssyiBXzlhvOEEMPuLBuSqarHoXpRvML1M= -github.com/aws/aws-sdk-go-v2/service/lexmodelbuildingservice v1.34.5/go.mod h1:iE4e1/ovGtt3keD9WWXuHfjoascElN+sEwN0Ff5Tys4= -github.com/aws/aws-sdk-go-v2/service/lexmodelsv2 v1.57.0 h1:alZjWGUSbcTTNYTrOhbFVh7B1mSgMuXEvmsxFybSKYo= -github.com/aws/aws-sdk-go-v2/service/lexmodelsv2 v1.57.0/go.mod h1:jcWBQtwCe0xBJLEVkz4ny1N+SRNRQQdpPUT1MKRwyu0= -github.com/aws/aws-sdk-go-v2/service/licensemanager v1.36.12 h1:e6Q/2pgy/KKhpG8uBEq51rboXTepDcMKqmJTn1sv/Hg= -github.com/aws/aws-sdk-go-v2/service/licensemanager v1.36.12/go.mod h1:jXdt+CSYTcfzhA60pRhvdlBEGWkHdb96/4+v8hJrYxU= -github.com/aws/aws-sdk-go-v2/service/lightsail v1.50.6 h1:cMYT6YsNkZjo4vguBxkgGCVffhaS0Dc2BZs/nGr4uLs= -github.com/aws/aws-sdk-go-v2/service/lightsail v1.50.6/go.mod h1:Nn2xx6HojGuNMtUFxxz/nyNLSS+tHMRsMhe3+W3wB5k= -github.com/aws/aws-sdk-go-v2/service/location v1.50.4 h1:95HV4iCeSPGfTTiPI5JjmZAHud0YCn0wB1KViqk+Epk= -github.com/aws/aws-sdk-go-v2/service/location v1.50.4/go.mod h1:XqDleYNKtPYvlUb14t3vWzJL/j81V1wyxALzAkhakfs= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.5 h1:Hjkh7kE6D81PgrHlE/m9gx+4TyyeLHuY8xJs7yXN5C4= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.5/go.mod h1:nPRXgyCfAurhyaTMoBMwRBYBhaHI4lNPAnJmjM0Tslc= +github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.11.14 h1:3exo28cClRTVnxdj/LULxkESZSSv74RUIjZ7tfHXfWQ= +github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.11.14/go.mod h1:yLon9pByjyB6JZq5IAmwnjE3ObIhD0QibfRWH7tUhLU= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.14 h1:FIouAnCE46kyYqyhs0XEBDFFSREtdnr8HQuLPQPLCrY= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.14/go.mod h1:UTwDc5COa5+guonQU8qBikJo1ZJ4ln2r1MkF7Dqag1E= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.14 h1:FzQE21lNtUor0Fb7QNgnEyiRCBlolLTX/Z1j65S7teM= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.14/go.mod h1:s1ydyWG9pm3ZwmmYN21HKyG9WzAZhYVW85wMHs5FV6w= +github.com/aws/aws-sdk-go-v2/service/internetmonitor v1.26.5 h1:uZ3e+BLTEpL9cCjSBTJv5oqMZgYwvW5FD5L+EEqGuHA= +github.com/aws/aws-sdk-go-v2/service/internetmonitor v1.26.5/go.mod h1:J8RQE9xwBZAJ25Wj0PQkIGj08MlsEiUH9bENWKBX90Q= +github.com/aws/aws-sdk-go-v2/service/invoicing v1.8.1 h1:FsebZXhOZwR0P9KeQVphARHiTEfNbDxbOM+kpPkLCEk= +github.com/aws/aws-sdk-go-v2/service/invoicing v1.8.1/go.mod h1:USbFxWPkR7XqQEaCIT8UXHx/zxnAmgGvRoCp/5AI4Fg= +github.com/aws/aws-sdk-go-v2/service/iot v1.69.12 h1:0iGQ8E3lI6HDGWncMb3Pc3INqFlvWxLRiELTlJcn9b4= +github.com/aws/aws-sdk-go-v2/service/iot v1.69.12/go.mod h1:ANXaCZ47zCebU523nUJGwmWbH11zb6WCUPeZsNyDMKE= +github.com/aws/aws-sdk-go-v2/service/ivs v1.48.6 h1:b2y0fqRrcH0GADD6MxqqcD9xEwRSVzI2IKqUUwjK0uA= +github.com/aws/aws-sdk-go-v2/service/ivs v1.48.6/go.mod h1:b+o/OzgfCLUcim+FYJjW5waJ3I4wMD3Jnwa/B9kPElc= +github.com/aws/aws-sdk-go-v2/service/ivschat v1.21.12 h1:L0YlNIZJOIFXuNcagtUui/ZypJnI9VpP6BKz7fOE4Ac= +github.com/aws/aws-sdk-go-v2/service/ivschat v1.21.12/go.mod h1:rtYYk9VC7rDU1pXJcZk0nb7KGmfOKLQqpx8hE3OUL78= +github.com/aws/aws-sdk-go-v2/service/kafka v1.46.1 h1:9UqRpFW8NWcvkxWI7yZFUndXY0lQhhucp6fihT6/Hvw= +github.com/aws/aws-sdk-go-v2/service/kafka v1.46.1/go.mod h1:3R/wG7m2FKySTQRlby/6o6Tt3x1ya46jV7dC66dt+Aw= +github.com/aws/aws-sdk-go-v2/service/kafkaconnect v1.27.13 h1:99xl60JgVaGiNUR0XsSmqVZ2LPPomCObCqn/1W8k220= +github.com/aws/aws-sdk-go-v2/service/kafkaconnect v1.27.13/go.mod h1:fbxzHuCmlChUeajxfNnD8zf+czNzJ2gT7IH6w3ZPUTw= +github.com/aws/aws-sdk-go-v2/service/kendra v1.60.13 h1:s5jJI3t8egjld+EplBzVPSjXykFcw2i5eep/VQe0iU8= +github.com/aws/aws-sdk-go-v2/service/kendra v1.60.13/go.mod h1:LptW+o12B3xI4tNrosmp/soMdWVyrbQfKSvtgDBYTh8= +github.com/aws/aws-sdk-go-v2/service/keyspaces v1.24.6 h1:bMK3Gmgtz6Q2yMDyMbzcGh8Fj8fScfluBvpq5chPa3M= +github.com/aws/aws-sdk-go-v2/service/keyspaces v1.24.6/go.mod h1:3mOsyaewScMTAZcNseSz4wDGANjLGSewwBH8JDM42CU= +github.com/aws/aws-sdk-go-v2/service/kinesis v1.42.5 h1:z/3UF0h4JawOs2ZyB2CjgAa9jP8YSj2GP3dukcpbli8= +github.com/aws/aws-sdk-go-v2/service/kinesis v1.42.5/go.mod h1:2R0Wat51k1YDy58MSkEUzyiAK0L2ibRoChvSc76fXY0= +github.com/aws/aws-sdk-go-v2/service/kinesisanalytics v1.30.13 h1:JbaUt22QMVUXJCjnAjnVIPJWr2NiARcuf8q7S9ZprJ4= +github.com/aws/aws-sdk-go-v2/service/kinesisanalytics v1.30.13/go.mod h1:sVQO7d3jcLPligf7HTcW4V3jPmY1qMpyh0B6e2fnTbQ= +github.com/aws/aws-sdk-go-v2/service/kinesisanalyticsv2 v1.36.14 h1:N3ZHwR7LOi/HukhkUkkI+mQJP/KaBATVOl3M4sSr8pg= +github.com/aws/aws-sdk-go-v2/service/kinesisanalyticsv2 v1.36.14/go.mod h1:dRJmZnaobfQXdApLl1l8MZEZ2S7vFqE9mV5rHRhEx8w= +github.com/aws/aws-sdk-go-v2/service/kinesisvideo v1.32.12 h1:jOBJy4U65LPhbHFWGcY7qCNDW8CMWypjRcnANA0EYBk= +github.com/aws/aws-sdk-go-v2/service/kinesisvideo v1.32.12/go.mod h1:bT1LpvvITw2zFfy8K9hKHDx3nM8Dpt9vEZRXz4zviZg= +github.com/aws/aws-sdk-go-v2/service/kms v1.48.3 h1:7prvylN3hXi4dMNUklsZgdkz/9jGxq/EJVhB7kSv6+0= +github.com/aws/aws-sdk-go-v2/service/kms v1.48.3/go.mod h1:NZo9WJqQ0sxQ1Yqu1IwCHQFQunTms2MlVgejg16S1rY= +github.com/aws/aws-sdk-go-v2/service/lakeformation v1.46.0 h1:Y+soJVyhAohkNbGltQK2towlPr39cSqsfMEPlS9StY4= +github.com/aws/aws-sdk-go-v2/service/lakeformation v1.46.0/go.mod h1:R47fTqDEjHcU6Km9C5Ph61QpJlkExSM3uzaSqmOcgXA= +github.com/aws/aws-sdk-go-v2/service/lambda v1.82.1 h1:ELCyYLHALEjsWyRlZ8q4LELH+GSGC9TTlw4poPpUKb0= +github.com/aws/aws-sdk-go-v2/service/lambda v1.82.1/go.mod h1:eIjSAyPg9Qgrxc3hO8ppauvdjVnWbmudyAevEnOuat8= +github.com/aws/aws-sdk-go-v2/service/launchwizard v1.13.13 h1:E4HJDFjPQS3ZD8xDl24fkQIubrpU/huugtCnHhyDjDA= +github.com/aws/aws-sdk-go-v2/service/launchwizard v1.13.13/go.mod h1:wNNgc9jKEfEHYsBDZWrTTbA6mvATb10JRa3ofCNSYPY= +github.com/aws/aws-sdk-go-v2/service/lexmodelbuildingservice v1.34.6 h1:SKhi04iDu5sZI/QCQn+1yx36/W5IyNLmeQuLBgf3y0o= +github.com/aws/aws-sdk-go-v2/service/lexmodelbuildingservice v1.34.6/go.mod h1:DmDYqHJ2cOvo/nA9LyFhWUaiV/CBTCfl9iD9rIzgzLs= +github.com/aws/aws-sdk-go-v2/service/lexmodelsv2 v1.57.1 h1:6X/7Ls8JAg9/OZgTarFSguEScH+SeYPF/y9DBtSvs0Y= +github.com/aws/aws-sdk-go-v2/service/lexmodelsv2 v1.57.1/go.mod h1:/zVTvCHZwDsSx0pS94PYjvS8tLh+kZil/nKhNaslRfE= +github.com/aws/aws-sdk-go-v2/service/licensemanager v1.37.0 h1:9gckoRoE/7FrpeylhMvWdvO7+ohIOCQLGENBf2XJXw4= +github.com/aws/aws-sdk-go-v2/service/licensemanager v1.37.0/go.mod h1:hOEVTzUvxa3cACGfGG9ITLIJyu38xfNo7Ro/OaP/y0s= +github.com/aws/aws-sdk-go-v2/service/lightsail v1.50.7 h1:o5kT+nFYZbestjv0GWibkVS3bCf+ZijhGiMc3Xxj/hg= +github.com/aws/aws-sdk-go-v2/service/lightsail v1.50.7/go.mod h1:x+omzRoqYYFX+H8/va+Gt2Yg4xGaHZMRowr77Y/UGIA= +github.com/aws/aws-sdk-go-v2/service/location v1.50.5 h1:W+btCDgh5jJSEb4UT/u3/OKp8yW4kmgpoyDxLNEoz2Q= +github.com/aws/aws-sdk-go-v2/service/location v1.50.5/go.mod h1:4Qh2hQkY2QVsH3Km3nMSyokJI79SjVjHaEFvYXPTXLQ= github.com/aws/aws-sdk-go-v2/service/lookoutmetrics v1.37.2 h1:IXo/4IslBFio+k7Pm0gLptSh+B2GvSZQKRTDwfs9jkc= github.com/aws/aws-sdk-go-v2/service/lookoutmetrics v1.37.2/go.mod h1:tF6+C2s8Ru1RIyN1jPJR4VVk10Zz7pBhrYgZ72rFy7c= -github.com/aws/aws-sdk-go-v2/service/m2 v1.26.5 h1:36dEuPAWGx9dmFvxAbsaoueMqEx24E1VYQEcJiaamF4= -github.com/aws/aws-sdk-go-v2/service/m2 v1.26.5/go.mod h1:TcXLSXdIt/knslZsVOxLz85TXJHYftEnZp2Pkqcmd/g= -github.com/aws/aws-sdk-go-v2/service/macie2 v1.50.4 h1:9RF/3sDLXY55O2MJJl9iejd1IDuTMztpNdpYe9BigVk= -github.com/aws/aws-sdk-go-v2/service/macie2 v1.50.4/go.mod h1:UqgjJRAxzo2p/JJAaa4U10r468sb5dB7XdTojQM3J6I= -github.com/aws/aws-sdk-go-v2/service/mediaconnect v1.46.0 h1:ZISa5LjOv1UP8/i0NZiFVFn0TRcLI8iceeW4MzyWOlk= -github.com/aws/aws-sdk-go-v2/service/mediaconnect v1.46.0/go.mod h1:h8kJMoJzHMU0zZWycpQpGmcxYLKhrhfC8RI1O4E4lv0= -github.com/aws/aws-sdk-go-v2/service/mediaconvert v1.85.0 h1:IQwKEYP9sQ4USJc+xX5N/P85SyLAsWk0Kxx2Bx/xz4k= -github.com/aws/aws-sdk-go-v2/service/mediaconvert v1.85.0/go.mod h1:69w+ev30uz0EQ+Z3brr3IecMA4D7Pkr3PtnQc0VGEZs= -github.com/aws/aws-sdk-go-v2/service/medialive v1.87.0 h1:nkvCXOE1zFYMaq9A7SMAeY+TWPQ/fe0BTkls8SrfyDM= -github.com/aws/aws-sdk-go-v2/service/medialive v1.87.0/go.mod h1:SRJh9enbB1Urr1hv5+LKTbRlmXlhbjzvy3AwZkB7AHY= -github.com/aws/aws-sdk-go-v2/service/mediapackage v1.39.12 h1:jw/o+ERI9EecbrQLGzrzHCPlpjd52ysHRkHV2G3T0lw= -github.com/aws/aws-sdk-go-v2/service/mediapackage v1.39.12/go.mod h1:7As8fD4Tr7DZAKWm0YOPFaoNymtw3xsCUkjQobfsZ7E= -github.com/aws/aws-sdk-go-v2/service/mediapackagev2 v1.33.0 h1:0kXTtfY0fCyncN3yEf6UjeVRyouqUPLzrDCF/sRJqsE= -github.com/aws/aws-sdk-go-v2/service/mediapackagev2 v1.33.0/go.mod h1:w/Cotl6ORtnl+0i3hsOfzeV3bq5msbjgTrDhN57KTQU= -github.com/aws/aws-sdk-go-v2/service/mediapackagevod v1.39.12 h1:3uZcDQNSq2K8+l26JGiI5ruvs8C4ZjG/uiUDU81LLok= -github.com/aws/aws-sdk-go-v2/service/mediapackagevod v1.39.12/go.mod h1:eiBfqNKAQK1rLuvKJOc6n5r9JZjgvdcMjxHHJlQwO3o= -github.com/aws/aws-sdk-go-v2/service/mediastore v1.29.12 h1:NcvtI4JsJXem0VZSkt2u7ODCF7GZpoXr6hakfgOdbqs= -github.com/aws/aws-sdk-go-v2/service/mediastore v1.29.12/go.mod h1:p0DZlc3953qm+OFFjWYXI4pUVN0Vtx7wxn/0sT6HjrQ= -github.com/aws/aws-sdk-go-v2/service/memorydb v1.33.5 h1:jLxCVjcFucXlpF4LFHMPbmeDjyRP0ssZ0+/RlC1Hglk= -github.com/aws/aws-sdk-go-v2/service/memorydb v1.33.5/go.mod h1:iehQZb2FgCH28RyIL7fJCWgxmjCilIHVMJ3LXuZakCI= -github.com/aws/aws-sdk-go-v2/service/mgn v1.38.4 h1:OSiWqiIVbyUiQcwyuPGc+BJRED9cfp8IV7ToFGitzl8= -github.com/aws/aws-sdk-go-v2/service/mgn v1.38.4/go.mod h1:n6Jxq0qdghot9uUi6ckEeaz0QvYv41DnFnSkNEwkKa8= -github.com/aws/aws-sdk-go-v2/service/mq v1.34.10 h1:LkV65nQNkhPblwXWKB6jree3BEgfPtmC93NFRsp+Nuo= -github.com/aws/aws-sdk-go-v2/service/mq v1.34.10/go.mod h1:ygM6WHFaCHMQ4+Pn3cMqFhWpbc06reGq4VTsv89bBrA= -github.com/aws/aws-sdk-go-v2/service/mwaa v1.39.12 h1:GzwknGap79FTpA5CbbD2OF0rDnl0/bqN23zqwzHkdFg= -github.com/aws/aws-sdk-go-v2/service/mwaa v1.39.12/go.mod h1:1D+jlQDjJVp+zWuj+7fkdWRAId2DbnWm92v/QxcaMec= -github.com/aws/aws-sdk-go-v2/service/neptune v1.43.3 h1:PFGZA4R64W8ZvC+MF4qE7Qkav/2LoexbhpdRAGvrQW8= -github.com/aws/aws-sdk-go-v2/service/neptune v1.43.3/go.mod h1:zZ58Zd5x0GGqnSgDLV4R3C1Xazzg3htNhg3kUpNB94M= -github.com/aws/aws-sdk-go-v2/service/neptunegraph v1.21.11 h1:aHQda8rOysKlF7xSoPu9Qk5t2Ph5fyvrh/HWNEuNwYA= -github.com/aws/aws-sdk-go-v2/service/neptunegraph v1.21.11/go.mod h1:dUFhAeruwm9ZYvMRk2JU6AR+YFcQ+4h34C3yNmz4T88= -github.com/aws/aws-sdk-go-v2/service/networkfirewall v1.58.0 h1:gH0mo9odFg6ZI2g6pHcvihWMfCEjyOF0U271zEprUoc= -github.com/aws/aws-sdk-go-v2/service/networkfirewall v1.58.0/go.mod h1:wCjIj4guias8uhaV3dqeSag/7v04X3xJQa4Ur9zJttc= -github.com/aws/aws-sdk-go-v2/service/networkflowmonitor v1.11.0 h1:UiALLI9ec1KVMT+AJcXXIaknC3zkC7zzYoR/9DaX5K4= -github.com/aws/aws-sdk-go-v2/service/networkflowmonitor v1.11.0/go.mod h1:jIxhoFIXY3j5+i8UsPKY1jSMSGP8wKG4rHh1nF8fmzw= -github.com/aws/aws-sdk-go-v2/service/networkmanager v1.40.5 h1:yVU4b7twe9pLU5dxkC0D6lUEgcZa7zWizXuRbvHp/d8= -github.com/aws/aws-sdk-go-v2/service/networkmanager v1.40.5/go.mod h1:nikytN6kEOGDn0q0o2NzpF93khMy4sO69ZVnh7D0owM= -github.com/aws/aws-sdk-go-v2/service/networkmonitor v1.13.4 h1:PmyRpUoTfR2J1CfvGB2qz6kBiOROgDoR95N6CWG2SbA= -github.com/aws/aws-sdk-go-v2/service/networkmonitor v1.13.4/go.mod h1:6T6POkqNtemejwenhFM2l1sipv8saMi+Xewc2Q+4C+Y= -github.com/aws/aws-sdk-go-v2/service/notifications v1.7.10 h1:i3wbNbKZdi40cAs+qyBEtG75DUOpbJJV/HwqGg35DkE= -github.com/aws/aws-sdk-go-v2/service/notifications v1.7.10/go.mod h1:DKnhbgXWeGgz1mzRZ+0b/jKqB3xy9yuy8LKIHUnv1ZM= -github.com/aws/aws-sdk-go-v2/service/notificationscontacts v1.5.14 h1:jbaCixU9rvfTGNli4NSkT1jwJeoVWTKR5vlta/E5smM= -github.com/aws/aws-sdk-go-v2/service/notificationscontacts v1.5.14/go.mod h1:D6RFOazSGFCJcdxSEgw0ukJ+k2QgFfOdB3dVYNcHPVA= -github.com/aws/aws-sdk-go-v2/service/oam v1.23.5 h1:DJqoutE8UpAtbqWeT/T62W3t9scS9ZZKAJJh6dGb8cY= -github.com/aws/aws-sdk-go-v2/service/oam v1.23.5/go.mod h1:pz+AbYsaeY7dySgPSGl/Zr1zPJMOyOE/mR9+XtyhV9c= -github.com/aws/aws-sdk-go-v2/service/observabilityadmin v1.8.6 h1:MsffOU8pULJVmQcvo8DarlR1rXAazOvITj7XuJB3QWo= -github.com/aws/aws-sdk-go-v2/service/observabilityadmin v1.8.6/go.mod h1:2GvP5es3RAok0PA4Fx95x5fJ0Xn7muSESZFHw1vp1BM= -github.com/aws/aws-sdk-go-v2/service/odb v1.5.6 h1:JLUu5UEdUX210Ojg5uTjzeRw5auZe6/10dd1vuCFlso= -github.com/aws/aws-sdk-go-v2/service/odb v1.5.6/go.mod h1:jhCkBILzvRrCEyX2Wl+xn2BOBmrBedW7On1p1gzf3rA= -github.com/aws/aws-sdk-go-v2/service/opensearch v1.54.0 h1:hN7HAN0qO5eLnh08ezJPfqsBBdNj6AWD7w5YQSLtYiM= -github.com/aws/aws-sdk-go-v2/service/opensearch v1.54.0/go.mod h1:iVj8M5s79sFaX4eWUnBihWn+7PPHSdmCH6EqWQoySE4= -github.com/aws/aws-sdk-go-v2/service/opensearchserverless v1.27.4 h1:7ijoIap1uO5GkJR6lzllEYYJxYp31nGQbKuyCbMMCZs= -github.com/aws/aws-sdk-go-v2/service/opensearchserverless v1.27.4/go.mod h1:oLdL9Vhmp6N8H/f8Ttak+0SdUKk1E7Iwe84z9doZ87Q= -github.com/aws/aws-sdk-go-v2/service/organizations v1.46.4 h1:a8FVhpNC4CSPnlXcgHzyIxm2/8LpQ9F60WPV6+tyFmU= -github.com/aws/aws-sdk-go-v2/service/organizations v1.46.4/go.mod h1:tnWiGtBYsKa4astPsL0YPaysffUcAp2C4Y0cZw6ZzGA= -github.com/aws/aws-sdk-go-v2/service/osis v1.21.5 h1:02dpYRwi3zGFWKll5a0IVr2u0g0QGZCB7+PfvtR2eCA= -github.com/aws/aws-sdk-go-v2/service/osis v1.21.5/go.mod h1:QGkOJj++ElJ2YmESnpRrwM7R38qf4ViMCCFIZVOHNgg= -github.com/aws/aws-sdk-go-v2/service/outposts v1.57.6 h1:FXA9OzvJlakCrbvKw3qmLrRG6q3EDt9FZnaS4Tx3upQ= -github.com/aws/aws-sdk-go-v2/service/outposts v1.57.6/go.mod h1:rPsJtWQtj/V1kgdAFC9WyswmqrvJaOgHfLwibijL52o= -github.com/aws/aws-sdk-go-v2/service/paymentcryptography v1.26.3 h1:Cws5mb47NYtqUZxkcCRR/9T0gwXmrXoweeVDeD0sRRI= -github.com/aws/aws-sdk-go-v2/service/paymentcryptography v1.26.3/go.mod h1:GqTw5UV5AIwHTpaKzHzt2KjETEO+hoBdIxbA/s7Fxzc= -github.com/aws/aws-sdk-go-v2/service/pcaconnectorad v1.15.12 h1:VIxyAXmasuMqPn26ayhxZX6FK2yD+1iHHL0WDcGVIgk= -github.com/aws/aws-sdk-go-v2/service/pcaconnectorad v1.15.12/go.mod h1:GeIQIKjm5JhrcR/BB7x5DWPo2Bfhfm+Ui4w8x5TFz0I= -github.com/aws/aws-sdk-go-v2/service/pcs v1.15.0 h1:jODJJvvzp3BtBc2rREK0foH2e8vyEhaCZ2z+nnOI/oE= -github.com/aws/aws-sdk-go-v2/service/pcs v1.15.0/go.mod h1:lG3E3PuHFsK508yCPxHBtDoM7S5bVuZOCaqECHkEM64= -github.com/aws/aws-sdk-go-v2/service/pinpoint v1.39.12 h1:fvCN4jZKj+gNhl/miNYBAs0OnVDKYwqrWLjpWdIV/zU= -github.com/aws/aws-sdk-go-v2/service/pinpoint v1.39.12/go.mod h1:TmcGUQZpICbZKTvzURsi73eQMl/psfpgY/xse7pPf/4= -github.com/aws/aws-sdk-go-v2/service/pinpointsmsvoicev2 v1.26.2 h1:LUeDu/bWhIz1eO8ANBlxcxm7bjv3BY6r4fF7p2CIDQE= -github.com/aws/aws-sdk-go-v2/service/pinpointsmsvoicev2 v1.26.2/go.mod h1:eGDzes2BcpQDsKZ37KPgnrUujaLjA6B9doY+PmlROQE= -github.com/aws/aws-sdk-go-v2/service/pipes v1.23.11 h1:PiQERt6yzJUeuPtcKgZ+HKhcJfFdLEU75rPX4O0XCqY= -github.com/aws/aws-sdk-go-v2/service/pipes v1.23.11/go.mod h1:vIeg0zOANsRAyRGYsXQLdaYh9XGmKMhY8r20NzkPPvg= -github.com/aws/aws-sdk-go-v2/service/polly v1.54.5 h1:72kDYtnJAiFF/9xzKpPEUZBGNetCC9tiNK6K8Moypkk= -github.com/aws/aws-sdk-go-v2/service/polly v1.54.5/go.mod h1:IR55PMJ6jNjEu62EfCEP5v5oB4oGuRL3DvECBy0X1ps= -github.com/aws/aws-sdk-go-v2/service/pricing v1.40.5 h1:H10gQvrDF1MX5vzVlTgQxH4UipAZunirvOSLHLO1QMc= -github.com/aws/aws-sdk-go-v2/service/pricing v1.40.5/go.mod h1:qlgOQg0EL8GDTAPe5CcbgpaJGfSzA6ndypXctsMiW9E= -github.com/aws/aws-sdk-go-v2/service/qbusiness v1.33.12 h1:5cOyDQZyhL094oRlmMiRtn1QhaESZWyTvIBIJkMMozo= -github.com/aws/aws-sdk-go-v2/service/qbusiness v1.33.12/go.mod h1:GrEm52MEfQXhAXsGFZEFiPt8AKvlD1uMkJ8KWRdlft0= +github.com/aws/aws-sdk-go-v2/service/m2 v1.26.6 h1:zpwYmq7xX44rrjO86D1lqUPGWDsEL1fxnY6dOcWCd6g= +github.com/aws/aws-sdk-go-v2/service/m2 v1.26.6/go.mod h1:QIrh5zZOXwPjwk3llMjstgEh5W8wFhmezc2AyZ7g614= +github.com/aws/aws-sdk-go-v2/service/macie2 v1.50.5 h1:cw3M/pkIjK1KFjvGWFqNCdJqmQU2LSB926+8SJujaC8= +github.com/aws/aws-sdk-go-v2/service/macie2 v1.50.5/go.mod h1:Kf88uRmhon+OBPr4lxBurhtuBbqfUI0rv9/Aov+YL6U= +github.com/aws/aws-sdk-go-v2/service/mediaconnect v1.46.1 h1:p2+f+Shraq1bQ5ZC1uatSaSuuw0DPiaWWIGqBrSmW74= +github.com/aws/aws-sdk-go-v2/service/mediaconnect v1.46.1/go.mod h1:94SjqD15a1A7EA66nvs2J1VHjpB293vL0tPmTz8hpf0= +github.com/aws/aws-sdk-go-v2/service/mediaconvert v1.85.1 h1:lSP4Ia50W+u+7mR6X/hDdZpNLIsA+lfrLYapzxRZhvA= +github.com/aws/aws-sdk-go-v2/service/mediaconvert v1.85.1/go.mod h1:4QcXtIFYPP5uwt82LvxjVGawWvGTL+22P+Zhe3PVEhM= +github.com/aws/aws-sdk-go-v2/service/medialive v1.87.1 h1:JaSfGJOvkV3iWI/2MhSy/6nkfVGkO4pRbAHn5lKEurE= +github.com/aws/aws-sdk-go-v2/service/medialive v1.87.1/go.mod h1:lo4HBgRUfQoPK+UoALzkBbtJ7G3VgoZ+ZK0JoY3Da6Q= +github.com/aws/aws-sdk-go-v2/service/mediapackage v1.39.13 h1:HpR+NAUetXZPf2Yh+rtgHu9FxDDBvKBMAkTcW6oChT4= +github.com/aws/aws-sdk-go-v2/service/mediapackage v1.39.13/go.mod h1:oxVvpbtnfXfjb6klvJnxBbXXvEiwDesOVdXJfTAWelk= +github.com/aws/aws-sdk-go-v2/service/mediapackagev2 v1.33.1 h1:B0yrE7niKPqIrhn2zRybxR/ztHNI97VXGIhf1BU7FlM= +github.com/aws/aws-sdk-go-v2/service/mediapackagev2 v1.33.1/go.mod h1:QoGJcWvPGVM0YXJgzcQht0STBGXu1CIpKM79uELmxOk= +github.com/aws/aws-sdk-go-v2/service/mediapackagevod v1.39.13 h1:PtGmG5x5b+gqkrQy9+H1ekmB0Bi2MNOHHVQY0erbvmI= +github.com/aws/aws-sdk-go-v2/service/mediapackagevod v1.39.13/go.mod h1:Ftgd5Wy90eNYPkQuVaV3TmQQzALXgxd1e7z2ZwQIS9s= +github.com/aws/aws-sdk-go-v2/service/mediastore v1.29.13 h1:FMWt9zQAbQp+9cInr9Cl6XWXpWPZN0+Trk+3ZdzN52w= +github.com/aws/aws-sdk-go-v2/service/mediastore v1.29.13/go.mod h1:Eutp4qNNpuZTT4nd8qQnuboixxqSjyghu31va93178g= +github.com/aws/aws-sdk-go-v2/service/memorydb v1.33.6 h1:IaVNG2u1nzyzUiWUj4YRasRVh1E1kjIuYYPCxudEbU4= +github.com/aws/aws-sdk-go-v2/service/memorydb v1.33.6/go.mod h1:VXJEWOG51Hiu9t0lT/7eYtSh9WNi8yU1yoAEXst1kOw= +github.com/aws/aws-sdk-go-v2/service/mgn v1.38.5 h1:+RJrQ8lDoDA91qh93UJ3Q/WBLPOtojhCT+RDuAvdcWk= +github.com/aws/aws-sdk-go-v2/service/mgn v1.38.5/go.mod h1:6t1r8BTGp7vdZUfIj58tomiYzGEmJUaJFrCYUrODKNI= +github.com/aws/aws-sdk-go-v2/service/mq v1.34.11 h1:D8r2O16aBEH/dG8xYYlhX+Tb0yWslvAlvjv2bbdWjJA= +github.com/aws/aws-sdk-go-v2/service/mq v1.34.11/go.mod h1:dp1WwnKbfltN4RJ39DIu2HFIif7DoZIQ1EsfB8BGUWA= +github.com/aws/aws-sdk-go-v2/service/mwaa v1.39.13 h1:wIqi6JVRFEfiN6kTVGWjg7zb3FEVPTvT2tpI3PArORU= +github.com/aws/aws-sdk-go-v2/service/mwaa v1.39.13/go.mod h1:06+ehiGrk+iaZXv4/BaooFPq8XRvmw4VWnxuNPoX6SM= +github.com/aws/aws-sdk-go-v2/service/neptune v1.43.4 h1:SR0OowjSvC8VhRvqvhp8mOTgnulFWdnYJZMbP4jfRfI= +github.com/aws/aws-sdk-go-v2/service/neptune v1.43.4/go.mod h1:u/db+lzLiyv8jAQe0S6t74UVXhqRGvB5tTkFBzmJ9Eg= +github.com/aws/aws-sdk-go-v2/service/neptunegraph v1.21.12 h1:cnBJ7+jr3h9PTSBu6/bVOGRoZM9hz0+pGDKC5mT7Yi0= +github.com/aws/aws-sdk-go-v2/service/neptunegraph v1.21.12/go.mod h1:wEqf9eooamtp7LRQIROz4tgf0e0qt8uqotiX7tk06Lk= +github.com/aws/aws-sdk-go-v2/service/networkfirewall v1.58.1 h1:ZKGnBg6lBGEd+ynpMM2CAtq/DHIlWpuDfflik267DvY= +github.com/aws/aws-sdk-go-v2/service/networkfirewall v1.58.1/go.mod h1:gvepatTXIpepuVOlPZOjFlrvUxfK9z0A5lnbcTUtDK0= +github.com/aws/aws-sdk-go-v2/service/networkflowmonitor v1.11.1 h1:XxFPXJ5Ji02Stsv7Br56Cd3y83pCK2hnAmlDJTquHnM= +github.com/aws/aws-sdk-go-v2/service/networkflowmonitor v1.11.1/go.mod h1:iTOL+4d/ivm5QLj9ZqVDv/TdbgQ8x9xjhyAkAHpcy4c= +github.com/aws/aws-sdk-go-v2/service/networkmanager v1.41.0 h1:qWp7IsxaNSlXisgd91YXxhtt8gjA8PWt5fDVrbEUvRk= +github.com/aws/aws-sdk-go-v2/service/networkmanager v1.41.0/go.mod h1:kgNPUOUJoF58RxEVq5Orwc6y6boN/3+u/l93bRNTKm8= +github.com/aws/aws-sdk-go-v2/service/networkmonitor v1.13.5 h1:UCtGo3Xx5wBUnvzRjZ01R3KzjVEZvEfVW7meZP4dQoE= +github.com/aws/aws-sdk-go-v2/service/networkmonitor v1.13.5/go.mod h1:VTgUYjO5kDR4/V8OtY/FgbTK88st+pTYEqd02VNt750= +github.com/aws/aws-sdk-go-v2/service/notifications v1.7.11 h1:lOmbQa3OiVAr9FpNyQ+eSmo4HSrBOPBFB/fOxdRfoT0= +github.com/aws/aws-sdk-go-v2/service/notifications v1.7.11/go.mod h1:w1FYcp9uektX2jjOBok9exgx9K01Ly0VgFN9rFjJu9c= +github.com/aws/aws-sdk-go-v2/service/notificationscontacts v1.5.15 h1:kEMTeGHiBg+aIIab4gwW3eO19bFaCHkAqVd5TtTRuw8= +github.com/aws/aws-sdk-go-v2/service/notificationscontacts v1.5.15/go.mod h1:HdA06DT0yuzIYRJs0nVV/Ex+WL0ve2Gy1UnAHT4JkAY= +github.com/aws/aws-sdk-go-v2/service/oam v1.23.6 h1:JHJ/PeT/yQJuZBtEq5/Qwchk3+PsJBZJqeHi65v5t0Y= +github.com/aws/aws-sdk-go-v2/service/oam v1.23.6/go.mod h1:dhCUbm8ln+gUKZKPuee0wIX2sr7JAxjKuYwHbrlNTic= +github.com/aws/aws-sdk-go-v2/service/observabilityadmin v1.8.7 h1:r64c1yvTAZLO0sjh4x6HcnwdFxOAzKYnH3NacqvJ9nI= +github.com/aws/aws-sdk-go-v2/service/observabilityadmin v1.8.7/go.mod h1:NKutYfxwSyTo5XxXJpOFmLyh5rHEzlS4/WSyVHksszc= +github.com/aws/aws-sdk-go-v2/service/odb v1.5.7 h1:gPLec3HA03IVHJiFFQEKySYjl++3SD8adv4aft+UZDQ= +github.com/aws/aws-sdk-go-v2/service/odb v1.5.7/go.mod h1:CGSmIL8RmXhK+jTqR6JsOYdTvtEq3caJgUbIkKJbYb4= +github.com/aws/aws-sdk-go-v2/service/opensearch v1.54.1 h1:q6+equIWYjS0r//bpc0DO1OAf7EzKTvmZapo46Y0+XI= +github.com/aws/aws-sdk-go-v2/service/opensearch v1.54.1/go.mod h1:RbMHS+zR3M5kpiug3An8h1mK4PsjMRRB/rwy5CFogyA= +github.com/aws/aws-sdk-go-v2/service/opensearchserverless v1.27.5 h1:1ISJyDYgkvHKnKm9uQT5T75f+EE8vSQquIxlGH6iRKk= +github.com/aws/aws-sdk-go-v2/service/opensearchserverless v1.27.5/go.mod h1:pjwpkoVGRhAKuGmP5n98P+6T1kEeOhf5Ki1bvyt27G4= +github.com/aws/aws-sdk-go-v2/service/organizations v1.47.0 h1:pbspTixTzr9O/AnKCs68XjD6lUYAoI8AtJUsXdMmAt8= +github.com/aws/aws-sdk-go-v2/service/organizations v1.47.0/go.mod h1:m9/mMkoPC0gZenV4x7iStoVecSyLax8mfnRaglZMXGE= +github.com/aws/aws-sdk-go-v2/service/osis v1.21.6 h1:6xcK9jPf0BcS38c6hEVf77GE/TKsfhT5VqI3xL34k5E= +github.com/aws/aws-sdk-go-v2/service/osis v1.21.6/go.mod h1:R/ExxBuvqyHs52JXVjNBNE/gYFi+CgsyNMXXnYZzsb4= +github.com/aws/aws-sdk-go-v2/service/outposts v1.57.7 h1:bCFa84n5+eYIrKPkA0RGjnW4HzOVlYxK7/x3Ve2mAQk= +github.com/aws/aws-sdk-go-v2/service/outposts v1.57.7/go.mod h1:3osURGv9q/2wxP1qYnB15GWYgr6w2AbQkSxYtE6vTaY= +github.com/aws/aws-sdk-go-v2/service/paymentcryptography v1.26.4 h1:nc8/QRKQ7U9nOvGQO2h2PNq2K1Z3f2BjDKMjNQR/B+o= +github.com/aws/aws-sdk-go-v2/service/paymentcryptography v1.26.4/go.mod h1:JxIrFROtjPM29WYprdr2CCD0riMeiVjeBOJa7V130EI= +github.com/aws/aws-sdk-go-v2/service/pcaconnectorad v1.15.13 h1:bYUqdM6nHGwYBi8NdoJ98L17NBSjL+oEGbyEVfXSSFg= +github.com/aws/aws-sdk-go-v2/service/pcaconnectorad v1.15.13/go.mod h1:aN7peo8Mf8CPvSAo3z/qqhKOZud3ghqkb5xAsvznhA0= +github.com/aws/aws-sdk-go-v2/service/pcs v1.15.1 h1:V86d11QRfw3X9uduZGwqPorgh+kNIE2qmJioEXF89nk= +github.com/aws/aws-sdk-go-v2/service/pcs v1.15.1/go.mod h1:AwSaPC3/EBpXqEagXb7DlAj71uGuF07H+VIMTp8i3JY= +github.com/aws/aws-sdk-go-v2/service/pinpoint v1.39.13 h1:uLHubX6wA/XdG44VHpYA8XE/sW0Uu+dTMlFpstZhvNg= +github.com/aws/aws-sdk-go-v2/service/pinpoint v1.39.13/go.mod h1:Rgpvz1J3Zts6piyQv5Uzmu7ADsWo3H8sDeCjyBTOSPQ= +github.com/aws/aws-sdk-go-v2/service/pinpointsmsvoicev2 v1.26.3 h1:d/KGUFGj4rUsvfktq1q5ibMwS6CUdsRpimwVQXLXH+o= +github.com/aws/aws-sdk-go-v2/service/pinpointsmsvoicev2 v1.26.3/go.mod h1:4RlEX3hI45Yxb0YCmPM+O/8mH4uVq28SyrUfT+L2fdg= +github.com/aws/aws-sdk-go-v2/service/pipes v1.23.12 h1:cjgKU2XCAOf5y98cHZWzV0njx0nj3XGTwPheiD3Z3Tc= +github.com/aws/aws-sdk-go-v2/service/pipes v1.23.12/go.mod h1:AY/h78GCZU1JBxyB1RrqJnyVdsU550wRFCafkJjnkSM= +github.com/aws/aws-sdk-go-v2/service/polly v1.54.6 h1:lFK+NrSJBURl1pG4S+c5UUeBHqtlu2jixi7IbNX0nMA= +github.com/aws/aws-sdk-go-v2/service/polly v1.54.6/go.mod h1:WhFdA98OEGe89bFru0POZxf+lunoMrgfMO2ROpWAfRw= +github.com/aws/aws-sdk-go-v2/service/pricing v1.40.6 h1:4ovg3PbNxrwpwbFpB8BR6JkhHoFVTRO8ZEzK1aFgshI= +github.com/aws/aws-sdk-go-v2/service/pricing v1.40.6/go.mod h1:PyqiJ2tbEVI+TpEoJQVGYYNXBTU2b9PNJhNOmjQekBM= +github.com/aws/aws-sdk-go-v2/service/qbusiness v1.33.13 h1:PCq+H1+eMPoPe2VXsuKZgl9QiakWrFMq51SIISyE75A= +github.com/aws/aws-sdk-go-v2/service/qbusiness v1.33.13/go.mod h1:SjaUXhkq1IvFeoF8bSt/WfS9g0eDhNLtEiD9FL0rQ/c= github.com/aws/aws-sdk-go-v2/service/qldb v1.32.2 h1:tSctQisNHgXnDmyoOdLXkSQmHYo5yPQuvYK+4c4QiNI= github.com/aws/aws-sdk-go-v2/service/qldb v1.32.2/go.mod h1:m6bmXbLs5XiGnTLcgKn9eNk5+GCO5e/wHQsIuN7d1Tw= -github.com/aws/aws-sdk-go-v2/service/quicksight v1.96.2 h1:OLAvMy2oEGGNRh7qjf+cGzupp/dEW57yH4oJ8eLfp9E= -github.com/aws/aws-sdk-go-v2/service/quicksight v1.96.2/go.mod h1:I8KrlgJxmNejc1VR3BWJ+J/uJuoLgaqTS/u/tJHIKA8= -github.com/aws/aws-sdk-go-v2/service/ram v1.34.13 h1:cr/kal5RvNdcBTmjjzOaRoBALpH9I/owczic7k/Ir18= -github.com/aws/aws-sdk-go-v2/service/ram v1.34.13/go.mod h1:XVmWvCpgKVITq+ThzyDzJkCbVycgzv8P8KzdhwijsyQ= -github.com/aws/aws-sdk-go-v2/service/rbin v1.26.13 h1:NHQqKZhCNB6K7hNanxoMKZQ9ZSY7Osg9wJ/4JFmY4lU= -github.com/aws/aws-sdk-go-v2/service/rbin v1.26.13/go.mod h1:HSYlwezMfkOFle385IG72Np892kUVbGvYsdM+BEG+9U= -github.com/aws/aws-sdk-go-v2/service/rds v1.109.0 h1:kAHatNQ1iaWVqVoFcZr5k0+o3dNSrnd+QZRFq4uTvZY= -github.com/aws/aws-sdk-go-v2/service/rds v1.109.0/go.mod h1:mGQNxzRLKlj1cQU5uaMIjAhle0HkSeZDwoPfP+/nRYk= -github.com/aws/aws-sdk-go-v2/service/redshift v1.60.0 h1:Kmh10uuGvak38mlg3FcveihltgP5rXbVcguCj9j3Ms8= -github.com/aws/aws-sdk-go-v2/service/redshift v1.60.0/go.mod h1:nroSRWOCQNS3b/vooHNsxwT5KRXzO+A8ouHyKsQenRc= -github.com/aws/aws-sdk-go-v2/service/redshiftdata v1.37.12 h1:oGiE4s2UAJmarRMSjui8/um4sqXnk2LFwPL+A1KV3UI= -github.com/aws/aws-sdk-go-v2/service/redshiftdata v1.37.12/go.mod h1:9beFz0fgqQr+Lkcz0lD54cquuuPUIV54fRbnLDQ7MNI= -github.com/aws/aws-sdk-go-v2/service/redshiftserverless v1.31.15 h1:q9nTCnHFttPjoz2vMC7u35u4jONksuXE060nBOcXD6E= -github.com/aws/aws-sdk-go-v2/service/redshiftserverless v1.31.15/go.mod h1:fgg+LQ1jrDB3K18lra3Qx4tTGCZE9yX+eUQzxUjMhAs= -github.com/aws/aws-sdk-go-v2/service/rekognition v1.51.11 h1:bs3xqr92wJuHiHkNhlkipDe2HSY1LZ4hUkEAek/N4X4= -github.com/aws/aws-sdk-go-v2/service/rekognition v1.51.11/go.mod h1:r0M9WlvDeB2fPsZk2es9ZrjyUNIRPKoxm8xEU+CKbE0= -github.com/aws/aws-sdk-go-v2/service/resiliencehub v1.35.4 h1:8yORXc5cW+paBUU1f7z41+ZpwMjt4FHUS3kJEC+YQo0= -github.com/aws/aws-sdk-go-v2/service/resiliencehub v1.35.4/go.mod h1:efsKs5+XMP1JeFtYuLvLfHrBN3GmitdOUgKqDW2Xp9M= -github.com/aws/aws-sdk-go-v2/service/resourceexplorer2 v1.22.6 h1:kkoaQ06wQZ5AlqoJ+QYaqMs/WSho8Eii+E++PI5g+H8= -github.com/aws/aws-sdk-go-v2/service/resourceexplorer2 v1.22.6/go.mod h1:3A/lTLOEWLwbIFsOrriZuVdhibD0E4riboU0VaoV1mc= -github.com/aws/aws-sdk-go-v2/service/resourcegroups v1.33.14 h1:257Y5fn4QZOqofLk8ckt9yJT8LV57lpDEHKO4lchu6U= -github.com/aws/aws-sdk-go-v2/service/resourcegroups v1.33.14/go.mod h1:6k9FPdJPkYmyrO0PFg1R+k3Rw5RYJT4MGdNqvodIGGY= -github.com/aws/aws-sdk-go-v2/service/resourcegroupstaggingapi v1.31.0 h1:W8c1GPeHBlwIeuz+DuwvYaoRBrSDy1Cp8DwXIzXTAWg= -github.com/aws/aws-sdk-go-v2/service/resourcegroupstaggingapi v1.31.0/go.mod h1:+nL0z6xUm9NK9bOAkam66NQDgNH8Qa6T6SS3f8dkzXU= -github.com/aws/aws-sdk-go-v2/service/rolesanywhere v1.21.12 h1:voPlA/Poy1EatBhjehk4yVWnC+os9+Wn0VwxAB6aPzs= -github.com/aws/aws-sdk-go-v2/service/rolesanywhere v1.21.12/go.mod h1:/WVeeJKvbKmaTWEtt7y2005MHRKlh+Ee5Nr3qmPMQpY= -github.com/aws/aws-sdk-go-v2/service/route53 v1.60.0 h1:UlmdpHo/xdaEB/80wOqcBVkzsPdmct02FuOfg5Rrd3U= -github.com/aws/aws-sdk-go-v2/service/route53 v1.60.0/go.mod h1:TUbfYOisWZWyT2qjmlMh93ERw1Ry8G4q/yT2Q8TsDag= -github.com/aws/aws-sdk-go-v2/service/route53domains v1.34.10 h1:+eeUZjA6+GoTYmFjOlfx21du3eljT6fea39jI3TWjDw= -github.com/aws/aws-sdk-go-v2/service/route53domains v1.34.10/go.mod h1:lxTo/orhKjYQIgzo0ED2KQyU5yC7zPw6vgImZBp5Opc= -github.com/aws/aws-sdk-go-v2/service/route53profiles v1.9.12 h1:6W3ERfxp0q+oNMinc59z4Uzcd5vDC4NOsIxFl71CNmI= -github.com/aws/aws-sdk-go-v2/service/route53profiles v1.9.12/go.mod h1:Nvyw2yEW8po15FmApho3Biz63mgQirrO6dxseYQb1u8= -github.com/aws/aws-sdk-go-v2/service/route53recoverycontrolconfig v1.32.5 h1:hT6/2e3FTRRh/QPYW73GRJlLZLH6hqxDn+F76EL1Gxg= -github.com/aws/aws-sdk-go-v2/service/route53recoverycontrolconfig v1.32.5/go.mod h1:uuKkzsDRNyxWABenHqS3Ms7KoEUf+3EHsNCnMBVMslo= -github.com/aws/aws-sdk-go-v2/service/route53recoveryreadiness v1.26.12 h1:Iury32NIQy7GGFzQzPAUJlydeeo6O+Gf1iheLW8Ax9Y= -github.com/aws/aws-sdk-go-v2/service/route53recoveryreadiness v1.26.12/go.mod h1:FPoma320xUxwC7BRaqJPYjpyIgbuxrAF//JdP9ybfjQ= -github.com/aws/aws-sdk-go-v2/service/route53resolver v1.41.0 h1:8dRPme2++LKhXPTD3VbiCGkwZ1tfPgwjkFwhpiMF1Yk= -github.com/aws/aws-sdk-go-v2/service/route53resolver v1.41.0/go.mod h1:RtTRuj33VUDMd7i7eDEuhX2x69JWtPkWODE2b2TeiS4= -github.com/aws/aws-sdk-go-v2/service/rum v1.30.0 h1:EVwrOhq7sTe0luu/k/blau3VyU4ub/Mkw8yuTbF4yuU= -github.com/aws/aws-sdk-go-v2/service/rum v1.30.0/go.mod h1:aoij2zkJWvNtGzPvyaOZtNazKNjMBEVOmdDystHnh8g= -github.com/aws/aws-sdk-go-v2/service/s3 v1.91.0 h1:b8FQI84BFRqCHjInLKS7bo+iSH8oVJ9C2noKC2H3jwY= -github.com/aws/aws-sdk-go-v2/service/s3 v1.91.0/go.mod h1:+wArOOrcHUevqdto9k1tKOF5++YTe9JEcPSc9Tx2ZSw= -github.com/aws/aws-sdk-go-v2/service/s3control v1.66.9 h1:1GWUaLfzsa0AzsRQW3KUNkO1ZnD7ngR1aPedX9HwqxY= -github.com/aws/aws-sdk-go-v2/service/s3control v1.66.9/go.mod h1:c+ERB7DbWT1uR6QvBn7W0gB2YczXacCEoLegFLwPAE8= -github.com/aws/aws-sdk-go-v2/service/s3outposts v1.34.3 h1:iCv2rBKUo+ZbWwZW+/sEjmAX+X0HsT9bgs9DqORRaPc= -github.com/aws/aws-sdk-go-v2/service/s3outposts v1.34.3/go.mod h1:4XtnGsaxnIiUsurxxTMzn9Wl9/utEAN46rcMPVKLGAM= -github.com/aws/aws-sdk-go-v2/service/s3tables v1.12.0 h1:11XumI/hI9fLn3MXs0rAAzU+c01TPpnXmgDGX2gprVU= -github.com/aws/aws-sdk-go-v2/service/s3tables v1.12.0/go.mod h1:t1l6loaBQWttife9bosS3OspbGv+CP18UbGxMIQie4A= -github.com/aws/aws-sdk-go-v2/service/s3vectors v1.5.2 h1:QX1IetutOdnutzPJ+FD9YnkguYqnIKGv9wDcZLaphWM= -github.com/aws/aws-sdk-go-v2/service/s3vectors v1.5.2/go.mod h1:+sgMaDJqPLY3w2QXsvbhgSlvIaQ4+4cYk6Cdp388Swg= -github.com/aws/aws-sdk-go-v2/service/sagemaker v1.224.0 h1:HJdoaripEfZVveELxCCgNdMsRXc9/5zNNMpr++nB2Lk= -github.com/aws/aws-sdk-go-v2/service/sagemaker v1.224.0/go.mod h1:JnrlXHI1oM/gVNI0/NH1Ru4UZr4sWx/WZclCsJtbmCM= -github.com/aws/aws-sdk-go-v2/service/scheduler v1.17.12 h1:VOBt5H2SeS7yGq7YIOp38dW2cLeEMjIULi68tvP6iE0= -github.com/aws/aws-sdk-go-v2/service/scheduler v1.17.12/go.mod h1:UohrBXfiKjUlaqaMzj3jtBBfrNFSCjq+LLwDbtsvAIo= -github.com/aws/aws-sdk-go-v2/service/schemas v1.34.3 h1:s+siGYfqvmOJGiQJRRz/eUzsDJDZoQ6oN3F5m+AEL0I= -github.com/aws/aws-sdk-go-v2/service/schemas v1.34.3/go.mod h1:ipui3c5k/ozPT734rqfqsFgieDEny9ABk4sp7zCWjkM= -github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.40.0 h1:Wm8i2WjGbemRw3adxuKQAbzi3Uq7DgynajCxVnKGQyQ= -github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.40.0/go.mod h1:QgVIY03/XoQs2iFr0MbQuQ/Tf1RwlkOvuySWMh1wph4= -github.com/aws/aws-sdk-go-v2/service/securityhub v1.65.4 h1:PkMuUN9eBC5BrK3msGCz5lajFeCjG8qBJsK3e81pUzo= -github.com/aws/aws-sdk-go-v2/service/securityhub v1.65.4/go.mod h1:QaXNTOs7OkNR7y9uFWajUymXwUh28Q7cTz3tqWiE6sc= -github.com/aws/aws-sdk-go-v2/service/securitylake v1.25.4 h1:8wd+JhD0YwePy+QiMLpm/jMwNKhN6SdCZTJtB/nDiWI= -github.com/aws/aws-sdk-go-v2/service/securitylake v1.25.4/go.mod h1:8psZ/OINrXmUJhyXWm0NzLaKP5bp1t/dh0/D2Pj/YAo= -github.com/aws/aws-sdk-go-v2/service/serverlessapplicationrepository v1.30.3 h1:b6b1QcN9yzuAQw4bq34kAF75u5ToRBFgmTuBC4dnksI= -github.com/aws/aws-sdk-go-v2/service/serverlessapplicationrepository v1.30.3/go.mod h1:OmVOd812JbwvNOwaQMpeMmj2bnN6dgUZnVaD1UIvyVg= -github.com/aws/aws-sdk-go-v2/service/servicecatalog v1.39.3 h1:IcQ+ja++SXCVUvsvp7lKUHZqB+Ee6KhktY4OINyknUs= -github.com/aws/aws-sdk-go-v2/service/servicecatalog v1.39.3/go.mod h1:fA60HaKYi8WBwj1uf+n2sZkyefVWWUTkKB69Th3pTB0= -github.com/aws/aws-sdk-go-v2/service/servicecatalogappregistry v1.35.12 h1:5f7+VPi0JMU1U0fdmvh4u3h1BzCXYl21S72hMrTTXqk= -github.com/aws/aws-sdk-go-v2/service/servicecatalogappregistry v1.35.12/go.mod h1:H/pz3dQJmZHdKf3DMgD0znZwoP0h8Umx9uPhBRXOkxE= -github.com/aws/aws-sdk-go-v2/service/servicediscovery v1.39.16 h1:lzAqM9zMFwAy3ghxjeJfROdwnzO/KCPY8RYEAYpGbCM= -github.com/aws/aws-sdk-go-v2/service/servicediscovery v1.39.16/go.mod h1:lYyuDbeQ6vtjRP4gb9h2MReluEb0US5u+07X84akGKg= -github.com/aws/aws-sdk-go-v2/service/servicequotas v1.33.7 h1:f0u4ARkdAWxISBgm7RtckKuKHyn8BWprVOLjyM31Loo= -github.com/aws/aws-sdk-go-v2/service/servicequotas v1.33.7/go.mod h1:TvpkfbD0qaLoadCivfVCzpgavaEJvmRpG0pzZOo4pX0= -github.com/aws/aws-sdk-go-v2/service/ses v1.34.11 h1:DZpXGSoAP6ZB0//dl31ZkRCrEVwmGzgT6AR86WeThbo= -github.com/aws/aws-sdk-go-v2/service/ses v1.34.11/go.mod h1:CeGX4LAFCsrBp24qazKmO/dwxghNCGbAoTbi64dGSEM= -github.com/aws/aws-sdk-go-v2/service/sesv2 v1.54.4 h1:T8XudbCBzHztu2uYYUzlAQhSMxWJVk7zya/7/RLocZE= -github.com/aws/aws-sdk-go-v2/service/sesv2 v1.54.4/go.mod h1:uxpQTTvKs2FUajNzmQic0lqMB5X0zjX8jpalkvkhIQI= -github.com/aws/aws-sdk-go-v2/service/sfn v1.40.0 h1:nbTZ7tF36OMkm6anz5M35t9iqRKYGSInHCrHRWMvQQE= -github.com/aws/aws-sdk-go-v2/service/sfn v1.40.0/go.mod h1:fhG61r7sW7WsxXcZAips5CFQta1i2sQwRaEQeQwSrks= -github.com/aws/aws-sdk-go-v2/service/shield v1.34.12 h1:+TCfMnn82wi0zO4NzoqRNHlFIwWn0nQVGYxUZggnSFM= -github.com/aws/aws-sdk-go-v2/service/shield v1.34.12/go.mod h1:6B2EvRYLO2QsWbNoEsxazaKhVufZBDPApqPkpQ2arJI= -github.com/aws/aws-sdk-go-v2/service/signer v1.31.12 h1:HieRc7Lr0KPod0rv7dIa3F51/cGcV5yYCaUZNocJ6SA= -github.com/aws/aws-sdk-go-v2/service/signer v1.31.12/go.mod h1:F44pi85d2IzaTcwWULuLl2cdYjFkKr948NbU7gCmcKY= -github.com/aws/aws-sdk-go-v2/service/sns v1.39.5 h1:SKUhwz9XqabTspg48L5ZTP2D5pdbNHttPFeG0Fljqtg= -github.com/aws/aws-sdk-go-v2/service/sns v1.39.5/go.mod h1:1LvRsmADXI6174y66InuSDQiEztkQgCLbcw62VLC0FQ= -github.com/aws/aws-sdk-go-v2/service/sqs v1.42.15 h1:uoPRUh1/r/E2Vn3Witk0tZppmmsCXmsAuBmx3QorXDk= -github.com/aws/aws-sdk-go-v2/service/sqs v1.42.15/go.mod h1:ZS67woOy/ftzvKK2+P53u2NPqImAPTWz+hBn+tchP7k= -github.com/aws/aws-sdk-go-v2/service/ssm v1.67.2 h1:ybM2UK1Fx4AeurfSGzLKdnjw5j6g6mwVI0Lsr7ZnuEc= -github.com/aws/aws-sdk-go-v2/service/ssm v1.67.2/go.mod h1:uNHuYAQazkHqpD+hVomA2+eDSuKJzerno7Fnha6N6/Y= -github.com/aws/aws-sdk-go-v2/service/ssmcontacts v1.31.5 h1:56hyzh8TcjBUxUNg05wj427i+fBMc2y31grE28B37nI= -github.com/aws/aws-sdk-go-v2/service/ssmcontacts v1.31.5/go.mod h1:m9mkIFFGnEY00U3IpPs/TZLbbgOxARLDtqsDbGqzjik= -github.com/aws/aws-sdk-go-v2/service/ssmincidents v1.39.11 h1:X3FuvC+O/n15wFyRhUct0uR3u68GvQwpngvFHrZ6d+o= -github.com/aws/aws-sdk-go-v2/service/ssmincidents v1.39.11/go.mod h1:TUCeZ43VbibNN5TTa0oWium4Cj2ee/Xg93xNRVx+iUw= -github.com/aws/aws-sdk-go-v2/service/ssmquicksetup v1.8.12 h1:a03QlxefOXmq1sVd60DDteR70yaT7X2Q2zaXAz2i3Z0= -github.com/aws/aws-sdk-go-v2/service/ssmquicksetup v1.8.12/go.mod h1:h/ogxk4gxt67ItMvhzCJSST5AHjaYYuMC/wdLMBLOrI= -github.com/aws/aws-sdk-go-v2/service/ssmsap v1.25.11 h1:i2bIm3mt03P2bH1oybSOAID7FRm0IZD2+C5cUMmcYEo= -github.com/aws/aws-sdk-go-v2/service/ssmsap v1.25.11/go.mod h1:9/Q7dAszR79doau18RBveSfZX9RASAs4Tubh196QR8A= -github.com/aws/aws-sdk-go-v2/service/sso v1.30.3 h1:NjShtS1t8r5LUfFVtFeI8xLAHQNTa7UI0VawXlrBMFQ= -github.com/aws/aws-sdk-go-v2/service/sso v1.30.3/go.mod h1:fKvyjJcz63iL/ftA6RaM8sRCtN4r4zl4tjL3qw5ec7k= -github.com/aws/aws-sdk-go-v2/service/ssoadmin v1.36.8 h1:7g2FaXrm2gJyjcVjyC1jweXVNRhlK9X52wJ7wcUBISA= -github.com/aws/aws-sdk-go-v2/service/ssoadmin v1.36.8/go.mod h1:CzDlwLoYGIK0Q7ISrzqCD1/Zgf6nsIdct4f0ZoyKoHI= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.7 h1:gTsnx0xXNQ6SBbymoDvcoRHL+q4l/dAFsQuKfDWSaGc= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.7/go.mod h1:klO+ejMvYsB4QATfEOIXk8WAEwN4N0aBfJpvC+5SZBo= -github.com/aws/aws-sdk-go-v2/service/storagegateway v1.43.4 h1:bz3k661WLBZIXESAlqqumtcYSQp2m8rjT8m1/b0QLUE= -github.com/aws/aws-sdk-go-v2/service/storagegateway v1.43.4/go.mod h1:JKIFhh/dRv/Ft85RarJH3G3ewl419X6gmD/1fEXjDnI= -github.com/aws/aws-sdk-go-v2/service/sts v1.41.0 h1:JoO/STlEltv5nSbzbg709MLNW0/BWgyK2t/R9OWcCyQ= -github.com/aws/aws-sdk-go-v2/service/sts v1.41.0/go.mod h1:E19xDjpzPZC7LS2knI9E6BaRFDK43Eul7vd6rSq2HWk= -github.com/aws/aws-sdk-go-v2/service/swf v1.33.6 h1:VsuWtkucF7FwWd7cBXwXPx5BOU853UEws1maHKmY0iQ= -github.com/aws/aws-sdk-go-v2/service/swf v1.33.6/go.mod h1:mmUGhXHOTZ0YLexnps/Zn0u5T+p9QkpGRpXuf5L2b7A= -github.com/aws/aws-sdk-go-v2/service/synthetics v1.42.4 h1:XO316jX9V7JywHSsmjhgp19K0NUzFAXbGRUSIl5zABU= -github.com/aws/aws-sdk-go-v2/service/synthetics v1.42.4/go.mod h1:NoN2h4JljGuHzAYWNB3WVGKnuKczRbHoqVh5Z7Z4YdM= -github.com/aws/aws-sdk-go-v2/service/taxsettings v1.16.12 h1:m20Zhil+oCtuHCpNrkoG2ihK3xjbsGWJRdv7jX3U2bU= -github.com/aws/aws-sdk-go-v2/service/taxsettings v1.16.12/go.mod h1:mch3G+DUo5AjLDfRe7XL3QhVf1K+tk+u1WQiAj5tvzs= -github.com/aws/aws-sdk-go-v2/service/timestreaminfluxdb v1.17.6 h1:wYMxv6TtFtGARWlzQ4IAR8+VbTHB9Lncg+Gi5nB06h4= -github.com/aws/aws-sdk-go-v2/service/timestreaminfluxdb v1.17.6/go.mod h1:ATSASzt7xr2/Xcj8ZjMQg9woL5SyhrghAPCb7nArWVY= -github.com/aws/aws-sdk-go-v2/service/timestreamquery v1.36.5 h1:qZgibsVrtn0JVsk+g6eb5jQiQFtpvngQMn0MtwMPwz8= -github.com/aws/aws-sdk-go-v2/service/timestreamquery v1.36.5/go.mod h1:b34PXpekNN9TeyqzUNcFiOEAm3DFd4e+viL/XbQtzuk= -github.com/aws/aws-sdk-go-v2/service/timestreamwrite v1.35.11 h1:ylTUvLe7i1rEk7nTsL1qW2kUIdZSqYw5Jb0XFfnp6H8= -github.com/aws/aws-sdk-go-v2/service/timestreamwrite v1.35.11/go.mod h1:WOhN8208dG/kUp22L0kch06lMtCQJ/+Ypv2W3TTC6vg= -github.com/aws/aws-sdk-go-v2/service/transcribe v1.53.6 h1:2k93IkW8MnhrLQdAJDqKKTL9mjvy7N0GhE8lQi/Gy0A= -github.com/aws/aws-sdk-go-v2/service/transcribe v1.53.6/go.mod h1:juatw/4IEOV9unN2B/ZmVXIGA8YnhDTXzY/ZdIBS11w= -github.com/aws/aws-sdk-go-v2/service/transfer v1.67.6 h1:yJnWTq8tYhxl677goBXEHi/JQ12gQB+yb8JEZQC+Jv8= -github.com/aws/aws-sdk-go-v2/service/transfer v1.67.6/go.mod h1:X1hqrnuqgk5EY3Ic+agUr6P4/CJCrp8HrcC343qi/74= -github.com/aws/aws-sdk-go-v2/service/verifiedpermissions v1.30.2 h1:OpOUGQJm2fHX/miVu6DS1rlreleaoNihxaxrQFpanLM= -github.com/aws/aws-sdk-go-v2/service/verifiedpermissions v1.30.2/go.mod h1:m3YeM8yB49t1fzKYEe43wiowaSO7x/3YmHS/UGOaks8= -github.com/aws/aws-sdk-go-v2/service/vpclattice v1.20.2 h1:WLmuDZpc9IlVVKQ+XID+bebCjtbxbrvCfg7Kb6LBiKw= -github.com/aws/aws-sdk-go-v2/service/vpclattice v1.20.2/go.mod h1:fp9PvIVx7/jyef3CaWCemFPGK+ghu2Du2XJFGaqc4iE= -github.com/aws/aws-sdk-go-v2/service/waf v1.30.11 h1:Lq4PpRIWw/3HSansKRRhycylCwp85287783VTCNfJMo= -github.com/aws/aws-sdk-go-v2/service/waf v1.30.11/go.mod h1:/wwPzZRBcPxG/kAOAzei/UX/FKo2H+aZcx0x99xJPpA= -github.com/aws/aws-sdk-go-v2/service/wafregional v1.30.12 h1:kkie0K7P3VOnwJhaaofC4lbJpc82e3rbGKmXW+PjhHE= -github.com/aws/aws-sdk-go-v2/service/wafregional v1.30.12/go.mod h1:eaFrizONYIw5QJPDxoBUr8NNM21ISTZDjFhkGVt4NZY= -github.com/aws/aws-sdk-go-v2/service/wafv2 v1.70.0 h1:mZMnchrgTVjUinijiTKDh0tvz5HhzAoMXfIjOAWpdB4= -github.com/aws/aws-sdk-go-v2/service/wafv2 v1.70.0/go.mod h1:RtLkquPOQfQASVPWLuXr4hJgaZ5ChNq7eWahkj/CoCQ= -github.com/aws/aws-sdk-go-v2/service/wellarchitected v1.39.12 h1:niwCZWFfIaglbSRA1Cbc7fMCOfsmAfeaWX8ll25sfOI= -github.com/aws/aws-sdk-go-v2/service/wellarchitected v1.39.12/go.mod h1:t6nyl94d8gQdt34LEo0SH4uGPNruy0T3oMaxcOHdWUU= -github.com/aws/aws-sdk-go-v2/service/workmail v1.36.10 h1:lznZYmkvDu6gHqSKpornaZw2WCwYDN/NYSpfziIgsr8= -github.com/aws/aws-sdk-go-v2/service/workmail v1.36.10/go.mod h1:JW6rMNuboHOnWx7I1fZfHAG1kcUiBZfTkZuD69oNw2w= -github.com/aws/aws-sdk-go-v2/service/workspaces v1.64.4 h1:yX/JSkp/zildXMrGuqm7VRUn+S8an7dZt0Jyy8L6DVg= -github.com/aws/aws-sdk-go-v2/service/workspaces v1.64.4/go.mod h1:TmJI48Dm4ftRxBmMoZOeC8Et2WEStJoPpv8BoXZ/eZw= -github.com/aws/aws-sdk-go-v2/service/workspacesweb v1.34.0 h1:gfDV7Oa2SA+xTJxWZwPiGF/aBew2/OVIGRZ1qipeZ6Q= -github.com/aws/aws-sdk-go-v2/service/workspacesweb v1.34.0/go.mod h1:V4nPCxgIBn6Yf5JhnI3Cs0iKVTB+wkzXG8fEGYqLYkU= -github.com/aws/aws-sdk-go-v2/service/xray v1.36.11 h1:K0g9kBUVHv8da1OpfeLbvteZyTy2dUWBO2ZfwYXw1D8= -github.com/aws/aws-sdk-go-v2/service/xray v1.36.11/go.mod h1:JghyUyM7u0syGGk+S5Res2mLfceuyLigCgtcrpsEESM= +github.com/aws/aws-sdk-go-v2/service/quicksight v1.97.0 h1:9ogCHJCe+nGXJnfBjwp3TAOHrpzUVt+JvwgGtUil+ls= +github.com/aws/aws-sdk-go-v2/service/quicksight v1.97.0/go.mod h1:94THejlBvEJHNpLFY+v3EvpK3j0aRmo3qgsZ1WqK5no= +github.com/aws/aws-sdk-go-v2/service/ram v1.34.14 h1:rBkgTXwg1YN7b67f3dCvJ9zCrzomchzebnPy5Qgdmm4= +github.com/aws/aws-sdk-go-v2/service/ram v1.34.14/go.mod h1:34/yHgldzuEsrLgSFH9obW0wvIWpc5Na9yxCeUkZ9R0= +github.com/aws/aws-sdk-go-v2/service/rbin v1.27.0 h1:6n6wd4xLZmBfpMB70fnS174K7slKw8BCPY6oI0VRsXU= +github.com/aws/aws-sdk-go-v2/service/rbin v1.27.0/go.mod h1:n9hrfwpLS7AUP0s6iGtCGFFRCixnlCFQqax6IIuf2FE= +github.com/aws/aws-sdk-go-v2/service/rds v1.110.0 h1:nT6SmXNA8QvdHCkFNfNotCi/JyiY0PzftX2HEaL4XYk= +github.com/aws/aws-sdk-go-v2/service/rds v1.110.0/go.mod h1:DCoBFX5nu7ZQxaZqGe+5Ai8Qd3lLpcQF1EhMrlC/FWU= +github.com/aws/aws-sdk-go-v2/service/redshift v1.60.1 h1:ZVs9gGijfI+YHQNt/AiWHmLX7/ibZHMHRoDnkScd2kA= +github.com/aws/aws-sdk-go-v2/service/redshift v1.60.1/go.mod h1:i/7qjbmYknaQFO0ngVOwQxom9SR4RAxG1ZgJgcxAJZg= +github.com/aws/aws-sdk-go-v2/service/redshiftdata v1.38.0 h1:LoIvzYFQjsts0dkYtrkkX4C238k5CNiOjeejbPA3Iog= +github.com/aws/aws-sdk-go-v2/service/redshiftdata v1.38.0/go.mod h1:bkvaZap+q1XCO9jJ/G5ee31reF0o5LjnNpymcfJfRS8= +github.com/aws/aws-sdk-go-v2/service/redshiftserverless v1.31.16 h1:1xqamHzrqzsCKLx+2vdP+EzfcTb3ZrIbAXKgl19fia0= +github.com/aws/aws-sdk-go-v2/service/redshiftserverless v1.31.16/go.mod h1:elkDPupfwuagGDxk6UxynoevhaMi1GXm103VxlWLpJc= +github.com/aws/aws-sdk-go-v2/service/rekognition v1.51.12 h1:28b9Kjlue5rzZpmdTROq5irrBFE2D9AkDUwKeC/ePA4= +github.com/aws/aws-sdk-go-v2/service/rekognition v1.51.12/go.mod h1:OYrkEDsOrsb0uzlaloXZpqqLYYWKAJG8lBnNePZQvsI= +github.com/aws/aws-sdk-go-v2/service/resiliencehub v1.35.5 h1:FpssBdBrVHTqQnatqjRhH77nAydFk2ZeNMo8xN2t8pM= +github.com/aws/aws-sdk-go-v2/service/resiliencehub v1.35.5/go.mod h1:gkPbHCTH3JYH0JESTRJxTNugjr8cOdUa0oXzAXcYTgI= +github.com/aws/aws-sdk-go-v2/service/resourceexplorer2 v1.22.7 h1:ybmzYrIQHuel279rSEAmhQ4ECrWgwhrRS0C4Bn5r6mA= +github.com/aws/aws-sdk-go-v2/service/resourceexplorer2 v1.22.7/go.mod h1:GnXrmUWHPBKfIiYuxe550s3JydugMSpEs9ZFbvkEbdk= +github.com/aws/aws-sdk-go-v2/service/resourcegroups v1.33.15 h1:obIB3dHPpU6KstNnIe0098a2moKahM+onrPcmO4n6Qs= +github.com/aws/aws-sdk-go-v2/service/resourcegroups v1.33.15/go.mod h1:SId/9odVYgeotyaiqowTbeasqjEWnfKdVPWOm19kZV0= +github.com/aws/aws-sdk-go-v2/service/resourcegroupstaggingapi v1.31.1 h1:dSSvIM4/755D7EkUeUc+BChEC6my1174OZ9U3glm3KI= +github.com/aws/aws-sdk-go-v2/service/resourcegroupstaggingapi v1.31.1/go.mod h1:LAr8C2ATopaEf8qvoLrkZDHZPLKuYhZlh4TADgJvVbk= +github.com/aws/aws-sdk-go-v2/service/rolesanywhere v1.21.13 h1:za4QeTDsu4M6YJrw85m4aXsIxtSDImeaAxFRX1X//7I= +github.com/aws/aws-sdk-go-v2/service/rolesanywhere v1.21.13/go.mod h1:Sojaj+ChUXvjjbl/zVWNY9V2mid6ClTl8TFThvRkuHY= +github.com/aws/aws-sdk-go-v2/service/route53 v1.60.1 h1:dU7oc4LXR9j4mi1DtD8549D/rUtKA4rcWNY1HPoKzx8= +github.com/aws/aws-sdk-go-v2/service/route53 v1.60.1/go.mod h1:Wa3q5R2uwIfIL3HZH+vG1/P9y7CjjfzTgcz5IWXlsZs= +github.com/aws/aws-sdk-go-v2/service/route53domains v1.34.11 h1:yPlet3cmD+qMiwdFIlptk5XvrCFLCGA1Q3R0+TMtKi0= +github.com/aws/aws-sdk-go-v2/service/route53domains v1.34.11/go.mod h1:mket8PmDPRvTj2Alr11ZkNCLBl2j2i0425xGWZyPw8M= +github.com/aws/aws-sdk-go-v2/service/route53profiles v1.9.13 h1:l+My5+pw8pJeVVsAsMYUDkvV2mxBPh9ivXm8oWGrIn8= +github.com/aws/aws-sdk-go-v2/service/route53profiles v1.9.13/go.mod h1:6nqxjPsXNUryUJaL4GkH+BELMODHiL2hKJGBnv+GDfE= +github.com/aws/aws-sdk-go-v2/service/route53recoverycontrolconfig v1.32.6 h1:fr6kQ/We9xhSb4lRUZgqODxCLXztXRLvPok+PS3UYIg= +github.com/aws/aws-sdk-go-v2/service/route53recoverycontrolconfig v1.32.6/go.mod h1:rLZ42YKHIBXAWQ40WgOMNX1axZHuK7kl8JcJNHaYGyM= +github.com/aws/aws-sdk-go-v2/service/route53recoveryreadiness v1.26.13 h1:QfezB1y1kBa0wsn1QxjalplQr2zIhLDs0ZkihYNlZ0k= +github.com/aws/aws-sdk-go-v2/service/route53recoveryreadiness v1.26.13/go.mod h1:icxw7RaIz+k0KpzVwXhgTVKQzeAL5F0pBj2OUrhtg6M= +github.com/aws/aws-sdk-go-v2/service/route53resolver v1.41.1 h1:nhXTcE5IxAz+AIRSw0qj8/Qzx5SQPQJ5jbh64Py1a3A= +github.com/aws/aws-sdk-go-v2/service/route53resolver v1.41.1/go.mod h1:sw/NeWUDqWachTcxgkz7ah43Tap829L5AyaHkBJKx4Q= +github.com/aws/aws-sdk-go-v2/service/rum v1.30.1 h1:3u274twXLUV/BSKaIWnljGP8j2fKL49rV2pyaD4uvgI= +github.com/aws/aws-sdk-go-v2/service/rum v1.30.1/go.mod h1:IEXD0Zq/ZJNBsuTvM5eKguxzqMC52sYJJwDq6o4Jm6g= +github.com/aws/aws-sdk-go-v2/service/s3 v1.92.0 h1:8FshVvnV2sr9kOSAbOnc/vwVmmAwMjOedKH6JW2ddPM= +github.com/aws/aws-sdk-go-v2/service/s3 v1.92.0/go.mod h1:wYNqY3L02Z3IgRYxOBPH9I1zD9Cjh9hI5QOy/eOjQvw= +github.com/aws/aws-sdk-go-v2/service/s3control v1.66.10 h1:1pjfq74OUPI4ZbBpBG8PClSzHM0X+MhI4maiNuOsBWs= +github.com/aws/aws-sdk-go-v2/service/s3control v1.66.10/go.mod h1:jylbu2Ud/Os7uaKxBQeBnRh8mPPDJRfFkDUhTJEW0bc= +github.com/aws/aws-sdk-go-v2/service/s3outposts v1.34.4 h1:W7dO+rK0O7jC+V9nEzwtRCoj/el+/mDbpp9Sg7eeMsw= +github.com/aws/aws-sdk-go-v2/service/s3outposts v1.34.4/go.mod h1:oB8H++IzGctkv+1rWGXVO5IVVnKkfQVxGLppMSFN0lQ= +github.com/aws/aws-sdk-go-v2/service/s3tables v1.12.1 h1:oxFit2u0Mn4g6LhyXfrEImp3rBltj/xsT3dynX45Ecc= +github.com/aws/aws-sdk-go-v2/service/s3tables v1.12.1/go.mod h1:bI6V4KDGYAuIagoD+7U9MAct+mJ4masG6XMmLJK4ha0= +github.com/aws/aws-sdk-go-v2/service/s3vectors v1.5.3 h1:7lAOw5kkr7gwwfsVR7zELt1eg2aP4/xZQaqfQMKpfQ8= +github.com/aws/aws-sdk-go-v2/service/s3vectors v1.5.3/go.mod h1:R4L5tr5WAgywKPxVoRSbZMG32y2RLyVJvcZ2FHD5Jog= +github.com/aws/aws-sdk-go-v2/service/sagemaker v1.225.0 h1:2Ak704qNv6HbWcY/Q9B7Rwvr6L0AVYAEpis2A0gn0w4= +github.com/aws/aws-sdk-go-v2/service/sagemaker v1.225.0/go.mod h1:TC1g0DtCISdIRBh4NtI3B8YBv7Pu4XVMzXuTntzDOl4= +github.com/aws/aws-sdk-go-v2/service/scheduler v1.17.13 h1:C/TEq8PExKqE1h6R3buJEsXzAaUuiOkskI7afvprpFI= +github.com/aws/aws-sdk-go-v2/service/scheduler v1.17.13/go.mod h1:P5rgopIySg7bbVySzYJc3wm3PnsVb4joELbRuWJSQBw= +github.com/aws/aws-sdk-go-v2/service/schemas v1.34.4 h1:Bm2jyC8CALFjnjOO6A651V8JfrICSaNAsMUcItNlFH0= +github.com/aws/aws-sdk-go-v2/service/schemas v1.34.4/go.mod h1:Jh8sCBsi4eHPDgfjF8eGilyd+/IqNG69DF035k5+luU= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.40.1 h1:w6a0H79HrHf3lr+zrw+pSzR5B+caiQFAKiNHlrUcnoc= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.40.1/go.mod h1:c6Vg0BRiU7v0MVhHupw90RyL120QBwAMLbDCzptGeMk= +github.com/aws/aws-sdk-go-v2/service/securityhub v1.66.0 h1:pHds0NVhV7qN/G4aYmtTk9AS3J/HQOr0gj5tvsImZw0= +github.com/aws/aws-sdk-go-v2/service/securityhub v1.66.0/go.mod h1:QO1Dvdr9q8oznnqvgiaBiOknf4wRGLeFwTeNzZygVJ0= +github.com/aws/aws-sdk-go-v2/service/securitylake v1.25.5 h1:n/fbZlHabKIPumugkmxQW4YROXiMiV054sWfRHSdU5Y= +github.com/aws/aws-sdk-go-v2/service/securitylake v1.25.5/go.mod h1:La7W0rY+7xl6lWNwXv8ObtNPASUrDYpF5UMxbre2dSI= +github.com/aws/aws-sdk-go-v2/service/serverlessapplicationrepository v1.30.4 h1:mnWXxYJifdPWGqlbTVeVGzMgX25lrByujN5i0Go+2dY= +github.com/aws/aws-sdk-go-v2/service/serverlessapplicationrepository v1.30.4/go.mod h1:txPCrDnWp0uu8qk/45C8Ns1gAEJWJmu1Eb4N9KxVLnI= +github.com/aws/aws-sdk-go-v2/service/servicecatalog v1.39.4 h1:D6D+o1LFhk2nas48FougSlFWko+7adW6bIMJYcLFyZQ= +github.com/aws/aws-sdk-go-v2/service/servicecatalog v1.39.4/go.mod h1:fUe3hv3clT//lFnT+LypAdDSyGhtf2ryDUbJmDSJvTc= +github.com/aws/aws-sdk-go-v2/service/servicecatalogappregistry v1.35.13 h1:Mp0R88cpSQ4XzD3VhvCY2lrNlD/+kQVo4H+nd3fSzBg= +github.com/aws/aws-sdk-go-v2/service/servicecatalogappregistry v1.35.13/go.mod h1:OvveqO8xNyzhEjtXvYeB+3M07sqBpIdQlAiyA/vpGOk= +github.com/aws/aws-sdk-go-v2/service/servicediscovery v1.39.17 h1:ITbjAlXNOkkawki6h3pqQvbiT216gxuoA5CfmjJW8pw= +github.com/aws/aws-sdk-go-v2/service/servicediscovery v1.39.17/go.mod h1:3rS31ijj+ZlrPMQwOgxE3KVUwrzl/InN6U2/2qH+WHg= +github.com/aws/aws-sdk-go-v2/service/servicequotas v1.33.8 h1:ea1fG2JoUwFiIWQiRCtA5qhPZSqWHQjWVtuF01oUlKE= +github.com/aws/aws-sdk-go-v2/service/servicequotas v1.33.8/go.mod h1:IvHDV/gvL+WAsJPytSpXWX6SAL8JGIAf+OQhc/1my1w= +github.com/aws/aws-sdk-go-v2/service/ses v1.34.12 h1:q1UruiOpAbJuHKH/WsGuHkXKQL1TwJB0KOTYu5fs0Jk= +github.com/aws/aws-sdk-go-v2/service/ses v1.34.12/go.mod h1:w+iUMP1i8+1u4wO6QjfdfqPFXGQV5Qy5qK+c3/rcYDg= +github.com/aws/aws-sdk-go-v2/service/sesv2 v1.54.5 h1:TZlN0yXMnlqssHwrIWGdpCioZDq1SEunhOEKazXFjss= +github.com/aws/aws-sdk-go-v2/service/sesv2 v1.54.5/go.mod h1:Ba7wqTP7zxhjWIW7IU3l7ctI5nynyVVZ6k3dznWGE3s= +github.com/aws/aws-sdk-go-v2/service/sfn v1.40.1 h1:pL8r2p6surW9kdCllZDoEsR2dC/+Eu/mwqYdImsGE28= +github.com/aws/aws-sdk-go-v2/service/sfn v1.40.1/go.mod h1:SfQJec/CUwt2weEeSHMXxqaIoDafaWTdKjcHqkJ+OVc= +github.com/aws/aws-sdk-go-v2/service/shield v1.34.13 h1:jzBe45jJuCXibwxqWwhpcHnHOOEaFf7sCBjPoYIE7l0= +github.com/aws/aws-sdk-go-v2/service/shield v1.34.13/go.mod h1:58GIJDFNCraKixtFWBf/3rMuHp1QcrhwDl+WP5vnBjo= +github.com/aws/aws-sdk-go-v2/service/signer v1.31.13 h1:XV3XaGNIIPWiTE5/DyEKWrEX8Szw5Q18y7Y6+6n5mlQ= +github.com/aws/aws-sdk-go-v2/service/signer v1.31.13/go.mod h1:G+ybTyGiY54z/i1aMXNErPGhKv/AHTXWgkoi1jarwK8= +github.com/aws/aws-sdk-go-v2/service/signin v1.0.1 h1:BDgIUYGEo5TkayOWv/oBLPphWwNm/A91AebUjAu5L5g= +github.com/aws/aws-sdk-go-v2/service/signin v1.0.1/go.mod h1:iS6EPmNeqCsGo+xQmXv0jIMjyYtQfnwg36zl2FwEouk= +github.com/aws/aws-sdk-go-v2/service/sns v1.39.6 h1:8s+1N633s5iFerufb10Dr2wa52zuWbVO1PCynr6XjV8= +github.com/aws/aws-sdk-go-v2/service/sns v1.39.6/go.mod h1:gFahrattA8ulEtiS4XL/fQiQ77l+Urc52Y96/r1e6ks= +github.com/aws/aws-sdk-go-v2/service/sqs v1.42.16 h1:WQuccuCHV4wvJ0+pGeA38c78oKXBqz7ccN/u8CM/nhE= +github.com/aws/aws-sdk-go-v2/service/sqs v1.42.16/go.mod h1:ZxqweFQ2w6NNznWMUvWV9AvkAfM6J8F/MC250Mb4n1I= +github.com/aws/aws-sdk-go-v2/service/ssm v1.67.3 h1:ofiQvKwka2E3T8FXBsU1iWj7Yvk2wd1p4ZCdS6qGiKQ= +github.com/aws/aws-sdk-go-v2/service/ssm v1.67.3/go.mod h1:+nlWvcgDPQ56mChEBzTC0puAMck+4onOFaHg5cE+Lgg= +github.com/aws/aws-sdk-go-v2/service/ssmcontacts v1.31.6 h1:iMVZS8c9bNAqQW7qVc/ZEe+0BsHn+ECWtBDTFWjOj/A= +github.com/aws/aws-sdk-go-v2/service/ssmcontacts v1.31.6/go.mod h1:xgrX3CK8h0vKQMp/6Wsefx4wiZSqW+ByE3dnPsaHGt4= +github.com/aws/aws-sdk-go-v2/service/ssmincidents v1.39.12 h1:lpXM1buRbsNbbQmGKUEUQ3gwIi9QBIRelB0wDcuRWGw= +github.com/aws/aws-sdk-go-v2/service/ssmincidents v1.39.12/go.mod h1:8n5J1fKTYwbb2TRgE0siw4FeJ0+odR9Nx9kEKdvVVow= +github.com/aws/aws-sdk-go-v2/service/ssmquicksetup v1.8.13 h1:F6LGJuob6D2KmJa85gwLBwlHW7CRJN+13j9WxELrTY0= +github.com/aws/aws-sdk-go-v2/service/ssmquicksetup v1.8.13/go.mod h1:HdhKpfbmLfWqt10AGTmMGkxy8n8YNuONYWnYFEPOll0= +github.com/aws/aws-sdk-go-v2/service/ssmsap v1.25.12 h1:w6LJhDIEPsjvaeh6MgVDq4U7AxoVR5WFyMaBgD6AF1g= +github.com/aws/aws-sdk-go-v2/service/ssmsap v1.25.12/go.mod h1:NQQlr4JSL0fmJxKE6fE84cHEz+Jl7+WMNIx3kTDbT5s= +github.com/aws/aws-sdk-go-v2/service/sso v1.30.4 h1:U//SlnkE1wOQiIImxzdY5PXat4Wq+8rlfVEw4Y7J8as= +github.com/aws/aws-sdk-go-v2/service/sso v1.30.4/go.mod h1:av+ArJpoYf3pgyrj6tcehSFW+y9/QvAY8kMooR9bZCw= +github.com/aws/aws-sdk-go-v2/service/ssoadmin v1.36.9 h1:g86uQ28zGQ/EQe8rcb4cqi9V0HXmLwNm3igeWJDQOB8= +github.com/aws/aws-sdk-go-v2/service/ssoadmin v1.36.9/go.mod h1:/whnzb8vdsOOiXghELNVyLOYbgbT1dQ5bqanTxFhm4s= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.8 h1:MvlNs/f+9eM0mOjD9JzBUbf5jghyTk3p+O9yHMXX94Y= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.8/go.mod h1:/j67Z5XBVDx8nZVp9EuFM9/BS5dvBznbqILGuu73hug= +github.com/aws/aws-sdk-go-v2/service/storagegateway v1.43.5 h1:LnjZ10PxR2jdEwlhKwONVT94XNLHrcI+ggvevlpx2iU= +github.com/aws/aws-sdk-go-v2/service/storagegateway v1.43.5/go.mod h1:n/pED5o/1PwNMwXbNBZ3TGJc+Wl5tw2vfJtmTgXZIPc= +github.com/aws/aws-sdk-go-v2/service/sts v1.41.1 h1:GdGmKtG+/Krag7VfyOXV17xjTCz0i9NT+JnqLTOI5nA= +github.com/aws/aws-sdk-go-v2/service/sts v1.41.1/go.mod h1:6TxbXoDSgBQ225Qd8Q+MbxUxUh6TtNKwbRt/EPS9xso= +github.com/aws/aws-sdk-go-v2/service/swf v1.33.7 h1:q9qGfvj5z3UYoC32Iam9ErWCOIfcrP+D3QuWxcRRrJU= +github.com/aws/aws-sdk-go-v2/service/swf v1.33.7/go.mod h1:n2f9dMgQHVocWs3c5vcHoO8VENaRixfjpiaMxB5B/ng= +github.com/aws/aws-sdk-go-v2/service/synthetics v1.42.5 h1:7f4OkoIFVz7dAhWHzH0LUiuGu8F7cMyK/YHPUo32Is0= +github.com/aws/aws-sdk-go-v2/service/synthetics v1.42.5/go.mod h1:5HkdZ/qGBpTHwDxaAiC7+B9HeLCDloMk7ugzUD4DZsc= +github.com/aws/aws-sdk-go-v2/service/taxsettings v1.16.13 h1:m0FGv5sQQFrxtKN6vpNq9aKYScFHjy66C4Zq1mHl9nY= +github.com/aws/aws-sdk-go-v2/service/taxsettings v1.16.13/go.mod h1:ZICkAgNrD7k63wZg8cnN/yIZwFnn73+QxUpjENeTB7k= +github.com/aws/aws-sdk-go-v2/service/timestreaminfluxdb v1.17.7 h1:1h5iikgW0O0lOPzUDwgFBa2l7py0eJBgvkECGNtOBnQ= +github.com/aws/aws-sdk-go-v2/service/timestreaminfluxdb v1.17.7/go.mod h1:EWV93YNSnGlftcPAG3E1JiRntqVtv2q538pQLHjHqRo= +github.com/aws/aws-sdk-go-v2/service/timestreamquery v1.36.6 h1:aeVYvltyK9TLLSthJrHYdqwxQzSj8aEPVw7CKwWm8iE= +github.com/aws/aws-sdk-go-v2/service/timestreamquery v1.36.6/go.mod h1:QZe19kHWe3eSbS+Gpqj9cnAilJUTMwZnXQ94CkCLj9w= +github.com/aws/aws-sdk-go-v2/service/timestreamwrite v1.35.12 h1:5b383+fzv31JLcXjbZ2OK7GvLyEB3cAtPN13vGbFpTw= +github.com/aws/aws-sdk-go-v2/service/timestreamwrite v1.35.12/go.mod h1:a8HKhwshd+PjtMYuo+warkOKK2UOWJRHlZCywkCWwek= +github.com/aws/aws-sdk-go-v2/service/transcribe v1.53.7 h1:jcc7/9JGeusxSFXCFhFU36YY0bbGvkwfFPfAnwsSGBE= +github.com/aws/aws-sdk-go-v2/service/transcribe v1.53.7/go.mod h1:4ZpuKHwzZ9FA7h8uX9+mwUs4nRrQHwYMzFsOH1wW+g0= +github.com/aws/aws-sdk-go-v2/service/transfer v1.67.7 h1:RNDCiJXuHITlOjgczKe79NBLAGhypaUHMLhBrtXMy3w= +github.com/aws/aws-sdk-go-v2/service/transfer v1.67.7/go.mod h1:MUWNVxbIwccAqDVTnRiBFpfzZsgetBdx0oXyKF7YPBQ= +github.com/aws/aws-sdk-go-v2/service/verifiedpermissions v1.30.3 h1:QAKdsrBbGWBUojwN3abkjhtIMcv7tO9/0TX60JNnKNQ= +github.com/aws/aws-sdk-go-v2/service/verifiedpermissions v1.30.3/go.mod h1:DKPC0FQgnE8EHcjmc2hSHtGb8CkQrziGtvwvaLjONJU= +github.com/aws/aws-sdk-go-v2/service/vpclattice v1.20.3 h1:2aGsFMPJV9L6F7Ux7XFXrJ2t3yJetfCnfImoLOOuOUM= +github.com/aws/aws-sdk-go-v2/service/vpclattice v1.20.3/go.mod h1:SUUz0r//mNiaxl+pJylRRopCBJAtJu43GTXuqUBWMLI= +github.com/aws/aws-sdk-go-v2/service/waf v1.30.12 h1:+gVBPjTnJ+VDSht4TAgAArBCQ/3U0ijQGlbtj7FeQMM= +github.com/aws/aws-sdk-go-v2/service/waf v1.30.12/go.mod h1:kbhrm8R19AC3tn7EmqvMx+lbIoIXidY0Iz0bmTmMlWQ= +github.com/aws/aws-sdk-go-v2/service/wafregional v1.30.13 h1:eW6fj6sqBgWpKjkm8g9n2qAhxakpL2FjP9rF54Xwk5g= +github.com/aws/aws-sdk-go-v2/service/wafregional v1.30.13/go.mod h1:nViv+xQD0gblzk2I28ZBO6v4YZm3dyjCW754Tmc3UcM= +github.com/aws/aws-sdk-go-v2/service/wafv2 v1.70.1 h1:2EdpxkkjDz+z7UWmI8bYuVx1y4PlyykhbzhIUB6Q544= +github.com/aws/aws-sdk-go-v2/service/wafv2 v1.70.1/go.mod h1:o5YGYZtdkLM2Jy0MGQ6ZxvYFt8okNf6lMAb9Wn3O5As= +github.com/aws/aws-sdk-go-v2/service/wellarchitected v1.39.13 h1:UOxKsjE+MAKhnJe63tw6ax35dB0/ShUAGwDKig2syTU= +github.com/aws/aws-sdk-go-v2/service/wellarchitected v1.39.13/go.mod h1:hjAi8K+sIOVVbsIkF4su18Gml2DLTZ3T4VM5KvL9Vmw= +github.com/aws/aws-sdk-go-v2/service/workmail v1.36.11 h1:GHzvbrw9spON35BBniFxMN+fg6MNa1aAxWM4ZjBqwWI= +github.com/aws/aws-sdk-go-v2/service/workmail v1.36.11/go.mod h1:zk367N2jAR3ILjECShpUkDqgkS82Zd1Z2EEy+vDMUX8= +github.com/aws/aws-sdk-go-v2/service/workspaces v1.64.5 h1:5rdpVb8ecAo9IiaOMmQIcFnct2NOLMchVTCyGMEysAg= +github.com/aws/aws-sdk-go-v2/service/workspaces v1.64.5/go.mod h1:x/FEB9ZRwxTJ3ef/r4hPnA0E+QFwsxP8bxQHWfrJDRk= +github.com/aws/aws-sdk-go-v2/service/workspacesweb v1.34.1 h1:6X2pC1S8BehTGQQvJr85ia9cEbF/1+x+PjeY90Etzmo= +github.com/aws/aws-sdk-go-v2/service/workspacesweb v1.34.1/go.mod h1:Jp186sz4W1dlIrkBAK6sn5xq0U1nPSA7EdeHsmb/uuc= +github.com/aws/aws-sdk-go-v2/service/xray v1.36.12 h1:nqn56yOJ2/r6WxIBMRT/bT0I2rBOHAy7D68Pxvwo6qo= +github.com/aws/aws-sdk-go-v2/service/xray v1.36.12/go.mod h1:1hlRhW+26LYxyR7Oy2One3agC/jU4DhiPFdDniFBL6s= github.com/aws/smithy-go v1.23.2 h1:Crv0eatJUQhaManss33hS5r40CG3ZFH+21XSkqMrIUM= github.com/aws/smithy-go v1.23.2/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0= github.com/beevik/etree v1.6.0 h1:u8Kwy8pp9D9XeITj2Z0XtA5qqZEmtJtuXZRQi+j03eE= @@ -819,8 +821,8 @@ go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42s 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.44.0 h1:A97SsFvM3AIwEEmTBiaxPPTYpDC47w720rdiiUvgoAU= -golang.org/x/crypto v0.44.0/go.mod h1:013i+Nw79BMiQiMsOPcVCB5ZIJbYkerPrGnOa00tvmc= +golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= +golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= golang.org/x/exp v0.0.0-20220921023135-46d9e7742f1e h1:Ctm9yurWsg7aWwIpH9Bnap/IdSVxixymIb3MhiMEQQA= golang.org/x/exp v0.0.0-20220921023135-46d9e7742f1e/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= diff --git a/internal/acctest/acctest.go b/internal/acctest/acctest.go index 0428f5ecdedb..19633ed781db 100644 --- a/internal/acctest/acctest.go +++ b/internal/acctest/acctest.go @@ -36,6 +36,7 @@ import ( organizationstypes "github.com/aws/aws-sdk-go-v2/service/organizations/types" "github.com/aws/aws-sdk-go-v2/service/outposts" "github.com/aws/aws-sdk-go-v2/service/pinpoint" + "github.com/aws/aws-sdk-go-v2/service/resourcegroupstaggingapi" "github.com/aws/aws-sdk-go-v2/service/ssoadmin" ssoadmintypes "github.com/aws/aws-sdk-go-v2/service/ssoadmin/types" "github.com/aws/aws-sdk-go-v2/service/wafv2" @@ -1284,6 +1285,23 @@ func PreCheckRegionOptIn(ctx context.Context, t *testing.T, region string) { } } +func PreCheckResourceGroupsTaggingAPIRequiredTags(ctx context.Context, t *testing.T) { + t.Helper() + + conn := Provider.Meta().(*conns.AWSClient).ResourceGroupsTaggingAPIClient(ctx) + input := resourcegroupstaggingapi.ListRequiredTagsInput{} + + output, err := conn.ListRequiredTags(ctx, &input) + if err != nil { + t.Skipf("listing required tags: %s", err) + } + + // Ensure some required tags are configured + if output == nil || len(output.RequiredTags) == 0 { + t.Skip("no required tags found") + } +} + func PreCheckSSOAdminInstances(ctx context.Context, t *testing.T) { PreCheckSSOAdminInstancesWithRegion(ctx, t, Region()) } @@ -1292,7 +1310,7 @@ func PreCheckSSOAdminInstancesWithRegion(ctx context.Context, t *testing.T, regi t.Helper() // Push region into Context. - ctx = conns.NewResourceContext(ctx, "", "", region) + ctx = conns.NewResourceContext(ctx, "", "", "", region) conn := Provider.Meta().(*conns.AWSClient).SSOAdminClient(ctx) input := ssoadmin.ListInstancesInput{} var instances []ssoadmintypes.InstanceMetadata @@ -1898,19 +1916,19 @@ func CheckACMPCACertificateAuthorityActivateRootCA(ctx context.Context, certific return fmt.Errorf("attempting to activate ACM PCA %s Certificate Authority", v) } - arn := aws.ToString(certificateAuthority.Arn) + caARN := aws.ToString(certificateAuthority.Arn) getCSRInput := acmpca.GetCertificateAuthorityCsrInput{ - CertificateAuthorityArn: aws.String(arn), + CertificateAuthorityArn: aws.String(caARN), } getCsrOutput, err := conn.GetCertificateAuthorityCsr(ctx, &getCSRInput) if err != nil { - return fmt.Errorf("getting ACM PCA Certificate Authority (%s) CSR: %w", arn, err) + return fmt.Errorf("getting ACM PCA Certificate Authority (%s) CSR: %w", caARN, err) } issueCertInput := acmpca.IssueCertificateInput{ - CertificateAuthorityArn: aws.String(arn), + CertificateAuthorityArn: aws.String(caARN), Csr: []byte(aws.ToString(getCsrOutput.Csr)), IdempotencyToken: aws.String(id.UniqueId()), SigningAlgorithm: certificateAuthority.CertificateAuthorityConfiguration.SigningAlgorithm, @@ -1922,26 +1940,28 @@ func CheckACMPCACertificateAuthorityActivateRootCA(ctx context.Context, certific } issueCertOutput, err := conn.IssueCertificate(ctx, &issueCertInput) if err != nil { - return fmt.Errorf("issuing ACM PCA Certificate Authority (%s) Root CA certificate from CSR: %w", arn, err) + return fmt.Errorf("issuing ACM PCA Certificate Authority (%s) Root CA certificate from CSR: %w", caARN, err) } + caCertARN := aws.ToString(issueCertOutput.CertificateArn) + // Wait for certificate status to become ISSUED. getCertOutput, err := tfresource.RetryWhenIsA[*acmpca.GetCertificateOutput, *acmpcatypes.RequestInProgressException](ctx, CertificateIssueTimeout, func(ctx context.Context) (*acmpca.GetCertificateOutput, error) { - return tfacmpca.FindCertificateByTwoPartKey(ctx, conn, arn, aws.ToString(issueCertOutput.CertificateArn)) + return tfacmpca.FindCertificateByTwoPartKey(ctx, conn, caCertARN, caARN) }) if err != nil { - return fmt.Errorf("waiting for ACM PCA Certificate Authority (%s) Root CA certificate to become ISSUED: %w", arn, err) + return fmt.Errorf("waiting for ACM PCA Certificate Authority (%s) Root CA certificate (%s) to become ISSUED: %w", caARN, caCertARN, err) } importCACertificateInput := acmpca.ImportCertificateAuthorityCertificateInput{ - CertificateAuthorityArn: aws.String(arn), + CertificateAuthorityArn: aws.String(caARN), Certificate: []byte(aws.ToString(getCertOutput.Certificate)), } _, err = conn.ImportCertificateAuthorityCertificate(ctx, &importCACertificateInput) if err != nil { - return fmt.Errorf("importing ACM PCA Certificate Authority (%s) Root CA certificate: %w", arn, err) + return fmt.Errorf("importing ACM PCA Certificate Authority (%s) Root CA certificate: %w", caARN, err) } return err @@ -1956,21 +1976,21 @@ func CheckACMPCACertificateAuthorityActivateSubordinateCA(ctx context.Context, r return fmt.Errorf("attempting to activate ACM PCA %s Certificate Authority", v) } - arn := aws.ToString(certificateAuthority.Arn) + caARN := aws.ToString(certificateAuthority.Arn) getCSRInput := acmpca.GetCertificateAuthorityCsrInput{ - CertificateAuthorityArn: aws.String(arn), + CertificateAuthorityArn: aws.String(caARN), } getCsrOutput, err := conn.GetCertificateAuthorityCsr(ctx, &getCSRInput) if err != nil { - return fmt.Errorf("getting ACM PCA Certificate Authority (%s) CSR: %w", arn, err) + return fmt.Errorf("getting ACM PCA Certificate Authority (%s) CSR: %w", caARN, err) } - rootCertificateAuthorityArn := aws.ToString(rootCertificateAuthority.Arn) + rootCAARN := aws.ToString(rootCertificateAuthority.Arn) issueCertInput := acmpca.IssueCertificateInput{ - CertificateAuthorityArn: aws.String(rootCertificateAuthorityArn), + CertificateAuthorityArn: aws.String(rootCAARN), Csr: []byte(aws.ToString(getCsrOutput.Csr)), IdempotencyToken: aws.String(id.UniqueId()), SigningAlgorithm: certificateAuthority.CertificateAuthorityConfiguration.SigningAlgorithm, @@ -1982,27 +2002,29 @@ func CheckACMPCACertificateAuthorityActivateSubordinateCA(ctx context.Context, r } issueCertOutput, err := conn.IssueCertificate(ctx, &issueCertInput) if err != nil { - return fmt.Errorf("issuing ACM PCA Certificate Authority (%s) Subordinate CA certificate from CSR: %w", arn, err) + return fmt.Errorf("issuing ACM PCA Certificate Authority (%s) Subordinate CA certificate from CSR: %w", caARN, err) } + caCertARN := aws.ToString(issueCertOutput.CertificateArn) + // Wait for certificate status to become ISSUED. getCertOutput, err := tfresource.RetryWhenIsA[*acmpca.GetCertificateOutput, *acmpcatypes.RequestInProgressException](ctx, CertificateIssueTimeout, func(ctx context.Context) (*acmpca.GetCertificateOutput, error) { - return tfacmpca.FindCertificateByTwoPartKey(ctx, conn, rootCertificateAuthorityArn, aws.ToString(issueCertOutput.CertificateArn)) + return tfacmpca.FindCertificateByTwoPartKey(ctx, conn, caCertARN, rootCAARN) }) if err != nil { - return fmt.Errorf("waiting for ACM PCA Certificate Authority (%s) Subordinate CA certificate (%s) to become ISSUED: %w", arn, aws.ToString(issueCertOutput.CertificateArn), err) + return fmt.Errorf("waiting for ACM PCA Certificate Authority (%s) Subordinate CA certificate (%s) to become ISSUED: %w", caARN, caCertARN, err) } importCACertificateInput := acmpca.ImportCertificateAuthorityCertificateInput{ - CertificateAuthorityArn: aws.String(arn), + CertificateAuthorityArn: aws.String(caARN), Certificate: []byte(aws.ToString(getCertOutput.Certificate)), CertificateChain: []byte(aws.ToString(getCertOutput.CertificateChain)), } _, err = conn.ImportCertificateAuthorityCertificate(ctx, &importCACertificateInput) if err != nil { - return fmt.Errorf("importing ACM PCA Certificate Authority (%s) Subordinate CA certificate: %w", arn, err) + return fmt.Errorf("importing ACM PCA Certificate Authority (%s) Subordinate CA certificate: %w", caARN, err) } return err diff --git a/internal/acctest/configs.go b/internal/acctest/configs.go index 5e7d1c11a89a..26fbea8bf988 100644 --- a/internal/acctest/configs.go +++ b/internal/acctest/configs.go @@ -182,6 +182,33 @@ provider "aws" { `, key1) } +// ConfigTagPolicyCompliance enables tag policy enforcement with the provided severity +func ConfigTagPolicyCompliance(severity string) string { + //lintignore:AT004 + return fmt.Sprintf(` +provider "aws" { + tag_policy_compliance = %[1]q +} +`, severity) +} + +// ConfigTagPolicyComplianceAndDefaultTags1 enables tag policy enforcement with the +// provided severity and a default tag +func ConfigTagPolicyComplianceAndDefaultTags1(severity, key1, value1 string) string { + //lintignore:AT004 + return fmt.Sprintf(` +provider "aws" { + tag_policy_compliance = %[1]q + + default_tags { + tags = { + %[2]s = %[3]q + } + } +} +`, severity, key1, value1) +} + func ConfigWithEchoProvider(ephemeralResourceData string) string { //lintignore:AT004 return fmt.Sprintf(` diff --git a/internal/acctest/statecheck/full_tags.go b/internal/acctest/statecheck/full_tags.go index 153fac5ae4b7..f1dee8aa2204 100644 --- a/internal/acctest/statecheck/full_tags.go +++ b/internal/acctest/statecheck/full_tags.go @@ -62,7 +62,7 @@ func (e expectFullTagsCheck) CheckState(ctx context.Context, req statecheck.Chec return } - ctx = tftags.NewContext(ctx, nil, nil) + ctx = tftags.NewContext(ctx, nil, nil, nil) var err error if v, ok := sp.(tftags.ServiceTagLister); ok { diff --git a/internal/conns/awsclient.go b/internal/conns/awsclient.go index 93aca9b3ee53..12aa747442be 100644 --- a/internal/conns/awsclient.go +++ b/internal/conns/awsclient.go @@ -42,6 +42,7 @@ type AWSClient struct { s3UsePathStyle bool // From provider configuration. s3USEast1RegionalEndpoint string // From provider configuration. stsRegion string // From provider configuration. + tagPolicyConfig *tftags.TagPolicyConfig terraformVersion string // From provider configuration. } @@ -81,6 +82,10 @@ func (c *AWSClient) IgnoreTagsConfig(context.Context) *tftags.IgnoreConfig { return c.ignoreTagsConfig } +func (c *AWSClient) TagPolicyConfig(context.Context) *tftags.TagPolicyConfig { + return c.tagPolicyConfig +} + func (c *AWSClient) AwsConfig(context.Context) aws.Config { // nosemgrep:ci.aws-in-func-name return c.awsConfig.Copy() } diff --git a/internal/conns/awsclient_test.go b/internal/conns/awsclient_test.go index 7f7399f0ff86..ae5459cf4608 100644 --- a/internal/conns/awsclient_test.go +++ b/internal/conns/awsclient_test.go @@ -243,7 +243,7 @@ func TestAWSClientValidateInContextRegionInPartition(t *testing.T) { // nosemgre t.Run(testCase.Name, func(t *testing.T) { t.Parallel() - ctx = NewResourceContext(ctx, "test", "Test", testCase.Region) + ctx = NewResourceContext(ctx, "test", "Test", "aws_test_test", testCase.Region) err := testCase.AWSClient.ValidateInContextRegionInPartition(ctx) if got := err == nil; got != testCase.Expected { diff --git a/internal/conns/config.go b/internal/conns/config.go index 6c47241c1150..90f85d5a691f 100644 --- a/internal/conns/config.go +++ b/internal/conns/config.go @@ -21,6 +21,7 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/errs" "github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag" tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" + "github.com/hashicorp/terraform-provider-aws/internal/tags/tagpolicy" "github.com/hashicorp/terraform-provider-aws/names" "github.com/hashicorp/terraform-provider-aws/version" ) @@ -56,6 +57,7 @@ type Config struct { SkipRequestingAccountId bool STSRegion string SuppressDebugLog bool + TagPolicyConfig *tftags.TagPolicyConfig TerraformVersion string Token string TokenBucketRateLimiterCapacity int @@ -191,9 +193,25 @@ func (c *Config) ConfigureProvider(ctx context.Context, client *AWSClient) (*AWS } } + // Fetch tag policy details when enforced + if c.TagPolicyConfig != nil { + tflog.Debug(ctx, "Retrieving tag policy details") + reqTags, err := tagpolicy.GetRequiredTags(ctx, cfg) + if err != nil { + diags = append(diags, errs.NewErrorDiagnostic( + "Retrieving Required Tags", + `Failed to retrieve required tags from the organizations tag policies. Ensure the calling principal `+ + `has the "tag:ListRequiredTags" IAM permission and that tag policies are attached to the target account.`+ + fmt.Sprintf("\n\nOriginal error: %s", err))) + return nil, diags + } + c.TagPolicyConfig.RequiredTags = reqTags + } + client.accountID = accountID client.defaultTagsConfig = c.DefaultTagsConfig client.ignoreTagsConfig = c.IgnoreTagsConfig + client.tagPolicyConfig = c.TagPolicyConfig client.terraformVersion = c.TerraformVersion // Used for lazy-loading AWS API clients. diff --git a/internal/conns/conns.go b/internal/conns/conns.go index c824c3d33b20..075c5c7333ec 100644 --- a/internal/conns/conns.go +++ b/internal/conns/conns.go @@ -57,6 +57,7 @@ var ( type InContext struct { overrideRegion string // Any currently in effect per-resource Region override. resourceName string // Friendly resource name, e.g. "Subnet" + typeName string // Resource type name, e.g. "aws_iam_role" servicePackageName string // Canonical name defined as a constant in names package vcrEnabled bool // Whether VCR testing is enabled } @@ -71,6 +72,11 @@ func (c *InContext) ResourceName() string { return c.resourceName } +// TypeName returns the resource type name, e.g. "aws_iam_role". +func (c *InContext) TypeName() string { + return c.typeName +} + // ServicePackageName returns the canonical service name defined as a constant in the `names` package. func (c *InContext) ServicePackageName() string { return c.servicePackageName @@ -81,10 +87,11 @@ func (c *InContext) VCREnabled() bool { return c.vcrEnabled } -func NewResourceContext(ctx context.Context, servicePackageName, resourceName, overrideRegion string) context.Context { +func NewResourceContext(ctx context.Context, servicePackageName, resourceName, typeName, overrideRegion string) context.Context { v := InContext{ overrideRegion: overrideRegion, resourceName: resourceName, + typeName: typeName, servicePackageName: servicePackageName, vcrEnabled: vcr.IsEnabled(), } diff --git a/internal/framework/list_resource_with_sdkv2_tags.go b/internal/framework/list_resource_with_sdkv2_tags.go index 03f017a0c4b8..108957811612 100644 --- a/internal/framework/list_resource_with_sdkv2_tags.go +++ b/internal/framework/list_resource_with_sdkv2_tags.go @@ -23,7 +23,7 @@ func (r *ListResourceWithSDKv2Tags) SetTagsSpec(tags unique.Handle[inttypes.Serv } func (r *ListResourceWithSDKv2Tags) SetTags(ctx context.Context, client *conns.AWSClient, d *schema.ResourceData) error { - sp, _, _, tagsInContext, ok := interceptors.InfoFromContext(ctx, client) + sp, _, _, _, tagsInContext, ok := interceptors.InfoFromContext(ctx, client) if !ok { return nil } diff --git a/internal/generate/attrconsts/constOrQuote.gtpl b/internal/generate/attrconsts/constOrQuote.gtpl index c21965e30d55..076dbed211af 100644 --- a/internal/generate/attrconsts/constOrQuote.gtpl +++ b/internal/generate/attrconsts/constOrQuote.gtpl @@ -12,6 +12,10 @@ import ( // Otherwise, it returns the attribute quoted. This is intended for use in // generated code and templates. func ConstOrQuote(constant string) string { + if constant == "" { + return "" + } + allConstants := map[string]string{ {{- range .Constants }} "{{ .Literal }}": "Attr{{ .Constant }}", diff --git a/internal/generate/common/resource_identity.go b/internal/generate/common/resource_identity.go new file mode 100644 index 000000000000..face50439971 --- /dev/null +++ b/internal/generate/common/resource_identity.go @@ -0,0 +1,271 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package common + +import ( + "errors" + "fmt" + "slices" + "strconv" + "strings" + + tfslices "github.com/hashicorp/terraform-provider-aws/internal/slices" + namesgen "github.com/hashicorp/terraform-provider-aws/names/generate" +) + +type TriBoolean uint + +const ( + TriBooleanUnset TriBoolean = iota + TriBooleanTrue + TriBooleanFalse +) + +func TriBool(b bool) TriBoolean { + if b { + return TriBooleanTrue + } else { + return TriBooleanFalse + } +} + +type Implementation string + +const ( + ImplementationFramework Implementation = "framework" + ImplementationSDK Implementation = "sdk" +) + +type ResourceIdentity struct { + isARNIdentity bool + isCustomInherentRegionIdentity bool + isSingletonIdentity bool + identityAttributeName string + IdentityDuplicateAttrNames []string + IdentityAttributes []IdentityAttribute + MutableIdentity bool + IdentityVersion int64 + SDKv2IdentityUpgraders []string + CustomInherentRegionParser string + HasV6_0NullValuesError bool + HasV6_0RefreshError bool +} + +func (r ResourceIdentity) HasResourceIdentity() bool { + return r.IsParameterizedIdentity() || r.isARNIdentity || r.isSingletonIdentity || r.isCustomInherentRegionIdentity +} + +func (r ResourceIdentity) HasInherentRegionIdentity() bool { + return r.isARNIdentity || r.isCustomInherentRegionIdentity +} + +func (r ResourceIdentity) IsARNIdentity() bool { + return r.isARNIdentity +} + +func (r ResourceIdentity) IsCustomInherentRegionIdentity() bool { + return r.isCustomInherentRegionIdentity +} + +func (r ResourceIdentity) IsParameterizedIdentity() bool { + return len(r.IdentityAttributes) > 0 +} + +func (r ResourceIdentity) IsSingletonIdentity() bool { + return r.isSingletonIdentity +} + +func (r ResourceIdentity) IdentityAttribute() string { + return namesgen.ConstOrQuote(r.IdentityAttributeName()) +} + +func (r ResourceIdentity) IdentityAttributeName() string { + return r.identityAttributeName +} + +func (r ResourceIdentity) HasIdentityDuplicateAttrs() bool { + return len(r.IdentityDuplicateAttrNames) > 0 +} + +func (r ResourceIdentity) IdentityDuplicateAttrs() []string { + return tfslices.ApplyToAll(r.IdentityDuplicateAttrNames, func(s string) string { + return namesgen.ConstOrQuote(s) + }) +} + +type IdentityAttribute struct { + Name_ string + Optional bool + ResourceAttributeName_ string + TestNotNull bool +} + +func (a IdentityAttribute) Name() string { + return namesgen.ConstOrQuote(a.Name_) +} + +func (a IdentityAttribute) ResourceAttributeName() string { + return namesgen.ConstOrQuote(a.ResourceAttributeName_) +} + +func ParseResourceIdentity(annotationName string, args Args, implementation Implementation, d *ResourceIdentity, goImports *[]GoImport) error { + switch annotationName { + case "ArnIdentity": + d.isARNIdentity = true + if len(args.Positional) == 0 { + d.identityAttributeName = "arn" + } else { + d.identityAttributeName = args.Positional[0] + } + + parseIdentityDuplicateAttrNames(args, implementation, d) + + case "CustomInherentRegionIdentity": + d.isCustomInherentRegionIdentity = true + + if len(args.Positional) < 2 { + return errors.New("CustomInherentRegionIdentity missing required parameters") + } + + d.identityAttributeName = args.Positional[0] + + parseIdentityDuplicateAttrNames(args, implementation, d) + + attr := args.Positional[1] + if funcName, importSpec, err := ParseIdentifierSpec(attr); err != nil { + return fmt.Errorf("%q: %w", attr, err) + } else { + d.CustomInherentRegionParser = funcName + if importSpec != nil { + *goImports = append(*goImports, *importSpec) + } + } + + case "IdentityAttribute": + if len(args.Positional) == 0 { + return errors.New("no Identity attribute name") + } + + identityAttribute := IdentityAttribute{ + Name_: args.Positional[0], + } + + if attr, ok := args.Keyword["optional"]; ok { + if b, err := ParseBoolAttr("optional", attr); err != nil { + return err + } else { + identityAttribute.Optional = b + } + } + + if attr, ok := args.Keyword["resourceAttributeName"]; ok { + identityAttribute.ResourceAttributeName_ = attr + } + + if attr, ok := args.Keyword["testNotNull"]; ok { + if b, err := ParseBoolAttr("testNotNull", attr); err != nil { + return err + } else { + identityAttribute.TestNotNull = b + } + } + + d.IdentityAttributes = append(d.IdentityAttributes, identityAttribute) + + case "IdentityVersion": + attr := args.Positional[0] + if i, err := strconv.ParseInt(attr, 10, 64); err != nil { + return fmt.Errorf("invalid IdentityVersion value: %q. Should be integer value.", attr) + } else { + d.IdentityVersion = i + } + + if attr, ok := args.Keyword["sdkV2IdentityUpgraders"]; ok { + attrs := strings.Split(attr, ";") + d.SDKv2IdentityUpgraders = attrs + } + + case "MutableIdentity": + d.MutableIdentity = true + + case "SingletonIdentity": + d.isSingletonIdentity = true + + // FIXME: Not actually for Global, but the value is never used + d.identityAttributeName = "region" + + parseIdentityDuplicateAttrNames(args, implementation, d) + + // TODO: allow underscore? + case "V60SDKv2Fix": + d.HasV6_0NullValuesError = true + + if attr, ok := args.Keyword["v60RefreshError"]; ok { + if b, err := ParseBoolAttr("v60RefreshError", attr); err != nil { + return err + } else { + d.HasV6_0RefreshError = b + } + } + } + + return nil +} + +type GoImport struct { + Path string + Alias string +} + +func ParseIdentifierSpec(s string) (string, *GoImport, error) { + parts := strings.Split(s, ";") + switch len(parts) { + case 1: + return parts[0], nil, nil + + case 2: + return parts[1], &GoImport{ + Path: parts[0], + }, nil + + case 3: + return parts[2], &GoImport{ + Path: parts[0], + Alias: parts[1], + }, nil + + default: + return "", nil, fmt.Errorf("invalid generator value: %q", s) + } +} + +func ParseBoolAttr(name, value string) (bool, error) { + if b, err := strconv.ParseBool(value); err != nil { + return b, fmt.Errorf("invalid %s value %q: Should be boolean value.", name, value) + } else { + return b, nil + } +} + +func parseIdentityDuplicateAttrNames(args Args, implementation Implementation, d *ResourceIdentity) { + var attrs []string + if attr, ok := args.Keyword["identityDuplicateAttributes"]; ok { + attrs = strings.Split(attr, ";") + } + if implementation == ImplementationSDK { + attrs = append(attrs, "id") + } + + // Sort `id` to first position, the rest alphabetically + slices.SortFunc(attrs, func(a, b string) int { + if a == "id" { + return -1 + } else if b == "id" { + return 1 + } else { + return strings.Compare(a, b) + } + }) + d.IdentityDuplicateAttrNames = slices.Compact(attrs) +} diff --git a/internal/generate/identitytests/main.go b/internal/generate/identitytests/main.go index 113f91e3061d..b737f5ff2b41 100644 --- a/internal/generate/identitytests/main.go +++ b/internal/generate/identitytests/main.go @@ -27,7 +27,6 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/generate/common" "github.com/hashicorp/terraform-provider-aws/internal/generate/tests" tfmaps "github.com/hashicorp/terraform-provider-aws/internal/maps" - tfslices "github.com/hashicorp/terraform-provider-aws/internal/slices" "github.com/hashicorp/terraform-provider-aws/names/data" namesgen "github.com/hashicorp/terraform-provider-aws/names/generate" ) @@ -107,12 +106,8 @@ func main() { } if resource.IsGlobal { - if resource.isARNFormatGlobal == triBooleanUnset { - if resource.IsGlobal { - resource.isARNFormatGlobal = triBooleanTrue - } else { - resource.isARNFormatGlobal = triBooleanFalse - } + if resource.isARNFormatGlobal == common.TriBooleanUnset { + resource.isARNFormatGlobal = common.TriBool(resource.IsGlobal) } } @@ -364,38 +359,22 @@ func (sr serviceRecords) ARNNamespace() string { return sr.primary.ARNNamespace() } -type triBoolean uint - -const ( - triBooleanUnset triBoolean = iota - triBooleanTrue - triBooleanFalse -) - type ResourceDatum struct { - service *serviceRecords - FileName string - idAttrDuplicates string // TODO: Remove. Still needed for Parameterized Identity - GenerateConfig bool - ARNFormat string - arnAttribute string - isARNFormatGlobal triBoolean - isARNIdentity bool - MutableIdentity bool - IsGlobal bool - isSingleton bool - HasRegionOverrideTest bool - identityAttributes []identityAttribute - identityAttribute string - IdentityDuplicateAttrs []string - IDAttrFormat string - HasV6_0NullValuesError bool - HasV6_0RefreshError bool - HasNoPreExistingResource bool - PreIdentityVersion *version.Version - IsCustomInherentRegionIdentity bool - IdentityVersions map[int64]*version.Version + service *serviceRecords + FileName string + idAttrDuplicates string // TODO: Remove. Still needed for Parameterized Identity + GenerateConfig bool + ARNFormat string + arnAttribute string + isARNFormatGlobal common.TriBoolean + IsGlobal bool + HasRegionOverrideTest bool + IDAttrFormat string + HasNoPreExistingResource bool + PreIdentityVersion *version.Version + IdentityVersions map[int64]*version.Version tests.CommonArgs + common.ResourceIdentity } func (d ResourceDatum) ProviderPackage() string { @@ -422,12 +401,8 @@ func (d ResourceDatum) IDAttrDuplicates() string { return namesgen.ConstOrQuote(d.idAttrDuplicates) } -func (d ResourceDatum) IsARNIdentity() bool { - return d.isARNIdentity -} - func (d ResourceDatum) IsGlobalARNFormatForRegionalResource() bool { - return d.isARNIdentity && !d.IsGlobal && d.IsARNFormatGlobal() + return d.IsARNIdentity() && !d.IsGlobal && d.IsARNFormatGlobal() } func (d ResourceDatum) ARNAttribute() string { @@ -435,43 +410,23 @@ func (d ResourceDatum) ARNAttribute() string { } func (d ResourceDatum) IsGlobalSingleton() bool { - return d.isSingleton && d.IsGlobal + return d.IsSingletonIdentity() && d.IsGlobal } func (d ResourceDatum) IsRegionalSingleton() bool { - return d.isSingleton && !d.IsGlobal -} - -func (d ResourceDatum) IsSingleton() bool { - return d.isSingleton + return d.IsSingletonIdentity() && !d.IsGlobal } func (d ResourceDatum) GenerateRegionOverrideTest() bool { return !d.IsGlobal && d.HasRegionOverrideTest } -func (d ResourceDatum) HasInherentRegionIdentity() bool { - return d.IsARNIdentity() || d.IsCustomInherentRegionIdentity -} - func (d ResourceDatum) HasInherentRegionImportID() bool { - return d.IsARNIdentity() || d.IsRegionalSingleton() || d.IsCustomInherentRegionIdentity -} - -func (d ResourceDatum) IdentityAttribute() string { - return namesgen.ConstOrQuote(d.identityAttribute) -} - -func (r ResourceDatum) HasIdentityDuplicateAttrs() bool { - return len(r.IdentityDuplicateAttrs) > 0 + return d.IsARNIdentity() || d.IsRegionalSingleton() || d.IsCustomInherentRegionIdentity() } func (r ResourceDatum) IsARNFormatGlobal() bool { - return r.isARNFormatGlobal == triBooleanTrue -} - -func (r ResourceDatum) IdentityAttributes() []identityAttribute { - return r.identityAttributes + return r.isARNFormatGlobal == common.TriBooleanTrue } func (r ResourceDatum) LatestIdentityVersion() int64 { @@ -481,16 +436,6 @@ func (r ResourceDatum) LatestIdentityVersion() int64 { return slices.Max(slices.Collect(maps.Keys(r.IdentityVersions))) } -type identityAttribute struct { - name string - Optional bool - TestNotNull bool -} - -func (i identityAttribute) Name() string { - return namesgen.ConstOrQuote(i.name) -} - type commonConfig struct { AdditionalTfVars []string WithRName bool @@ -580,7 +525,6 @@ func (v *visitor) processFuncDecl(funcDecl *ast.FuncDecl) { HasRegionOverrideTest: true, IdentityVersions: make(map[int64]*version.Version, 0), } - hasIdentity := false skip := false generatorSeen := false tlsKey := false @@ -590,13 +534,12 @@ func (v *visitor) processFuncDecl(funcDecl *ast.FuncDecl) { line := line.Text if m := annotation.FindStringSubmatch(line); len(m) > 0 { - switch annotationName := m[1]; annotationName { + switch annotationName, args := m[1], common.ParseArgs(m[3]); annotationName { case "FrameworkDataSource": break case "FrameworkResource": - d.Implementation = tests.ImplementationFramework - args := common.ParseArgs(m[3]) + d.Implementation = common.ImplementationFramework if len(args.Positional) == 0 { v.errs = append(v.errs, fmt.Errorf("no type name: %s", fmt.Sprintf("%s.%s", v.packageName, v.functionName))) continue @@ -612,8 +555,7 @@ func (v *visitor) processFuncDecl(funcDecl *ast.FuncDecl) { break case "SDKResource": - d.Implementation = tests.ImplementationSDK - args := common.ParseArgs(m[3]) + d.Implementation = common.ImplementationSDK if len(args.Positional) == 0 { v.errs = append(v.errs, fmt.Errorf("no type name: %s", fmt.Sprintf("%s.%s", v.packageName, v.functionName))) continue @@ -625,67 +567,7 @@ func (v *visitor) processFuncDecl(funcDecl *ast.FuncDecl) { d.Name = strings.ReplaceAll(attr, "-", "") } - case "ArnIdentity": - hasIdentity = true - d.isARNIdentity = true - args := common.ParseArgs(m[3]) - if len(args.Positional) == 0 { - d.arnAttribute = "arn" - d.identityAttribute = "arn" - } else { - d.arnAttribute = args.Positional[0] - d.identityAttribute = args.Positional[0] - } - - populateInherentRegionIdentity(&d, args) - - case "CustomInherentRegionIdentity": - hasIdentity = true - d.IsCustomInherentRegionIdentity = true - args := common.ParseArgs(m[3]) - d.identityAttribute = args.Positional[0] - - populateInherentRegionIdentity(&d, args) - - case "IdentityAttribute": - hasIdentity = true - args := common.ParseArgs(m[3]) - if len(args.Positional) == 0 { - v.errs = append(v.errs, fmt.Errorf("no Identity attribute name: %s", fmt.Sprintf("%s.%s", v.packageName, v.functionName))) - continue - } - - identityAttribute := identityAttribute{ - name: args.Positional[0], - } - - if attr, ok := args.Keyword["optional"]; ok { - if b, err := strconv.ParseBool(attr); err != nil { - v.errs = append(v.errs, fmt.Errorf("invalid optional value: %q at %s. Should be boolean value.", attr, fmt.Sprintf("%s.%s", v.packageName, v.functionName))) - continue - } else { - identityAttribute.Optional = b - } - } - - if attr, ok := args.Keyword["testNotNull"]; ok { - if b, err := strconv.ParseBool(attr); err != nil { - v.errs = append(v.errs, fmt.Errorf("invalid optional value: %q at %s. Should be boolean value.", attr, fmt.Sprintf("%s.%s", v.packageName, v.functionName))) - continue - } else { - identityAttribute.TestNotNull = b - } - } - - d.identityAttributes = append(d.identityAttributes, identityAttribute) - - case "SingletonIdentity": - hasIdentity = true - d.isSingleton = true - d.Serialize = true - case "ArnFormat": - args := common.ParseArgs(m[3]) if len(args.Positional) > 0 { d.ARNFormat = args.Positional[0] } @@ -695,29 +577,20 @@ func (v *visitor) processFuncDecl(funcDecl *ast.FuncDecl) { } if attr, ok := args.Keyword["global"]; ok { - if b, err := tests.ParseBoolAttr("global", attr); err != nil { + if b, err := common.ParseBoolAttr("global", attr); err != nil { v.errs = append(v.errs, err) continue } else { - if b { - d.isARNFormatGlobal = triBooleanTrue - } else { - d.isARNFormatGlobal = triBooleanFalse - } + d.isARNFormatGlobal = common.TriBool(b) } } case "IdAttrFormat": - args := common.ParseArgs(m[3]) if len(args.Positional) > 0 { d.IDAttrFormat = args.Positional[0] } - case "MutableIdentity": - d.MutableIdentity = true - case "Region": - args := common.ParseArgs(m[3]) if attr, ok := args.Keyword["global"]; ok { if global, err := strconv.ParseBool(attr); err != nil { v.errs = append(v.errs, fmt.Errorf("invalid Region/global value (%s): %s: %w", attr, fmt.Sprintf("%s.%s", v.packageName, v.functionName), err)) @@ -729,23 +602,7 @@ func (v *visitor) processFuncDecl(funcDecl *ast.FuncDecl) { case "NoImport": d.NoImport = true - // TODO: allow underscore? - case "V60SDKv2Fix": - d.HasV6_0NullValuesError = true - d.PreIdentityVersion = v5_100_0 - - args := common.ParseArgs(m[3]) - if attr, ok := args.Keyword["v60RefreshError"]; ok { - if b, err := tests.ParseBoolAttr("v60RefreshError", attr); err != nil { - v.errs = append(v.errs, err) - } else { - d.HasV6_0RefreshError = b - } - } - case "Testing": - args := common.ParseArgs(m[3]) - if err := tests.ParseTestingAnnotations(args, &d.CommonArgs); err != nil { v.errs = append(v.errs, fmt.Errorf("%s: %w", fmt.Sprintf("%s.%s", v.packageName, v.functionName), err)) continue @@ -759,10 +616,10 @@ func (v *visitor) processFuncDecl(funcDecl *ast.FuncDecl) { if attr, ok := args.Keyword["idAttrDuplicates"]; ok { d.idAttrDuplicates = attr d.GoImports = append(d.GoImports, - tests.GoImport{ + common.GoImport{ Path: "github.com/hashicorp/terraform-plugin-testing/config", }, - tests.GoImport{ + common.GoImport{ Path: "github.com/hashicorp/terraform-plugin-testing/tfjsonpath", }, ) @@ -770,9 +627,6 @@ func (v *visitor) processFuncDecl(funcDecl *ast.FuncDecl) { if attr, ok := args.Keyword["identityTest"]; ok { switch attr { - case "true": - hasIdentity = true - case "false": v.g.Infof("Skipping Identity test for %s.%s", v.packageName, v.functionName) skip = true @@ -783,7 +637,7 @@ func (v *visitor) processFuncDecl(funcDecl *ast.FuncDecl) { } } if attr, ok := args.Keyword["identityRegionOverrideTest"]; ok { - if b, err := tests.ParseBoolAttr("identityRegionOverrideTest", attr); err != nil { + if b, err := common.ParseBoolAttr("identityRegionOverrideTest", attr); err != nil { v.errs = append(v.errs, err) continue } else { @@ -791,7 +645,7 @@ func (v *visitor) processFuncDecl(funcDecl *ast.FuncDecl) { } } if attr, ok := args.Keyword["v60NullValuesError"]; ok { - if b, err := tests.ParseBoolAttr("v60NullValuesError", attr); err != nil { + if b, err := common.ParseBoolAttr("v60NullValuesError", attr); err != nil { v.errs = append(v.errs, err) } else { d.HasV6_0NullValuesError = b @@ -801,7 +655,7 @@ func (v *visitor) processFuncDecl(funcDecl *ast.FuncDecl) { } } if attr, ok := args.Keyword["v60RefreshError"]; ok { - if b, err := tests.ParseBoolAttr("v60RefreshError", attr); err != nil { + if b, err := common.ParseBoolAttr("v60RefreshError", attr); err != nil { v.errs = append(v.errs, err) } else { d.HasV6_0RefreshError = b @@ -819,14 +673,14 @@ func (v *visitor) processFuncDecl(funcDecl *ast.FuncDecl) { d.PreIdentityVersion = version } if attr, ok := args.Keyword["hasNoPreExistingResource"]; ok { - if b, err := tests.ParseBoolAttr("hasNoPreExistingResource", attr); err != nil { + if b, err := common.ParseBoolAttr("hasNoPreExistingResource", attr); err != nil { v.errs = append(v.errs, err) } else { d.HasNoPreExistingResource = b } } if attr, ok := args.Keyword["tlsKey"]; ok { - if b, err := tests.ParseBoolAttr("tlsKey", attr); err != nil { + if b, err := common.ParseBoolAttr("tlsKey", attr); err != nil { v.errs = append(v.errs, err) continue } else { @@ -856,6 +710,12 @@ func (v *visitor) processFuncDecl(funcDecl *ast.FuncDecl) { } d.IdentityVersions[identityVersion] = providerVersion } + + default: + if err := common.ParseResourceIdentity(annotationName, args, d.Implementation, &d.ResourceIdentity, &d.GoImports); err != nil { + v.errs = append(v.errs, fmt.Errorf("%s.%s: %w", v.packageName, v.functionName, err)) + continue + } } } } @@ -864,7 +724,7 @@ func (v *visitor) processFuncDecl(funcDecl *ast.FuncDecl) { if len(tlsKeyCN) == 0 { tlsKeyCN = "acctest.RandomDomain().String()" d.GoImports = append(d.GoImports, - tests.GoImport{ + common.GoImport{ Path: "github.com/hashicorp/terraform-provider-aws/internal/acctest", }, ) @@ -883,22 +743,18 @@ func (v *visitor) processFuncDecl(funcDecl *ast.FuncDecl) { } } - if d.IsRegionalSingleton() { - d.idAttrDuplicates = "region" - } - if d.IsGlobal { d.HasRegionOverrideTest = false } - if hasIdentity { + if d.HasResourceIdentity() { if !skip { if d.idAttrDuplicates != "" { d.GoImports = append(d.GoImports, - tests.GoImport{ + common.GoImport{ Path: "github.com/hashicorp/terraform-plugin-testing/config", }, - tests.GoImport{ + common.GoImport{ Path: "github.com/hashicorp/terraform-plugin-testing/tfjsonpath", }, ) @@ -907,6 +763,9 @@ func (v *visitor) processFuncDecl(funcDecl *ast.FuncDecl) { v.errs = append(v.errs, fmt.Errorf("no name parameter set: %s", fmt.Sprintf("%s.%s", v.packageName, v.functionName))) return } + if d.HasV6_0NullValuesError { + d.PreIdentityVersion = v5_100_0 + } if !d.HasNoPreExistingResource && d.PreIdentityVersion == nil { v.errs = append(v.errs, fmt.Errorf("preIdentityVersion is required when hasNoPreExistingResource is false: %s", fmt.Sprintf("%s.%s", v.packageName, v.functionName))) return @@ -914,15 +773,28 @@ func (v *visitor) processFuncDecl(funcDecl *ast.FuncDecl) { if !generatorSeen { d.Generator = "sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)" d.GoImports = append(d.GoImports, - tests.GoImport{ + common.GoImport{ Path: "github.com/hashicorp/terraform-plugin-testing/helper/acctest", Alias: "sdkacctest", }, - tests.GoImport{ + common.GoImport{ Path: "github.com/hashicorp/terraform-provider-aws/internal/acctest", }, ) } + if d.IsARNIdentity() { + d.arnAttribute = d.IdentityAttributeName() + } + if d.HasInherentRegionIdentity() { + if d.Implementation == common.ImplementationFramework { + if !slices.Contains(d.IdentityDuplicateAttrNames, "id") { + d.SetImportStateIDAttribute(d.IdentityAttributeName()) + } + } + } + if d.IsSingletonIdentity() { + d.Serialize = true + } v.identityResources = append(v.identityResources, d) } } @@ -969,22 +841,3 @@ func generateTestConfig(g *common.Generator, dirPath, test string, tfTemplates * g.Fatalf("generating file (%s): %s", mainPath, err) } } - -func populateInherentRegionIdentity(d *ResourceDatum, args common.Args) { - var attrs []string - if attr, ok := args.Keyword["identityDuplicateAttributes"]; ok { - attrs = strings.Split(attr, ";") - } - if d.Implementation == tests.ImplementationSDK { - attrs = append(attrs, "id") - } else { - if !slices.Contains(attrs, "id") { - d.SetImportStateIDAttribute(d.identityAttribute) - } - } - slices.Sort(attrs) - attrs = slices.Compact(attrs) - d.IdentityDuplicateAttrs = tfslices.ApplyToAll(attrs, func(s string) string { - return namesgen.ConstOrQuote(s) - }) -} diff --git a/internal/generate/identitytests/resource_test.go.gtpl b/internal/generate/identitytests/resource_test.go.gtpl index c95179548826..e1daff72669c 100644 --- a/internal/generate/identitytests/resource_test.go.gtpl +++ b/internal/generate/identitytests/resource_test.go.gtpl @@ -271,14 +271,14 @@ func {{ template "testname" . }}_Identity_Basic(t *testing.T) { tfstatecheck.ExpectRegionalARNFormat(resourceName, tfjsonpath.New({{ .ARNAttribute }}), "{{ .ARNNamespace }}", "{{ .ARNFormat }}"), {{ end -}} {{ end -}} - {{ if .HasIdentityDuplicateAttrs -}} + {{ if .IsGlobalSingleton -}} + statecheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrID), tfknownvalue.AccountID()), + {{ else if .HasIdentityDuplicateAttrs -}} {{ range .IdentityDuplicateAttrs -}} statecheck.CompareValuePairs(resourceName, tfjsonpath.New({{ . }}), resourceName, tfjsonpath.New({{ $.IdentityAttribute }}), compare.ValuesSame()), {{ end -}} {{ else if .HasIDAttrDuplicates -}} statecheck.CompareValuePairs(resourceName, tfjsonpath.New(names.AttrID), resourceName, tfjsonpath.New({{ .IDAttrDuplicates }}), compare.ValuesSame()), - {{ else if .IsGlobalSingleton -}} - statecheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrID), tfknownvalue.AccountID()), {{ end -}} {{ if not .IsGlobal -}} statecheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrRegion), knownvalue.StringExact(acctest.Region())), diff --git a/internal/generate/servicepackage/main.go b/internal/generate/servicepackage/main.go index 5f346eb02505..292366479da0 100644 --- a/internal/generate/servicepackage/main.go +++ b/internal/generate/servicepackage/main.go @@ -22,7 +22,6 @@ import ( "github.com/YakDriver/regexache" "github.com/hashicorp/terraform-provider-aws/internal/generate/common" - tfslices "github.com/hashicorp/terraform-provider-aws/internal/slices" "github.com/hashicorp/terraform-provider-aws/names" "github.com/hashicorp/terraform-provider-aws/names/data" namesgen "github.com/hashicorp/terraform-provider-aws/names/generate" @@ -93,10 +92,7 @@ func main() { for key, value := range v.frameworkListResources { if val, exists := v.frameworkResources[key]; exists { value.Name = val.Name - value.IdentityAttributes = val.IdentityAttributes - value.IdentityDuplicateAttrs = val.IdentityDuplicateAttrs - value.ARNIdentity = val.ARNIdentity - value.SingletonIdentity = val.SingletonIdentity + value.ResourceIdentity = val.ResourceIdentity value.TransparentTagging = val.TransparentTagging value.TagsResourceType = val.TagsResourceType value.TagsIdentifierAttribute = val.TagsIdentifierAttribute @@ -110,10 +106,7 @@ func main() { for key, value := range v.sdkListResources { if val, exists := v.sdkResources[key]; exists { value.Name = val.Name - value.IdentityAttributes = val.IdentityAttributes - value.IdentityDuplicateAttrs = val.IdentityDuplicateAttrs - value.ARNIdentity = val.ARNIdentity - value.SingletonIdentity = val.SingletonIdentity + value.ResourceIdentity = val.ResourceIdentity value.TransparentTagging = val.TransparentTagging value.TagsResourceType = val.TagsResourceType value.TagsIdentifierAttribute = val.TagsIdentifierAttribute @@ -141,7 +134,7 @@ func main() { SDKListResources: v.sdkListResources, } - var imports []goImport + var imports []common.GoImport for _, resource := range v.actions { imports = append(imports, resource.goImports...) } @@ -166,7 +159,7 @@ func main() { for _, resource := range v.sdkListResources { imports = append(imports, resource.goImports...) } - slices.SortFunc(imports, func(a, b goImport) int { + slices.SortFunc(imports, func(a, b common.GoImport) int { if n := strings.Compare(a.Path, b.Path); n != 0 { return n } @@ -223,68 +216,30 @@ type ResourceDatum struct { TagsIdentifierAttribute string TagsResourceType string ValidateRegionOverrideInPartition bool - IdentityAttributes []identityAttribute - ARNIdentity bool - arnAttribute string isARNFormatGlobal arnFormatState - SingletonIdentity bool - MutableIdentity bool - WrappedImport bool + wrappedImport common.TriBoolean CustomImport bool - goImports []goImport - IdentityDuplicateAttrs []string + goImports []common.GoImport ImportIDHandler string SetIDAttribute bool - HasV6_0SDKv2Fix bool HasIdentityFix bool - IdentityVersion int64 - SDKv2IdentityUpgraders []string - CustomInherentRegionIdentity bool - customIdentityAttribute string - CustomInherentRegionParser string + common.ResourceIdentity } func (r ResourceDatum) IsARNFormatGlobal() bool { return r.isARNFormatGlobal == arnFormatStateGlobal } -type identityAttribute struct { - Name string - Optional bool - ResourceAttributeName string -} - -type goImport struct { - Path string - Alias string - ARNIdentity bool - arnAttribute string - SingletonIdentity bool - WrappedImport bool -} - -func (r ResourceDatum) HasARNAttribute() bool { - return r.arnAttribute != "" && r.arnAttribute != "arn" -} - -func (r ResourceDatum) ARNAttribute() string { - return namesgen.ConstOrQuote(r.arnAttribute) +func (r ResourceDatum) HasAlternateARNAttribute() bool { + return r.IdentityAttributeName() != "" && r.IdentityAttributeName() != "arn" } func (d ResourceDatum) RegionOverrideEnabled() bool { return d.regionOverrideEnabled && !d.IsGlobal } -func (r ResourceDatum) HasIdentityDuplicateAttrs() bool { - return len(r.IdentityDuplicateAttrs) > 0 -} - -func (r ResourceDatum) HasResourceIdentity() bool { - return len(r.IdentityAttributes) > 0 || r.ARNIdentity || r.SingletonIdentity || r.CustomInherentRegionIdentity -} - -func (r ResourceDatum) CustomIdentityAttribute() string { - return namesgen.ConstOrQuote(r.customIdentityAttribute) +func (r ResourceDatum) WrappedImport() bool { + return r.wrappedImport == common.TriBooleanTrue } type ServiceDatum struct { @@ -302,7 +257,7 @@ type ServiceDatum struct { SDKDataSources map[string]ResourceDatum SDKResources map[string]ResourceDatum SDKListResources map[string]ResourceDatum - GoImports []goImport + GoImports []common.GoImport } //go:embed service_package_gen.go.gtpl @@ -398,8 +353,16 @@ func (v *visitor) processFuncDecl(funcDecl *ast.FuncDecl) { for _, line := range funcDecl.Doc.List { line := line.Text + var implementation common.Implementation + if m := annotation.FindStringSubmatch(line); len(m) > 0 { switch annotationName, args := m[1], common.ParseArgs(m[3]); annotationName { + case "FrameworkResource": + implementation = common.ImplementationFramework + + case "SDKResource": + implementation = common.ImplementationSDK + case "Region": if attr, ok := args.Keyword["global"]; ok { if global, err := strconv.ParseBool(attr); err != nil { @@ -442,32 +405,6 @@ func (v *visitor) processFuncDecl(funcDecl *ast.FuncDecl) { d.TagsResourceType = attr } - case "IdentityAttribute": - d.WrappedImport = true - if len(args.Positional) == 0 { - v.errs = append(v.errs, fmt.Errorf("no Identity attribute name: %s", fmt.Sprintf("%s.%s", v.packageName, v.functionName))) - continue - } - - identityAttribute := identityAttribute{ - Name: namesgen.ConstOrQuote(args.Positional[0]), - } - - if attr, ok := args.Keyword["optional"]; ok { - if b, err := strconv.ParseBool(attr); err != nil { - v.errs = append(v.errs, fmt.Errorf("invalid optional value: %q at %s. Should be boolean value.", attr, fmt.Sprintf("%s.%s", v.packageName, v.functionName))) - continue - } else { - identityAttribute.Optional = b - } - } - - if attr, ok := args.Keyword["resourceAttributeName"]; ok { - identityAttribute.ResourceAttributeName = namesgen.ConstOrQuote(attr) - } - - d.IdentityAttributes = append(d.IdentityAttributes, identityAttribute) - case "WrappedImport": if len(args.Positional) != 1 { v.errs = append(v.errs, fmt.Errorf("WrappedImport missing required parameter: at %s", fmt.Sprintf("%s.%s", v.packageName, v.functionName))) @@ -477,33 +414,14 @@ func (v *visitor) processFuncDecl(funcDecl *ast.FuncDecl) { v.errs = append(v.errs, fmt.Errorf("invalid WrappedImport value: %q at %s. Should be boolean value.", attr, fmt.Sprintf("%s.%s", v.packageName, v.functionName))) continue } else { - d.WrappedImport = b + d.wrappedImport = common.TriBool(b) } } case "CustomImport": d.CustomImport = true - case "ArnIdentity": - d.ARNIdentity = true - d.WrappedImport = true - args := common.ParseArgs(m[3]) - if len(args.Positional) == 0 { - d.arnAttribute = "arn" - } else { - d.arnAttribute = args.Positional[0] - } - - if attr, ok := args.Keyword["identityDuplicateAttributes"]; ok { - attrs := strings.Split(attr, ";") - d.IdentityDuplicateAttrs = tfslices.ApplyToAll(attrs, func(s string) string { - return namesgen.ConstOrQuote(s) - }) - } - case "ArnFormat": - args := common.ParseArgs(m[3]) - if attr, ok := args.Keyword["global"]; ok { if b, err := strconv.ParseBool(attr); err != nil { v.errs = append(v.errs, fmt.Errorf("invalid global value: %q at %s. Should be boolean value.", attr, fmt.Sprintf("%s.%s", v.packageName, v.functionName))) @@ -517,27 +435,12 @@ func (v *visitor) processFuncDecl(funcDecl *ast.FuncDecl) { } } - case "MutableIdentity": - d.MutableIdentity = true - - case "SingletonIdentity": - d.SingletonIdentity = true - d.WrappedImport = true - - if attr, ok := args.Keyword["identityDuplicateAttributes"]; ok { - attrs := strings.Split(attr, ";") - d.IdentityDuplicateAttrs = tfslices.ApplyToAll(attrs, func(s string) string { - return namesgen.ConstOrQuote(s) - }) - } - case "NoImport": - d.WrappedImport = false + d.wrappedImport = common.TriBooleanFalse case "ImportIDHandler": - args := common.ParseArgs(m[3]) attr := args.Positional[0] - if typeName, importSpec, err := parseIdentifierSpec(attr); err != nil { + if typeName, importSpec, err := common.ParseIdentifierSpec(attr); err != nil { v.errs = append(v.errs, fmt.Errorf("%q at %s: %w", attr, fmt.Sprintf("%s.%s", v.packageName, v.functionName), err)) continue } else { @@ -556,62 +459,24 @@ func (v *visitor) processFuncDecl(funcDecl *ast.FuncDecl) { } } - case "IdentityVersion": - args := common.ParseArgs(m[3]) - attr := args.Positional[0] - if i, err := strconv.ParseInt(attr, 10, 64); err != nil { - v.errs = append(v.errs, fmt.Errorf("invalid IdentityVersion value: %q at %s. Should be integer value.", attr, fmt.Sprintf("%s.%s", v.packageName, v.functionName))) - continue - } else { - d.IdentityVersion = i - } - - if attr, ok := args.Keyword["sdkV2IdentityUpgraders"]; ok { - attrs := strings.Split(attr, ";") - d.SDKv2IdentityUpgraders = attrs - } - - case "CustomInherentRegionIdentity": - d.CustomInherentRegionIdentity = true - d.WrappedImport = true - - args := common.ParseArgs(m[3]) - - if len(args.Positional) < 2 { - v.errs = append(v.errs, fmt.Errorf("CustomInherentRegionIdentity missing required parameters: at %s", fmt.Sprintf("%s.%s", v.packageName, v.functionName))) - continue - } - - d.customIdentityAttribute = args.Positional[0] + case "IdentityFix": + d.HasIdentityFix = true - attr := args.Positional[1] - if funcName, importSpec, err := parseIdentifierSpec(attr); err != nil { - v.errs = append(v.errs, fmt.Errorf("%q at %s: %w", attr, fmt.Sprintf("%s.%s", v.packageName, v.functionName), err)) + default: + if err := common.ParseResourceIdentity(annotationName, args, implementation, &d.ResourceIdentity, &d.goImports); err != nil { + v.errs = append(v.errs, fmt.Errorf("%s.%s: %w", v.packageName, v.functionName, err)) continue - } else { - d.CustomInherentRegionParser = funcName - if importSpec != nil { - d.goImports = append(d.goImports, *importSpec) - } - } - - if attr, ok := args.Keyword["identityDuplicateAttributes"]; ok { - attrs := strings.Split(attr, ";") - d.IdentityDuplicateAttrs = tfslices.ApplyToAll(attrs, func(s string) string { - return namesgen.ConstOrQuote(s) - }) } - - // TODO: allow underscore? - case "V60SDKv2Fix": - d.HasV6_0SDKv2Fix = true - - case "IdentityFix": - d.HasIdentityFix = true } } } + if d.HasResourceIdentity() { + if d.wrappedImport == common.TriBooleanUnset { + d.wrappedImport = common.TriBooleanTrue + } + } + // Then build the resource maps, looking for duplicates. for _, line := range funcDecl.Doc.List { line := line.Text @@ -674,7 +539,7 @@ func (v *visitor) processFuncDecl(funcDecl *ast.FuncDecl) { v.ephemeralResources[typeName] = d } - if d.HasV6_0SDKv2Fix { + if d.HasV6_0NullValuesError { v.errs = append(v.errs, fmt.Errorf("V60SDKv2Fix not supported for Ephemeral Resources: %s", fmt.Sprintf("%s.%s", v.packageName, v.functionName))) } @@ -702,7 +567,7 @@ func (v *visitor) processFuncDecl(funcDecl *ast.FuncDecl) { v.frameworkDataSources[typeName] = d } - if d.HasV6_0SDKv2Fix { + if d.HasV6_0NullValuesError { v.errs = append(v.errs, fmt.Errorf("V60SDKv2Fix not supported for Data Sources: %s", fmt.Sprintf("%s.%s", v.packageName, v.functionName))) } @@ -730,7 +595,7 @@ func (v *visitor) processFuncDecl(funcDecl *ast.FuncDecl) { v.frameworkResources[typeName] = d } - if d.HasV6_0SDKv2Fix { + if d.HasV6_0NullValuesError { v.errs = append(v.errs, fmt.Errorf("V60SDKv2Fix not supported for Framework Resources: %s", fmt.Sprintf("%s.%s", v.packageName, v.functionName))) } @@ -762,7 +627,7 @@ func (v *visitor) processFuncDecl(funcDecl *ast.FuncDecl) { v.sdkDataSources[typeName] = d } - if d.HasV6_0SDKv2Fix { + if d.HasV6_0NullValuesError { v.errs = append(v.errs, fmt.Errorf("V60SDKv2Fix not supported for Data Sources: %s", fmt.Sprintf("%s.%s", v.packageName, v.functionName))) } @@ -854,25 +719,3 @@ func (v *visitor) Visit(node ast.Node) ast.Visitor { return v } - -func parseIdentifierSpec(s string) (string, *goImport, error) { - parts := strings.Split(s, ";") - switch len(parts) { - case 1: - return parts[0], nil, nil - - case 2: - return parts[1], &goImport{ - Path: parts[0], - }, nil - - case 3: - return parts[2], &goImport{ - Path: parts[0], - Alias: parts[1], - }, nil - - default: - return "", nil, fmt.Errorf("invalid generator value: %q", s) - } -} diff --git a/internal/generate/servicepackage/service_package_gen.go.gtpl b/internal/generate/servicepackage/service_package_gen.go.gtpl index 71da93ebe911..65f0132cd0d9 100644 --- a/internal/generate/servicepackage/service_package_gen.go.gtpl +++ b/internal/generate/servicepackage/service_package_gen.go.gtpl @@ -16,7 +16,7 @@ inttypes.StringIdentityAttribute( {{- end }} {{ define "SDKv2CommonIdentityOpts" -}} -{{- if .HasV6_0SDKv2Fix }} +{{- if .HasV6_0NullValuesError }} inttypes.WithV6_0SDKv2Fix(), {{- end }} {{- template "CommonIdentityOpts" . -}} @@ -214,23 +214,23 @@ func (p *servicePackage) FrameworkResources(ctx context.Context) []*inttypes.Ser {{- template "CommonIdentityOpts" . -}} ), {{- end }} - {{- else if $value.ARNIdentity }} + {{- else if $value.IsARNIdentity }} {{- if $.IsGlobal }} - {{- if $value.HasARNAttribute }} - inttypes.GlobalARNIdentityNamed({{ $value.ARNAttribute }}, + {{- if $value.HasAlternateARNAttribute }} + inttypes.GlobalARNIdentityNamed({{ $value.IdentityAttribute }}, {{- else }} inttypes.GlobalARNIdentity( {{- end }} {{- else }} {{- if $value.IsARNFormatGlobal }} - {{- if $value.HasARNAttribute }} - inttypes.RegionalResourceWithGlobalARNFormatNamed({{ $value.ARNAttribute }}, + {{- if $value.HasAlternateARNAttribute }} + inttypes.RegionalResourceWithGlobalARNFormatNamed({{ $value.IdentityAttribute }}, {{- else }} inttypes.RegionalResourceWithGlobalARNFormat( {{- end }} {{- else }} - {{- if $value.HasARNAttribute }} - inttypes.RegionalARNIdentityNamed({{ $value.ARNAttribute }}, + {{- if $value.HasAlternateARNAttribute }} + inttypes.RegionalARNIdentityNamed({{ $value.IdentityAttribute }}, {{- else }} inttypes.RegionalARNIdentity( {{- end }} @@ -241,7 +241,7 @@ func (p *servicePackage) FrameworkResources(ctx context.Context) []*inttypes.Ser {{- end -}} {{- template "CommonIdentityOpts" . -}} ), - {{- else if $value.SingletonIdentity }} + {{- else if $value.IsSingletonIdentity }} {{- if or $.IsGlobal $value.IsGlobal }} inttypes.GlobalSingletonIdentity( {{- if .HasIdentityDuplicateAttrs -}} @@ -344,23 +344,23 @@ func (p *servicePackage) FrameworkListResources(ctx context.Context) iter.Seq[*i {{- template "CommonIdentityOpts" . -}} ), {{- end }} - {{- else if $value.ARNIdentity }} + {{- else if $value.IsARNIdentity }} {{- if $.IsGlobal }} - {{- if $value.HasARNAttribute }} - inttypes.GlobalARNIdentityNamed({{ $value.ARNAttribute }}, + {{- if $value.HasAlternateARNAttribute }} + inttypes.GlobalARNIdentityNamed({{ $value.IdentityAttribute }}, {{- else }} inttypes.GlobalARNIdentity( {{- end }} {{- else }} {{- if $value.IsARNFormatGlobal }} - {{- if $value.HasARNAttribute }} - inttypes.RegionalResourceWithGlobalARNFormatNamed({{ $value.ARNAttribute }}, + {{- if $value.HasAlternateARNAttribute }} + inttypes.RegionalResourceWithGlobalARNFormatNamed({{ $value.IdentityAttribute }}, {{- else }} inttypes.RegionalResourceWithGlobalARNFormat( {{- end }} {{- else }} - {{- if $value.HasARNAttribute }} - inttypes.RegionalARNIdentityNamed({{ $value.ARNAttribute }}, + {{- if $value.HasAlternateARNAttribute }} + inttypes.RegionalARNIdentityNamed({{ $value.IdentityAttribute }}, {{- else }} inttypes.RegionalARNIdentity( {{- end }} @@ -371,7 +371,7 @@ func (p *servicePackage) FrameworkListResources(ctx context.Context) iter.Seq[*i {{- end -}} {{- template "CommonIdentityOpts" . -}} ), - {{- else if $value.SingletonIdentity }} + {{- else if $value.IsSingletonIdentity }} {{- if or $.IsGlobal $value.IsGlobal }} inttypes.GlobalSingletonIdentity( {{- if .HasIdentityDuplicateAttrs -}} @@ -492,16 +492,16 @@ func (p *servicePackage) SDKResources(ctx context.Context) []*inttypes.ServicePa {{- template "SDKv2CommonIdentityOpts" . }} ), {{- end }} - {{- else if $value.ARNIdentity }} + {{- else if $value.IsARNIdentity }} {{- if $.IsGlobal }} - {{- if $value.HasARNAttribute }} - inttypes.GlobalARNIdentityNamed({{ $value.ARNAttribute }}, + {{- if $value.HasAlternateARNAttribute }} + inttypes.GlobalARNIdentityNamed({{ $value.IdentityAttribute }}, {{- else }} inttypes.GlobalARNIdentity( {{- end }} {{- else -}} - {{- if $value.HasARNAttribute }} - inttypes.RegionalARNIdentityNamed({{ $value.ARNAttribute }}, + {{- if $value.HasAlternateARNAttribute }} + inttypes.RegionalARNIdentityNamed({{ $value.IdentityAttribute }}, {{- else }} inttypes.RegionalARNIdentity( {{- end }} @@ -509,7 +509,7 @@ func (p *servicePackage) SDKResources(ctx context.Context) []*inttypes.ServicePa inttypes.WithIdentityDuplicateAttrs(names.AttrID), {{- template "SDKv2CommonIdentityOpts" . }} ), - {{- else if $value.SingletonIdentity }} + {{- else if $value.IsSingletonIdentity }} {{- if or $.IsGlobal $value.IsGlobal }} inttypes.GlobalSingletonIdentity( {{- template "SDKv2CommonIdentityOpts" . }} @@ -519,8 +519,8 @@ func (p *servicePackage) SDKResources(ctx context.Context) []*inttypes.ServicePa {{- template "SDKv2CommonIdentityOpts" . }} ), {{- end }} - {{- else if $value.CustomInherentRegionIdentity -}} - inttypes.RegionalCustomInherentRegionIdentity({{ .CustomIdentityAttribute }}, {{ .CustomInherentRegionParser }}, + {{- else if $value.IsCustomInherentRegionIdentity -}} + inttypes.RegionalCustomInherentRegionIdentity({{ .IdentityAttribute }}, {{ .CustomInherentRegionParser }}, inttypes.WithIdentityDuplicateAttrs(names.AttrID), {{- template "SDKv2CommonIdentityOpts" . }} ), @@ -608,23 +608,23 @@ func (p *servicePackage) SDKListResources(ctx context.Context) iter.Seq[*inttype {{- template "CommonIdentityOpts" . -}} ), {{- end }} - {{- else if $value.ARNIdentity }} + {{- else if $value.IsARNIdentity }} {{- if $.IsGlobal }} - {{- if $value.HasARNAttribute }} - inttypes.GlobalARNIdentityNamed({{ $value.ARNAttribute }}, + {{- if $value.HasAlternateARNAttribute }} + inttypes.GlobalARNIdentityNamed({{ $value.IdentityAttribute }}, {{- else }} inttypes.GlobalARNIdentity( {{- end }} {{- else }} {{- if $value.IsARNFormatGlobal }} - {{- if $value.HasARNAttribute }} - inttypes.RegionalResourceWithGlobalARNFormatNamed({{ $value.ARNAttribute }}, + {{- if $value.HasAlternateARNAttribute }} + inttypes.RegionalResourceWithGlobalARNFormatNamed({{ $value.IdentityAttribute }}, {{- else }} inttypes.RegionalResourceWithGlobalARNFormat( {{- end }} {{- else -}} - {{- if $value.HasARNAttribute }} - inttypes.RegionalARNIdentityNamed({{ $value.ARNAttribute }}, + {{- if $value.HasAlternateARNAttribute }} + inttypes.RegionalARNIdentityNamed({{ $value.IdentityAttribute }}, {{- else }} inttypes.RegionalARNIdentity( {{- end }} @@ -635,7 +635,7 @@ func (p *servicePackage) SDKListResources(ctx context.Context) iter.Seq[*inttype {{- end -}} {{- template "CommonIdentityOpts" . -}} ), - {{- else if $value.SingletonIdentity }} + {{- else if $value.IsSingletonIdentity }} {{- if or $.IsGlobal $value.IsGlobal }} inttypes.GlobalSingletonIdentity( {{- if .HasIdentityDuplicateAttrs -}} @@ -651,8 +651,8 @@ func (p *servicePackage) SDKListResources(ctx context.Context) iter.Seq[*inttype {{- template "CommonIdentityOpts" . -}} ), {{- end }} - {{- else if $value.CustomInherentRegionIdentity }} - inttypes.RegionalCustomInherentRegionIdentity({{ .CustomIdentityAttribute }}, + {{- else if $value.IsCustomInherentRegionIdentity }} + inttypes.RegionalCustomInherentRegionIdentity({{ .IdentityAttribute }}, inttypes.WithIdentityDuplicateAttrs(names.AttrID), {{- template "SDKv2CommonIdentityOpts" . }} ), diff --git a/internal/generate/tagpolicy/generate.go b/internal/generate/tagpolicy/generate.go new file mode 100644 index 000000000000..5ce5605d501a --- /dev/null +++ b/internal/generate/tagpolicy/generate.go @@ -0,0 +1,8 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +//go:generate go run lookup.go +//go:generate go run tag_policy_compliance.go +// ONLY generate directives and package declaration! Do not add anything else to this file. + +package tagpolicy diff --git a/internal/generate/tagpolicy/lookup.go b/internal/generate/tagpolicy/lookup.go new file mode 100644 index 000000000000..126d5f06d0b0 --- /dev/null +++ b/internal/generate/tagpolicy/lookup.go @@ -0,0 +1,70 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +//go:build generate + +package main + +import ( + "cmp" + _ "embed" + "slices" + "strings" + + "github.com/hashicorp/terraform-provider-aws/internal/generate/common" +) + +//go:embed lookup.tmpl +var tmpl string + +func main() { + const ( + source = `../../../internal/tags/tagpolicy/tagris-cfn-terraform-mapping.csv` + filename = `../../../internal/tags/tagpolicy/lookup_gen.go` + ) + g := common.NewGenerator() + + g.Infof("Generating %s", strings.TrimPrefix(filename, "../../../")) + + rows, err := common.ReadAllCSVData(source) + if err != nil { + g.Fatalf("generating file (%s): %s", filename, err) + } + + type m struct { + Tagris string + Tf string + } + var mapping []m + for _, r := range rows[1:] { + if len(r) != 3 { + continue + } + + if r[2] != "" { + mapping = append(mapping, m{Tagris: r[1], Tf: r[2]}) + continue + } + + // g.Infof("No lookup match found for: %s", r[1]) + } + + // Sort by tag type name + slices.SortFunc(mapping, func(a, b m) int { + return cmp.Compare(a.Tagris, b.Tagris) + }) + + data := map[string]any{ + "Mapping": mapping, + } + + d := g.NewGoFileDestination(filename) + + if err := d.BufferTemplate("lookup", tmpl, data); err != nil { + g.Fatalf("generating file (%s): %s", filename, err) + } + + if err := d.Write(); err != nil { + g.Fatalf("generating file (%s): %s", filename, err) + } +} diff --git a/internal/generate/tagpolicy/lookup.tmpl b/internal/generate/tagpolicy/lookup.tmpl new file mode 100644 index 000000000000..a729185f08e5 --- /dev/null +++ b/internal/generate/tagpolicy/lookup.tmpl @@ -0,0 +1,13 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 +// Code generated by internal/generate/tagpolicy/lookup.go; DO NOT EDIT. + +package tagpolicy + +// Lookup cross references Tagris resource type names to a corresponding +// Terraform resource type +var Lookup = map[string]string{ + {{- range $_, $m := .Mapping }} + "{{ $m.Tagris }}": "{{ $m.Tf }}", + {{- end }} +} diff --git a/internal/generate/tagpolicy/tag_policy_compliance.go b/internal/generate/tagpolicy/tag_policy_compliance.go new file mode 100644 index 000000000000..72460ea8983d --- /dev/null +++ b/internal/generate/tagpolicy/tag_policy_compliance.go @@ -0,0 +1,73 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +//go:build generate + +package main + +import ( + "cmp" + _ "embed" + "slices" + "strings" + + "github.com/hashicorp/terraform-provider-aws/internal/generate/common" +) + +//go:embed tag_policy_compliance_header.gtpl +var header string + +//go:embed tag_policy_compliance_lookup.gtpl +var tmpl string + +func main() { + const ( + source = `../../../internal/tags/tagpolicy/tagris-cfn-terraform-mapping.csv` + filename = `../../../website/docs/guides/tag-policy-compliance.html.markdown` + ) + g := common.NewGenerator() + + g.Infof("Generating %s", strings.TrimPrefix(filename, "../../../")) + + rows, err := common.ReadAllCSVData(source) + if err != nil { + g.Fatalf("generating file (%s): %s", filename, err) + } + + type m struct { + Tagris string + Tf string + } + var mapping []m + for _, r := range rows[1:] { + if len(r) != 3 { + continue + } + + if r[2] != "" { + mapping = append(mapping, m{Tagris: r[1], Tf: r[2]}) + continue + } + + // g.Infof("No lookup match found for: %s", r[1]) + } + + // Sort by tag type name + slices.SortFunc(mapping, func(a, b m) int { + return cmp.Compare(a.Tagris, b.Tagris) + }) + + data := map[string]any{ + "Mapping": mapping, + } + + d := g.NewUnformattedFileDestination(filename) + + if err := d.BufferTemplate("tag_policy_compliance", header+tmpl, data); err != nil { + g.Fatalf("generating file (%s): %s", filename, err) + } + + if err := d.Write(); err != nil { + g.Fatalf("generating file (%s): %s", filename, err) + } +} diff --git a/internal/generate/tagpolicy/tag_policy_compliance_header.gtpl b/internal/generate/tagpolicy/tag_policy_compliance_header.gtpl new file mode 100644 index 000000000000..bf71e9946e1b --- /dev/null +++ b/internal/generate/tagpolicy/tag_policy_compliance_header.gtpl @@ -0,0 +1,216 @@ +--- +subcategory: "" +layout: "aws" +page_title: "Tag Policy Compliance" +description: |- + The Terraform AWS provider supports enforcing compliance with organizational tag policies during plan and apply operations. +--- + + + +# Tag Policy Compliance + +The Terraform AWS provider supports enforcing compliance with organizational tag policies during plan and apply operations. +See the [AWS documentation on tag policies](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_tag-policies.html) for additional information on configuring tag policies for an organization. + + + +- [Getting Started](#getting-started) + - [Creating a Tag Policy](#creating-a-tag-policy) +- [Enforcing Tag Policy Compliance](#enforcing-tag-policy-compliance) +- [Additional Considerations](#additional-considerations) + - [Validation Timing](#validation-timing) + - [Warning Diagnostics with Plugin SDKV2 Resources](#warning-diagnostics-with-plugin-sdkv2-resources) +- [Resource Type Cross Reference](#resource-types-cross-reference) + + + +## Getting Started + +In order to utilize this feature: + +- **The AWS account must have a tag policy attached.** +To observe the effects of validation, this policy should define required tags for at least one resource. +- **The calling principal used to execute Terraform must have the [`ListRequiredTags`](https://docs.aws.amazon.com/resourcegroupstagging/latest/APIReference/API_ListRequireTags.html) [IAM permission](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonresourcegrouptaggingapi.html).** +This API was introduced in November 2025, and may require modification of existing permissions. + +If an appropriate tag policy is already in place, proceed to [Enforcing Tag Policy Compliance](#enforcing-tag-policy-compliance). +Otherwise, refer to [Creating a Tag Policy](#creating-a-tag-policy) for the necessary setup. + +### Creating a Tag Policy + +The Terraform AWS provider will enforce compliance with any required tags defined in an organization's effective tag policy. +An "effective" tag policy in this context is the policy resulting from the merged content of all tag policies attached to a given account. + +The [`aws_organizations_policy`](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/organizations_policy) and [`aws_organizations_policy_attachment`](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/organizations_policy_attachment) resources from the Terraform AWS provider can be used to perform this function via Terraform. +These resources wrap the [`CreatePolicy`](https://docs.aws.amazon.com/organizations/latest/APIReference/API_CreatePolicy.html) and [`AttachPolicy`](https://docs.aws.amazon.com/organizations/latest/APIReference/API_AttachPolicy.html) APIs, respectively. + +-> Tag policies must be created in the management account of an AWS organization. + +A tag policy enforcing required tags might look like the following: + +```json +{ + "tags": { + "Owner": { + "tag_key": { + "@@assign": "Owner" + }, + "report_required_tag_for": { + "@@assign": [ + "logs:log-group" + ] + } + } + } +} +``` + +In this policy, the `Owner` key is **required** on all `logs:log-group` resource types. +This tag resource type maps to the [`aws_cloudwatch_log_group`](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) resource in the Terraform AWS provider. + +The Terraform configuration below will create a tag policy and attach it to the current account. +The policy content is inlined for demonstration purposes. +Consider moving this to a separate JSON file for more complex policy definitions. + +```hcl +data "aws_caller_identity" "current" {} + +resource "aws_organizations_policy" "example" { + name = "tag-policy-example" + content = < Notably, _non-tag updates to existing resources are always permitted_, even if the existing tags are non-compliant. +This approach avoids blocking unrelated resource updates while still enforcing compliance once **any** tags are modified. + +### Warning Diagnostics with Plugin SDKV2 Resources + +Due to a limitation in the plan-time validation methods exposed by [Terraform Plugin SDK V2](https://developer.hashicorp.com/terraform/plugin/sdkv2), resources based on this library cannot emit warning diagnostics for tag policy compliance violations. +Instead, the provider will emit a log message with a `WARN` level. + +To view this message in the CLI output, set `TF_LOG=warn`. +For example, + +```console +% TF_LOG=warn terraform plan +``` + +~> A majority of resources in the Terraform AWS provider are implemented with Terraform Plugin SDK V2. +While all net-new resources [must use](https://github.com/hashicorp/terraform-provider-aws/issues/32917) the preferred [Terraform Plugin Framework](https://developer.hashicorp.com/terraform/plugin/framework), this limitation will affect many of the oldest and most popular resources until they are migrated or an enhancement is made to Plugin SDK V2. + +## Resource Type Cross Reference + +The following table contains a cross reference of tag resource types to Terraform AWS provider resource types. +This may be useful to determine which Terraform resource types are impacted by a tag policy constraint, or to ensure the correct tag resource name is present in a tag policy. + +-> The table below is generated, and will be updated over time as AWS service teams add tagging support for new resource types and the AWS provider implements new resources. diff --git a/internal/generate/tagpolicy/tag_policy_compliance_lookup.gtpl b/internal/generate/tagpolicy/tag_policy_compliance_lookup.gtpl new file mode 100644 index 000000000000..e34722f94eef --- /dev/null +++ b/internal/generate/tagpolicy/tag_policy_compliance_lookup.gtpl @@ -0,0 +1,6 @@ + +|Tag Resource Type|Terraform Resource Type| +|-----------------|-----------------------| +{{- range $_, $m := .Mapping }} +| `{{ $m.Tagris }}` | `{{ $m.Tf }}` | +{{- end }} diff --git a/internal/generate/tagstests/main.go b/internal/generate/tagstests/main.go index bee4f6ce4b60..d79b6e87ecbf 100644 --- a/internal/generate/tagstests/main.go +++ b/internal/generate/tagstests/main.go @@ -398,12 +398,11 @@ type ResourceDatum struct { TagsUpdateForceNew bool TagsUpdateGetTagsIn bool // TODO: Works around a bug when getTagsIn() is used to pass tags directly to Update call IsDataSource bool - DataSourceResourceImplementation tests.Implementation + DataSourceResourceImplementation common.Implementation overrideIdentifierAttribute string OverrideResourceType string tests.CommonArgs - isARNIdentity bool - identityAttribute string + common.ResourceIdentity } func (d ResourceDatum) ProviderPackage() string { @@ -526,14 +525,13 @@ func (v *visitor) processFuncDecl(funcDecl *ast.FuncDecl) { line := line.Text if m := annotation.FindStringSubmatch(line); len(m) > 0 { - switch annotationName := m[1]; annotationName { + switch annotationName, args := m[1], common.ParseArgs(m[3]); annotationName { case "FrameworkDataSource": d.IsDataSource = true fallthrough case "FrameworkResource": - d.Implementation = tests.ImplementationFramework - args := common.ParseArgs(m[3]) + d.Implementation = common.ImplementationFramework if len(args.Positional) == 0 { v.errs = append(v.errs, fmt.Errorf("no type name: %s", fmt.Sprintf("%s.%s", v.packageName, v.functionName))) continue @@ -550,8 +548,7 @@ func (v *visitor) processFuncDecl(funcDecl *ast.FuncDecl) { fallthrough case "SDKResource": - d.Implementation = tests.ImplementationSDK - args := common.ParseArgs(m[3]) + d.Implementation = common.ImplementationSDK if len(args.Positional) == 0 { v.errs = append(v.errs, fmt.Errorf("no type name: %s", fmt.Sprintf("%s.%s", v.packageName, v.functionName))) continue @@ -572,7 +569,6 @@ func (v *visitor) processFuncDecl(funcDecl *ast.FuncDecl) { case "Tags": tagged = true - args := common.ParseArgs(m[3]) if _, ok := args.Keyword["identifierAttribute"]; ok { hasIdentifierAttribute = true } @@ -580,20 +576,7 @@ func (v *visitor) processFuncDecl(funcDecl *ast.FuncDecl) { case "NoImport": d.NoImport = true - case "ArnIdentity": - d.isARNIdentity = true - args := common.ParseArgs(m[3]) - if len(args.Positional) == 0 { - d.identityAttribute = "arn" - } else { - d.identityAttribute = args.Positional[0] - } - - populateInherentRegionIdentity(&d, args) - case "Testing": - args := common.ParseArgs(m[3]) - if err := tests.ParseTestingAnnotations(args, &d.CommonArgs); err != nil { v.errs = append(v.errs, fmt.Errorf("%s: %w", fmt.Sprintf("%s.%s", v.packageName, v.functionName), err)) continue @@ -627,7 +610,7 @@ func (v *visitor) processFuncDecl(funcDecl *ast.FuncDecl) { } // TODO: should probably be a parameter on @Tags if attr, ok := args.Keyword["tagsUpdateForceNew"]; ok { - if b, err := tests.ParseBoolAttr("tagsUpdateForceNew", attr); err != nil { + if b, err := common.ParseBoolAttr("tagsUpdateForceNew", attr); err != nil { v.errs = append(v.errs, err) continue } else { @@ -635,7 +618,7 @@ func (v *visitor) processFuncDecl(funcDecl *ast.FuncDecl) { } } if attr, ok := args.Keyword["tagsUpdateGetTagsIn"]; ok { - if b, err := tests.ParseBoolAttr("tagsUpdateGetTagsIn", attr); err != nil { + if b, err := common.ParseBoolAttr("tagsUpdateGetTagsIn", attr); err != nil { v.errs = append(v.errs, err) continue } else { @@ -643,7 +626,7 @@ func (v *visitor) processFuncDecl(funcDecl *ast.FuncDecl) { } } if attr, ok := args.Keyword["skipEmptyTags"]; ok { - if b, err := tests.ParseBoolAttr("skipEmptyTags", attr); err != nil { + if b, err := common.ParseBoolAttr("skipEmptyTags", attr); err != nil { v.errs = append(v.errs, err) continue } else { @@ -651,7 +634,7 @@ func (v *visitor) processFuncDecl(funcDecl *ast.FuncDecl) { } } if attr, ok := args.Keyword["skipNullTags"]; ok { - if b, err := tests.ParseBoolAttr("skipNullTags", attr); err != nil { + if b, err := common.ParseBoolAttr("skipNullTags", attr); err != nil { v.errs = append(v.errs, err) continue } else { @@ -659,7 +642,7 @@ func (v *visitor) processFuncDecl(funcDecl *ast.FuncDecl) { } } if attr, ok := args.Keyword["noRemoveTags"]; ok { - if b, err := tests.ParseBoolAttr("noRemoveTags", attr); err != nil { + if b, err := common.ParseBoolAttr("noRemoveTags", attr); err != nil { v.errs = append(v.errs, err) continue } else { @@ -667,7 +650,7 @@ func (v *visitor) processFuncDecl(funcDecl *ast.FuncDecl) { } } if attr, ok := args.Keyword["tlsKey"]; ok { - if b, err := tests.ParseBoolAttr("tlsKey", attr); err != nil { + if b, err := common.ParseBoolAttr("tlsKey", attr); err != nil { v.errs = append(v.errs, err) continue } else { @@ -677,6 +660,12 @@ func (v *visitor) processFuncDecl(funcDecl *ast.FuncDecl) { if attr, ok := args.Keyword["tlsKeyDomain"]; ok { tlsKeyCN = attr } + + default: + if err := common.ParseResourceIdentity(annotationName, args, d.Implementation, &d.ResourceIdentity, &d.GoImports); err != nil { + v.errs = append(v.errs, fmt.Errorf("%s.%s: %w", v.packageName, v.functionName, err)) + continue + } } } } @@ -685,7 +674,7 @@ func (v *visitor) processFuncDecl(funcDecl *ast.FuncDecl) { if len(tlsKeyCN) == 0 { tlsKeyCN = "acctest.RandomDomain().String()" d.GoImports = append(d.GoImports, - tests.GoImport{ + common.GoImport{ Path: "github.com/hashicorp/terraform-provider-aws/internal/acctest", }, ) @@ -717,11 +706,21 @@ func (v *visitor) processFuncDecl(funcDecl *ast.FuncDecl) { if !generatorSeen { d.Generator = "acctest.RandomWithPrefix(t, acctest.ResourcePrefix)" d.GoImports = append(d.GoImports, - tests.GoImport{ + common.GoImport{ Path: "github.com/hashicorp/terraform-provider-aws/internal/acctest", }, ) } + if d.HasInherentRegionIdentity() { + if d.Implementation == common.ImplementationFramework { + if !slices.Contains(d.IdentityDuplicateAttrNames, "id") { + d.SetImportStateIDAttribute(d.IdentityAttributeName()) + } + } + } + if d.IsSingletonIdentity() { + d.Serialize = true + } v.taggedResources = append(v.taggedResources, d) } } @@ -775,19 +774,3 @@ func count[T any](s iter.Seq[T], f func(T) bool) (c int) { } return c } - -func populateInherentRegionIdentity(d *ResourceDatum, args common.Args) { - var attrs []string - if attr, ok := args.Keyword["identityDuplicateAttributes"]; ok { - attrs = strings.Split(attr, ";") - } - if d.Implementation == tests.ImplementationSDK { - attrs = append(attrs, "id") - } else { - if !slices.Contains(attrs, "id") { - d.SetImportStateIDAttribute(d.identityAttribute) - } - } - slices.Sort(attrs) - attrs = slices.Compact(attrs) -} diff --git a/internal/generate/tests/annotations.go b/internal/generate/tests/annotations.go index b4d774761b86..0dfa88a4c357 100644 --- a/internal/generate/tests/annotations.go +++ b/internal/generate/tests/annotations.go @@ -5,7 +5,6 @@ package tests import ( "fmt" - "strconv" "strings" acctestgen "github.com/hashicorp/terraform-provider-aws/internal/acctest/generate" @@ -17,17 +16,10 @@ import ( "golang.org/x/text/language" ) -type Implementation string - -const ( - ImplementationFramework Implementation = "framework" - ImplementationSDK Implementation = "sdk" -) - type CommonArgs struct { Name string // Resource Type Name TypeName string // Terraform Type Name - Implementation Implementation + Implementation common.Implementation // CheckDestroy CheckDestroyNoop bool @@ -63,7 +55,7 @@ type CommonArgs struct { RequiredEnvVars []string - GoImports []GoImport + GoImports []common.GoImport InitCodeBlocks []CodeBlock AdditionalTfVars_ map[string]TFVar } @@ -129,11 +121,6 @@ func (i importAction) String() string { } } -type GoImport struct { - Path string - Alias string -} - type CodeBlock struct { Code string } @@ -157,12 +144,12 @@ func ParseTestingAnnotations(args common.Args, stuff *CommonArgs) error { // DestroyCheck if attr, ok := args.Keyword["checkDestroyNoop"]; ok { - if b, err := ParseBoolAttr("checkDestroyNoop", attr); err != nil { + if b, err := common.ParseBoolAttr("checkDestroyNoop", attr); err != nil { return err } else { stuff.CheckDestroyNoop = b stuff.GoImports = append(stuff.GoImports, - GoImport{ + common.GoImport{ Path: "github.com/hashicorp/terraform-provider-aws/internal/acctest", }, ) @@ -170,7 +157,7 @@ func ParseTestingAnnotations(args common.Args, stuff *CommonArgs) error { } if attr, ok := args.Keyword["destroyTakesT"]; ok { - if b, err := ParseBoolAttr("destroyTakesT", attr); err != nil { + if b, err := common.ParseBoolAttr("destroyTakesT", attr); err != nil { return err } else { stuff.DestroyTakesT = b @@ -179,7 +166,7 @@ func ParseTestingAnnotations(args common.Args, stuff *CommonArgs) error { // ExistsCheck if attr, ok := args.Keyword["hasExistsFunction"]; ok { - if b, err := ParseBoolAttr("hasExistsFunction", attr); err != nil { + if b, err := common.ParseBoolAttr("hasExistsFunction", attr); err != nil { return err } else { stuff.HasExistsFunc = b @@ -187,7 +174,7 @@ func ParseTestingAnnotations(args common.Args, stuff *CommonArgs) error { } if attr, ok := args.Keyword["existsType"]; ok { - if typeName, importSpec, err := ParseIdentifierSpec(attr); err != nil { + if typeName, importSpec, err := common.ParseIdentifierSpec(attr); err != nil { return fmt.Errorf("%s: %w", attr, err) } else { stuff.ExistsTypeName = typeName @@ -198,7 +185,7 @@ func ParseTestingAnnotations(args common.Args, stuff *CommonArgs) error { } if attr, ok := args.Keyword["existsTakesT"]; ok { - if b, err := ParseBoolAttr("existsTakesT", attr); err != nil { + if b, err := common.ParseBoolAttr("existsTakesT", attr); err != nil { return err } else { stuff.ExistsTakesT = b @@ -229,7 +216,7 @@ func ParseTestingAnnotations(args common.Args, stuff *CommonArgs) error { } if attr, ok := args.Keyword["noImport"]; ok { - if b, err := ParseBoolAttr("noImport", attr); err != nil { + if b, err := common.ParseBoolAttr("noImport", attr); err != nil { return err } else { stuff.NoImport = b @@ -254,7 +241,7 @@ func ParseTestingAnnotations(args common.Args, stuff *CommonArgs) error { // Serialization if attr, ok := args.Keyword["serialize"]; ok { - if b, err := ParseBoolAttr("serialize", attr); err != nil { + if b, err := common.ParseBoolAttr("serialize", attr); err != nil { return err } else { stuff.Serialize = b @@ -262,7 +249,7 @@ func ParseTestingAnnotations(args common.Args, stuff *CommonArgs) error { } if attr, ok := args.Keyword["serializeParallelTests"]; ok { - if b, err := ParseBoolAttr("serializeParallelTests", attr); err != nil { + if b, err := common.ParseBoolAttr("serializeParallelTests", attr); err != nil { return err } else { stuff.SerializeParallelTests = b @@ -270,7 +257,7 @@ func ParseTestingAnnotations(args common.Args, stuff *CommonArgs) error { } if attr, ok := args.Keyword["serializeDelay"]; ok { - if b, err := ParseBoolAttr("serializeDelay", attr); err != nil { + if b, err := common.ParseBoolAttr("serializeDelay", attr); err != nil { return err } else { stuff.SerializeDelay = b @@ -279,7 +266,7 @@ func ParseTestingAnnotations(args common.Args, stuff *CommonArgs) error { // PreChecks if attr, ok := args.Keyword["preCheck"]; ok { - if code, importSpec, err := ParseIdentifierSpec(attr); err != nil { + if code, importSpec, err := common.ParseIdentifierSpec(attr); err != nil { return fmt.Errorf("%s: %w", attr, err) } else { stuff.PreChecks = append(stuff.PreChecks, CodeBlock{ @@ -297,14 +284,14 @@ func ParseTestingAnnotations(args common.Args, stuff *CommonArgs) error { return endpointsConstOrQuote(s) }) stuff.GoImports = append(stuff.GoImports, - GoImport{ + common.GoImport{ Path: "github.com/hashicorp/aws-sdk-go-base/v2/endpoints", }, ) } if attr, ok := args.Keyword["preCheckWithRegion"]; ok { - if code, importSpec, err := ParseIdentifierSpec(attr); err != nil { + if code, importSpec, err := common.ParseIdentifierSpec(attr); err != nil { return fmt.Errorf("%s: %w", attr, err) } else { stuff.PreChecksWithRegion = append(stuff.PreChecksWithRegion, CodeBlock{ @@ -321,7 +308,7 @@ func ParseTestingAnnotations(args common.Args, stuff *CommonArgs) error { } if attr, ok := args.Keyword["useAlternateAccount"]; ok { - if b, err := ParseBoolAttr("useAlternateAccount", attr); err != nil { + if b, err := common.ParseBoolAttr("useAlternateAccount", attr); err != nil { return err } else if b { stuff.UseAlternateAccount = true @@ -329,7 +316,7 @@ func ParseTestingAnnotations(args common.Args, stuff *CommonArgs) error { Code: "acctest.PreCheckAlternateAccount(t)", }) stuff.GoImports = append(stuff.GoImports, - GoImport{ + common.GoImport{ Path: "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema", }, ) @@ -337,7 +324,7 @@ func ParseTestingAnnotations(args common.Args, stuff *CommonArgs) error { } if attr, ok := args.Keyword["altRegionProvider"]; ok { - if b, err := ParseBoolAttr("altRegionProvider", attr); err != nil { + if b, err := common.ParseBoolAttr("altRegionProvider", attr); err != nil { return err } else { stuff.AlternateRegionProvider = b @@ -347,7 +334,7 @@ func ParseTestingAnnotations(args common.Args, stuff *CommonArgs) error { // TF Variables if attr, ok := args.Keyword["generator"]; ok { if attr != "false" { - if funcName, importSpec, err := ParseIdentifierSpec(attr); err != nil { + if funcName, importSpec, err := common.ParseIdentifierSpec(attr); err != nil { return fmt.Errorf("%s: %w", attr, err) } else { stuff.Generator = funcName @@ -364,7 +351,7 @@ func ParseTestingAnnotations(args common.Args, stuff *CommonArgs) error { varName = attr } stuff.GoImports = append(stuff.GoImports, - GoImport{ + common.GoImport{ Path: "github.com/hashicorp/terraform-provider-aws/internal/acctest", }, ) @@ -385,7 +372,7 @@ func ParseTestingAnnotations(args common.Args, stuff *CommonArgs) error { varName = attr } stuff.GoImports = append(stuff.GoImports, - GoImport{ + common.GoImport{ Path: "github.com/hashicorp/terraform-provider-aws/internal/acctest", }, ) @@ -411,7 +398,7 @@ func ParseTestingAnnotations(args common.Args, stuff *CommonArgs) error { } } stuff.GoImports = append(stuff.GoImports, - GoImport{ + common.GoImport{ Path: "github.com/hashicorp/terraform-provider-aws/internal/acctest", }, ) @@ -435,7 +422,7 @@ func ParseTestingAnnotations(args common.Args, stuff *CommonArgs) error { parts := strings.Split(attr, ";") varName := "rBgpAsn" stuff.GoImports = append(stuff.GoImports, - GoImport{ + common.GoImport{ Path: "github.com/hashicorp/terraform-plugin-testing/helper/acctest", Alias: "sdkacctest", }, @@ -452,7 +439,7 @@ func ParseTestingAnnotations(args common.Args, stuff *CommonArgs) error { if attr, ok := args.Keyword["randomIPv4Address"]; ok { varName := "rIPv4Address" stuff.GoImports = append(stuff.GoImports, - GoImport{ + common.GoImport{ Path: "github.com/hashicorp/terraform-plugin-testing/helper/acctest", Alias: "sdkacctest", }, @@ -471,7 +458,7 @@ if err != nil { } if attr, ok := args.Keyword["tlsEcdsaPublicKeyPem"]; ok { - if _, err := ParseBoolAttr("tlsEcdsaPublicKeyPem", attr); err != nil { + if _, err := common.ParseBoolAttr("tlsEcdsaPublicKeyPem", attr); err != nil { return err } else { varName := "rTlsEcdsaPublicKeyPem" @@ -489,36 +476,6 @@ if err != nil { return nil } -func ParseBoolAttr(name, value string) (bool, error) { - if b, err := strconv.ParseBool(value); err != nil { - return b, fmt.Errorf("invalid %s value %q: Should be boolean value.", name, value) - } else { - return b, nil - } -} - -func ParseIdentifierSpec(s string) (string, *GoImport, error) { - parts := strings.Split(s, ";") - switch len(parts) { - case 1: - return parts[0], nil, nil - - case 2: - return parts[1], &GoImport{ - Path: parts[0], - }, nil - - case 3: - return parts[2], &GoImport{ - Path: parts[0], - Alias: parts[1], - }, nil - - default: - return "", nil, fmt.Errorf("invalid generator value: %q", s) - } -} - func endpointsConstOrQuote(region string) string { var buf strings.Builder buf.WriteString("endpoints.") diff --git a/internal/provider/framework/identity_interceptor_test.go b/internal/provider/framework/identity_interceptor_test.go index 26c3206cf1da..0b5f1522d5d1 100644 --- a/internal/provider/framework/identity_interceptor_test.go +++ b/internal/provider/framework/identity_interceptor_test.go @@ -262,6 +262,10 @@ func (c mockClient) ServicePackage(_ context.Context, name string) conns.Service panic("not implemented") //lintignore:R009 } +func (c mockClient) TagPolicyConfig(ctx context.Context) *tftags.TagPolicyConfig { + panic("not implemented") //lintignore:R009 +} + func (c mockClient) ValidateInContextRegionInPartition(ctx context.Context) error { panic("not implemented") //lintignore:R009 } diff --git a/internal/provider/framework/intercept.go b/internal/provider/framework/intercept.go index 2d4367f71df2..cef7f41388cf 100644 --- a/internal/provider/framework/intercept.go +++ b/internal/provider/framework/intercept.go @@ -27,6 +27,7 @@ type awsClient interface { IgnoreTagsConfig(ctx context.Context) *tftags.IgnoreConfig Partition(context.Context) string ServicePackage(_ context.Context, name string) conns.ServicePackage + TagPolicyConfig(ctx context.Context) *tftags.TagPolicyConfig ValidateInContextRegionInPartition(ctx context.Context) error AwsConfig(context.Context) aws.Config } diff --git a/internal/provider/framework/listresource/list_result_intercept.go b/internal/provider/framework/listresource/list_result_intercept.go index c6e316e88aec..155377a1b013 100644 --- a/internal/provider/framework/listresource/list_result_intercept.go +++ b/internal/provider/framework/listresource/list_result_intercept.go @@ -58,7 +58,7 @@ func TagsInterceptor(tags unique.Handle[inttypes.ServicePackageResourceTags]) ta func (r tagsInterceptor) Read(ctx context.Context, params InterceptorParams) diag.Diagnostics { var diags diag.Diagnostics - sp, serviceName, resourceName, tagsInContext, ok := interceptors.InfoFromContext(ctx, params.C) + sp, serviceName, resourceName, _, tagsInContext, ok := interceptors.InfoFromContext(ctx, params.C) if !ok { return diags } diff --git a/internal/provider/framework/provider.go b/internal/provider/framework/provider.go index 36df45dc55f8..285757a057f6 100644 --- a/internal/provider/framework/provider.go +++ b/internal/provider/framework/provider.go @@ -199,6 +199,14 @@ func (*frameworkProvider) Schema(ctx context.Context, request provider.SchemaReq Optional: true, Description: "The region where AWS STS operations will take place. Examples\nare us-east-1 and us-west-2.", // lintignore:AWSAT003 }, + "tag_policy_compliance": schema.StringAttribute{ + Optional: true, + Description: `The severity with which to enforce organizational tagging policies on resources managed by this provider instance. ` + + `At this time this only includes compliance with required tag keys by resource type. ` + + `Valid values are "error", "warning", and "disabled". ` + + `When unset or "disabled", tag policy compliance will not be enforced by the provider. ` + + `Can also be configured with the ` + tftags.TagPolicyComplianceEnvVar + ` environment variable.`, + }, "token": schema.StringAttribute{ Optional: true, Description: "session token. A session token is only required if you are\nusing temporary security credentials.", diff --git a/internal/provider/framework/tags_interceptor.go b/internal/provider/framework/tags_interceptor.go index 93330f785de1..fd0d9ffe6863 100644 --- a/internal/provider/framework/tags_interceptor.go +++ b/internal/provider/framework/tags_interceptor.go @@ -6,6 +6,7 @@ package framework import ( "context" "fmt" + "slices" "unique" "github.com/hashicorp/terraform-plugin-framework/datasource" @@ -31,7 +32,7 @@ func (r tagsDataSourceInterceptor) read(ctx context.Context, opts interceptorOpt return } - sp, serviceName, resourceName, tagsInContext, ok := interceptors.InfoFromContext(ctx, c) + sp, serviceName, resourceName, _, tagsInContext, ok := interceptors.InfoFromContext(ctx, c) if !ok { return } @@ -86,7 +87,7 @@ func (r tagsResourceInterceptor) create(ctx context.Context, opts interceptorOpt return } - sp, _, _, tagsInContext, ok := interceptors.InfoFromContext(ctx, c) + sp, _, _, _, tagsInContext, ok := interceptors.InfoFromContext(ctx, c) if !ok { return } @@ -123,7 +124,7 @@ func (r tagsResourceInterceptor) read(ctx context.Context, opts interceptorOptio return } - sp, serviceName, resourceName, tagsInContext, ok := interceptors.InfoFromContext(ctx, c) + sp, serviceName, resourceName, _, tagsInContext, ok := interceptors.InfoFromContext(ctx, c) if !ok { return } @@ -179,7 +180,7 @@ func (r tagsResourceInterceptor) update(ctx context.Context, opts interceptorOpt return } - sp, serviceName, resourceName, tagsInContext, ok := interceptors.InfoFromContext(ctx, c) + sp, serviceName, resourceName, _, tagsInContext, ok := interceptors.InfoFromContext(ctx, c) if !ok { return } @@ -261,3 +262,74 @@ func resourceTransparentTagging(servicePackageResourceTags unique.Handle[inttype HTags: interceptors.HTags(servicePackageResourceTags), } } + +// resourceValidateRequiredTags validates that required tags are present for a given resource type. +func resourceValidateRequiredTags() resourceModifyPlanInterceptor { + return &resourceValidateRequiredTagsInterceptor{} +} + +type resourceValidateRequiredTagsInterceptor struct{} + +func (r resourceValidateRequiredTagsInterceptor) modifyPlan(ctx context.Context, opts interceptorOptions[resource.ModifyPlanRequest, resource.ModifyPlanResponse]) { + c := opts.c + + _, _, _, typeName, _, ok := interceptors.InfoFromContext(ctx, c) //nolint:dogsled // legitimate use as-is, signature to be refactored + if !ok { + return + } + + policy := c.TagPolicyConfig(ctx) + if policy == nil { + return + } + reqTags, ok := policy.RequiredTags[typeName] + if !ok { + return + } + + switch request, _, when := opts.request, opts.response, opts.when; when { + case Before: + // If the entire plan is null, the resource is planned for destruction. + if request.Plan.Raw.IsNull() { + return + } + + var planTags, stateTags tftags.Map + opts.response.Diagnostics.Append(request.Plan.GetAttribute(ctx, path.Root(names.AttrTags), &planTags)...) + opts.response.Diagnostics.Append(request.State.GetAttribute(ctx, path.Root(names.AttrTags), &stateTags)...) + if opts.response.Diagnostics.HasError() { + return + } + + if !planTags.IsWhollyKnown() { + return + } + + allPlanTags := c.DefaultTagsConfig(ctx).MergeTags(tftags.New(ctx, planTags)) + allStateTags := c.DefaultTagsConfig(ctx).MergeTags(tftags.New(ctx, stateTags)) + + isCreate := request.State.Raw.IsNull() + hasTagsChange := !allPlanTags.Equal(allStateTags) + + if !isCreate && !hasTagsChange { + return + } + + if allPlanTags.ContainsAllKeys(reqTags) { + return + } + + missing := reqTags.Removed(allPlanTags).Keys() + slices.Sort(missing) + + summary := "Missing Required Tags" + detail := fmt.Sprintf("An organizational tag policy requires the following tags for %s: %s", typeName, missing) + + switch policy.Severity { + case "warning": + opts.response.Diagnostics.AddAttributeWarning(path.Root(names.AttrTags), summary, detail) + default: + opts.response.Diagnostics.AddAttributeError(path.Root(names.AttrTags), summary, detail) + } + } +} diff --git a/internal/provider/framework/tags_interceptor_test.go b/internal/provider/framework/tags_interceptor_test.go new file mode 100644 index 000000000000..685bf1b5cdc9 --- /dev/null +++ b/internal/provider/framework/tags_interceptor_test.go @@ -0,0 +1,411 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package framework + +import ( + "context" + "testing" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-go/tftypes" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" + inttypes "github.com/hashicorp/terraform-provider-aws/internal/types" + "github.com/hashicorp/terraform-provider-aws/names" +) + +type mockRequiredTagsClient struct { + mockClient +} + +func (c mockRequiredTagsClient) DefaultTagsConfig(ctx context.Context) *tftags.DefaultConfig { + return nil +} + +func (c mockRequiredTagsClient) IgnoreTagsConfig(ctx context.Context) *tftags.IgnoreConfig { + return nil +} + +func (c mockRequiredTagsClient) ServicePackage(_ context.Context, name string) conns.ServicePackage { + return mockServicePackage{} +} + +func (c mockRequiredTagsClient) TagPolicyConfig(ctx context.Context) *tftags.TagPolicyConfig { + return &tftags.TagPolicyConfig{ + Severity: "error", + RequiredTags: map[string]tftags.KeyValueTags{ + "aws_test": { + "foo": nil, + "bar": nil, + }, + }, + } +} + +type mockServicePackage struct{} + +func (sp mockServicePackage) FrameworkDataSources(context.Context) []*inttypes.ServicePackageFrameworkDataSource { + return nil +} + +func (sp mockServicePackage) FrameworkResources(context.Context) []*inttypes.ServicePackageFrameworkResource { + return nil +} + +func (sp mockServicePackage) SDKDataSources(context.Context) []*inttypes.ServicePackageSDKDataSource { + return nil +} + +func (sp mockServicePackage) SDKResources(context.Context) []*inttypes.ServicePackageSDKResource { + return nil +} + +func (sp mockServicePackage) ServicePackageName() string { + return "Test" +} + +func Test_resourceValidateRequiredTagsInterceptor(t *testing.T) { + t.Parallel() + ctx := t.Context() + + bootstrapContext := func(ctx context.Context, meta any) context.Context { + ctx = conns.NewResourceContext(ctx, "Test", "test", "aws_test", "") + if v, ok := meta.(awsClient); ok { + ctx = tftags.NewContext(ctx, v.DefaultTagsConfig(ctx), v.IgnoreTagsConfig(ctx), v.TagPolicyConfig(ctx)) + } + + return ctx + } + + resourceSchema := schema.Schema{ + Attributes: map[string]schema.Attribute{ + "name": schema.StringAttribute{ + Required: true, + }, + "tags": tftags.TagsAttribute(), + }, + } + + // Null tags + attrs := map[string]tftypes.Value{ + "name": tftypes.NewValue(tftypes.String, "test"), + "tags": tftypes.NewValue(tftypes.Map{ElementType: tftypes.String}, nil), + } + rawVal := tftypes.NewValue(resourceSchema.Type().TerraformType(ctx), attrs) + + // Partial required tags + attrsPartial := map[string]tftypes.Value{ + "name": tftypes.NewValue(tftypes.String, "test"), + "tags": tftypes.NewValue(tftypes.Map{ElementType: tftypes.String}, map[string]tftypes.Value{ + "bar": tftypes.NewValue(tftypes.String, nil), + }), + } + rawValPartial := tftypes.NewValue(resourceSchema.Type().TerraformType(ctx), attrsPartial) + + // All required tags + attrsRequired := map[string]tftypes.Value{ + "name": tftypes.NewValue(tftypes.String, "test"), + "tags": tftypes.NewValue(tftypes.Map{ElementType: tftypes.String}, map[string]tftypes.Value{ + "foo": tftypes.NewValue(tftypes.String, nil), + "bar": tftypes.NewValue(tftypes.String, nil), + }), + } + rawValRequired := tftypes.NewValue(resourceSchema.Type().TerraformType(ctx), attrsRequired) + + // Unknown tag values + attrsUnknown := map[string]tftypes.Value{ + "name": tftypes.NewValue(tftypes.String, "test"), + "tags": tftypes.NewValue(tftypes.Map{ElementType: tftypes.String}, map[string]tftypes.Value{ + "foo": tftypes.NewValue(tftypes.String, tftypes.UnknownValue), + "bar": tftypes.NewValue(tftypes.String, tftypes.UnknownValue), + }), + } + rawValUnknown := tftypes.NewValue(resourceSchema.Type().TerraformType(ctx), attrsUnknown) + + tests := []struct { + name string + opts interceptorOptions[resource.ModifyPlanRequest, resource.ModifyPlanResponse] + wantDiags diag.Diagnostics + }{ + { + name: "create, missing tags", + opts: interceptorOptions[resource.ModifyPlanRequest, resource.ModifyPlanResponse]{ + c: mockRequiredTagsClient{}, + request: &resource.ModifyPlanRequest{ + Config: tfsdk.Config{ + Raw: rawVal, + Schema: resourceSchema, + }, + State: tfsdk.State{ + Raw: tftypes.NewValue(resourceSchema.Type().TerraformType(ctx), nil), // Raw state is null on creation + Schema: resourceSchema, + }, + Plan: tfsdk.Plan{ + Raw: rawVal, + Schema: resourceSchema, + }, + }, + response: &resource.ModifyPlanResponse{ + Plan: tfsdk.Plan{ + Raw: rawVal, + Schema: resourceSchema, + }, + }, + when: Before, + }, + wantDiags: diag.Diagnostics{diag.NewAttributeErrorDiagnostic( + path.Root(names.AttrTags), + "Missing Required Tags", + "An organizational tag policy requires the following tags for aws_test: [bar foo]", + ), + }, + }, + { + name: "create, partial tags", + opts: interceptorOptions[resource.ModifyPlanRequest, resource.ModifyPlanResponse]{ + c: mockRequiredTagsClient{}, + request: &resource.ModifyPlanRequest{ + Config: tfsdk.Config{ + Raw: rawValPartial, + Schema: resourceSchema, + }, + State: tfsdk.State{ + Raw: tftypes.NewValue(resourceSchema.Type().TerraformType(ctx), nil), // Raw state is null on creation + Schema: resourceSchema, + }, + Plan: tfsdk.Plan{ + Raw: rawValPartial, + Schema: resourceSchema, + }, + }, + response: &resource.ModifyPlanResponse{ + Plan: tfsdk.Plan{ + Raw: rawValPartial, + Schema: resourceSchema, + }, + }, + when: Before, + }, + wantDiags: diag.Diagnostics{diag.NewAttributeErrorDiagnostic( + path.Root(names.AttrTags), + "Missing Required Tags", + "An organizational tag policy requires the following tags for aws_test: [foo]", + ), + }, + }, + { + name: "create, required tags", + opts: interceptorOptions[resource.ModifyPlanRequest, resource.ModifyPlanResponse]{ + c: mockRequiredTagsClient{}, + request: &resource.ModifyPlanRequest{ + Config: tfsdk.Config{ + Raw: rawValRequired, + Schema: resourceSchema, + }, + State: tfsdk.State{ + Raw: tftypes.NewValue(resourceSchema.Type().TerraformType(ctx), nil), // Raw state is null on creation + Schema: resourceSchema, + }, + Plan: tfsdk.Plan{ + Raw: rawValRequired, + Schema: resourceSchema, + }, + }, + response: &resource.ModifyPlanResponse{ + Plan: tfsdk.Plan{ + Raw: rawValRequired, + Schema: resourceSchema, + }, + }, + when: Before, + }, + }, + { + name: "create, unknown tag values", + opts: interceptorOptions[resource.ModifyPlanRequest, resource.ModifyPlanResponse]{ + c: mockRequiredTagsClient{}, + request: &resource.ModifyPlanRequest{ + Config: tfsdk.Config{ + Raw: rawValUnknown, + Schema: resourceSchema, + }, + State: tfsdk.State{ + Raw: tftypes.NewValue(resourceSchema.Type().TerraformType(ctx), nil), // Raw state is null on creation + Schema: resourceSchema, + }, + Plan: tfsdk.Plan{ + Raw: rawValUnknown, + Schema: resourceSchema, + }, + }, + response: &resource.ModifyPlanResponse{ + Plan: tfsdk.Plan{ + Raw: rawValUnknown, + Schema: resourceSchema, + }, + }, + when: Before, + }, + }, + { + name: "update, no tags change", + opts: interceptorOptions[resource.ModifyPlanRequest, resource.ModifyPlanResponse]{ + c: mockRequiredTagsClient{}, + request: &resource.ModifyPlanRequest{ + Config: tfsdk.Config{ + Raw: rawVal, + Schema: resourceSchema, + }, + State: tfsdk.State{ + Raw: rawVal, + Schema: resourceSchema, + }, + Plan: tfsdk.Plan{ + Raw: rawVal, + Schema: resourceSchema, + }, + }, + response: &resource.ModifyPlanResponse{ + Plan: tfsdk.Plan{ + Raw: rawVal, + Schema: resourceSchema, + }, + }, + when: Before, + }, + }, + { + name: "update, add required", + opts: interceptorOptions[resource.ModifyPlanRequest, resource.ModifyPlanResponse]{ + c: mockRequiredTagsClient{}, + request: &resource.ModifyPlanRequest{ + Config: tfsdk.Config{ + Raw: rawValRequired, + Schema: resourceSchema, + }, + State: tfsdk.State{ + Raw: rawValPartial, + Schema: resourceSchema, + }, + Plan: tfsdk.Plan{ + Raw: rawValRequired, + Schema: resourceSchema, + }, + }, + response: &resource.ModifyPlanResponse{ + Plan: tfsdk.Plan{ + Raw: rawValRequired, + Schema: resourceSchema, + }, + }, + when: Before, + }, + }, + { + name: "update, remove required", + opts: interceptorOptions[resource.ModifyPlanRequest, resource.ModifyPlanResponse]{ + c: mockRequiredTagsClient{}, + request: &resource.ModifyPlanRequest{ + Config: tfsdk.Config{ + Raw: rawValPartial, + Schema: resourceSchema, + }, + State: tfsdk.State{ + Raw: rawValRequired, + Schema: resourceSchema, + }, + Plan: tfsdk.Plan{ + Raw: rawValPartial, + Schema: resourceSchema, + }, + }, + response: &resource.ModifyPlanResponse{ + Plan: tfsdk.Plan{ + Raw: rawValRequired, + Schema: resourceSchema, + }, + }, + when: Before, + }, + wantDiags: diag.Diagnostics{diag.NewAttributeErrorDiagnostic( + path.Root(names.AttrTags), + "Missing Required Tags", + "An organizational tag policy requires the following tags for aws_test: [foo]", + ), + }, + }, + { + name: "update, unknown tag values", + opts: interceptorOptions[resource.ModifyPlanRequest, resource.ModifyPlanResponse]{ + c: mockRequiredTagsClient{}, + request: &resource.ModifyPlanRequest{ + Config: tfsdk.Config{ + Raw: rawValUnknown, + Schema: resourceSchema, + }, + State: tfsdk.State{ + Raw: rawValPartial, + Schema: resourceSchema, + }, + Plan: tfsdk.Plan{ + Raw: rawValUnknown, + Schema: resourceSchema, + }, + }, + response: &resource.ModifyPlanResponse{ + Plan: tfsdk.Plan{ + Raw: rawValUnknown, + Schema: resourceSchema, + }, + }, + when: Before, + }, + }, + { + name: "destroy", + opts: interceptorOptions[resource.ModifyPlanRequest, resource.ModifyPlanResponse]{ + c: mockRequiredTagsClient{}, + request: &resource.ModifyPlanRequest{ + Config: tfsdk.Config{ + Raw: rawVal, + Schema: resourceSchema, + }, + State: tfsdk.State{ + Raw: rawVal, + Schema: resourceSchema, + }, + Plan: tfsdk.Plan{ + Raw: tftypes.NewValue(resourceSchema.Type().TerraformType(ctx), nil), // Raw plan is null on destroy + Schema: resourceSchema, + }, + }, + response: &resource.ModifyPlanResponse{ + Plan: tfsdk.Plan{ + Raw: tftypes.NewValue(resourceSchema.Type().TerraformType(ctx), nil), // Raw plan is null on destroy + Schema: resourceSchema, + }, + }, + when: Before, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + + r := resourceValidateRequiredTags() + ctx = bootstrapContext(ctx, tt.opts.c) + r.modifyPlan(ctx, tt.opts) + + if !tt.opts.response.Diagnostics.Equal(tt.wantDiags) { + t.Errorf("response diagnostics not equal. got: %s want: %s", tt.opts.response.Diagnostics, tt.wantDiags) + } + }) + } +} diff --git a/internal/provider/framework/wrap.go b/internal/provider/framework/wrap.go index ad7554ed08c7..2db655b74adb 100644 --- a/internal/provider/framework/wrap.go +++ b/internal/provider/framework/wrap.go @@ -94,9 +94,9 @@ func (w *wrappedDataSource) context(ctx context.Context, getAttribute getAttribu overrideRegion = target.ValueString() } - ctx = conns.NewResourceContext(ctx, w.servicePackageName, w.spec.Name, overrideRegion) + ctx = conns.NewResourceContext(ctx, w.servicePackageName, w.spec.Name, w.spec.TypeName, overrideRegion) if c != nil { - ctx = tftags.NewContext(ctx, c.DefaultTagsConfig(ctx), c.IgnoreTagsConfig(ctx)) + ctx = tftags.NewContext(ctx, c.DefaultTagsConfig(ctx), c.IgnoreTagsConfig(ctx), c.TagPolicyConfig(ctx)) ctx = c.RegisterLogger(ctx) ctx = fwflex.RegisterLogger(ctx) } @@ -244,7 +244,7 @@ func (w *wrappedEphemeralResource) context(ctx context.Context, getAttribute get overrideRegion = target.ValueString() } - ctx = conns.NewResourceContext(ctx, w.servicePackageName, w.spec.Name, overrideRegion) + ctx = conns.NewResourceContext(ctx, w.servicePackageName, w.spec.Name, w.spec.TypeName, overrideRegion) if c != nil { ctx = c.RegisterLogger(ctx) ctx = fwflex.RegisterLogger(ctx) @@ -414,7 +414,7 @@ func (w *wrappedAction) context(ctx context.Context, getAttribute getAttributeFu overrideRegion = target.ValueString() } - ctx = conns.NewResourceContext(ctx, w.servicePackageName, w.spec.Name, overrideRegion) + ctx = conns.NewResourceContext(ctx, w.servicePackageName, w.spec.Name, w.spec.TypeName, overrideRegion) if c != nil { ctx = c.RegisterLogger(ctx) ctx = fwflex.RegisterLogger(ctx) @@ -546,6 +546,7 @@ func newWrappedResource(spec *inttypes.ServicePackageFrameworkResource, serviceP if !tfunique.IsHandleNil(spec.Tags) { interceptors = append(interceptors, resourceTransparentTagging(spec.Tags)) + interceptors = append(interceptors, resourceValidateRequiredTags()) } inner, _ := spec.Factory(context.TODO()) @@ -602,9 +603,9 @@ func (w *wrappedResource) context(ctx context.Context, getAttribute getAttribute overrideRegion = target.ValueString() } - ctx = conns.NewResourceContext(ctx, w.servicePackageName, w.spec.Name, overrideRegion) + ctx = conns.NewResourceContext(ctx, w.servicePackageName, w.spec.Name, w.spec.TypeName, overrideRegion) if c != nil { - ctx = tftags.NewContext(ctx, c.DefaultTagsConfig(ctx), c.IgnoreTagsConfig(ctx)) + ctx = tftags.NewContext(ctx, c.DefaultTagsConfig(ctx), c.IgnoreTagsConfig(ctx), c.TagPolicyConfig(ctx)) ctx = c.RegisterLogger(ctx) ctx = fwflex.RegisterLogger(ctx) } @@ -881,9 +882,9 @@ func (w *wrappedListResourceFramework) context(ctx context.Context, getAttribute } } - ctx = conns.NewResourceContext(ctx, w.servicePackageName, w.spec.Name, overrideRegion) + ctx = conns.NewResourceContext(ctx, w.servicePackageName, w.spec.Name, w.spec.TypeName, overrideRegion) if c != nil { - ctx = tftags.NewContext(ctx, c.DefaultTagsConfig(ctx), c.IgnoreTagsConfig(ctx)) + ctx = tftags.NewContext(ctx, c.DefaultTagsConfig(ctx), c.IgnoreTagsConfig(ctx), c.TagPolicyConfig(ctx)) ctx = c.RegisterLogger(ctx) ctx = fwflex.RegisterLogger(ctx) } @@ -1008,9 +1009,9 @@ func (w *wrappedListResourceSDK) context(ctx context.Context, getAttribute getAt } } - ctx = conns.NewResourceContext(ctx, w.servicePackageName, w.spec.Name, overrideRegion) + ctx = conns.NewResourceContext(ctx, w.servicePackageName, w.spec.Name, w.spec.TypeName, overrideRegion) if c != nil { - ctx = tftags.NewContext(ctx, c.DefaultTagsConfig(ctx), c.IgnoreTagsConfig(ctx)) + ctx = tftags.NewContext(ctx, c.DefaultTagsConfig(ctx), c.IgnoreTagsConfig(ctx), c.TagPolicyConfig(ctx)) ctx = c.RegisterLogger(ctx) ctx = fwflex.RegisterLogger(ctx) } diff --git a/internal/provider/interceptors/info.go b/internal/provider/interceptors/info.go index 89d10eb15196..57bb14d48e5b 100644 --- a/internal/provider/interceptors/info.go +++ b/internal/provider/interceptors/info.go @@ -15,7 +15,7 @@ type infoAWSClient interface { ServicePackage(_ context.Context, name string) conns.ServicePackage } -func InfoFromContext(ctx context.Context, c infoAWSClient) (conns.ServicePackage, string, string, *tftags.InContext, bool) { +func InfoFromContext(ctx context.Context, c infoAWSClient) (conns.ServicePackage, string, string, string, *tftags.InContext, bool) { if inContext, ok := conns.FromContext(ctx); ok { if sp := c.ServicePackage(ctx, inContext.ServicePackageName()); sp != nil { serviceName, err := names.HumanFriendly(sp.ServicePackageName()) @@ -28,11 +28,16 @@ func InfoFromContext(ctx context.Context, c infoAWSClient) (conns.ServicePackage resourceName = "" } + typeName := inContext.TypeName() + if typeName == "" { + resourceName = "aws__" + } + if tagsInContext, ok := tftags.FromContext(ctx); ok { - return sp, serviceName, resourceName, tagsInContext, true + return sp, serviceName, resourceName, typeName, tagsInContext, true } } } - return nil, "", "", nil, false + return nil, "", "", "", nil, false } diff --git a/internal/provider/sdkv2/identity_interceptor_test.go b/internal/provider/sdkv2/identity_interceptor_test.go index eba5ca6a9651..8e083e10e268 100644 --- a/internal/provider/sdkv2/identity_interceptor_test.go +++ b/internal/provider/sdkv2/identity_interceptor_test.go @@ -307,6 +307,10 @@ func (c mockClient) IgnoreTagsConfig(ctx context.Context) *tftags.IgnoreConfig { panic("not implemented") //lintignore:R009 } +func (c mockClient) TagPolicyConfig(ctx context.Context) *tftags.TagPolicyConfig { + panic("not implemented") //lintignore:R009 +} + func (c mockClient) Partition(context.Context) string { panic("not implemented") //lintignore:R009 } diff --git a/internal/provider/sdkv2/intercept.go b/internal/provider/sdkv2/intercept.go index 0dc5f957781d..f644a8d52d9d 100644 --- a/internal/provider/sdkv2/intercept.go +++ b/internal/provider/sdkv2/intercept.go @@ -25,6 +25,7 @@ type awsClient interface { IgnoreTagsConfig(ctx context.Context) *tftags.IgnoreConfig Partition(context.Context) string ServicePackage(_ context.Context, name string) conns.ServicePackage + TagPolicyConfig(context.Context) *tftags.TagPolicyConfig ValidateInContextRegionInPartition(ctx context.Context) error AwsConfig(context.Context) aws.Config } diff --git a/internal/provider/sdkv2/provider.go b/internal/provider/sdkv2/provider.go index 1398c4e088eb..bfe7ebe0c09f 100644 --- a/internal/provider/sdkv2/provider.go +++ b/internal/provider/sdkv2/provider.go @@ -249,6 +249,15 @@ func NewProvider(ctx context.Context) (*schema.Provider, error) { Description: "The region where AWS STS operations will take place. Examples\n" + "are us-east-1 and us-west-2.", // lintignore:AWSAT003, }, + "tag_policy_compliance": { + Type: schema.TypeString, + Optional: true, + Description: `The severity with which to enforce organizational tagging policies on resources managed by this provider instance. ` + + `At this time this only includes compliance with required tag keys by resource type. ` + + `Valid values are "error", "warning", and "disabled". ` + + `When unset or "disabled", tag policy compliance will not be enforced by the provider. ` + + `Can also be configured with the ` + tftags.TagPolicyComplianceEnvVar + ` environment variable.`, + }, "token": { Type: schema.TypeString, Optional: true, @@ -465,6 +474,13 @@ func (p *sdkProvider) configure(ctx context.Context, d *schema.ResourceData) (an config.IgnoreTagsConfig = expandIgnoreTags(ctx, nil) } + tagCfg, dg := expandTagPolicyConfig(cty.GetAttrPath("tag_policy_compliance"), d.Get("tag_policy_compliance").(string)) + diags = append(diags, dg...) + if dg.HasError() { + return nil, diags + } + config.TagPolicyConfig = tagCfg + if v, ok := d.GetOk("max_retries"); ok { config.MaxRetries = v.(int) } @@ -586,9 +602,9 @@ func (p *sdkProvider) initialize(ctx context.Context) (map[string]conns.ServiceP } } - ctx = conns.NewResourceContext(ctx, servicePackageName, v.Name, overrideRegion) + ctx = conns.NewResourceContext(ctx, servicePackageName, v.Name, v.TypeName, overrideRegion) if c, ok := meta.(*conns.AWSClient); ok { - ctx = tftags.NewContext(ctx, c.DefaultTagsConfig(ctx), c.IgnoreTagsConfig(ctx)) + ctx = tftags.NewContext(ctx, c.DefaultTagsConfig(ctx), c.IgnoreTagsConfig(ctx), c.TagPolicyConfig(ctx)) ctx = c.RegisterLogger(ctx) } @@ -703,6 +719,11 @@ func (p *sdkProvider) initialize(ctx context.Context) (map[string]conns.ServiceP why: CustomizeDiff, interceptor: setTagsAll(), }) + interceptors = append(interceptors, interceptorInvocation{ + when: Before, + why: CustomizeDiff, + interceptor: validateRequiredTags(), + }) } if len(resource.Identity.Attributes) > 0 { @@ -751,9 +772,9 @@ func (p *sdkProvider) initialize(ctx context.Context) (map[string]conns.ServiceP } } - ctx = conns.NewResourceContext(ctx, servicePackageName, resource.Name, overrideRegion) + ctx = conns.NewResourceContext(ctx, servicePackageName, resource.Name, resource.TypeName, overrideRegion) if c, ok := meta.(*conns.AWSClient); ok { - ctx = tftags.NewContext(ctx, c.DefaultTagsConfig(ctx), c.IgnoreTagsConfig(ctx)) + ctx = tftags.NewContext(ctx, c.DefaultTagsConfig(ctx), c.IgnoreTagsConfig(ctx), c.TagPolicyConfig(ctx)) ctx = c.RegisterLogger(ctx) } @@ -1154,3 +1175,38 @@ func expandIgnoreTags(ctx context.Context, tfMap map[string]any) *tftags.IgnoreC return ignoreConfig } + +func expandTagPolicyConfig(path cty.Path, severity string) (*tftags.TagPolicyConfig, diag.Diagnostics) { + envSeverity := os.Getenv(tftags.TagPolicyComplianceEnvVar) + switch { + case severity != "" && severity != "disabled": + return &tftags.TagPolicyConfig{Severity: severity}, validateTagPolicySeverity(path, severity) + case envSeverity != "" && severity != "disabled": + return &tftags.TagPolicyConfig{Severity: envSeverity}, validateTagPolicySeverityEnvVar(envSeverity) + } + + return nil, nil +} + +func validateTagPolicySeverity(path cty.Path, s string) diag.Diagnostics { + switch s { + case "error", "warning", "disabled": + return nil + } + return diag.Diagnostics{errs.NewInvalidValueAttributeError(path, `Must be one of "error", "warning", or "disabled"`)} +} + +const ( + summaryInvalidEnvironmentVariableValue = "Invalid environment variable value" +) + +func validateTagPolicySeverityEnvVar(s string) diag.Diagnostics { + switch s { + case "error", "warning", "disabled": + return nil + } + return diag.Diagnostics{errs.NewErrorDiagnostic( + summaryInvalidEnvironmentVariableValue, + fmt.Sprintf(`%s must be one of "error", "warning", or "disabled"`, tftags.TagPolicyComplianceEnvVar), + )} +} diff --git a/internal/provider/sdkv2/tags_interceptor.go b/internal/provider/sdkv2/tags_interceptor.go index e579a2de16e3..0e613fae29dd 100644 --- a/internal/provider/sdkv2/tags_interceptor.go +++ b/internal/provider/sdkv2/tags_interceptor.go @@ -6,8 +6,10 @@ package sdkv2 import ( "context" "fmt" + "slices" "unique" + "github.com/hashicorp/terraform-plugin-log/tflog" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag" @@ -37,7 +39,7 @@ func (r tagsResourceCRUDInterceptor) run(ctx context.Context, opts crudIntercept return diags } - sp, serviceName, resourceName, tagsInContext, ok := interceptors.InfoFromContext(ctx, c) + sp, serviceName, resourceName, _, tagsInContext, ok := interceptors.InfoFromContext(ctx, c) if !ok { return diags } @@ -191,7 +193,7 @@ func (r tagsDataSourceCRUDInterceptor) run(ctx context.Context, opts crudInterce return diags } - sp, serviceName, resourceName, tagsInContext, ok := interceptors.InfoFromContext(ctx, c) + sp, serviceName, resourceName, _, tagsInContext, ok := interceptors.InfoFromContext(ctx, c) if !ok { return diags } @@ -297,3 +299,66 @@ func setTagsAll() customizeDiffInterceptor { return nil }) } + +func validateRequiredTags() customizeDiffInterceptor { + return interceptorFunc1[*schema.ResourceDiff, error](func(ctx context.Context, opts customizeDiffInterceptorOptions) error { + c := opts.c + + _, _, _, typeName, _, ok := interceptors.InfoFromContext(ctx, c) + if !ok { + return nil + } + + policy := c.TagPolicyConfig(ctx) + if policy == nil { + return nil + } + reqTags, ok := policy.RequiredTags[typeName] + if !ok { + return nil + } + + switch d, when, why := opts.d, opts.when, opts.why; when { + case Before: + switch why { + case CustomizeDiff: + isCreate := d.GetRawState().IsNull() + hasTagsChange := d.HasChange(names.AttrTags) + + if !isCreate && !hasTagsChange { + return nil + } + + if !d.GetRawPlan().GetAttr(names.AttrTags).IsWhollyKnown() { + return nil + } + + cfgTags := tftags.New(ctx, d.Get(names.AttrTags).(map[string]any)) + allTags := c.DefaultTagsConfig(ctx).MergeTags(cfgTags) + if allTags.ContainsAllKeys(reqTags) { + return nil + } + + missing := reqTags.Removed(allTags).Keys() + slices.Sort(missing) + summary := "Missing Required Tags" + detail := fmt.Sprintf("An organizational tag policy requires the following tags for %s: %s", typeName, missing) + + // CustomizeDiff does not support diagnostics (only an error return) + switch policy.Severity { + case "warning": + // Warning diagnostics are only logged + tflog.Warn(ctx, "Required Tags Validation", map[string]any{ + "summary": summary, + "detail": detail, + }) + default: + // Error diagnostics merge summary and detail into a single message + return fmt.Errorf("%s - %s", summary, detail) + } + } + } + + return nil + }) +} diff --git a/internal/provider/sdkv2/tags_interceptor_test.go b/internal/provider/sdkv2/tags_interceptor_test.go index a9f70670d119..ff3f634ca6ce 100644 --- a/internal/provider/sdkv2/tags_interceptor_test.go +++ b/internal/provider/sdkv2/tags_interceptor_test.go @@ -86,9 +86,9 @@ func TestTagsResourceInterceptor(t *testing.T) { })) bootstrapContext := func(ctx context.Context, meta any) context.Context { - ctx = conns.NewResourceContext(ctx, "Test", "aws_test", "") + ctx = conns.NewResourceContext(ctx, "Test", "test", "aws_test", "") if v, ok := meta.(*conns.AWSClient); ok { - ctx = tftags.NewContext(ctx, v.DefaultTagsConfig(ctx), v.IgnoreTagsConfig(ctx)) + ctx = tftags.NewContext(ctx, v.DefaultTagsConfig(ctx), v.IgnoreTagsConfig(ctx), v.TagPolicyConfig(ctx)) } return ctx diff --git a/internal/service/accessanalyzer/accessanalyzer_test.go b/internal/service/accessanalyzer/accessanalyzer_test.go index b07171570fb4..d911f513643d 100644 --- a/internal/service/accessanalyzer/accessanalyzer_test.go +++ b/internal/service/accessanalyzer/accessanalyzer_test.go @@ -26,6 +26,7 @@ func TestAccAccessAnalyzer_serial(t *testing.T) { "tags": testAccAccessAnalyzerAnalyzer_tagsSerial, "type_Organization": testAccAnalyzer_typeOrganization, "upgradeV5_95_0": testAccAnalyzer_upgradeV5_95_0, + "nullInResourceTags": testAccAnalyzer_nullInResourceTags, }, "ArchiveRule": { acctest.CtBasic: testAccAnalyzerArchiveRule_basic, diff --git a/internal/service/accessanalyzer/analyzer.go b/internal/service/accessanalyzer/analyzer.go index 1a05fc3011b7..221ec90ecc0f 100644 --- a/internal/service/accessanalyzer/analyzer.go +++ b/internal/service/accessanalyzer/analyzer.go @@ -397,25 +397,15 @@ func expandInternalAccessAnalysisRuleCriteria(tfMap map[string]any) *types.Inter apiObject := &types.InternalAccessAnalysisRuleCriteria{} if tfList, ok := tfMap["account_ids"].([]any); ok && len(tfList) > 0 { - for _, v := range tfList { - accountID, ok := v.(string) - if !ok { - continue - } - apiObject.AccountIds = append(apiObject.AccountIds, accountID) - } + apiObject.AccountIds = flex.ExpandStringValueList(tfList) } if tfList, ok := tfMap["resource_arns"].([]any); ok && len(tfList) > 0 { - for _, v := range tfList { - apiObject.ResourceArns = append(apiObject.ResourceArns, v.(string)) - } + apiObject.ResourceArns = flex.ExpandStringValueList(tfList) } if tfList, ok := tfMap["resource_types"].([]any); ok && len(tfList) > 0 { - for _, v := range tfList { - apiObject.ResourceTypes = append(apiObject.ResourceTypes, types.ResourceType(v.(string))) - } + apiObject.ResourceTypes = flex.ExpandStringyValueList[types.ResourceType](tfList) } return apiObject @@ -478,17 +468,14 @@ func expandAnalysisRuleCriteria(tfMap map[string]any) *types.AnalysisRuleCriteri apiObject := &types.AnalysisRuleCriteria{} if tfList, ok := tfMap["account_ids"].([]any); ok && len(tfList) > 0 { - for _, v := range tfList { - accountID, ok := v.(string) - if !ok { - continue - } - apiObject.AccountIds = append(apiObject.AccountIds, accountID) - } + apiObject.AccountIds = flex.ExpandStringValueList(tfList) } if tfList, ok := tfMap[names.AttrResourceTags].([]any); ok && len(tfList) > 0 { for _, v := range tfList { + if v == nil { + continue + } apiObject.ResourceTags = append(apiObject.ResourceTags, flex.ExpandStringValueMap(v.(map[string]any))) } } diff --git a/internal/service/accessanalyzer/analyzer_test.go b/internal/service/accessanalyzer/analyzer_test.go index a8af6ff59288..e845e3d5c576 100644 --- a/internal/service/accessanalyzer/analyzer_test.go +++ b/internal/service/accessanalyzer/analyzer_test.go @@ -8,6 +8,7 @@ import ( "fmt" "testing" + "github.com/YakDriver/regexache" "github.com/aws/aws-sdk-go-v2/service/accessanalyzer/types" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/plancheck" @@ -358,6 +359,29 @@ func testAccAnalyzer_upgradeV5_95_0(t *testing.T) { }) } +// https://github.com/hashicorp/terraform-provider-aws/issues/45136. +func testAccAnalyzer_nullInResourceTags(t *testing.T) { + ctx := acctest.Context(t) + rName := acctest.RandomWithPrefix(t, acctest.ResourcePrefix) + + acctest.Test(ctx, t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(ctx, t) + testAccPreCheck(ctx, t) + }, + ErrorCheck: acctest.ErrorCheck(t, names.AccessAnalyzerServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckAnalyzerDestroy(ctx, t), + Steps: []resource.TestStep{ + { + Config: testAccAnalyzerConfig_nullInResourceTags(rName), + // Error, but no crash. + ExpectError: regexache.MustCompile(`External Access analyzers cannot be created with the configuration`), + }, + }, + }) +} + func testAccCheckAnalyzerDestroy(ctx context.Context, t *testing.T) resource.TestCheckFunc { return func(s *terraform.State) error { conn := acctest.ProviderMeta(ctx, t).AccessAnalyzerClient(ctx) @@ -603,3 +627,30 @@ resource "aws_accessanalyzer_analyzer" "test" { } `, rName) } + +func testAccAnalyzerConfig_nullInResourceTags(rName string) string { + return fmt.Sprintf(` +resource "aws_accessanalyzer_analyzer" "test" { + analyzer_name = %[1]q + + configuration { + unused_access { + unused_access_age = 180 + analysis_rule { + exclusion { + account_ids = [ + "123456789012", + "234567890123", + ] + } + exclusion { + resource_tags = [ + { key1 = null }, + ] + } + } + } + } +} +`, rName) +} diff --git a/internal/service/appfabric/app_bundle_test.go b/internal/service/appfabric/app_bundle_test.go index d655d395d2fb..19f098a9beb8 100644 --- a/internal/service/appfabric/app_bundle_test.go +++ b/internal/service/appfabric/app_bundle_test.go @@ -649,7 +649,7 @@ func testAccCheckAppBundleExists(ctx context.Context, n string, v *awstypes.AppB func testAccCheckAppBundleExistsInRegion(ctx context.Context, n string, v *awstypes.AppBundle, region string) resource.TestCheckFunc { // Push region into Context. - ctx = conns.NewResourceContext(ctx, "AppFabric", "aws_appfabric_app_bundle", region) + ctx = conns.NewResourceContext(ctx, "AppFabric", "App Bundle", "aws_appfabric_app_bundle", region) return testAccCheckAppBundleExists(ctx, n, v) } diff --git a/internal/service/batch/job_queue.go b/internal/service/batch/job_queue.go index 016528d222bb..acb4f88aa27d 100644 --- a/internal/service/batch/job_queue.go +++ b/internal/service/batch/job_queue.go @@ -576,7 +576,7 @@ func (r jobQueueResource) List(ctx context.Context, request list.ListRequest, st return } - ctx = tftags.NewContext(ctx, awsClient.DefaultTagsConfig(ctx), awsClient.IgnoreTagsConfig(ctx)) + ctx = tftags.NewContext(ctx, awsClient.DefaultTagsConfig(ctx), awsClient.IgnoreTagsConfig(ctx), awsClient.TagPolicyConfig(ctx)) var data jobQueueResourceModel diff --git a/internal/service/bedrock/guardrail.go b/internal/service/bedrock/guardrail.go index da5ccd7eed1d..14993b25a44c 100644 --- a/internal/service/bedrock/guardrail.go +++ b/internal/service/bedrock/guardrail.go @@ -152,10 +152,40 @@ func (r *guardrailResource) Schema(ctx context.Context, req resource.SchemaReque CustomType: fwtypes.NewSetNestedObjectTypeOf[guardrailContentFilterConfigModel](ctx), NestedObject: schema.NestedBlockObject{ Attributes: map[string]schema.Attribute{ + "input_action": schema.StringAttribute{ + Optional: true, + CustomType: fwtypes.StringEnumType[awstypes.GuardrailContentFilterAction](), + }, + "input_enabled": schema.BoolAttribute{ + Optional: true, + }, + "input_modalities": schema.ListAttribute{ + Optional: true, + CustomType: fwtypes.ListOfStringEnumType[awstypes.GuardrailModality](), + ElementType: types.StringType, + Validators: []validator.List{ + listvalidator.SizeAtLeast(1), + }, + }, "input_strength": schema.StringAttribute{ Required: true, CustomType: fwtypes.StringEnumType[awstypes.GuardrailFilterStrength](), }, + "output_action": schema.StringAttribute{ + Optional: true, + CustomType: fwtypes.StringEnumType[awstypes.GuardrailContentFilterAction](), + }, + "output_enabled": schema.BoolAttribute{ + Optional: true, + }, + "output_modalities": schema.ListAttribute{ + Optional: true, + CustomType: fwtypes.ListOfStringEnumType[awstypes.GuardrailModality](), + ElementType: types.StringType, + Validators: []validator.List{ + listvalidator.SizeAtLeast(1), + }, + }, "output_strength": schema.StringAttribute{ Required: true, CustomType: fwtypes.StringEnumType[awstypes.GuardrailFilterStrength](), @@ -799,9 +829,15 @@ type guardrailContentPolicyConfigModel struct { } type guardrailContentFilterConfigModel struct { - InputStrength fwtypes.StringEnum[awstypes.GuardrailFilterStrength] `tfsdk:"input_strength"` - OutputStrength fwtypes.StringEnum[awstypes.GuardrailFilterStrength] `tfsdk:"output_strength"` - Type fwtypes.StringEnum[awstypes.GuardrailContentFilterType] `tfsdk:"type"` + InputAction fwtypes.StringEnum[awstypes.GuardrailContentFilterAction] `tfsdk:"input_action"` + InputEnabled types.Bool `tfsdk:"input_enabled"` + InputModalities fwtypes.ListOfStringEnum[awstypes.GuardrailModality] `tfsdk:"input_modalities"` + InputStrength fwtypes.StringEnum[awstypes.GuardrailFilterStrength] `tfsdk:"input_strength"` + OutputAction fwtypes.StringEnum[awstypes.GuardrailContentFilterAction] `tfsdk:"output_action"` + OutputEnabled types.Bool `tfsdk:"output_enabled"` + OutputModalities fwtypes.ListOfStringEnum[awstypes.GuardrailModality] `tfsdk:"output_modalities"` + OutputStrength fwtypes.StringEnum[awstypes.GuardrailFilterStrength] `tfsdk:"output_strength"` + Type fwtypes.StringEnum[awstypes.GuardrailContentFilterType] `tfsdk:"type"` } type guardrailContentFiltersTierConfigModel struct { diff --git a/internal/service/bedrock/guardrail_test.go b/internal/service/bedrock/guardrail_test.go index 7094b58f71ab..2931ee8ba9f0 100644 --- a/internal/service/bedrock/guardrail_test.go +++ b/internal/service/bedrock/guardrail_test.go @@ -334,6 +334,61 @@ func TestAccBedrockGuardrail_crossRegion(t *testing.T) { }) } +func TestAccBedrockGuardrail_contentPolicyConfigAction(t *testing.T) { + ctx := acctest.Context(t) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_bedrock_guardrail.test" + var guardrail bedrock.GetGuardrailOutput + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(ctx, t) + acctest.PreCheckPartitionHasService(t, names.BedrockEndpointID) + }, + ErrorCheck: acctest.ErrorCheck(t, names.BedrockServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckGuardrailDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccGuardrailConfig_contentPolicyConfigAction(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckGuardrailExists(ctx, resourceName, &guardrail), + resource.TestCheckResourceAttrSet(resourceName, "guardrail_arn"), + resource.TestCheckResourceAttr(resourceName, "blocked_input_messaging", "test"), + resource.TestCheckResourceAttr(resourceName, "blocked_outputs_messaging", "test"), + resource.TestCheckResourceAttr(resourceName, "content_policy_config.#", "1"), + resource.TestCheckResourceAttr(resourceName, "content_policy_config.0.filters_config.#", "1"), + resource.TestCheckResourceAttr(resourceName, "content_policy_config.0.filters_config.0.input_action", string(types.GuardrailContentFilterActionBlock)), + resource.TestCheckResourceAttr(resourceName, "content_policy_config.0.filters_config.0.input_enabled", acctest.CtTrue), + resource.TestCheckResourceAttr(resourceName, "content_policy_config.0.filters_config.0.input_modalities.#", "1"), + resource.TestCheckTypeSetElemAttr(resourceName, "content_policy_config.0.filters_config.0.input_modalities.*", "TEXT"), + resource.TestCheckResourceAttr(resourceName, "content_policy_config.0.filters_config.0.input_strength", string(types.GuardrailFilterStrengthMedium)), + resource.TestCheckResourceAttr(resourceName, "content_policy_config.0.filters_config.0.output_action", string(types.GuardrailContentFilterActionNone)), + resource.TestCheckResourceAttr(resourceName, "content_policy_config.0.filters_config.0.output_enabled", acctest.CtFalse), + resource.TestCheckResourceAttr(resourceName, "content_policy_config.0.filters_config.0.input_modalities.#", "1"), + resource.TestCheckResourceAttr(resourceName, "content_policy_config.0.filters_config.0.output_strength", string(types.GuardrailFilterStrengthMedium)), + resource.TestCheckResourceAttr(resourceName, "contextual_grounding_policy_config.#", "0"), + resource.TestCheckResourceAttrSet(resourceName, names.AttrCreatedAt), + resource.TestCheckResourceAttr(resourceName, names.AttrDescription, "test"), + resource.TestCheckResourceAttr(resourceName, names.AttrName, rName), + resource.TestCheckResourceAttr(resourceName, "sensitive_information_policy_config.#", "0"), + resource.TestCheckResourceAttr(resourceName, names.AttrStatus, "READY"), + resource.TestCheckResourceAttr(resourceName, "topic_policy_config.#", "0"), + resource.TestCheckResourceAttr(resourceName, names.AttrVersion, "DRAFT"), + resource.TestCheckResourceAttr(resourceName, "word_policy_config.#", "0"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateIdFunc: testAccGuardrailImportStateIDFunc(resourceName), + ImportStateVerify: true, + ImportStateVerifyIdentifierAttribute: "guardrail_id", + }, + }, + }) +} + func testAccGuardrailImportStateIDFunc(resourceName string) resource.ImportStateIdFunc { return func(s *terraform.State) (string, error) { rs, ok := s.RootModule().Resources[resourceName] @@ -774,3 +829,30 @@ resource "aws_bedrock_guardrail" "test" { } `, rName) } + +func testAccGuardrailConfig_contentPolicyConfigAction(rName string) string { + return acctest.ConfigCompose( + testAccCustomModelConfig_base(rName), + fmt.Sprintf(` +resource "aws_bedrock_guardrail" "test" { + name = %[1]q + blocked_input_messaging = "test" + blocked_outputs_messaging = "test" + description = "test" + + content_policy_config { + filters_config { + input_action = "BLOCK" + input_enabled = true + input_modalities = ["TEXT"] + input_strength = "MEDIUM" + output_action = "NONE" + output_enabled = false + output_modalities = ["IMAGE"] + output_strength = "MEDIUM" + type = "HATE" + } + } +} +`, rName)) +} diff --git a/internal/service/billing/exports_test.go b/internal/service/billing/exports_test.go new file mode 100644 index 000000000000..756e42964be2 --- /dev/null +++ b/internal/service/billing/exports_test.go @@ -0,0 +1,9 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package billing + +var ( + FindViewByARN = findViewByARN + ResourceView = newResourceView +) diff --git a/internal/service/billing/generate.go b/internal/service/billing/generate.go index 512939b943bb..56d43996403f 100644 --- a/internal/service/billing/generate.go +++ b/internal/service/billing/generate.go @@ -1,6 +1,7 @@ // Copyright (c) HashiCorp, Inc. // SPDX-License-Identifier: MPL-2.0 +//go:generate go run ../../generate/tags/main.go -ServiceTagsSlice -TagType=ResourceTag -ListTags -UpdateTags -ListTagsOutTagsElem=ResourceTags -UntagInTagsElem=ResourceTagKeys -TagInTagsElem=ResourceTags //go:generate go run ../../generate/servicepackage/main.go // ONLY generate directives and package declaration! Do not add anything else to this file. diff --git a/internal/service/billing/service_package_gen.go b/internal/service/billing/service_package_gen.go index 5e30758bd55f..a33b03554a82 100644 --- a/internal/service/billing/service_package_gen.go +++ b/internal/service/billing/service_package_gen.go @@ -36,7 +36,17 @@ func (p *servicePackage) FrameworkDataSources(ctx context.Context) []*inttypes.S } func (p *servicePackage) FrameworkResources(ctx context.Context) []*inttypes.ServicePackageFrameworkResource { - return []*inttypes.ServicePackageFrameworkResource{} + return []*inttypes.ServicePackageFrameworkResource{ + { + Factory: newResourceView, + TypeName: "aws_billing_view", + Name: "View", + Tags: unique.Make(inttypes.ServicePackageResourceTags{ + IdentifierAttribute: names.AttrARN, + }), + Region: unique.Make(inttypes.ResourceRegionDisabled()), + }, + } } func (p *servicePackage) SDKDataSources(ctx context.Context) []*inttypes.ServicePackageSDKDataSource { diff --git a/internal/service/billing/sweep.go b/internal/service/billing/sweep.go new file mode 100644 index 000000000000..fa50a556c0a8 --- /dev/null +++ b/internal/service/billing/sweep.go @@ -0,0 +1,43 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package billing + +import ( + "context" + + "github.com/YakDriver/smarterr" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/billing" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + "github.com/hashicorp/terraform-provider-aws/internal/sweep" + "github.com/hashicorp/terraform-provider-aws/internal/sweep/awsv2" + "github.com/hashicorp/terraform-provider-aws/internal/sweep/framework" + "github.com/hashicorp/terraform-provider-aws/names" +) + +func RegisterSweepers() { + awsv2.Register("aws_billing_view", sweepViews) +} + +func sweepViews(ctx context.Context, client *conns.AWSClient) ([]sweep.Sweepable, error) { + input := billing.ListBillingViewsInput{} + conn := client.BillingClient(ctx) + var sweepResources []sweep.Sweepable + + pages := billing.NewListBillingViewsPaginator(conn, &input) + for pages.HasMorePages() { + page, err := pages.NextPage(ctx) + if err != nil { + return nil, smarterr.NewError(err) + } + + for _, v := range page.BillingViews { + sweepResources = append(sweepResources, framework.NewSweepResource(newResourceView, client, + framework.NewAttribute(names.AttrARN, aws.ToString(v.Arn))), + ) + } + } + + return sweepResources, nil +} diff --git a/internal/service/billing/tags_gen.go b/internal/service/billing/tags_gen.go new file mode 100644 index 000000000000..04996f32bb29 --- /dev/null +++ b/internal/service/billing/tags_gen.go @@ -0,0 +1,146 @@ +// Code generated by internal/generate/tags/main.go; DO NOT EDIT. +package billing + +import ( + "context" + + "github.com/YakDriver/smarterr" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/billing" + awstypes "github.com/aws/aws-sdk-go-v2/service/billing/types" + "github.com/hashicorp/terraform-plugin-log/tflog" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + "github.com/hashicorp/terraform-provider-aws/internal/logging" + tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" + "github.com/hashicorp/terraform-provider-aws/internal/types/option" + "github.com/hashicorp/terraform-provider-aws/names" +) + +// listTags lists billing service tags. +// The identifier is typically the Amazon Resource Name (ARN), although +// it may also be a different identifier depending on the service. +func listTags(ctx context.Context, conn *billing.Client, identifier string, optFns ...func(*billing.Options)) (tftags.KeyValueTags, error) { + input := billing.ListTagsForResourceInput{ + ResourceArn: aws.String(identifier), + } + + output, err := conn.ListTagsForResource(ctx, &input, optFns...) + + if err != nil { + return tftags.New(ctx, nil), smarterr.NewError(err) + } + + return keyValueTags(ctx, output.ResourceTags), nil +} + +// ListTags lists billing service tags and set them in Context. +// It is called from outside this package. +func (p *servicePackage) ListTags(ctx context.Context, meta any, identifier string) error { + tags, err := listTags(ctx, meta.(*conns.AWSClient).BillingClient(ctx), identifier) + + if err != nil { + return smarterr.NewError(err) + } + + if inContext, ok := tftags.FromContext(ctx); ok { + inContext.TagsOut = option.Some(tags) + } + + return nil +} + +// []*SERVICE.Tag handling + +// svcTags returns billing service tags. +func svcTags(tags tftags.KeyValueTags) []awstypes.ResourceTag { + result := make([]awstypes.ResourceTag, 0, len(tags)) + + for k, v := range tags.Map() { + tag := awstypes.ResourceTag{ + Key: aws.String(k), + Value: aws.String(v), + } + + result = append(result, tag) + } + + return result +} + +// keyValueTags creates tftags.KeyValueTags from billing service tags. +func keyValueTags(ctx context.Context, tags []awstypes.ResourceTag) tftags.KeyValueTags { + m := make(map[string]*string, len(tags)) + + for _, tag := range tags { + m[aws.ToString(tag.Key)] = tag.Value + } + + return tftags.New(ctx, m) +} + +// getTagsIn returns billing service tags from Context. +// nil is returned if there are no input tags. +func getTagsIn(ctx context.Context) []awstypes.ResourceTag { + if inContext, ok := tftags.FromContext(ctx); ok { + if tags := svcTags(inContext.TagsIn.UnwrapOrDefault()); len(tags) > 0 { + return tags + } + } + + return nil +} + +// setTagsOut sets billing service tags in Context. +func setTagsOut(ctx context.Context, tags []awstypes.ResourceTag) { + if inContext, ok := tftags.FromContext(ctx); ok { + inContext.TagsOut = option.Some(keyValueTags(ctx, tags)) + } +} + +// updateTags updates billing service tags. +// The identifier is typically the Amazon Resource Name (ARN), although +// it may also be a different identifier depending on the service. +func updateTags(ctx context.Context, conn *billing.Client, identifier string, oldTagsMap, newTagsMap any, optFns ...func(*billing.Options)) error { + oldTags := tftags.New(ctx, oldTagsMap) + newTags := tftags.New(ctx, newTagsMap) + + ctx = tflog.SetField(ctx, logging.KeyResourceId, identifier) + + removedTags := oldTags.Removed(newTags) + removedTags = removedTags.IgnoreSystem(names.Billing) + if len(removedTags) > 0 { + input := billing.UntagResourceInput{ + ResourceArn: aws.String(identifier), + ResourceTagKeys: removedTags.Keys(), + } + + _, err := conn.UntagResource(ctx, &input, optFns...) + + if err != nil { + return smarterr.NewError(err) + } + } + + updatedTags := oldTags.Updated(newTags) + updatedTags = updatedTags.IgnoreSystem(names.Billing) + if len(updatedTags) > 0 { + input := billing.TagResourceInput{ + ResourceArn: aws.String(identifier), + ResourceTags: svcTags(updatedTags), + } + + _, err := conn.TagResource(ctx, &input, optFns...) + + if err != nil { + return smarterr.NewError(err) + } + } + + return nil +} + +// UpdateTags updates billing service tags. +// It is called from outside this package. +func (p *servicePackage) UpdateTags(ctx context.Context, meta any, identifier string, oldTags, newTags any) error { + return updateTags(ctx, meta.(*conns.AWSClient).BillingClient(ctx), identifier, oldTags, newTags) +} diff --git a/internal/service/billing/tags_gen_test.go b/internal/service/billing/tags_gen_test.go new file mode 100644 index 000000000000..228fe27eed48 --- /dev/null +++ b/internal/service/billing/tags_gen_test.go @@ -0,0 +1,16 @@ +// Code generated by internal/generate/tagstests/main.go; DO NOT EDIT. + +package billing_test + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-testing/knownvalue" + "github.com/hashicorp/terraform-plugin-testing/statecheck" + tfstatecheck "github.com/hashicorp/terraform-provider-aws/internal/acctest/statecheck" + tfbilling "github.com/hashicorp/terraform-provider-aws/internal/service/billing" +) + +func expectFullResourceTags(ctx context.Context, resourceAddress string, knownValue knownvalue.Check) statecheck.StateCheck { + return tfstatecheck.ExpectFullResourceTags(tfbilling.ServicePackage(ctx), resourceAddress, knownValue) +} diff --git a/internal/service/billing/view.go b/internal/service/billing/view.go new file mode 100644 index 000000000000..179b9ed0c4ba --- /dev/null +++ b/internal/service/billing/view.go @@ -0,0 +1,504 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package billing + +import ( + "context" + "errors" + "time" + + "github.com/YakDriver/smarterr" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/billing" + awstypes "github.com/aws/aws-sdk-go-v2/service/billing/types" + "github.com/hashicorp/terraform-plugin-framework-timeouts/resource/timeouts" + "github.com/hashicorp/terraform-plugin-framework-timetypes/timetypes" + "github.com/hashicorp/terraform-plugin-framework-validators/listvalidator" + "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/listplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "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-aws/internal/enum" + "github.com/hashicorp/terraform-provider-aws/internal/errs" + "github.com/hashicorp/terraform-provider-aws/internal/errs/fwdiag" + "github.com/hashicorp/terraform-provider-aws/internal/framework" + "github.com/hashicorp/terraform-provider-aws/internal/framework/flex" + fwtypes "github.com/hashicorp/terraform-provider-aws/internal/framework/types" + "github.com/hashicorp/terraform-provider-aws/internal/retry" + "github.com/hashicorp/terraform-provider-aws/internal/smerr" + tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" + "github.com/hashicorp/terraform-provider-aws/names" +) + +// @FrameworkResource("aws_billing_view", name="View") +// @Tags(identifierAttribute="arn") +func newResourceView(_ context.Context) (resource.ResourceWithConfigure, error) { + r := &resourceView{} + + r.SetDefaultCreateTimeout(5 * time.Minute) + r.SetDefaultUpdateTimeout(5 * time.Minute) + r.SetDefaultDeleteTimeout(5 * time.Minute) + + return r, nil +} + +const ( + ResNameView = "View" +) + +type resourceView struct { + framework.ResourceWithModel[resourceViewModel] + framework.WithTimeouts +} + +func (r *resourceView) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { + resp.Schema = schema.Schema{ + Attributes: map[string]schema.Attribute{ + names.AttrARN: framework.ARNAttributeComputedOnly(), + "billing_view_type": schema.StringAttribute{ + CustomType: fwtypes.StringEnumType[awstypes.BillingViewType](), + Computed: true, + }, + names.AttrCreatedAt: schema.StringAttribute{ + CustomType: timetypes.RFC3339Type{}, + Computed: true, + }, + "derived_view_count": schema.Int32Attribute{ + Computed: true, + }, + names.AttrDescription: schema.StringAttribute{ + Optional: true, + Validators: []validator.String{stringvalidator.LengthBetween(0, 1024)}, + }, + names.AttrName: schema.StringAttribute{ + Required: true, + Validators: []validator.String{stringvalidator.LengthBetween(1, 128)}, + }, + names.AttrOwnerAccountID: schema.StringAttribute{ + Computed: true, + }, + "source_account_id": schema.StringAttribute{ + Computed: true, + }, + "source_view_count": schema.Int32Attribute{ + Computed: true, + }, + "source_views": schema.ListAttribute{ + CustomType: fwtypes.ListOfStringType, + ElementType: types.StringType, + Optional: true, + Validators: []validator.List{ + listvalidator.SizeBetween(1, 10), + }, + PlanModifiers: []planmodifier.List{ + listplanmodifier.RequiresReplace(), + }, + }, + names.AttrTags: tftags.TagsAttribute(), + names.AttrTagsAll: tftags.TagsAttributeComputedOnly(), + "updated_at": schema.StringAttribute{ + CustomType: timetypes.RFC3339Type{}, + Computed: true, + }, + "view_definition_last_updated_at": schema.StringAttribute{ + CustomType: timetypes.RFC3339Type{}, + Computed: true, + }, + }, + Blocks: map[string]schema.Block{ + "data_filter_expression": schema.ListNestedBlock{ + CustomType: fwtypes.NewListNestedObjectTypeOf[dataFilterExpressionModel](ctx), + Validators: []validator.List{ + listvalidator.SizeAtMost(1), + }, + NestedObject: schema.NestedBlockObject{ + Blocks: map[string]schema.Block{ + "dimensions": schema.ListNestedBlock{ + CustomType: fwtypes.NewListNestedObjectTypeOf[dimensionsModel](ctx), + Validators: []validator.List{ + listvalidator.SizeAtMost(1), + }, + NestedObject: schema.NestedBlockObject{ + Attributes: map[string]schema.Attribute{ + names.AttrKey: schema.StringAttribute{ + CustomType: fwtypes.StringEnumType[awstypes.Dimension](), + Required: true, + }, + names.AttrValues: schema.ListAttribute{ + CustomType: fwtypes.ListOfStringType, + ElementType: types.StringType, + Required: true, + Validators: []validator.List{ + listvalidator.SizeAtLeast(1), + }, + }, + }, + }, + }, + names.AttrTags: schema.ListNestedBlock{ + CustomType: fwtypes.NewListNestedObjectTypeOf[tagValuesModel](ctx), + NestedObject: schema.NestedBlockObject{ + Attributes: map[string]schema.Attribute{ + names.AttrKey: schema.StringAttribute{ + Required: true, + }, + names.AttrValues: schema.ListAttribute{ + CustomType: fwtypes.ListOfStringType, + ElementType: types.StringType, + Required: true, + Validators: []validator.List{ + listvalidator.SizeAtLeast(1), + }, + }, + }, + }, + }, + "time_range": schema.ListNestedBlock{ + CustomType: fwtypes.NewListNestedObjectTypeOf[timeRangeModel](ctx), + Validators: []validator.List{ + listvalidator.SizeAtMost(1), + }, + NestedObject: schema.NestedBlockObject{ + Attributes: map[string]schema.Attribute{ + "begin_date_inclusive": schema.StringAttribute{ + CustomType: timetypes.RFC3339Type{}, + Required: true, + }, + "end_date_inclusive": schema.StringAttribute{ + CustomType: timetypes.RFC3339Type{}, + Required: true, + }, + }, + }, + }, + }, + }, + }, + names.AttrTimeouts: timeouts.Block(ctx, timeouts.Opts{ + Create: true, + Update: true, + Delete: true, + }), + }, + } +} + +func (r *resourceView) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { + conn := r.Meta().BillingClient(ctx) + + var plan resourceViewModel + smerr.AddEnrich(ctx, &resp.Diagnostics, req.Plan.Get(ctx, &plan)) + if resp.Diagnostics.HasError() { + return + } + + var input billing.CreateBillingViewInput + smerr.AddEnrich(ctx, &resp.Diagnostics, flex.Expand(ctx, plan, &input)) + if resp.Diagnostics.HasError() { + return + } + + input.ResourceTags = getTagsIn(ctx) + + out, err := conn.CreateBillingView(ctx, &input) + if err != nil { + smerr.AddError(ctx, &resp.Diagnostics, err, smerr.ID, plan.Name.String()) + return + } + if out == nil || out.Arn == nil { + smerr.AddError(ctx, &resp.Diagnostics, errors.New("empty output"), smerr.ID, plan.Name.String()) + return + } + + plan.ARN = flex.StringToFramework(ctx, out.Arn) + + createTimeout := r.CreateTimeout(ctx, plan.Timeouts) + view, err := waitViewCreated(ctx, conn, plan.ARN.ValueString(), createTimeout) + if err != nil { + smerr.AddError(ctx, &resp.Diagnostics, err, smerr.ID, plan.Name.String()) + return + } + smerr.AddEnrich(ctx, &resp.Diagnostics, flex.Flatten(ctx, view, &plan)) + if resp.Diagnostics.HasError() { + return + } + + smerr.AddEnrich(ctx, &resp.Diagnostics, resp.State.Set(ctx, plan)) +} + +func (r *resourceView) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { + conn := r.Meta().BillingClient(ctx) + + var state resourceViewModel + smerr.AddEnrich(ctx, &resp.Diagnostics, req.State.Get(ctx, &state)) + if resp.Diagnostics.HasError() { + return + } + + out, err := findViewByARN(ctx, conn, state.ARN.ValueString()) + + if retry.NotFound(err) { + resp.Diagnostics.Append(fwdiag.NewResourceNotFoundWarningDiagnostic(err)) + resp.State.RemoveResource(ctx) + return + } + if err != nil { + smerr.AddError(ctx, &resp.Diagnostics, err, smerr.ID, state.Name.String()) + return + } + + smerr.AddEnrich(ctx, &resp.Diagnostics, flex.Flatten(ctx, out, &state)) + if resp.Diagnostics.HasError() { + return + } + + sourceViews, err := findSourceViewsByARN(ctx, conn, state.ARN.ValueString()) + if err != nil { + smerr.AddError(ctx, &resp.Diagnostics, err, smerr.ID, state.Name.String()) + return + } + state.SourceViews = flex.FlattenFrameworkStringValueListOfString(ctx, sourceViews) + + smerr.AddEnrich(ctx, &resp.Diagnostics, resp.State.Set(ctx, &state)) +} + +func (r *resourceView) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { + conn := r.Meta().BillingClient(ctx) + + var plan, state resourceViewModel + smerr.AddEnrich(ctx, &resp.Diagnostics, req.Plan.Get(ctx, &plan)) + smerr.AddEnrich(ctx, &resp.Diagnostics, req.State.Get(ctx, &state)) + if resp.Diagnostics.HasError() { + return + } + + diff, d := flex.Diff(ctx, plan, state) + smerr.AddEnrich(ctx, &resp.Diagnostics, d) + if resp.Diagnostics.HasError() { + return + } + + if diff.HasChanges() { + var input billing.UpdateBillingViewInput + smerr.AddEnrich(ctx, &resp.Diagnostics, flex.Expand(ctx, plan, &input)) + if resp.Diagnostics.HasError() { + return + } + + out, err := conn.UpdateBillingView(ctx, &input) + if err != nil { + smerr.AddError(ctx, &resp.Diagnostics, err, smerr.ID, plan.Name.String()) + return + } + if out == nil || out.Arn == nil { + smerr.AddError(ctx, &resp.Diagnostics, errors.New("empty output"), smerr.ID, plan.Name.String()) + return + } + + plan.ARN = flex.StringToFramework(ctx, out.Arn) + } + + updateTimeout := r.UpdateTimeout(ctx, plan.Timeouts) + view, err := waitViewUpdated(ctx, conn, plan.ARN.ValueString(), updateTimeout) + if err != nil { + smerr.AddError(ctx, &resp.Diagnostics, err, smerr.ID, plan.Name.String()) + return + } + smerr.AddEnrich(ctx, &resp.Diagnostics, flex.Flatten(ctx, view, &plan)) + smerr.AddEnrich(ctx, &resp.Diagnostics, resp.State.Set(ctx, &plan)) +} + +func (r *resourceView) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { + conn := r.Meta().BillingClient(ctx) + + var state resourceViewModel + smerr.AddEnrich(ctx, &resp.Diagnostics, req.State.Get(ctx, &state)) + if resp.Diagnostics.HasError() { + return + } + + input := billing.DeleteBillingViewInput{ + Arn: state.ARN.ValueStringPointer(), + } + + _, err := conn.DeleteBillingView(ctx, &input) + if err != nil { + if errs.IsA[*awstypes.ResourceNotFoundException](err) { + return + } + + smerr.AddError(ctx, &resp.Diagnostics, err, smerr.ID, state.Name.String()) + return + } + + deleteTimeout := r.DeleteTimeout(ctx, state.Timeouts) + _, err = waitViewDeleted(ctx, conn, state.ARN.ValueString(), deleteTimeout) + if err != nil { + smerr.AddError(ctx, &resp.Diagnostics, err, smerr.ID, state.Name.String()) + return + } +} + +func (r *resourceView) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { + resource.ImportStatePassthroughID(ctx, path.Root(names.AttrARN), req, resp) +} + +func findViewByARN(ctx context.Context, conn *billing.Client, arn string) (*awstypes.BillingViewElement, error) { + input := billing.GetBillingViewInput{ + Arn: aws.String(arn), + } + + out, err := conn.GetBillingView(ctx, &input) + if err != nil { + if errs.IsA[*awstypes.ResourceNotFoundException](err) { + return nil, smarterr.NewError(&retry.NotFoundError{ + LastError: err, + }) + } + + return nil, smarterr.NewError(err) + } + + if out == nil || out.BillingView.Arn == nil { + return nil, smarterr.NewError(tfresource.NewEmptyResultError(&input)) + } + + return out.BillingView, nil +} + +func findSourceViewsByARN(ctx context.Context, conn *billing.Client, arn string) ([]string, error) { + sourceViews := make([]string, 0) + + paginator := billing.NewListSourceViewsForBillingViewPaginator(conn, &billing.ListSourceViewsForBillingViewInput{ + Arn: aws.String(arn), + }) + + for paginator.HasMorePages() { + sourceView, err := paginator.NextPage(ctx) + if err != nil { + tflog.Error(ctx, "Listing source views for billing view", map[string]any{ + names.AttrARN: arn, + "error": err.Error(), + }) + return nil, err + } + + sourceViews = append(sourceViews, sourceView.SourceViews...) + } + + return sourceViews, nil +} + +func statusView(conn *billing.Client, arn string) retry.StateRefreshFunc { + return func(ctx context.Context) (any, string, error) { + output, err := findViewByARN(ctx, conn, arn) + + if retry.NotFound(err) { + return nil, "", nil + } + + if err != nil { + return nil, "", err + } + + return output, string(output.HealthStatus.StatusCode), nil + } +} + +func waitViewCreated(ctx context.Context, conn *billing.Client, arn string, timeout time.Duration) (*awstypes.BillingViewElement, error) { + stateConf := &retry.StateChangeConf{ + Pending: enum.Slice(awstypes.BillingViewStatusCreating), + Target: enum.Slice(awstypes.BillingViewStatusHealthy), + Refresh: statusView(conn, arn), + Timeout: timeout, + } + + outputRaw, err := stateConf.WaitForStateContext(ctx) + + if output, ok := outputRaw.(*awstypes.BillingViewElement); ok { + return output, err + } + + return nil, err +} + +func waitViewUpdated(ctx context.Context, conn *billing.Client, arn string, timeout time.Duration) (*awstypes.BillingViewElement, error) { + stateConf := &retry.StateChangeConf{ + Pending: enum.Slice(awstypes.BillingViewStatusUpdating), + Target: enum.Slice(awstypes.BillingViewStatusHealthy), + Refresh: statusView(conn, arn), + Timeout: timeout, + } + + outputRaw, err := stateConf.WaitForStateContext(ctx) + + if output, ok := outputRaw.(*awstypes.BillingViewElement); ok { + return output, err + } + + return nil, err +} + +func waitViewDeleted(ctx context.Context, conn *billing.Client, arn string, timeout time.Duration) (*awstypes.BillingViewElement, error) { + stateConf := &retry.StateChangeConf{ + Pending: enum.Slice(awstypes.BillingViewStatusHealthy), + Target: []string{}, + Refresh: statusView(conn, arn), + Timeout: timeout, + } + + outputRaw, err := stateConf.WaitForStateContext(ctx) + + if output, ok := outputRaw.(*awstypes.BillingViewElement); ok { + return output, err + } + + return nil, err +} + +type resourceViewModel struct { + ARN types.String `tfsdk:"arn"` + BillingViewType fwtypes.StringEnum[awstypes.BillingViewType] `tfsdk:"billing_view_type"` + CreatedAt timetypes.RFC3339 `tfsdk:"created_at"` + DataFilterExpression fwtypes.ListNestedObjectValueOf[dataFilterExpressionModel] `tfsdk:"data_filter_expression"` + DerivedViewCount types.Int32 `tfsdk:"derived_view_count"` + Description types.String `tfsdk:"description"` + Name types.String `tfsdk:"name"` + OwnerAccountId types.String `tfsdk:"owner_account_id"` + Tags tftags.Map `tfsdk:"tags"` + TagsAll tftags.Map `tfsdk:"tags_all"` + SourceAccountId types.String `tfsdk:"source_account_id"` + SourceViewCount types.Int32 `tfsdk:"source_view_count"` + SourceViews fwtypes.ListOfString `tfsdk:"source_views"` + Timeouts timeouts.Value `tfsdk:"timeouts"` + UpdatedAt timetypes.RFC3339 `tfsdk:"updated_at"` + ViewDefinitionLastUpdatedAt timetypes.RFC3339 `tfsdk:"view_definition_last_updated_at"` +} + +type dataFilterExpressionModel struct { + Dimensions fwtypes.ListNestedObjectValueOf[dimensionsModel] `tfsdk:"dimensions"` + Tags fwtypes.ListNestedObjectValueOf[tagValuesModel] `tfsdk:"tags"` + TimeRange fwtypes.ListNestedObjectValueOf[timeRangeModel] `tfsdk:"time_range"` +} + +type dimensionsModel struct { + Key fwtypes.StringEnum[awstypes.Dimension] `tfsdk:"key"` + Values fwtypes.ListOfString `tfsdk:"values"` +} + +type tagValuesModel struct { + Key types.String `tfsdk:"key"` + Values fwtypes.ListOfString `tfsdk:"values"` +} + +type timeRangeModel struct { + BeginDateInclusive timetypes.RFC3339 `tfsdk:"begin_date_inclusive"` + EndDateInclusive timetypes.RFC3339 `tfsdk:"end_date_inclusive"` +} diff --git a/internal/service/billing/view_test.go b/internal/service/billing/view_test.go new file mode 100644 index 000000000000..ddb4f4fb25b7 --- /dev/null +++ b/internal/service/billing/view_test.go @@ -0,0 +1,314 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package billing_test + +import ( + "context" + "errors" + "fmt" + "testing" + + "github.com/aws/aws-sdk-go-v2/service/billing" + awstypes "github.com/aws/aws-sdk-go-v2/service/billing/types" + sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + "github.com/hashicorp/terraform-provider-aws/internal/create" + tfbilling "github.com/hashicorp/terraform-provider-aws/internal/service/billing" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" + "github.com/hashicorp/terraform-provider-aws/names" +) + +func TestAccBillingView_basic(t *testing.T) { + ctx := acctest.Context(t) + + var view awstypes.BillingViewElement + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_billing_view.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(ctx, t) + testAccPreCheck(ctx, t) + }, + ErrorCheck: acctest.ErrorCheck(t, names.BillingServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckViewDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccViewConfig_basic(rName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckViewExists(ctx, resourceName, &view), + resource.TestCheckResourceAttr(resourceName, names.AttrName, rName), + resource.TestCheckResourceAttr(resourceName, names.AttrDescription, "Test description"), + acctest.CheckResourceAttrContains(resourceName, names.AttrARN, "billingview/custom-"), + resource.TestCheckResourceAttr(resourceName, acctest.CtTagsPercent, "0"), + resource.TestCheckResourceAttr(resourceName, acctest.CtTagsAllPercent, "0"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateIdFunc: acctest.AttrImportStateIdFunc(resourceName, names.AttrARN), + ImportStateVerify: true, + ImportStateVerifyIdentifierAttribute: names.AttrARN, + }, + }, + }) +} + +func TestAccBillingView_update(t *testing.T) { + ctx := acctest.Context(t) + + var view awstypes.BillingViewElement + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_billing_view.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(ctx, t) + testAccPreCheck(ctx, t) + }, + ErrorCheck: acctest.ErrorCheck(t, names.BillingServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckViewDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccViewConfig_update(rName, "Test description"), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckViewExists(ctx, resourceName, &view), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateIdFunc: acctest.AttrImportStateIdFunc(resourceName, names.AttrARN), + ImportStateVerifyIdentifierAttribute: names.AttrARN, + }, + { + Config: testAccViewConfig_update(fmt.Sprintf("%s-updated", rName), "Test description updated"), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckViewExists(ctx, resourceName, &view), + resource.TestCheckResourceAttr(resourceName, names.AttrName, fmt.Sprintf("%s-updated", rName)), + resource.TestCheckResourceAttr(resourceName, names.AttrDescription, "Test description updated"), + acctest.CheckResourceAttrContains(resourceName, names.AttrARN, "billingview/custom-"), + ), + }, + }, + }) +} + +func TestAccBillingView_disappears(t *testing.T) { + ctx := acctest.Context(t) + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + + var view awstypes.BillingViewElement + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_billing_view.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(ctx, t) + testAccPreCheck(ctx, t) + }, + ErrorCheck: acctest.ErrorCheck(t, names.BillingServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckViewDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccViewConfig_basic(rName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckViewExists(ctx, resourceName, &view), + acctest.CheckFrameworkResourceDisappears(ctx, acctest.Provider, tfbilling.ResourceView, resourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func TestAccBillingView_tags(t *testing.T) { + ctx := acctest.Context(t) + + var view1, view2, view3 awstypes.BillingViewElement + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_billing_view.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(ctx, t) + testAccPreCheck(ctx, t) + }, + ErrorCheck: acctest.ErrorCheck(t, names.BillingServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckViewDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccViewConfig_tags1(rName, acctest.CtKey1, acctest.CtValue1), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckViewExists(ctx, resourceName, &view1), + resource.TestCheckResourceAttr(resourceName, names.AttrName, rName), + resource.TestCheckResourceAttr(resourceName, acctest.CtTagsPercent, "1"), + resource.TestCheckResourceAttr(resourceName, acctest.CtTagsKey1, acctest.CtValue1), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateIdFunc: acctest.AttrImportStateIdFunc(resourceName, names.AttrARN), + ImportStateVerify: true, + ImportStateVerifyIdentifierAttribute: names.AttrARN, + }, + { + Config: testAccViewConfig_tags2(rName, acctest.CtKey1, acctest.CtValue1Updated, acctest.CtKey2, acctest.CtValue2), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckViewExists(ctx, resourceName, &view2), + resource.TestCheckResourceAttr(resourceName, names.AttrName, rName), + resource.TestCheckResourceAttr(resourceName, acctest.CtTagsPercent, "2"), + resource.TestCheckResourceAttr(resourceName, acctest.CtTagsKey1, acctest.CtValue1Updated), + resource.TestCheckResourceAttr(resourceName, acctest.CtTagsKey2, acctest.CtValue2), + ), + }, + { + Config: testAccViewConfig_tags1(rName, acctest.CtKey2, acctest.CtValue2), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckViewExists(ctx, resourceName, &view3), + resource.TestCheckResourceAttr(resourceName, names.AttrName, rName), + resource.TestCheckResourceAttr(resourceName, acctest.CtTagsPercent, "1"), + resource.TestCheckResourceAttr(resourceName, acctest.CtTagsKey2, acctest.CtValue2), + ), + }, + }, + }) +} + +func testAccCheckViewDestroy(ctx context.Context) resource.TestCheckFunc { + return func(s *terraform.State) error { + conn := acctest.Provider.Meta().(*conns.AWSClient).BillingClient(ctx) + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_billing_view" { + continue + } + + arn := rs.Primary.Attributes[names.AttrARN] + if arn == "" { + return create.Error(names.Billing, create.ErrActionCheckingExistence, tfbilling.ResNameView, arn, errors.New("no ARN is set")) + } + + _, err := tfbilling.FindViewByARN(ctx, conn, arn) + if tfresource.NotFound(err) { + return nil + } + if err != nil { + return create.Error(names.Billing, create.ErrActionCheckingDestroyed, tfbilling.ResNameView, arn, err) + } + + return create.Error(names.Billing, create.ErrActionCheckingDestroyed, tfbilling.ResNameView, arn, errors.New("not destroyed")) + } + + return nil + } +} + +func testAccCheckViewExists(ctx context.Context, name string, view *awstypes.BillingViewElement) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[name] + if !ok { + return create.Error(names.Billing, create.ErrActionCheckingExistence, tfbilling.ResNameView, name, errors.New("not found")) + } + + conn := acctest.Provider.Meta().(*conns.AWSClient).BillingClient(ctx) + + arn := rs.Primary.Attributes[names.AttrARN] + if arn == "" { + return create.Error(names.Billing, create.ErrActionCheckingExistence, tfbilling.ResNameView, arn, errors.New("no ARN is set")) + } + + resp, err := tfbilling.FindViewByARN(ctx, conn, arn) + if err != nil { + return create.Error(names.Billing, create.ErrActionCheckingExistence, tfbilling.ResNameView, arn, err) + } + + *view = *resp + + return nil + } +} + +func testAccPreCheck(ctx context.Context, t *testing.T) { + conn := acctest.Provider.Meta().(*conns.AWSClient).BillingClient(ctx) + + input := billing.ListBillingViewsInput{} + + _, err := conn.ListBillingViews(ctx, &input) + + if acctest.PreCheckSkipError(err) { + t.Skipf("skipping acceptance testing: %s", err) + } + if err != nil { + t.Fatalf("unexpected PreCheck error: %s", err) + } +} + +func testAccViewConfig_base() string { + return ` +data "aws_caller_identity" "current" {} +data "aws_partition" "current" {} +` +} + +func testAccViewConfig_basic(rName string) string { + return acctest.ConfigCompose(testAccViewConfig_base(), fmt.Sprintf(` +resource "aws_billing_view" "test" { + name = "%s" + description = "Test description" + source_views = ["arn:${data.aws_partition.current.partition}:billing::${data.aws_caller_identity.current.account_id}:billingview/primary"] +} +`, rName)) +} + +func testAccViewConfig_update(rName, description string) string { + return acctest.ConfigCompose(testAccViewConfig_base(), fmt.Sprintf(` +resource "aws_billing_view" "test" { + name = %[1]q + description = %[2]q + source_views = ["arn:${data.aws_partition.current.partition}:billing::${data.aws_caller_identity.current.account_id}:billingview/primary"] +} +`, rName, description)) +} + +func testAccViewConfig_tags1(rName, tagKey1, tagValue1 string) string { + return acctest.ConfigCompose(testAccViewConfig_base(), fmt.Sprintf(` +resource "aws_billing_view" "test" { + name = %[1]q + description = "Test description" + source_views = ["arn:${data.aws_partition.current.partition}:billing::${data.aws_caller_identity.current.account_id}:billingview/primary"] + + tags = { + %[2]q = %[3]q + } +} +`, rName, tagKey1, tagValue1)) +} + +func testAccViewConfig_tags2(rName, tagKey1, tagValue1, tagKey2, tagValue2 string) string { + return acctest.ConfigCompose(testAccViewConfig_base(), fmt.Sprintf(` +resource "aws_billing_view" "test" { + name = %[1]q + description = "Test description" + source_views = ["arn:${data.aws_partition.current.partition}:billing::${data.aws_caller_identity.current.account_id}:billingview/primary"] + + tags = { + %[2]q = %[3]q + %[4]q = %[5]q + } +} +`, rName, tagKey1, tagValue1, tagKey2, tagValue2)) +} diff --git a/internal/service/elbv2/load_balancer_test.go b/internal/service/elbv2/load_balancer_test.go index 211a2e7bbbed..87fffa462386 100644 --- a/internal/service/elbv2/load_balancer_test.go +++ b/internal/service/elbv2/load_balancer_test.go @@ -2403,7 +2403,7 @@ func testAccCheckLoadBalancerDestroy(ctx context.Context) resource.TestCheckFunc continue } - ctx = conns.NewResourceContext(ctx, "", "", rs.Primary.Attributes[names.AttrRegion]) + ctx = conns.NewResourceContext(ctx, "", "", "", rs.Primary.Attributes[names.AttrRegion]) conn := acctest.Provider.Meta().(*conns.AWSClient).ELBV2Client(ctx) _, err := tfelbv2.FindLoadBalancerByARN(ctx, conn, rs.Primary.ID) diff --git a/internal/service/fsx/openzfs_file_system.go b/internal/service/fsx/openzfs_file_system.go index 188add6186d5..e875e3f394e4 100644 --- a/internal/service/fsx/openzfs_file_system.go +++ b/internal/service/fsx/openzfs_file_system.go @@ -154,6 +154,26 @@ func resourceOpenZFSFileSystem() *schema.Resource { Type: schema.TypeString, Computed: true, }, + "read_cache_configuration": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + names.AttrSize: { + Type: schema.TypeInt, + Optional: true, + Computed: true, + ValidateFunc: validation.IntBetween(0, 2147483647), + }, + "sizing_mode": { + Type: schema.TypeString, + Optional: true, + ValidateDiagFunc: enum.Validate[awstypes.OpenZFSReadCacheSizingMode](), + }, + }, + }, + }, "preferred_subnet_id": { Type: schema.TypeString, Optional: true, @@ -336,6 +356,18 @@ func resourceOpenZFSFileSystem() *schema.Resource { return nil }, + func(_ context.Context, d *schema.ResourceDiff, meta any) error { + switch storageType := d.Get(names.AttrStorageType).(string); storageType { + case string(awstypes.StorageTypeIntelligentTiering): + if deploymentType := d.Get("deployment_type").(string); deploymentType != string(awstypes.OpenZFSDeploymentTypeMultiAz1) { + return fmt.Errorf("invalid deployment_type %q for storage_type %q: only %q is supported", deploymentType, storageType, awstypes.OpenZFSDeploymentTypeMultiAz1) + } + if _, ok := d.GetOk("storage_capacity"); ok { + return fmt.Errorf("storage_capacity cannot be specified for storage_type %q", storageType) + } + } + return nil + }, ), } } @@ -375,10 +407,9 @@ func resourceOpenZFSFileSystemCreate(ctx context.Context, d *schema.ResourceData DeploymentType: awstypes.OpenZFSDeploymentType(d.Get("deployment_type").(string)), AutomaticBackupRetentionDays: aws.Int32(int32(d.Get("automatic_backup_retention_days").(int))), }, - StorageCapacity: aws.Int32(int32(d.Get("storage_capacity").(int))), - StorageType: awstypes.StorageType(d.Get(names.AttrStorageType).(string)), - SubnetIds: flex.ExpandStringValueList(d.Get(names.AttrSubnetIDs).([]any)), - Tags: getTagsIn(ctx), + StorageType: awstypes.StorageType(d.Get(names.AttrStorageType).(string)), + SubnetIds: flex.ExpandStringValueList(d.Get(names.AttrSubnetIDs).([]any)), + Tags: getTagsIn(ctx), } inputB := &fsx.CreateFileSystemFromBackupInput{ ClientRequestToken: aws.String(id.UniqueId()), @@ -391,6 +422,10 @@ func resourceOpenZFSFileSystemCreate(ctx context.Context, d *schema.ResourceData Tags: getTagsIn(ctx), } + if v, ok := d.GetOk("storage_capacity"); ok { + inputC.StorageCapacity = aws.Int32(int32(v.(int))) + } + if v, ok := d.GetOk("copy_tags_to_backups"); ok { inputC.OpenZFSConfiguration.CopyTagsToBackups = aws.Bool(v.(bool)) inputB.OpenZFSConfiguration.CopyTagsToBackups = aws.Bool(v.(bool)) @@ -426,6 +461,11 @@ func resourceOpenZFSFileSystemCreate(ctx context.Context, d *schema.ResourceData inputB.OpenZFSConfiguration.PreferredSubnetId = aws.String(v.(string)) } + if v, ok := d.GetOk("read_cache_configuration"); ok { + inputC.OpenZFSConfiguration.ReadCacheConfiguration = expandOpenZFSReadCacheConfiguration(v.([]any)) + inputB.OpenZFSConfiguration.ReadCacheConfiguration = expandOpenZFSReadCacheConfiguration(v.([]any)) + } + if v, ok := d.GetOk("root_volume_configuration"); ok { inputC.OpenZFSConfiguration.RootVolumeConfiguration = expandOpenZFSCreateRootVolumeConfiguration(v.([]any)) inputB.OpenZFSConfiguration.RootVolumeConfiguration = expandOpenZFSCreateRootVolumeConfiguration(v.([]any)) @@ -513,6 +553,9 @@ func resourceOpenZFSFileSystemRead(ctx context.Context, d *schema.ResourceData, d.Set("network_interface_ids", filesystem.NetworkInterfaceIds) d.Set(names.AttrOwnerID, filesystem.OwnerId) d.Set("preferred_subnet_id", openZFSConfig.PreferredSubnetId) + if err := d.Set("read_cache_configuration", flattenOpenZFSReadCacheConfiguration(openZFSConfig.ReadCacheConfiguration)); err != nil { + return sdkdiag.AppendErrorf(diags, "setting read_cache_configuration: %s", err) + } rootVolumeID := aws.ToString(openZFSConfig.RootVolumeId) d.Set("root_volume_id", rootVolumeID) d.Set("route_table_ids", openZFSConfig.RouteTableIds) @@ -576,6 +619,10 @@ func resourceOpenZFSFileSystemUpdate(ctx context.Context, d *schema.ResourceData input.OpenZFSConfiguration.DiskIopsConfiguration = expandDiskIopsConfiguration(d.Get("disk_iops_configuration").([]any)) } + if d.HasChange("read_cache_configuration") { + input.OpenZFSConfiguration.ReadCacheConfiguration = expandOpenZFSReadCacheConfiguration(d.Get("read_cache_configuration").([]any)) + } + if d.HasChange("route_table_ids") { o, n := d.GetChange("route_table_ids") os, ns := o.(*schema.Set), n.(*schema.Set) @@ -590,7 +637,9 @@ func resourceOpenZFSFileSystemUpdate(ctx context.Context, d *schema.ResourceData } if d.HasChange("storage_capacity") { - input.StorageCapacity = aws.Int32(int32(d.Get("storage_capacity").(int))) + if v, ok := d.GetOk("storage_capacity"); ok { + input.StorageCapacity = aws.Int32(int32(v.(int))) + } } if d.HasChange("throughput_capacity") { @@ -736,6 +785,26 @@ func expandOpenZFSCreateRootVolumeConfiguration(tfList []any) *awstypes.OpenZFSC return apiObject } +func expandOpenZFSReadCacheConfiguration(tfList []any) *awstypes.OpenZFSReadCacheConfiguration { + if len(tfList) < 1 { + return nil + } + + tfMap := tfList[0].(map[string]any) + apiObject := &awstypes.OpenZFSReadCacheConfiguration{} + + if v, ok := tfMap["sizing_mode"].(string); ok { + apiObject.SizingMode = awstypes.OpenZFSReadCacheSizingMode(v) + } + if apiObject.SizingMode == awstypes.OpenZFSReadCacheSizingModeUserProvisioned { + if v, ok := tfMap[names.AttrSize].(int); ok && v > 0 { + apiObject.SizeGiB = aws.Int32(int32(v)) + } + } + + return apiObject +} + func expandUpdateOpenZFSVolumeConfiguration(tfList []any) *awstypes.UpdateOpenZFSVolumeConfiguration { if len(tfList) < 1 { return nil @@ -781,6 +850,23 @@ func flattenDiskIopsConfiguration(rs *awstypes.DiskIopsConfiguration) []any { return []any{m} } +func flattenOpenZFSReadCacheConfiguration(apiObject *awstypes.OpenZFSReadCacheConfiguration) []any { + if apiObject == nil { + return []any{} + } + + tfMap := make(map[string]any) + + if apiObject.SizingMode != "" { + tfMap["sizing_mode"] = string(apiObject.SizingMode) + } + + // if apiObject.SizeGiB is nil, tfMap[names.AttrSize] will be zero value (0) + tfMap[names.AttrSize] = aws.ToInt32(apiObject.SizeGiB) + + return []any{tfMap} +} + func flattenOpenZFSFileSystemRootVolume(apiObject *awstypes.Volume) []any { if apiObject == nil { return []any{} diff --git a/internal/service/fsx/openzfs_file_system_test.go b/internal/service/fsx/openzfs_file_system_test.go index a087854df3d4..70b345a841c1 100644 --- a/internal/service/fsx/openzfs_file_system_test.go +++ b/internal/service/fsx/openzfs_file_system_test.go @@ -13,6 +13,7 @@ import ( awstypes "github.com/aws/aws-sdk-go-v2/service/fsx/types" sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/plancheck" "github.com/hashicorp/terraform-plugin-testing/terraform" "github.com/hashicorp/terraform-provider-aws/internal/acctest" "github.com/hashicorp/terraform-provider-aws/internal/conns" @@ -1052,6 +1053,211 @@ func TestAccFSxOpenZFSFileSystem_deleteConfig(t *testing.T) { }) } +func TestAccFSxOpenZFSFileSystem_intelligentTiering(t *testing.T) { + ctx := acctest.Context(t) + var filesystem awstypes.FileSystem + resourceName := "aws_fsx_openzfs_file_system.test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t); acctest.PreCheckPartitionHasService(t, names.FSxEndpointID) }, + ErrorCheck: acctest.ErrorCheck(t, names.FSxServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckOpenZFSFileSystemDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccOpenZFSFileSystemConfig_intelligentTiering(rName), + ConfigPlanChecks: resource.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionCreate), + }, + }, + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckOpenZFSFileSystemExists(ctx, resourceName, &filesystem), + acctest.MatchResourceAttrRegionalARN(ctx, resourceName, names.AttrARN, "fsx", regexache.MustCompile(`file-system/fs-.+`)), + resource.TestCheckResourceAttr(resourceName, "automatic_backup_retention_days", "0"), + resource.TestCheckNoResourceAttr(resourceName, "backup_id"), + resource.TestCheckResourceAttr(resourceName, "copy_tags_to_backups", acctest.CtFalse), + resource.TestCheckResourceAttr(resourceName, "copy_tags_to_volumes", acctest.CtFalse), + resource.TestCheckResourceAttr(resourceName, "daily_automatic_backup_start_time", ""), + resource.TestCheckResourceAttr(resourceName, "deployment_type", string(awstypes.OpenZFSDeploymentTypeMultiAz1)), + resource.TestCheckResourceAttr(resourceName, "disk_iops_configuration.#", "0"), + resource.TestCheckResourceAttrSet(resourceName, names.AttrDNSName), + resource.TestCheckResourceAttrSet(resourceName, "endpoint_ip_address"), + resource.TestCheckResourceAttrSet(resourceName, "endpoint_ip_address_range"), + resource.TestCheckResourceAttrSet(resourceName, names.AttrKMSKeyID), + resource.TestCheckResourceAttr(resourceName, "network_interface_ids.#", "2"), + acctest.CheckResourceAttrAccountID(ctx, resourceName, names.AttrOwnerID), + resource.TestCheckResourceAttrPair(resourceName, "preferred_subnet_id", "aws_subnet.test.0", names.AttrID), + resource.TestCheckResourceAttr(resourceName, "read_cache_configuration.#", "1"), + resource.TestCheckResourceAttr(resourceName, "read_cache_configuration.0.size", "64"), + resource.TestCheckResourceAttr(resourceName, "read_cache_configuration.0.sizing_mode", string(awstypes.OpenZFSReadCacheSizingModeUserProvisioned)), + resource.TestCheckResourceAttr(resourceName, "root_volume_configuration.#", "1"), + resource.TestCheckResourceAttr(resourceName, "root_volume_configuration.0.data_compression_type", "NONE"), + resource.TestCheckResourceAttr(resourceName, "root_volume_configuration.0.nfs_exports.#", "1"), + resource.TestCheckResourceAttr(resourceName, "root_volume_configuration.0.nfs_exports.0.client_configurations.#", "1"), + resource.TestCheckResourceAttr(resourceName, "root_volume_configuration.0.nfs_exports.0.client_configurations.0.clients", "*"), + resource.TestCheckResourceAttr(resourceName, "root_volume_configuration.0.nfs_exports.0.client_configurations.0.options.#", "2"), + resource.TestCheckResourceAttr(resourceName, "root_volume_configuration.0.nfs_exports.0.client_configurations.0.options.0", "rw"), + resource.TestCheckResourceAttr(resourceName, "root_volume_configuration.0.nfs_exports.0.client_configurations.0.options.1", "crossmnt"), + resource.TestCheckResourceAttr(resourceName, "root_volume_configuration.0.read_only", acctest.CtFalse), + resource.TestCheckResourceAttr(resourceName, "root_volume_configuration.0.record_size_kib", "1024"), + resource.TestCheckResourceAttr(resourceName, "root_volume_configuration.0.user_and_group_quotas.#", "2"), + resource.TestCheckResourceAttrSet(resourceName, "root_volume_id"), + resource.TestCheckResourceAttr(resourceName, "route_table_ids.#", "1"), + resource.TestCheckResourceAttr(resourceName, "security_group_ids.#", "0"), + resource.TestCheckResourceAttr(resourceName, "skip_final_backup", acctest.CtTrue), + resource.TestCheckResourceAttr(resourceName, names.AttrStorageType, string(awstypes.StorageTypeIntelligentTiering)), + resource.TestCheckResourceAttr(resourceName, "subnet_ids.#", "2"), + resource.TestCheckTypeSetElemAttrPair(resourceName, "subnet_ids.*", "aws_subnet.test.0", names.AttrID), + resource.TestCheckTypeSetElemAttrPair(resourceName, "subnet_ids.*", "aws_subnet.test.1", names.AttrID), + resource.TestCheckResourceAttr(resourceName, acctest.CtTagsPercent, "1"), + resource.TestCheckResourceAttr(resourceName, "tags.Name", rName), + resource.TestCheckResourceAttr(resourceName, "throughput_capacity", "160"), + resource.TestCheckResourceAttrPair(resourceName, names.AttrVPCID, "aws_vpc.test", names.AttrID), + resource.TestMatchResourceAttr(resourceName, "weekly_maintenance_start_time", regexache.MustCompile(`^\d:\d\d:\d\d$`)), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "delete_options", + "final_backup_tags", + "skip_final_backup", + }, + }, + { + Config: testAccOpenZFSFileSystemConfig_intelligentTieringUpdated(rName, string(awstypes.OpenZFSReadCacheSizingModeProportionalToThroughputCapacity)), + ConfigPlanChecks: resource.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionUpdate), + }, + }, + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckOpenZFSFileSystemExists(ctx, resourceName, &filesystem), + acctest.MatchResourceAttrRegionalARN(ctx, resourceName, names.AttrARN, "fsx", regexache.MustCompile(`file-system/fs-.+`)), + resource.TestCheckResourceAttr(resourceName, "automatic_backup_retention_days", "0"), + resource.TestCheckNoResourceAttr(resourceName, "backup_id"), + resource.TestCheckResourceAttr(resourceName, "copy_tags_to_backups", acctest.CtFalse), + resource.TestCheckResourceAttr(resourceName, "copy_tags_to_volumes", acctest.CtFalse), + resource.TestCheckResourceAttr(resourceName, "daily_automatic_backup_start_time", ""), + resource.TestCheckResourceAttr(resourceName, "deployment_type", string(awstypes.OpenZFSDeploymentTypeMultiAz1)), + resource.TestCheckResourceAttr(resourceName, "disk_iops_configuration.#", "0"), + resource.TestCheckResourceAttrSet(resourceName, names.AttrDNSName), + resource.TestCheckResourceAttrSet(resourceName, "endpoint_ip_address"), + resource.TestCheckResourceAttrSet(resourceName, "endpoint_ip_address_range"), + resource.TestCheckResourceAttrSet(resourceName, names.AttrKMSKeyID), + resource.TestCheckResourceAttr(resourceName, "network_interface_ids.#", "2"), + acctest.CheckResourceAttrAccountID(ctx, resourceName, names.AttrOwnerID), + resource.TestCheckResourceAttrPair(resourceName, "preferred_subnet_id", "aws_subnet.test.0", names.AttrID), + resource.TestCheckResourceAttr(resourceName, "read_cache_configuration.#", "1"), + resource.TestCheckResourceAttr(resourceName, "read_cache_configuration.0.sizing_mode", string(awstypes.OpenZFSReadCacheSizingModeProportionalToThroughputCapacity)), + resource.TestCheckResourceAttr(resourceName, "read_cache_configuration.0.size", "800"), + resource.TestCheckResourceAttr(resourceName, "root_volume_configuration.#", "1"), + resource.TestCheckResourceAttr(resourceName, "root_volume_configuration.0.data_compression_type", "NONE"), + resource.TestCheckResourceAttr(resourceName, "root_volume_configuration.0.nfs_exports.#", "1"), + resource.TestCheckResourceAttr(resourceName, "root_volume_configuration.0.nfs_exports.0.client_configurations.#", "1"), + resource.TestCheckResourceAttr(resourceName, "root_volume_configuration.0.nfs_exports.0.client_configurations.0.clients", "*"), + resource.TestCheckResourceAttr(resourceName, "root_volume_configuration.0.nfs_exports.0.client_configurations.0.options.#", "2"), + resource.TestCheckResourceAttr(resourceName, "root_volume_configuration.0.nfs_exports.0.client_configurations.0.options.0", "rw"), + resource.TestCheckResourceAttr(resourceName, "root_volume_configuration.0.nfs_exports.0.client_configurations.0.options.1", "crossmnt"), + resource.TestCheckResourceAttr(resourceName, "root_volume_configuration.0.read_only", acctest.CtFalse), + resource.TestCheckResourceAttr(resourceName, "root_volume_configuration.0.record_size_kib", "1024"), + resource.TestCheckResourceAttr(resourceName, "root_volume_configuration.0.user_and_group_quotas.#", "2"), + resource.TestCheckResourceAttrSet(resourceName, "root_volume_id"), + resource.TestCheckResourceAttr(resourceName, "route_table_ids.#", "1"), + resource.TestCheckResourceAttr(resourceName, "security_group_ids.#", "0"), + resource.TestCheckResourceAttr(resourceName, "skip_final_backup", acctest.CtTrue), + resource.TestCheckResourceAttr(resourceName, names.AttrStorageType, string(awstypes.StorageTypeIntelligentTiering)), + resource.TestCheckResourceAttr(resourceName, "subnet_ids.#", "2"), + resource.TestCheckTypeSetElemAttrPair(resourceName, "subnet_ids.*", "aws_subnet.test.0", names.AttrID), + resource.TestCheckTypeSetElemAttrPair(resourceName, "subnet_ids.*", "aws_subnet.test.1", names.AttrID), + resource.TestCheckResourceAttr(resourceName, acctest.CtTagsPercent, "1"), + resource.TestCheckResourceAttr(resourceName, "tags.Name", rName), + resource.TestCheckResourceAttr(resourceName, "throughput_capacity", "160"), + resource.TestCheckResourceAttrPair(resourceName, names.AttrVPCID, "aws_vpc.test", names.AttrID), + resource.TestMatchResourceAttr(resourceName, "weekly_maintenance_start_time", regexache.MustCompile(`^\d:\d\d:\d\d$`)), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "delete_options", + "final_backup_tags", + "skip_final_backup", + }, + }, + { + Config: testAccOpenZFSFileSystemConfig_intelligentTieringUpdated(rName, string(awstypes.OpenZFSReadCacheSizingModeNoCache)), + ConfigPlanChecks: resource.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionUpdate), + }, + }, + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckOpenZFSFileSystemExists(ctx, resourceName, &filesystem), + acctest.MatchResourceAttrRegionalARN(ctx, resourceName, names.AttrARN, "fsx", regexache.MustCompile(`file-system/fs-.+`)), + resource.TestCheckResourceAttr(resourceName, "automatic_backup_retention_days", "0"), + resource.TestCheckNoResourceAttr(resourceName, "backup_id"), + resource.TestCheckResourceAttr(resourceName, "copy_tags_to_backups", acctest.CtFalse), + resource.TestCheckResourceAttr(resourceName, "copy_tags_to_volumes", acctest.CtFalse), + resource.TestCheckResourceAttr(resourceName, "daily_automatic_backup_start_time", ""), + resource.TestCheckResourceAttr(resourceName, "deployment_type", string(awstypes.OpenZFSDeploymentTypeMultiAz1)), + resource.TestCheckResourceAttr(resourceName, "disk_iops_configuration.#", "0"), + resource.TestCheckResourceAttrSet(resourceName, names.AttrDNSName), + resource.TestCheckResourceAttrSet(resourceName, "endpoint_ip_address"), + resource.TestCheckResourceAttrSet(resourceName, "endpoint_ip_address_range"), + resource.TestCheckResourceAttrSet(resourceName, names.AttrKMSKeyID), + resource.TestCheckResourceAttr(resourceName, "network_interface_ids.#", "2"), + acctest.CheckResourceAttrAccountID(ctx, resourceName, names.AttrOwnerID), + resource.TestCheckResourceAttrPair(resourceName, "preferred_subnet_id", "aws_subnet.test.0", names.AttrID), + resource.TestCheckResourceAttr(resourceName, "read_cache_configuration.#", "1"), + resource.TestCheckResourceAttr(resourceName, "read_cache_configuration.0.sizing_mode", string(awstypes.OpenZFSReadCacheSizingModeNoCache)), + resource.TestCheckResourceAttr(resourceName, "read_cache_configuration.0.size", "0"), + resource.TestCheckResourceAttr(resourceName, "root_volume_configuration.#", "1"), + resource.TestCheckResourceAttr(resourceName, "root_volume_configuration.0.data_compression_type", "NONE"), + resource.TestCheckResourceAttr(resourceName, "root_volume_configuration.0.nfs_exports.#", "1"), + resource.TestCheckResourceAttr(resourceName, "root_volume_configuration.0.nfs_exports.0.client_configurations.#", "1"), + resource.TestCheckResourceAttr(resourceName, "root_volume_configuration.0.nfs_exports.0.client_configurations.0.clients", "*"), + resource.TestCheckResourceAttr(resourceName, "root_volume_configuration.0.nfs_exports.0.client_configurations.0.options.#", "2"), + resource.TestCheckResourceAttr(resourceName, "root_volume_configuration.0.nfs_exports.0.client_configurations.0.options.0", "rw"), + resource.TestCheckResourceAttr(resourceName, "root_volume_configuration.0.nfs_exports.0.client_configurations.0.options.1", "crossmnt"), + resource.TestCheckResourceAttr(resourceName, "root_volume_configuration.0.read_only", acctest.CtFalse), + resource.TestCheckResourceAttr(resourceName, "root_volume_configuration.0.record_size_kib", "1024"), + resource.TestCheckResourceAttr(resourceName, "root_volume_configuration.0.user_and_group_quotas.#", "2"), + resource.TestCheckResourceAttrSet(resourceName, "root_volume_id"), + resource.TestCheckResourceAttr(resourceName, "route_table_ids.#", "1"), + resource.TestCheckResourceAttr(resourceName, "security_group_ids.#", "0"), + resource.TestCheckResourceAttr(resourceName, "skip_final_backup", acctest.CtTrue), + resource.TestCheckResourceAttr(resourceName, names.AttrStorageType, string(awstypes.StorageTypeIntelligentTiering)), + resource.TestCheckResourceAttr(resourceName, "subnet_ids.#", "2"), + resource.TestCheckTypeSetElemAttrPair(resourceName, "subnet_ids.*", "aws_subnet.test.0", names.AttrID), + resource.TestCheckTypeSetElemAttrPair(resourceName, "subnet_ids.*", "aws_subnet.test.1", names.AttrID), + resource.TestCheckResourceAttr(resourceName, acctest.CtTagsPercent, "1"), + resource.TestCheckResourceAttr(resourceName, "tags.Name", rName), + resource.TestCheckResourceAttr(resourceName, "throughput_capacity", "160"), + resource.TestCheckResourceAttrPair(resourceName, names.AttrVPCID, "aws_vpc.test", names.AttrID), + resource.TestMatchResourceAttr(resourceName, "weekly_maintenance_start_time", regexache.MustCompile(`^\d:\d\d:\d\d$`)), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "delete_options", + "final_backup_tags", + "skip_final_backup", + }, + }, + }, + }) +} + func testAccCheckOpenZFSFileSystemExists(ctx context.Context, n string, v *awstypes.FileSystem) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] @@ -1765,3 +1971,46 @@ resource "aws_fsx_openzfs_file_system" "test" { } `, finalTagKey1, finalTagValue1, finalTagKey2, finalTagValue2)) } + +func testAccOpenZFSFileSystemConfig_intelligentTiering(rName string) string { + return acctest.ConfigCompose(testAccOpenZFSFileSystemConfig_baseMultiAZ(rName), fmt.Sprintf(` +resource "aws_fsx_openzfs_file_system" "test" { + skip_final_backup = true + subnet_ids = aws_subnet.test[*].id + preferred_subnet_id = aws_subnet.test[0].id + deployment_type = "MULTI_AZ_1" + throughput_capacity = 160 + + storage_type = "INTELLIGENT_TIERING" + read_cache_configuration { + sizing_mode = "USER_PROVISIONED" + size = 64 + } + + tags = { + Name = %[1]q + } +} +`, rName)) +} + +func testAccOpenZFSFileSystemConfig_intelligentTieringUpdated(rName, sizingMode string) string { + return acctest.ConfigCompose(testAccOpenZFSFileSystemConfig_baseMultiAZ(rName), fmt.Sprintf(` +resource "aws_fsx_openzfs_file_system" "test" { + skip_final_backup = true + subnet_ids = aws_subnet.test[*].id + preferred_subnet_id = aws_subnet.test[0].id + deployment_type = "MULTI_AZ_1" + throughput_capacity = 160 + + storage_type = "INTELLIGENT_TIERING" + read_cache_configuration { + sizing_mode = %[2]q + } + + tags = { + Name = %[1]q + } +} +`, rName, sizingMode)) +} diff --git a/internal/service/iot/billing_group_test.go b/internal/service/iot/billing_group_test.go index e72ae309a8d5..83ddcb57562b 100644 --- a/internal/service/iot/billing_group_test.go +++ b/internal/service/iot/billing_group_test.go @@ -11,8 +11,11 @@ import ( "github.com/YakDriver/regexache" sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/knownvalue" "github.com/hashicorp/terraform-plugin-testing/plancheck" + "github.com/hashicorp/terraform-plugin-testing/statecheck" "github.com/hashicorp/terraform-plugin-testing/terraform" + "github.com/hashicorp/terraform-plugin-testing/tfjsonpath" "github.com/hashicorp/terraform-provider-aws/internal/acctest" "github.com/hashicorp/terraform-provider-aws/internal/conns" tfiot "github.com/hashicorp/terraform-provider-aws/internal/service/iot" @@ -267,6 +270,368 @@ func TestAccIoTBillingGroup_migrateFromPluginSDK_properties(t *testing.T) { }) } +func TestAccIoTBillingGroup_requiredTags(t *testing.T) { + ctx := acctest.Context(t) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_iot_billing_group.test" + tagKey := acctest.SkipIfEnvVarNotSet(t, "TF_ACC_REQUIRED_TAG_KEY") + nonRequiredTagKey := "NotARequiredKey" + + acctest.ParallelTest(ctx, t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(ctx, t) + acctest.PreCheckResourceGroupsTaggingAPIRequiredTags(ctx, t) + }, + ErrorCheck: acctest.ErrorCheck(t, names.IoTServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckBillingGroupDestroy(ctx), + Steps: []resource.TestStep{ + // New resources missing required tags fail + { + Config: acctest.ConfigCompose( + acctest.ConfigTagPolicyCompliance("error"), + testAccBillingGroupConfig_basic(rName), + ), + ConfigPlanChecks: resource.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionCreate), + }, + }, + ExpectError: regexache.MustCompile("Missing Required Tags"), + }, + // Creation with required tags succeeds + { + Config: acctest.ConfigCompose( + acctest.ConfigTagPolicyCompliance("error"), + testAccBillingGroupConfig_tags1(rName, tagKey, acctest.CtValue1), + ), + ConfigPlanChecks: resource.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionCreate), + plancheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrTags), knownvalue.MapExact(map[string]knownvalue.Check{ + tagKey: knownvalue.StringExact(acctest.CtValue1), + })), + plancheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrTagsAll), knownvalue.MapExact(map[string]knownvalue.Check{ + tagKey: knownvalue.StringExact(acctest.CtValue1), + })), + }, + }, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrTags), knownvalue.MapExact(map[string]knownvalue.Check{ + tagKey: knownvalue.StringExact(acctest.CtValue1), + })), + statecheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrTagsAll), knownvalue.MapExact(map[string]knownvalue.Check{ + tagKey: knownvalue.StringExact(acctest.CtValue1), + })), + }, + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckBillingGroupExists(ctx, resourceName), + ), + }, + // Updates which remove required tags fail + { + Config: acctest.ConfigCompose( + acctest.ConfigTagPolicyCompliance("error"), + testAccBillingGroupConfig_tags1(rName, nonRequiredTagKey, acctest.CtValue1), + ), + ConfigPlanChecks: resource.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionUpdate), + plancheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrTags), knownvalue.MapExact(map[string]knownvalue.Check{ + nonRequiredTagKey: knownvalue.StringExact(acctest.CtValue1), + })), + plancheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrTagsAll), knownvalue.MapExact(map[string]knownvalue.Check{ + nonRequiredTagKey: knownvalue.StringExact(acctest.CtValue1), + })), + }, + }, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrTags), knownvalue.MapExact(map[string]knownvalue.Check{ + tagKey: knownvalue.StringExact(acctest.CtValue1), + })), + statecheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrTagsAll), knownvalue.MapExact(map[string]knownvalue.Check{ + tagKey: knownvalue.StringExact(acctest.CtValue1), + })), + }, + ExpectError: regexache.MustCompile("Missing Required Tags"), + }, + }, + }) +} + +func TestAccIoTBillingGroup_requiredTags_defaultTags(t *testing.T) { + ctx := acctest.Context(t) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_iot_billing_group.test" + tagKey := acctest.SkipIfEnvVarNotSet(t, "TF_ACC_REQUIRED_TAG_KEY") + nonRequiredTagKey := "NotARequiredKey" + + acctest.ParallelTest(ctx, t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(ctx, t) + acctest.PreCheckResourceGroupsTaggingAPIRequiredTags(ctx, t) + }, + ErrorCheck: acctest.ErrorCheck(t, names.IoTServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckBillingGroupDestroy(ctx), + Steps: []resource.TestStep{ + // New resources missing required tags fail + { + Config: acctest.ConfigCompose( + acctest.ConfigTagPolicyCompliance("error"), + testAccBillingGroupConfig_basic(rName), + ), + ConfigPlanChecks: resource.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionCreate), + }, + }, + ExpectError: regexache.MustCompile("Missing Required Tags"), + }, + // Creation with required tags in default_tags succeeds + { + Config: acctest.ConfigCompose( + acctest.ConfigTagPolicyComplianceAndDefaultTags1("error", tagKey, acctest.CtValue1), + testAccBillingGroupConfig_basic(rName), + ), + ConfigPlanChecks: resource.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionCreate), + plancheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrTags), knownvalue.Null()), + plancheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrTagsAll), knownvalue.MapExact(map[string]knownvalue.Check{ + tagKey: knownvalue.StringExact(acctest.CtValue1), + })), + }, + }, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrTags), knownvalue.Null()), + statecheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrTagsAll), knownvalue.MapExact(map[string]knownvalue.Check{ + tagKey: knownvalue.StringExact(acctest.CtValue1), + })), + }, + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckBillingGroupExists(ctx, resourceName), + ), + }, + // Updates which remove required tags from default_tags fail + { + Config: acctest.ConfigCompose( + acctest.ConfigTagPolicyComplianceAndDefaultTags1("error", nonRequiredTagKey, acctest.CtValue1), + testAccBillingGroupConfig_basic(rName), + ), + ConfigPlanChecks: resource.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionUpdate), + plancheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrTags), knownvalue.Null()), + plancheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrTagsAll), knownvalue.MapExact(map[string]knownvalue.Check{ + nonRequiredTagKey: knownvalue.StringExact(acctest.CtValue1), + })), + }, + }, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrTags), knownvalue.Null()), + statecheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrTagsAll), knownvalue.MapExact(map[string]knownvalue.Check{ + tagKey: knownvalue.StringExact(acctest.CtValue1), + })), + }, + ExpectError: regexache.MustCompile("Missing Required Tags"), + }, + }, + }) +} + +func TestAccIoTBillingGroup_requiredTags_warning(t *testing.T) { + ctx := acctest.Context(t) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_iot_billing_group.test" + tagKey := acctest.SkipIfEnvVarNotSet(t, "TF_ACC_REQUIRED_TAG_KEY") + nonRequiredTagKey := "NotARequiredKey" + + acctest.ParallelTest(ctx, t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(ctx, t) + acctest.PreCheckResourceGroupsTaggingAPIRequiredTags(ctx, t) + }, + ErrorCheck: acctest.ErrorCheck(t, names.IoTServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckBillingGroupDestroy(ctx), + Steps: []resource.TestStep{ + // New resources missing required tags succeeds + { + Config: acctest.ConfigCompose( + acctest.ConfigTagPolicyCompliance("warning"), + testAccBillingGroupConfig_basic(rName), + ), + ConfigPlanChecks: resource.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionCreate), + }, + }, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrTags), knownvalue.Null()), + }, + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckBillingGroupExists(ctx, resourceName), + ), + }, + // Updates adding required tags succeeds + { + Config: acctest.ConfigCompose( + acctest.ConfigTagPolicyCompliance("warning"), + testAccBillingGroupConfig_tags1(rName, tagKey, acctest.CtValue1), + ), + ConfigPlanChecks: resource.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionUpdate), + plancheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrTags), knownvalue.MapExact(map[string]knownvalue.Check{ + tagKey: knownvalue.StringExact(acctest.CtValue1), + })), + plancheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrTagsAll), knownvalue.MapExact(map[string]knownvalue.Check{ + tagKey: knownvalue.StringExact(acctest.CtValue1), + })), + }, + }, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrTags), knownvalue.MapExact(map[string]knownvalue.Check{ + tagKey: knownvalue.StringExact(acctest.CtValue1), + })), + statecheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrTagsAll), knownvalue.MapExact(map[string]knownvalue.Check{ + tagKey: knownvalue.StringExact(acctest.CtValue1), + })), + }, + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckBillingGroupExists(ctx, resourceName), + ), + }, + // Updates which remove required tags also succeed + { + Config: acctest.ConfigCompose( + acctest.ConfigTagPolicyCompliance("warning"), + testAccBillingGroupConfig_tags1(rName, nonRequiredTagKey, acctest.CtValue1), + ), + ConfigPlanChecks: resource.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionUpdate), + plancheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrTags), knownvalue.MapExact(map[string]knownvalue.Check{ + nonRequiredTagKey: knownvalue.StringExact(acctest.CtValue1), + })), + plancheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrTagsAll), knownvalue.MapExact(map[string]knownvalue.Check{ + nonRequiredTagKey: knownvalue.StringExact(acctest.CtValue1), + })), + }, + }, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrTags), knownvalue.MapExact(map[string]knownvalue.Check{ + nonRequiredTagKey: knownvalue.StringExact(acctest.CtValue1), + })), + statecheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrTagsAll), knownvalue.MapExact(map[string]knownvalue.Check{ + nonRequiredTagKey: knownvalue.StringExact(acctest.CtValue1), + })), + }, + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckBillingGroupExists(ctx, resourceName), + ), + }, + }, + }) +} + +func TestAccIoTBillingGroup_requiredTags_disabled(t *testing.T) { + ctx := acctest.Context(t) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_iot_billing_group.test" + tagKey := acctest.SkipIfEnvVarNotSet(t, "TF_ACC_REQUIRED_TAG_KEY") + nonRequiredTagKey := "NotARequiredKey" + + acctest.ParallelTest(ctx, t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(ctx, t) + acctest.PreCheckResourceGroupsTaggingAPIRequiredTags(ctx, t) + }, + ErrorCheck: acctest.ErrorCheck(t, names.IoTServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckBillingGroupDestroy(ctx), + Steps: []resource.TestStep{ + // New resources missing required tags succeeds + { + Config: acctest.ConfigCompose( + acctest.ConfigTagPolicyCompliance("disabled"), + testAccBillingGroupConfig_basic(rName), + ), + ConfigPlanChecks: resource.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionCreate), + }, + }, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrTags), knownvalue.Null()), + }, + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckBillingGroupExists(ctx, resourceName), + ), + }, + // Updates adding required tags succeeds + { + Config: acctest.ConfigCompose( + acctest.ConfigTagPolicyCompliance("disabled"), + testAccBillingGroupConfig_tags1(rName, tagKey, acctest.CtValue1), + ), + ConfigPlanChecks: resource.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionUpdate), + plancheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrTags), knownvalue.MapExact(map[string]knownvalue.Check{ + tagKey: knownvalue.StringExact(acctest.CtValue1), + })), + plancheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrTagsAll), knownvalue.MapExact(map[string]knownvalue.Check{ + tagKey: knownvalue.StringExact(acctest.CtValue1), + })), + }, + }, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrTags), knownvalue.MapExact(map[string]knownvalue.Check{ + tagKey: knownvalue.StringExact(acctest.CtValue1), + })), + statecheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrTagsAll), knownvalue.MapExact(map[string]knownvalue.Check{ + tagKey: knownvalue.StringExact(acctest.CtValue1), + })), + }, + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckBillingGroupExists(ctx, resourceName), + ), + }, + // Updates which remove required tags also succeed + { + Config: acctest.ConfigCompose( + acctest.ConfigTagPolicyCompliance("disabled"), + testAccBillingGroupConfig_tags1(rName, nonRequiredTagKey, acctest.CtValue1), + ), + ConfigPlanChecks: resource.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionUpdate), + plancheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrTags), knownvalue.MapExact(map[string]knownvalue.Check{ + nonRequiredTagKey: knownvalue.StringExact(acctest.CtValue1), + })), + plancheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrTagsAll), knownvalue.MapExact(map[string]knownvalue.Check{ + nonRequiredTagKey: knownvalue.StringExact(acctest.CtValue1), + })), + }, + }, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrTags), knownvalue.MapExact(map[string]knownvalue.Check{ + nonRequiredTagKey: knownvalue.StringExact(acctest.CtValue1), + })), + statecheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrTagsAll), knownvalue.MapExact(map[string]knownvalue.Check{ + nonRequiredTagKey: knownvalue.StringExact(acctest.CtValue1), + })), + }, + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckBillingGroupExists(ctx, resourceName), + ), + }, + }, + }) +} + func testAccCheckBillingGroupExists(ctx context.Context, n string) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] diff --git a/internal/service/kafka/bootstrap_brokers_data_source_test.go b/internal/service/kafka/bootstrap_brokers_data_source_test.go index 9bc76a835279..31bfe7bf7ab5 100644 --- a/internal/service/kafka/bootstrap_brokers_data_source_test.go +++ b/internal/service/kafka/bootstrap_brokers_data_source_test.go @@ -47,7 +47,7 @@ func testAccBootstrapBrokersDataSourceConfig_basic(rName string) string { return acctest.ConfigCompose(testAccClusterConfig_base(rName), fmt.Sprintf(` resource "aws_msk_cluster" "test" { cluster_name = %[1]q - kafka_version = "2.8.1" + kafka_version = "3.8.x" number_of_broker_nodes = 3 broker_node_group_info { diff --git a/internal/service/kafka/broker_nodes_data_source_test.go b/internal/service/kafka/broker_nodes_data_source_test.go index 53db4f25521d..f59e2443630e 100644 --- a/internal/service/kafka/broker_nodes_data_source_test.go +++ b/internal/service/kafka/broker_nodes_data_source_test.go @@ -42,7 +42,7 @@ func testAccBrokerNodesDataSourceConfig_basic(rName string) string { return acctest.ConfigCompose(testAccClusterConfig_base(rName), fmt.Sprintf(` resource "aws_msk_cluster" "test" { cluster_name = %[1]q - kafka_version = "2.8.1" + kafka_version = "3.8.x" number_of_broker_nodes = 3 broker_node_group_info { diff --git a/internal/service/kafka/cluster.go b/internal/service/kafka/cluster.go index cbd95bbe6cad..5db41068586d 100644 --- a/internal/service/kafka/cluster.go +++ b/internal/service/kafka/cluster.go @@ -10,6 +10,7 @@ import ( "strings" "time" + "github.com/YakDriver/regexache" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/aws/arn" "github.com/aws/aws-sdk-go-v2/service/kafka" @@ -52,7 +53,7 @@ func resourceCluster() *schema.Resource { CustomizeDiff: customdiff.Sequence( customdiff.ForceNewIfChange("kafka_version", func(_ context.Context, old, new, meta any) bool { - return semver.LessThan(new.(string), old.(string)) + return semver.LessThan(normalizeKafkaVersion(new.(string)), normalizeKafkaVersion(old.(string))) }), customdiff.ForceNewIfChange("storage_mode", func(_ context.Context, old, new, meta any) bool { return types.StorageMode(new.(string)) == types.StorageModeLocal @@ -520,6 +521,22 @@ func resourceCluster() *schema.Resource { }, }, }, + "rebalancing": { + Type: schema.TypeList, + Optional: true, + Computed: true, + DiffSuppressFunc: verify.SuppressMissingOptionalConfigurationBlock, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + names.AttrStatus: { + Type: schema.TypeString, + Required: true, + ValidateDiagFunc: enum.Validate[types.RebalancingStatus](), + }, + }, + }, + }, "storage_mode": { Type: schema.TypeString, Optional: true, @@ -545,7 +562,7 @@ func resourceClusterCreate(ctx context.Context, d *schema.ResourceData, meta any conn := meta.(*conns.AWSClient).KafkaClient(ctx) name := d.Get(names.AttrClusterName).(string) - input := &kafka.CreateClusterInput{ + input := kafka.CreateClusterInput{ ClusterName: aws.String(name), KafkaVersion: aws.String(d.Get("kafka_version").(string)), NumberOfBrokerNodes: aws.Int32(int32(d.Get("number_of_broker_nodes").(int))), @@ -586,11 +603,15 @@ func resourceClusterCreate(ctx context.Context, d *schema.ResourceData, meta any input.OpenMonitoring = expandOpenMonitoringInfo(v.([]any)[0].(map[string]any)) } + if v, ok := d.GetOk("rebalancing"); ok && len(v.([]any)) > 0 && v.([]any)[0] != nil { + input.Rebalancing = expandRebalancing(v.([]any)[0].(map[string]any)) + } + if v, ok := d.GetOk("storage_mode"); ok { input.StorageMode = types.StorageMode(v.(string)) } - output, err := conn.CreateCluster(ctx, input) + output, err := conn.CreateCluster(ctx, &input) if err != nil { return sdkdiag.AppendErrorf(diags, "creating MSK Cluster (%s): %s", name, err) @@ -605,7 +626,7 @@ func resourceClusterCreate(ctx context.Context, d *schema.ResourceData, meta any } if vpcConnectivity != nil { - input := &kafka.UpdateConnectivityInput{ + input := kafka.UpdateConnectivityInput{ ClusterArn: aws.String(d.Id()), ConnectivityInfo: &types.ConnectivityInfo{ VpcConnectivity: vpcConnectivity, @@ -613,7 +634,7 @@ func resourceClusterCreate(ctx context.Context, d *schema.ResourceData, meta any CurrentVersion: cluster.CurrentVersion, } - output, err := conn.UpdateConnectivity(ctx, input) + output, err := conn.UpdateConnectivity(ctx, &input) if err != nil { return sdkdiag.AppendErrorf(diags, "updating MSK Cluster (%s) broker connectivity: %s", d.Id(), err) @@ -716,6 +737,13 @@ func resourceClusterRead(ctx context.Context, d *schema.ResourceData, meta any) } else { d.Set("open_monitoring", nil) } + if cluster.Rebalancing != nil { + if err := d.Set("rebalancing", []any{flattenRebalancing(cluster.Rebalancing)}); err != nil { + return sdkdiag.AppendErrorf(diags, "setting rebalancing: %s", err) + } + } else { + d.Set("rebalancing", nil) + } d.Set("storage_mode", cluster.StorageMode) d.Set("zookeeper_connect_string", sortEndpointsString(aws.ToString(cluster.ZookeeperConnectString))) d.Set("zookeeper_connect_string_tls", sortEndpointsString(aws.ToString(cluster.ZookeeperConnectStringTls))) @@ -730,7 +758,7 @@ func resourceClusterUpdate(ctx context.Context, d *schema.ResourceData, meta any conn := meta.(*conns.AWSClient).KafkaClient(ctx) if d.HasChange("broker_node_group_info.0.connectivity_info") { - input := &kafka.UpdateConnectivityInput{ + input := kafka.UpdateConnectivityInput{ ClusterArn: aws.String(d.Id()), CurrentVersion: aws.String(d.Get("current_version").(string)), } @@ -739,7 +767,7 @@ func resourceClusterUpdate(ctx context.Context, d *schema.ResourceData, meta any input.ConnectivityInfo = expandConnectivityInfo(v.([]any)[0].(map[string]any)) } - output, err := conn.UpdateConnectivity(ctx, input) + output, err := conn.UpdateConnectivity(ctx, &input) if err != nil { return sdkdiag.AppendErrorf(diags, "updating MSK Cluster (%s) broker connectivity: %s", d.Id(), err) @@ -758,13 +786,13 @@ func resourceClusterUpdate(ctx context.Context, d *schema.ResourceData, meta any } if d.HasChange("broker_node_group_info.0.instance_type") { - input := &kafka.UpdateBrokerTypeInput{ + input := kafka.UpdateBrokerTypeInput{ ClusterArn: aws.String(d.Id()), CurrentVersion: aws.String(d.Get("current_version").(string)), TargetInstanceType: aws.String(d.Get("broker_node_group_info.0.instance_type").(string)), } - output, err := conn.UpdateBrokerType(ctx, input) + output, err := conn.UpdateBrokerType(ctx, &input) if err != nil { return sdkdiag.AppendErrorf(diags, "updating MSK Cluster (%s) broker type: %s", d.Id(), err) @@ -783,7 +811,7 @@ func resourceClusterUpdate(ctx context.Context, d *schema.ResourceData, meta any } if d.HasChanges("broker_node_group_info.0.storage_info") { - input := &kafka.UpdateBrokerStorageInput{ + input := kafka.UpdateBrokerStorageInput{ ClusterArn: aws.String(d.Id()), CurrentVersion: aws.String(d.Get("current_version").(string)), TargetBrokerEBSVolumeInfo: []types.BrokerEBSVolumeInfo{{ @@ -799,7 +827,7 @@ func resourceClusterUpdate(ctx context.Context, d *schema.ResourceData, meta any input.TargetBrokerEBSVolumeInfo[0].ProvisionedThroughput = &types.ProvisionedThroughput{Enabled: aws.Bool(false)} } - output, err := conn.UpdateBrokerStorage(ctx, input) + output, err := conn.UpdateBrokerStorage(ctx, &input) if err != nil { return sdkdiag.AppendErrorf(diags, "updating MSK Cluster (%s) broker storage: %s", d.Id(), err) @@ -818,13 +846,13 @@ func resourceClusterUpdate(ctx context.Context, d *schema.ResourceData, meta any } if d.HasChange("number_of_broker_nodes") { - input := &kafka.UpdateBrokerCountInput{ + input := kafka.UpdateBrokerCountInput{ ClusterArn: aws.String(d.Id()), CurrentVersion: aws.String(d.Get("current_version").(string)), TargetNumberOfBrokerNodes: aws.Int32(int32(d.Get("number_of_broker_nodes").(int))), } - output, err := conn.UpdateBrokerCount(ctx, input) + output, err := conn.UpdateBrokerCount(ctx, &input) if err != nil { return sdkdiag.AppendErrorf(diags, "updating MSK Cluster (%s) broker count: %s", d.Id(), err) @@ -843,7 +871,7 @@ func resourceClusterUpdate(ctx context.Context, d *schema.ResourceData, meta any } if d.HasChanges("enhanced_monitoring", "logging_info", "open_monitoring") { - input := &kafka.UpdateMonitoringInput{ + input := kafka.UpdateMonitoringInput{ ClusterArn: aws.String(d.Id()), CurrentVersion: aws.String(d.Get("current_version").(string)), EnhancedMonitoring: types.EnhancedMonitoring(d.Get("enhanced_monitoring").(string)), @@ -857,7 +885,7 @@ func resourceClusterUpdate(ctx context.Context, d *schema.ResourceData, meta any input.OpenMonitoring = expandOpenMonitoringInfo(v.([]any)[0].(map[string]any)) } - output, err := conn.UpdateMonitoring(ctx, input) + output, err := conn.UpdateMonitoring(ctx, &input) if err != nil { return sdkdiag.AppendErrorf(diags, "updating MSK Cluster (%s) monitoring: %s", d.Id(), err) @@ -876,7 +904,7 @@ func resourceClusterUpdate(ctx context.Context, d *schema.ResourceData, meta any } if d.HasChange("configuration_info") && !d.HasChange("kafka_version") { - input := &kafka.UpdateClusterConfigurationInput{ + input := kafka.UpdateClusterConfigurationInput{ ClusterArn: aws.String(d.Id()), CurrentVersion: aws.String(d.Get("current_version").(string)), } @@ -885,7 +913,7 @@ func resourceClusterUpdate(ctx context.Context, d *schema.ResourceData, meta any input.ConfigurationInfo = expandConfigurationInfo(v.([]any)[0].(map[string]any)) } - output, err := conn.UpdateClusterConfiguration(ctx, input) + output, err := conn.UpdateClusterConfiguration(ctx, &input) if err != nil { return sdkdiag.AppendErrorf(diags, "updating MSK Cluster (%s) configuration: %s", d.Id(), err) @@ -904,7 +932,7 @@ func resourceClusterUpdate(ctx context.Context, d *schema.ResourceData, meta any } if d.HasChange("kafka_version") { - input := &kafka.UpdateClusterKafkaVersionInput{ + input := kafka.UpdateClusterKafkaVersionInput{ ClusterArn: aws.String(d.Id()), CurrentVersion: aws.String(d.Get("current_version").(string)), TargetKafkaVersion: aws.String(d.Get("kafka_version").(string)), @@ -916,7 +944,7 @@ func resourceClusterUpdate(ctx context.Context, d *schema.ResourceData, meta any } } - output, err := conn.UpdateClusterKafkaVersion(ctx, input) + output, err := conn.UpdateClusterKafkaVersion(ctx, &input) if err != nil { return sdkdiag.AppendErrorf(diags, "updating MSK Cluster (%s) Kafka version: %s", d.Id(), err) @@ -935,7 +963,7 @@ func resourceClusterUpdate(ctx context.Context, d *schema.ResourceData, meta any } if d.HasChanges("encryption_info", "client_authentication") { - input := &kafka.UpdateSecurityInput{ + input := kafka.UpdateSecurityInput{ ClusterArn: aws.String(d.Id()), CurrentVersion: aws.String(d.Get("current_version").(string)), } @@ -958,7 +986,7 @@ func resourceClusterUpdate(ctx context.Context, d *schema.ResourceData, meta any } } - output, err := conn.UpdateSecurity(ctx, input) + output, err := conn.UpdateSecurity(ctx, &input) if err != nil { return sdkdiag.AppendErrorf(diags, "updating MSK Cluster (%s) security: %s", d.Id(), err) @@ -1001,6 +1029,34 @@ func resourceClusterUpdate(ctx context.Context, d *schema.ResourceData, meta any } } + if d.HasChange("rebalancing") { + input := kafka.UpdateRebalancingInput{ + ClusterArn: aws.String(d.Id()), + CurrentVersion: aws.String(d.Get("current_version").(string)), + } + + if v, ok := d.GetOk("rebalancing"); ok && len(v.([]any)) > 0 && v.([]any)[0] != nil { + input.Rebalancing = expandRebalancing(v.([]any)[0].(map[string]any)) + } + + output, err := conn.UpdateRebalancing(ctx, &input) + + if err != nil { + return sdkdiag.AppendErrorf(diags, "updating MSK Cluster (%s) rebalancing: %s", d.Id(), err) + } + + clusterOperationARN := aws.ToString(output.ClusterOperationArn) + + if _, err := waitClusterOperationCompleted(ctx, conn, clusterOperationARN, d.Timeout(schema.TimeoutUpdate)); err != nil { + return sdkdiag.AppendErrorf(diags, "waiting for MSK Cluster (%s) operation (%s): %s", d.Id(), clusterOperationARN, err) + } + + // refresh the current_version attribute after each update + if err := refreshClusterVersion(ctx, d, meta); err != nil { + return sdkdiag.AppendFromErr(diags, err) + } + } + return append(diags, resourceClusterRead(ctx, d, meta)...) } @@ -1009,9 +1065,10 @@ func resourceClusterDelete(ctx context.Context, d *schema.ResourceData, meta any conn := meta.(*conns.AWSClient).KafkaClient(ctx) log.Printf("[DEBUG] Deleting MSK Cluster: %s", d.Id()) - _, err := conn.DeleteCluster(ctx, &kafka.DeleteClusterInput{ + input := kafka.DeleteClusterInput{ ClusterArn: aws.String(d.Id()), - }) + } + _, err := conn.DeleteCluster(ctx, &input) if errs.IsA[*types.NotFoundException](err) { return diags @@ -1043,10 +1100,14 @@ func refreshClusterVersion(ctx context.Context, d *schema.ResourceData, meta any } func findClusterByARN(ctx context.Context, conn *kafka.Client, arn string) (*types.ClusterInfo, error) { - input := &kafka.DescribeClusterInput{ + input := kafka.DescribeClusterInput{ ClusterArn: aws.String(arn), } + return findCluster(ctx, conn, &input) +} + +func findCluster(ctx context.Context, conn *kafka.Client, input *kafka.DescribeClusterInput) (*types.ClusterInfo, error) { output, err := conn.DescribeCluster(ctx, input) if errs.IsA[*types.NotFoundException](err) { @@ -1068,10 +1129,14 @@ func findClusterByARN(ctx context.Context, conn *kafka.Client, arn string) (*typ } func findClusterV2ByARN(ctx context.Context, conn *kafka.Client, arn string) (*types.Cluster, error) { - input := &kafka.DescribeClusterV2Input{ + input := kafka.DescribeClusterV2Input{ ClusterArn: aws.String(arn), } + return findClusterV2(ctx, conn, &input) +} + +func findClusterV2(ctx context.Context, conn *kafka.Client, input *kafka.DescribeClusterV2Input) (*types.Cluster, error) { output, err := conn.DescribeClusterV2(ctx, input) if errs.IsA[*types.NotFoundException](err) { @@ -1093,10 +1158,14 @@ func findClusterV2ByARN(ctx context.Context, conn *kafka.Client, arn string) (*t } func findClusterOperationByARN(ctx context.Context, conn *kafka.Client, arn string) (*types.ClusterOperationInfo, error) { - input := &kafka.DescribeClusterOperationInput{ + input := kafka.DescribeClusterOperationInput{ ClusterOperationArn: aws.String(arn), } + return findClusterOperation(ctx, conn, &input) +} + +func findClusterOperation(ctx context.Context, conn *kafka.Client, input *kafka.DescribeClusterOperationInput) (*types.ClusterOperationInfo, error) { output, err := conn.DescribeClusterOperation(ctx, input) if errs.IsA[*types.NotFoundException](err) { @@ -1118,10 +1187,14 @@ func findClusterOperationByARN(ctx context.Context, conn *kafka.Client, arn stri } func findBootstrapBrokersByARN(ctx context.Context, conn *kafka.Client, arn string) (*kafka.GetBootstrapBrokersOutput, error) { - input := &kafka.GetBootstrapBrokersInput{ + input := kafka.GetBootstrapBrokersInput{ ClusterArn: aws.String(arn), } + return findBootstrapBrokers(ctx, conn, &input) +} + +func findBootstrapBrokers(ctx context.Context, conn *kafka.Client, input *kafka.GetBootstrapBrokersInput) (*kafka.GetBootstrapBrokersOutput, error) { output, err := conn.GetBootstrapBrokers(ctx, input) if errs.IsA[*types.NotFoundException](err) { @@ -1244,6 +1317,10 @@ func clusterUUIDFromARN(clusterARN string) (string, error) { } // arn:${Partition}:kafka:${Region}:${Account}:cluster/${ClusterName}/${Uuid} + if parsedARN.Service != "kafka" { + return "", fmt.Errorf("invalid MSK Cluster ARN (%s)", clusterARN) + } + parts := strings.Split(parsedARN.Resource, "/") if len(parts) != 3 || parts[0] != "cluster" || parts[1] == "" || parts[2] == "" { return "", fmt.Errorf("invalid MSK Cluster ARN (%s)", clusterARN) @@ -1251,6 +1328,15 @@ func clusterUUIDFromARN(clusterARN string) (string, error) { return parts[2], nil } +// normalizeKafkaVersion removes any trailing non-numeric components from the version string. +func normalizeKafkaVersion(version string) string { // nosemgrep:ci.kafka-in-func-name + loc := regexache.MustCompile(`\.[[:alpha:]]+(\.[[:alpha:]]+)?$`).FindStringIndex(version) + if loc == nil || loc[1] != len(version) { + return version + } + return version[:loc[0]] +} + func expandBrokerNodeGroupInfo(tfMap map[string]any) *types.BrokerNodeGroupInfo { if tfMap == nil { return nil @@ -1696,6 +1782,20 @@ func expandNodeExporterInfo(tfMap map[string]any) *types.NodeExporterInfo { return apiObject } +func expandRebalancing(tfMap map[string]any) *types.Rebalancing { + if tfMap == nil { + return nil + } + + apiObject := &types.Rebalancing{} + + if v, ok := tfMap[names.AttrStatus].(string); ok && v != "" { + apiObject.Status = types.RebalancingStatus(v) + } + + return apiObject +} + func flattenBrokerNodeGroupInfo(apiObject *types.BrokerNodeGroupInfo) map[string]any { if apiObject == nil { return nil @@ -2132,3 +2232,15 @@ func flattenNodeExporter(apiObject *types.NodeExporter) map[string]any { return tfMap } + +func flattenRebalancing(apiObject *types.Rebalancing) map[string]any { + if apiObject == nil { + return nil + } + + tfMap := map[string]any{ + names.AttrStatus: apiObject.Status, + } + + return tfMap +} diff --git a/internal/service/kafka/cluster_data_source.go b/internal/service/kafka/cluster_data_source.go index 026782a91041..678718a2d034 100644 --- a/internal/service/kafka/cluster_data_source.go +++ b/internal/service/kafka/cluster_data_source.go @@ -216,12 +216,7 @@ func dataSourceClusterRead(ctx context.Context, d *schema.ResourceData, meta any ignoreTagsConfig := meta.(*conns.AWSClient).IgnoreTagsConfig(ctx) clusterName := d.Get(names.AttrClusterName).(string) - input := &kafka.ListClustersInput{ - ClusterNameFilter: aws.String(clusterName), - } - cluster, err := findCluster(ctx, conn, input, func(v *types.ClusterInfo) bool { - return aws.ToString(v.ClusterName) == clusterName - }) + cluster, err := findClusterByName(ctx, conn, clusterName) if err != nil { return sdkdiag.AppendErrorf(diags, "reading MSK Cluster (%s): %s", clusterName, err) @@ -265,8 +260,13 @@ func dataSourceClusterRead(ctx context.Context, d *schema.ResourceData, meta any return diags } -func findCluster(ctx context.Context, conn *kafka.Client, input *kafka.ListClustersInput, filter tfslices.Predicate[*types.ClusterInfo]) (*types.ClusterInfo, error) { - output, err := findClusters(ctx, conn, input, filter) +func findClusterByName(ctx context.Context, conn *kafka.Client, name string) (*types.ClusterInfo, error) { + input := kafka.ListClustersInput{ + ClusterNameFilter: aws.String(name), + } + output, err := findClusters(ctx, conn, &input, func(v *types.ClusterInfo) bool { + return aws.ToString(v.ClusterName) == name + }) if err != nil { return nil, err diff --git a/internal/service/kafka/cluster_data_source_test.go b/internal/service/kafka/cluster_data_source_test.go index 0ece4760f888..c3c1c789bdf6 100644 --- a/internal/service/kafka/cluster_data_source_test.go +++ b/internal/service/kafka/cluster_data_source_test.go @@ -76,7 +76,7 @@ func testAccClusterDataSourceConfig_basic(rName string) string { return acctest.ConfigCompose(testAccClusterConfig_base(rName), fmt.Sprintf(` resource "aws_msk_cluster" "test" { cluster_name = %[1]q - kafka_version = "2.8.1" + kafka_version = "3.8.x" number_of_broker_nodes = 3 broker_node_group_info { diff --git a/internal/service/kafka/cluster_test.go b/internal/service/kafka/cluster_test.go index 42de9d4f60cc..e91b051829f8 100644 --- a/internal/service/kafka/cluster_test.go +++ b/internal/service/kafka/cluster_test.go @@ -54,6 +54,65 @@ var ( clusterZookeeperConnectStringRegexp = regexache.MustCompile(fmt.Sprintf(clusterBrokerRegexpFormat, clusterPortZookeeper)) ) +func TestClusterUUIDFromARN(t *testing.T) { + t.Parallel() + + for _, tc := range []struct { + input string + output string + wantErr bool + }{ + { + input: "", + wantErr: true, + }, + { + input: "testing", + wantErr: true, + }, + { + input: "arn:aws:kafka:us-east-1:012345678012:cluster/exampleClusterName/abcdefab-1234-abcd-5678-cdef0123ab01-2", //lintignore:AWSAT003,AWSAT005 + output: "abcdefab-1234-abcd-5678-cdef0123ab01-2", + }, + { + input: "arn:aws:kafka:us-east-1:012345678012:cluster-operation/exampleClusterName/abcdefab-1234-abcd-5678-cdef0123ab01-2/0123abcd-abcd-4f7f-1234-9876543210ef", //lintignore:AWSAT003,AWSAT005 + wantErr: true, + }, + { + input: "arn:aws:globalaccelerator::123456789012:accelerator/a-123", //lintignore:AWSAT005 + wantErr: true, + }, + } { + got, err := tfkafka.ClusterUUIDFromARN(tc.input) + if gotErr := err != nil; gotErr != tc.wantErr { + t.Errorf("ClusterUUIDFromARN(%q) = %v, want error presence = %t", tc.input, err, tc.wantErr) + } else if want := tc.output; got != want { + t.Errorf("ClusterUUIDFromARN(%q) = %q, want %q", tc.input, got, want) + } + } +} + +func TestNormalizeKafkaVersion(t *testing.T) { + t.Parallel() + + for _, tc := range []struct { + input string + output string + }{ + {"", ""}, + {"2.8.1", "2.8.1"}, + {"2.8", "2.8"}, + {"2", "2"}, + {"3.8.x", "3.8"}, + {"3.8.link", "3.8"}, + {"4.1.x.kraft", "4.1"}, + } { + if got, want := tfkafka.NormalizeKafkaVersion(tc.input), tc.output; got != want { + t.Errorf("NormalizeKafkaVersion(%q) = %q, want %q", tc.input, got, want) + } + } +} + func TestAccKafkaCluster_basic(t *testing.T) { ctx := acctest.Context(t) var cluster types.ClusterInfo @@ -114,7 +173,7 @@ func TestAccKafkaCluster_basic(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "encryption_info.0.encryption_in_transit.0.client_broker", "TLS"), resource.TestCheckResourceAttr(resourceName, "encryption_info.0.encryption_in_transit.0.in_cluster", acctest.CtTrue), resource.TestCheckResourceAttr(resourceName, "enhanced_monitoring", string(types.EnhancedMonitoringDefault)), - resource.TestCheckResourceAttr(resourceName, "kafka_version", "2.8.1"), + resource.TestCheckResourceAttr(resourceName, "kafka_version", "3.8.x"), resource.TestCheckResourceAttr(resourceName, "number_of_broker_nodes", "3"), resource.TestCheckResourceAttrSet(resourceName, "storage_mode"), resource.TestCheckResourceAttr(resourceName, acctest.CtTagsPercent, "0"), @@ -1210,10 +1269,10 @@ func TestAccKafkaCluster_kafkaVersionUpgrade(t *testing.T) { CheckDestroy: testAccCheckClusterDestroy(ctx), Steps: []resource.TestStep{ { - Config: testAccClusterConfig_version(rName, "2.7.1"), + Config: testAccClusterConfig_version(rName, "3.8.x"), Check: resource.ComposeAggregateTestCheckFunc( testAccCheckClusterExists(ctx, resourceName, &cluster1), - resource.TestCheckResourceAttr(resourceName, "kafka_version", "2.7.1"), + resource.TestCheckResourceAttr(resourceName, "kafka_version", "3.8.x"), ), }, { @@ -1225,11 +1284,11 @@ func TestAccKafkaCluster_kafkaVersionUpgrade(t *testing.T) { }, }, { - Config: testAccClusterConfig_version(rName, "2.8.0"), + Config: testAccClusterConfig_version(rName, "3.9.x"), Check: resource.ComposeAggregateTestCheckFunc( testAccCheckClusterExists(ctx, resourceName, &cluster2), testAccCheckClusterNotRecreated(&cluster1, &cluster2), - resource.TestCheckResourceAttr(resourceName, "kafka_version", "2.8.0"), + resource.TestCheckResourceAttr(resourceName, "kafka_version", "3.9.x"), ), }, }, @@ -1249,10 +1308,10 @@ func TestAccKafkaCluster_kafkaVersionDowngrade(t *testing.T) { CheckDestroy: testAccCheckClusterDestroy(ctx), Steps: []resource.TestStep{ { - Config: testAccClusterConfig_version(rName, "2.8.0"), + Config: testAccClusterConfig_version(rName, "3.9.x"), Check: resource.ComposeAggregateTestCheckFunc( testAccCheckClusterExists(ctx, resourceName, &cluster1), - resource.TestCheckResourceAttr(resourceName, "kafka_version", "2.8.0"), + resource.TestCheckResourceAttr(resourceName, "kafka_version", "3.9.x"), resource.TestMatchResourceAttr(resourceName, "bootstrap_brokers", clusterBoostrapBrokersRegexp), resource.TestCheckResourceAttr(resourceName, "bootstrap_brokers_sasl_scram", ""), resource.TestMatchResourceAttr(resourceName, "bootstrap_brokers_tls", clusterBoostrapBrokersTLSRegexp), @@ -1269,11 +1328,11 @@ func TestAccKafkaCluster_kafkaVersionDowngrade(t *testing.T) { }, }, { - Config: testAccClusterConfig_version(rName, "2.7.1"), + Config: testAccClusterConfig_version(rName, "3.8.x"), Check: resource.ComposeAggregateTestCheckFunc( testAccCheckClusterExists(ctx, resourceName, &cluster2), testAccCheckClusterRecreated(&cluster1, &cluster2), - resource.TestCheckResourceAttr(resourceName, "kafka_version", "2.7.1"), + resource.TestCheckResourceAttr(resourceName, "kafka_version", "3.8.x"), resource.TestMatchResourceAttr(resourceName, "bootstrap_brokers", clusterBoostrapBrokersRegexp), resource.TestCheckResourceAttr(resourceName, "bootstrap_brokers_sasl_scram", ""), resource.TestMatchResourceAttr(resourceName, "bootstrap_brokers_tls", clusterBoostrapBrokersTLSRegexp), @@ -1300,10 +1359,10 @@ func TestAccKafkaCluster_kafkaVersionUpgradeWithInfo(t *testing.T) { CheckDestroy: testAccCheckClusterDestroy(ctx), Steps: []resource.TestStep{ { - Config: testAccClusterConfig_versionConfigurationInfo(rName, "2.7.1", "config1"), + Config: testAccClusterConfig_versionConfigurationInfo(rName, "3.8.x", "config1"), Check: resource.ComposeAggregateTestCheckFunc( testAccCheckClusterExists(ctx, resourceName, &cluster1), - resource.TestCheckResourceAttr(resourceName, "kafka_version", "2.7.1"), + resource.TestCheckResourceAttr(resourceName, "kafka_version", "3.8.x"), resource.TestCheckResourceAttr(resourceName, "configuration_info.#", "1"), resource.TestCheckResourceAttrPair(resourceName, "configuration_info.0.arn", configurationResourceName1, names.AttrARN), resource.TestCheckResourceAttrPair(resourceName, "configuration_info.0.revision", configurationResourceName1, "latest_revision"), @@ -1318,11 +1377,11 @@ func TestAccKafkaCluster_kafkaVersionUpgradeWithInfo(t *testing.T) { }, }, { - Config: testAccClusterConfig_versionConfigurationInfo(rName, "2.8.0", "config2"), + Config: testAccClusterConfig_versionConfigurationInfo(rName, "3.9.x", "config2"), Check: resource.ComposeAggregateTestCheckFunc( testAccCheckClusterExists(ctx, resourceName, &cluster2), testAccCheckClusterNotRecreated(&cluster1, &cluster2), - resource.TestCheckResourceAttr(resourceName, "kafka_version", "2.8.0"), + resource.TestCheckResourceAttr(resourceName, "kafka_version", "3.9.x"), resource.TestCheckResourceAttr(resourceName, "configuration_info.#", "1"), resource.TestCheckResourceAttrPair(resourceName, "configuration_info.0.arn", configurationResourceName2, names.AttrARN), resource.TestCheckResourceAttrPair(resourceName, "configuration_info.0.revision", configurationResourceName2, "latest_revision"), @@ -1332,6 +1391,44 @@ func TestAccKafkaCluster_kafkaVersionUpgradeWithInfo(t *testing.T) { }) } +func TestAccKafkaCluster_rebalancing(t *testing.T) { + ctx := acctest.Context(t) + acctest.SkipIfEnvVarNotSet(t, "MSK_EXPRESS_BROKER_ENABLED") + var cluster types.ClusterInfo + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_msk_cluster.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t); testAccPreCheck(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, names.KafkaServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckClusterDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccClusterConfig_rebalancing(rName, "ACTIVE"), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckClusterExists(ctx, resourceName, &cluster), + resource.TestCheckResourceAttr(resourceName, "rebalancing.#", "1"), + resource.TestCheckResourceAttr(resourceName, "rebalancing.0.status", "ACTIVE"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccClusterConfig_rebalancing(rName, "PAUSED"), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckClusterExists(ctx, resourceName, &cluster), + resource.TestCheckResourceAttr(resourceName, "rebalancing.#", "1"), + resource.TestCheckResourceAttr(resourceName, "rebalancing.0.status", "PAUSED"), + ), + }, + }, + }) +} + func testAccCheckResourceAttrIsSortedCSV(resourceName, attributeName string) resource.TestCheckFunc { return func(s *terraform.State) error { is, err := acctest.PrimaryInstanceState(s, resourceName) @@ -1515,7 +1612,7 @@ func testAccClusterConfig_basic(rName string) string { return acctest.ConfigCompose(testAccClusterConfig_base(rName), fmt.Sprintf(` resource "aws_msk_cluster" "test" { cluster_name = %[1]q - kafka_version = "2.8.1" + kafka_version = "3.8.x" number_of_broker_nodes = 3 broker_node_group_info { @@ -1537,7 +1634,7 @@ func testAccClusterConfig_brokerNodeGroupInfoStorageInfoVolumeSizeSetAndProvThro return acctest.ConfigCompose(testAccClusterConfig_base(rName), fmt.Sprintf(` resource "aws_msk_cluster" "test" { cluster_name = %[1]q - kafka_version = "2.8.1" + kafka_version = "3.8.x" number_of_broker_nodes = 3 broker_node_group_info { @@ -1561,7 +1658,7 @@ func testAccClusterConfig_brokerNodeGroupInfoStorageInfoVolumeSizeSetAndProvThro return acctest.ConfigCompose(testAccClusterConfig_base(rName), fmt.Sprintf(` resource "aws_msk_cluster" "test" { cluster_name = %[1]q - kafka_version = "2.8.1" + kafka_version = "3.8.x" number_of_broker_nodes = 3 broker_node_group_info { @@ -1586,7 +1683,7 @@ func testAccClusterConfig_brokerNodeGroupInfoStorageInfoVolumeSizeSetAndProvThro return acctest.ConfigCompose(testAccClusterConfig_base(rName), fmt.Sprintf(` resource "aws_msk_cluster" "test" { cluster_name = %[1]q - kafka_version = "2.8.1" + kafka_version = "3.8.x" number_of_broker_nodes = 3 broker_node_group_info { @@ -1607,7 +1704,7 @@ func testAccClusterConfig_brokerNodeGroupInfoInstanceType(rName string, t string return acctest.ConfigCompose(testAccClusterConfig_base(rName), fmt.Sprintf(` resource "aws_msk_cluster" "test" { cluster_name = %[1]q - kafka_version = "2.8.1" + kafka_version = "3.8.x" number_of_broker_nodes = 3 broker_node_group_info { @@ -1628,7 +1725,7 @@ resource "aws_msk_cluster" "test" { func testAccClusterConfig_allowEveryoneNoACLFoundFalse(rName string) string { return fmt.Sprintf(` resource "aws_msk_configuration" "test" { - kafka_versions = ["2.8.1"] + kafka_versions = ["3.8.x"] name = %[1]q server_properties = <<-PROPERTIES @@ -1644,7 +1741,7 @@ func testAccClusterConfig_brokerNodeGroupInfoNoPublicAccessSASLIAM(rName string) fmt.Sprintf(` resource "aws_msk_cluster" "test" { cluster_name = %[1]q - kafka_version = "2.8.1" + kafka_version = "3.8.x" number_of_broker_nodes = 3 broker_node_group_info { @@ -1680,7 +1777,7 @@ func testAccClusterConfig_brokerNodeGroupInfoPublicAccessSASLIAM(rName string, p fmt.Sprintf(` resource "aws_msk_cluster" "test" { cluster_name = %[1]q - kafka_version = "2.8.1" + kafka_version = "3.8.x" number_of_broker_nodes = 3 broker_node_group_info { @@ -1722,7 +1819,7 @@ func testAccClusterConfig_brokerNodeGroupInfoVPCConnectivitySASLIAM(rName string fmt.Sprintf(` resource "aws_msk_cluster" "test" { cluster_name = %[1]q - kafka_version = "2.8.1" + kafka_version = "3.8.x" number_of_broker_nodes = 3 broker_node_group_info { @@ -1786,7 +1883,7 @@ func testAccClusterConfig_clientAuthenticationTLSCertificateAuthorityARNs(rName, fmt.Sprintf(` resource "aws_msk_cluster" "test" { cluster_name = %[1]q - kafka_version = "2.8.1" + kafka_version = "3.8.x" number_of_broker_nodes = 3 broker_node_group_info { @@ -1828,7 +1925,7 @@ func testAccClusterConfig_rootCANoClientAuthentication(rName, commonName string) fmt.Sprintf(` resource "aws_msk_cluster" "test" { cluster_name = %[1]q - kafka_version = "2.8.1" + kafka_version = "3.8.x" number_of_broker_nodes = 3 broker_node_group_info { @@ -1857,7 +1954,7 @@ func testAccClusterConfig_clientAuthenticationSASLScram(rName string, scramEnabl return acctest.ConfigCompose(testAccClusterConfig_base(rName), fmt.Sprintf(` resource "aws_msk_cluster" "test" { cluster_name = %[1]q - kafka_version = "2.8.1" + kafka_version = "3.8.x" number_of_broker_nodes = 3 broker_node_group_info { @@ -1887,7 +1984,7 @@ func testAccClusterConfig_clientAuthenticationSASLIAM(rName string, saslEnabled return acctest.ConfigCompose(testAccClusterConfig_base(rName), fmt.Sprintf(` resource "aws_msk_cluster" "test" { cluster_name = %[1]q - kafka_version = "2.8.1" + kafka_version = "3.8.x" number_of_broker_nodes = 3 broker_node_group_info { @@ -1916,7 +2013,7 @@ resource "aws_msk_cluster" "test" { func testAccClusterConfig_configurationInfoRevision1(rName string) string { return acctest.ConfigCompose(testAccClusterConfig_base(rName), fmt.Sprintf(` resource "aws_msk_configuration" "test1" { - kafka_versions = ["2.8.1"] + kafka_versions = ["3.8.x"] name = "%[1]s-1" server_properties = < 0 && v.([]any)[0] != nil { + input.TenancyConfig = &awstypes.TenancyConfig{ + TenantIsolationMode: awstypes.TenantIsolationMode(v.([]any)[0].(map[string]any)["tenant_isolation_mode"].(string)), + } + } + if v, ok := d.GetOk("tracing_config"); ok && len(v.([]any)) > 0 && v.([]any)[0] != nil { input.TracingConfig = &awstypes.TracingConfig{ Mode: awstypes.TracingMode(v.([]any)[0].(map[string]any)[names.AttrMode].(string)), @@ -752,6 +773,15 @@ func resourceFunctionRead(ctx context.Context, d *schema.ResourceData, meta any) }); err != nil { return sdkdiag.AppendErrorf(diags, "setting tracing_config: %s", err) } + if function.TenancyConfig != nil { + if err := d.Set("tenancy_config", []any{ + map[string]any{ + "tenant_isolation_mode": string(function.TenancyConfig.TenantIsolationMode), + }, + }); err != nil { + return sdkdiag.AppendErrorf(diags, "setting tenancy_config: %s", err) + } + } if err := d.Set(names.AttrVPCConfig, flattenVPCConfigResponse(function.VpcConfig)); err != nil { return sdkdiag.AppendErrorf(diags, "setting vpc_config: %s", err) } diff --git a/internal/service/lambda/function_data_source.go b/internal/service/lambda/function_data_source.go index 82d3f2e71e41..dfe3fa87a319 100644 --- a/internal/service/lambda/function_data_source.go +++ b/internal/service/lambda/function_data_source.go @@ -209,6 +209,18 @@ func dataSourceFunction() *schema.Resource { Type: schema.TypeInt, Computed: true, }, + "tenancy_config": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "tenant_isolation_mode": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, "tracing_config": { Type: schema.TypeList, Computed: true, @@ -365,6 +377,15 @@ func dataSourceFunctionRead(ctx context.Context, d *schema.ResourceData, meta an d.Set("source_code_size", function.CodeSize) d.Set("source_kms_key_arn", functionCode.SourceKMSKeyArn) d.Set(names.AttrTimeout, function.Timeout) + if function.TenancyConfig != nil { + if err := d.Set("tenancy_config", []any{ + map[string]any{ + "tenant_isolation_mode": string(function.TenancyConfig.TenantIsolationMode), + }, + }); err != nil { + return sdkdiag.AppendErrorf(diags, "setting tenancy_config: %s", err) + } + } tracingConfigMode := awstypes.TracingModePassThrough if function.TracingConfig != nil { tracingConfigMode = function.TracingConfig.Mode diff --git a/internal/service/lambda/function_data_source_test.go b/internal/service/lambda/function_data_source_test.go index b98bdcc8a708..fef211dfc576 100644 --- a/internal/service/lambda/function_data_source_test.go +++ b/internal/service/lambda/function_data_source_test.go @@ -398,6 +398,29 @@ func TestAccLambdaFunctionDataSource_loggingConfig(t *testing.T) { }) } +func TestAccLambdaFunctionDataSource_tenancyConfig(t *testing.T) { + ctx := acctest.Context(t) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + dataSourceName := "data.aws_lambda_function.test" + resourceName := "aws_lambda_function.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, names.LambdaServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + Steps: []resource.TestStep{ + { + Config: testAccFunctionDataSourceConfig_tenancyConfig(rName), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttrPair(dataSourceName, names.AttrARN, resourceName, names.AttrARN), + resource.TestCheckResourceAttrPair(dataSourceName, "tenancy_config.#", resourceName, "tenancy_config.#"), + resource.TestCheckResourceAttrPair(dataSourceName, "tenancy_config.0.tenant_isolation_mode", resourceName, "tenancy_config.0.tenant_isolation_mode"), + ), + }, + }, + }) +} + func testAccImageLatestPreCheck(t *testing.T) { if os.Getenv("AWS_LAMBDA_IMAGE_LATEST_ID") == "" { t.Skip("AWS_LAMBDA_IMAGE_LATEST_ID env var must be set for Lambda Function Data Source Image Support acceptance tests.") @@ -850,3 +873,23 @@ data "aws_lambda_function" "test" { } `, rName, rName+"_custom")) } + +func testAccFunctionDataSourceConfig_tenancyConfig(rName string) string { + return acctest.ConfigCompose(testAccFunctionDataSourceConfig_base(rName), fmt.Sprintf(` +resource "aws_lambda_function" "test" { + filename = "test-fixtures/lambdatest.zip" + function_name = %[1]q + role = aws_iam_role.lambda.arn + handler = "exports.example" + runtime = "nodejs20.x" + + tenancy_config { + tenant_isolation_mode = "PER_TENANT" + } +} + +data "aws_lambda_function" "test" { + function_name = aws_lambda_function.test.function_name +} +`, rName)) +} diff --git a/internal/service/lambda/function_test.go b/internal/service/lambda/function_test.go index b4b6624f6664..6419ae3caa26 100644 --- a/internal/service/lambda/function_test.go +++ b/internal/service/lambda/function_test.go @@ -2410,6 +2410,72 @@ func TestAccLambdaFunction_sourceKMSKeyARN(t *testing.T) { }) } +func TestAccLambdaFunction_tenancyConfig(t *testing.T) { + ctx := acctest.Context(t) + var conf lambda.GetFunctionOutput + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_lambda_function.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, names.LambdaServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckFunctionDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccFunctionConfig_tenancyConfig(rName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckFunctionExists(ctx, resourceName, &conf), + resource.TestCheckResourceAttr(resourceName, "tenancy_config.#", "1"), + resource.TestCheckResourceAttr(resourceName, "tenancy_config.0.tenant_isolation_mode", "PER_TENANT"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"filename", "publish"}, + }, + }, + }) +} + +func TestAccLambdaFunction_tenancyConfigForceNew(t *testing.T) { + ctx := acctest.Context(t) + var conf lambda.GetFunctionOutput + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_lambda_function.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, names.LambdaServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckFunctionDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccFunctionConfig_basic(rName, rName, rName, rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckFunctionExists(ctx, resourceName, &conf), + resource.TestCheckResourceAttr(resourceName, "tenancy_config.#", "0"), + ), + }, + { + Config: testAccFunctionConfig_tenancyConfig(rName), + ConfigPlanChecks: resource.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionReplace), + }, + }, + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckFunctionExists(ctx, resourceName, &conf), + resource.TestCheckResourceAttr(resourceName, "tenancy_config.#", "1"), + resource.TestCheckResourceAttr(resourceName, "tenancy_config.0.tenant_isolation_mode", "PER_TENANT"), + ), + }, + }, + }) +} + func TestAccLambdaFunction_resetNonRefreshableAttributesAfterUpdateFailure(t *testing.T) { ctx := acctest.Context(t) var conf lambda.GetFunctionOutput @@ -4364,6 +4430,24 @@ resource "aws_lambda_function" "test" { `, rName, kmsIdentifier)) } +func testAccFunctionConfig_tenancyConfig(rName string) string { + return acctest.ConfigCompose( + acctest.ConfigLambdaBase(rName, rName, rName), + fmt.Sprintf(` +resource "aws_lambda_function" "test" { + filename = "test-fixtures/lambdatest.zip" + function_name = %[1]q + role = aws_iam_role.iam_for_lambda.arn + handler = "exports.example" + runtime = "nodejs20.x" + + tenancy_config { + tenant_isolation_mode = "PER_TENANT" + } +} +`, rName)) +} + func testAccFunctionConfig_skipDestroy(rName string) string { return acctest.ConfigCompose(acctest.ConfigLambdaBase(rName, rName, rName), fmt.Sprintf(` resource "aws_lambda_function" "test" { diff --git a/internal/service/lambda/invocation.go b/internal/service/lambda/invocation.go index d13e63c8b8c4..b1e795a13fa4 100644 --- a/internal/service/lambda/invocation.go +++ b/internal/service/lambda/invocation.go @@ -88,6 +88,10 @@ func resourceInvocation() *schema.Resource { Type: schema.TypeString, Computed: true, }, + "tenant_id": { + Type: schema.TypeString, + Optional: true, + }, "terraform_key": { Type: schema.TypeString, Optional: true, @@ -213,6 +217,9 @@ func invoke(ctx context.Context, conn *lambda.Client, d *schema.ResourceData, ac Payload: payload, Qualifier: aws.String(qualifier), } + if v, ok := d.GetOk("tenant_id"); ok { + input.TenantId = aws.String(v.(string)) + } output, err := conn.Invoke(ctx, input) diff --git a/internal/service/lambda/invocation_data_source.go b/internal/service/lambda/invocation_data_source.go index 2b848bc336d5..2eb061311147 100644 --- a/internal/service/lambda/invocation_data_source.go +++ b/internal/service/lambda/invocation_data_source.go @@ -42,6 +42,10 @@ func dataSourceInvocation() *schema.Resource { Type: schema.TypeString, Computed: true, }, + "tenant_id": { + Type: schema.TypeString, + Optional: true, + }, }, } } @@ -61,6 +65,10 @@ func dataSourceInvocationRead(ctx context.Context, d *schema.ResourceData, meta Qualifier: aws.String(qualifier), } + if v, ok := d.GetOk("tenant_id"); ok { + input.TenantId = aws.String(v.(string)) + } + output, err := conn.Invoke(ctx, input) if err != nil { diff --git a/internal/service/lambda/invocation_data_source_test.go b/internal/service/lambda/invocation_data_source_test.go index adf622ec172e..0b38207ed9e8 100644 --- a/internal/service/lambda/invocation_data_source_test.go +++ b/internal/service/lambda/invocation_data_source_test.go @@ -100,6 +100,26 @@ func TestAccLambdaInvocationDataSource_complex(t *testing.T) { }) } +func TestAccLambdaInvocationDataSource_tenantId(t *testing.T) { + ctx := acctest.Context(t) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + testData := "value3" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, names.LambdaServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + Steps: []resource.TestStep{ + { + Config: testAccInvocationDataSourceConfig_tenantId(rName, testData), + Check: resource.ComposeTestCheckFunc( + testAccCheckInvocationResult("data.aws_lambda_invocation.invocation_test", `{"key1":"value1","key2":"value2","key3":"`+testData+`"}`), + ), + }, + }, + }) +} + func testAccInvocationDataSource_base_config(roleName string) string { return fmt.Sprintf(` data "aws_iam_policy_document" "lambda_assume_role_policy" { @@ -230,3 +250,37 @@ JSON } `, rName, testData) } + +func testAccInvocationDataSourceConfig_tenantId(rName, testData string) string { + return fmt.Sprintf(testAccInvocationDataSource_base_config(rName)+` +resource "aws_lambda_function" "lambda" { + depends_on = [aws_iam_role_policy_attachment.lambda_role_policy] + + filename = "test-fixtures/lambda_invocation.zip" + function_name = "%s" + role = aws_iam_role.lambda_role.arn + handler = "lambda_invocation.handler" + runtime = "nodejs20.x" + tenancy_config { + tenant_isolation_mode = "PER_TENANT" + } + + environment { + variables = { + TEST_DATA = "%s" + } + } +} + +data "aws_lambda_invocation" "invocation_test" { + function_name = aws_lambda_function.lambda.function_name + tenant_id = "tenant-1" + input = < -## Non–region-aware resources +## Non–region-aware resources {#nonregion-aware-resources} This section lists resources that are not Region-aware—meaning `region` has not been added to them. diff --git a/website/docs/cdktf/typescript/guides/enhanced-region-support.html.markdown b/website/docs/cdktf/typescript/guides/enhanced-region-support.html.markdown index 5349fcc4befe..db81e3590550 100644 --- a/website/docs/cdktf/typescript/guides/enhanced-region-support.html.markdown +++ b/website/docs/cdktf/typescript/guides/enhanced-region-support.html.markdown @@ -629,7 +629,7 @@ class MyConvertedCode extends TerraformStack {

-## Non–region-aware resources +## Non–region-aware resources {#nonregion-aware-resources} This section lists resources that are not Region-aware—meaning `region` has not been added to them. diff --git a/website/docs/d/lambda_function.html.markdown b/website/docs/d/lambda_function.html.markdown index c0108877d25e..85e85388d9e1 100644 --- a/website/docs/d/lambda_function.html.markdown +++ b/website/docs/d/lambda_function.html.markdown @@ -145,6 +145,7 @@ This data source exports the following attributes in addition to the arguments a * `source_kms_key_arn` - ARN of the AWS Key Management Service key used to encrypt the function's `.zip` deployment package. * `tags` - Map of tags assigned to the Lambda Function. * `timeout` - Function execution time at which Lambda should terminate the function. +* `tenancy_config` - Tenancy settings of the function. [See below](#tenancy_config-attribute-reference). * `tracing_config` - Tracing settings of the function. [See below](#tracing_config-attribute-reference). * `version` - Version of the Lambda function returned. If `qualifier` is not set, this will resolve to the most recent published version. If no published version of the function exists, `version` will resolve to `$LATEST`. * `vpc_config` - VPC configuration associated with your Lambda function. [See below](#vpc_config-attribute-reference). @@ -173,6 +174,10 @@ This data source exports the following attributes in addition to the arguments a * `log_group` - CloudWatch log group your function sends logs to. * `system_log_level` - Detail level of the Lambda platform event logs sent to CloudWatch. +### tenancy_config + +* `tenant_isolation_mode` - (Required) Tenant Isolation Mode. Valid values: `PER_TENANT`. + ### tracing_config * `mode` - Tracing mode. Valid values: `Active`, `PassThrough`. diff --git a/website/docs/d/lambda_invocation.html.markdown b/website/docs/d/lambda_invocation.html.markdown index d90ec514624f..f02aeae2712e 100644 --- a/website/docs/d/lambda_invocation.html.markdown +++ b/website/docs/d/lambda_invocation.html.markdown @@ -103,6 +103,7 @@ The following arguments are optional: * `qualifier` - (Optional) Qualifier (a.k.a version) of the Lambda function. Defaults to `$LATEST`. * `region` - (Optional) Region where this resource will be [managed](https://docs.aws.amazon.com/general/latest/gr/rande.html#regional-endpoints). Defaults to the Region set in the [provider configuration](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#aws-configuration-reference). +* `tenant_id` - (Optional) Tenant Id to serve invocations from specified tenant. ## Attribute Reference diff --git a/website/docs/guides/enhanced-region-support.html.markdown b/website/docs/guides/enhanced-region-support.html.markdown index 2fc7a6284dd0..ff5731abaee9 100644 --- a/website/docs/guides/enhanced-region-support.html.markdown +++ b/website/docs/guides/enhanced-region-support.html.markdown @@ -496,7 +496,7 @@ resource "aws_s3_bucket_replication_configuration" "replication" {

-## Non–region-aware resources +## Non–region-aware resources {#nonregion-aware-resources} This section lists resources that are not Region-aware—meaning `region` has not been added to them. diff --git a/website/docs/guides/tag-policy-compliance.html.markdown b/website/docs/guides/tag-policy-compliance.html.markdown new file mode 100644 index 000000000000..f454467b00a7 --- /dev/null +++ b/website/docs/guides/tag-policy-compliance.html.markdown @@ -0,0 +1,660 @@ +--- +subcategory: "" +layout: "aws" +page_title: "Tag Policy Compliance" +description: |- + The Terraform AWS provider supports enforcing compliance with organizational tag policies during plan and apply operations. +--- + + + +# Tag Policy Compliance + +The Terraform AWS provider supports enforcing compliance with organizational tag policies during plan and apply operations. +See the [AWS documentation on tag policies](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_tag-policies.html) for additional information on configuring tag policies for an organization. + + + +- [Getting Started](#getting-started) + - [Creating a Tag Policy](#creating-a-tag-policy) +- [Enforcing Tag Policy Compliance](#enforcing-tag-policy-compliance) +- [Additional Considerations](#additional-considerations) + - [Validation Timing](#validation-timing) + - [Warning Diagnostics with Plugin SDKV2 Resources](#warning-diagnostics-with-plugin-sdkv2-resources) +- [Resource Type Cross Reference](#resource-types-cross-reference) + + + +## Getting Started + +In order to utilize this feature: + +- **The AWS account must have a tag policy attached.** +To observe the effects of validation, this policy should define required tags for at least one resource. +- **The calling principal used to execute Terraform must have the [`ListRequiredTags`](https://docs.aws.amazon.com/resourcegroupstagging/latest/APIReference/API_ListRequireTags.html) [IAM permission](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonresourcegrouptaggingapi.html).** +This API was introduced in November 2025, and may require modification of existing permissions. + +If an appropriate tag policy is already in place, proceed to [Enforcing Tag Policy Compliance](#enforcing-tag-policy-compliance). +Otherwise, refer to [Creating a Tag Policy](#creating-a-tag-policy) for the necessary setup. + +### Creating a Tag Policy + +The Terraform AWS provider will enforce compliance with any required tags defined in an organization's effective tag policy. +An "effective" tag policy in this context is the policy resulting from the merged content of all tag policies attached to a given account. + +The [`aws_organizations_policy`](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/organizations_policy) and [`aws_organizations_policy_attachment`](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/organizations_policy_attachment) resources from the Terraform AWS provider can be used to perform this function via Terraform. +These resources wrap the [`CreatePolicy`](https://docs.aws.amazon.com/organizations/latest/APIReference/API_CreatePolicy.html) and [`AttachPolicy`](https://docs.aws.amazon.com/organizations/latest/APIReference/API_AttachPolicy.html) APIs, respectively. + +-> Tag policies must be created in the management account of an AWS organization. + +A tag policy enforcing required tags might look like the following: + +```json +{ + "tags": { + "Owner": { + "tag_key": { + "@@assign": "Owner" + }, + "report_required_tag_for": { + "@@assign": [ + "logs:log-group" + ] + } + } + } +} +``` + +In this policy, the `Owner` key is **required** on all `logs:log-group` resource types. +This tag resource type maps to the [`aws_cloudwatch_log_group`](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) resource in the Terraform AWS provider. + +The Terraform configuration below will create a tag policy and attach it to the current account. +The policy content is inlined for demonstration purposes. +Consider moving this to a separate JSON file for more complex policy definitions. + +```hcl +data "aws_caller_identity" "current" {} + +resource "aws_organizations_policy" "example" { + name = "tag-policy-example" + content = < Notably, _non-tag updates to existing resources are always permitted_, even if the existing tags are non-compliant. +This approach avoids blocking unrelated resource updates while still enforcing compliance once **any** tags are modified. + +### Warning Diagnostics with Plugin SDKV2 Resources + +Due to a limitation in the plan-time validation methods exposed by [Terraform Plugin SDK V2](https://developer.hashicorp.com/terraform/plugin/sdkv2), resources based on this library cannot emit warning diagnostics for tag policy compliance violations. +Instead, the provider will emit a log message with a `WARN` level. + +To view this message in the CLI output, set `TF_LOG=warn`. +For example, + +```console +% TF_LOG=warn terraform plan +``` + +~> A majority of resources in the Terraform AWS provider are implemented with Terraform Plugin SDK V2. +While all net-new resources [must use](https://github.com/hashicorp/terraform-provider-aws/issues/32917) the preferred [Terraform Plugin Framework](https://developer.hashicorp.com/terraform/plugin/framework), this limitation will affect many of the oldest and most popular resources until they are migrated or an enhancement is made to Plugin SDK V2. + +## Resource Type Cross Reference + +The following table contains a cross reference of tag resource types to Terraform AWS provider resource types. +This may be useful to determine which Terraform resource types are impacted by a tag policy constraint, or to ensure the correct tag resource name is present in a tag policy. + +-> The table below is generated, and will be updated over time as AWS service teams add tagging support for new resource types and the AWS provider implements new resources. + +|Tag Resource Type|Terraform Resource Type| +|-----------------|-----------------------| +| `access-analyzer:analyzer` | `aws_accessanalyzer_analyzer` | +| `acm-pca:certificate-authority` | `aws_acmpca_certificate_authority` | +| `acm:certificate` | `aws_acm_certificate` | +| `airflow:environment` | `aws_mwaa_environment` | +| `amplify:apps` | `aws_amplify_app` | +| `aoss:collection` | `aws_opensearchserverless_collection` | +| `app-integrations:data-integration` | `aws_appintegrations_data_integration` | +| `app-integrations:event-integration` | `aws_appintegrations_event_integration` | +| `appconfig:application` | `aws_appconfig_application` | +| `appconfig:application/configurationprofile` | `aws_appconfig_configuration_profile` | +| `appconfig:application/environment` | `aws_appconfig_environment` | +| `appconfig:deploymentstrategy` | `aws_appconfig_deployment_strategy` | +| `appconfig:extension` | `aws_appconfig_extension` | +| `appconfig:extensionassociation` | `aws_appconfig_extension_association` | +| `appflow:flow` | `aws_appflow_flow` | +| `applicationinsights:application` | `aws_applicationinsights_application` | +| `appmesh:mesh` | `aws_appmesh_mesh` | +| `appmesh:mesh/virtualGateway` | `aws_appmesh_virtual_gateway` | +| `appmesh:mesh/virtualGateway/gatewayRoute` | `aws_appmesh_gateway_route` | +| `appmesh:mesh/virtualNode` | `aws_appmesh_virtual_node` | +| `appmesh:mesh/virtualRouter` | `aws_appmesh_virtual_router` | +| `appmesh:mesh/virtualRouter/route` | `aws_appmesh_route` | +| `appmesh:mesh/virtualService` | `aws_appmesh_virtual_service` | +| `apprunner:autoscalingconfiguration` | `aws_apprunner_auto_scaling_configuration_version` | +| `apprunner:observabilityconfiguration` | `aws_apprunner_observability_configuration` | +| `apprunner:service` | `aws_apprunner_service` | +| `apprunner:vpcconnector` | `aws_apprunner_vpc_connector` | +| `apprunner:vpcingressconnection` | `aws_apprunner_vpc_ingress_connection` | +| `appstream:fleet` | `aws_appstream_fleet` | +| `appstream:image-builder` | `aws_appstream_image_builder` | +| `appstream:stack` | `aws_appstream_stack` | +| `athena:capacity-reservation` | `aws_athena_capacity_reservation` | +| `athena:datacatalog` | `aws_athena_data_catalog` | +| `athena:workgroup` | `aws_athena_workgroup` | +| `auditmanager:assessment` | `aws_auditmanager_assessment` | +| `backup:backup-plan` | `aws_backup_plan` | +| `backup:framework` | `aws_backup_framework` | +| `backup:report-plan` | `aws_backup_report_plan` | +| `backup:restore-testing-plan` | `aws_backup_restore_testing_plan` | +| `batch:compute-environment` | `aws_batch_compute_environment` | +| `batch:job-definition` | `aws_batch_job_definition` | +| `batch:job-queue` | `aws_batch_job_queue` | +| `batch:scheduling-policy` | `aws_batch_scheduling_policy` | +| `bcm-data-exports:export` | `aws_bcmdataexports_export` | +| `bedrock:agent` | `aws_bedrockagent_agent` | +| `bedrock:agent-alias` | `aws_bedrockagent_agent_alias` | +| `bedrock:flow` | `aws_bedrockagent_flow` | +| `bedrock:guardrail` | `aws_bedrock_guardrail` | +| `bedrock:knowledge-base` | `aws_bedrockagent_knowledge_base` | +| `bedrock:prompt` | `aws_bedrockagent_prompt` | +| `budgets:budget` | `aws_budgets_budget` | +| `budgets:budget/action` | `aws_budgets_budget_action` | +| `cassandra:keyspace` | `aws_keyspaces_keyspace` | +| `catalog:portfolio` | `aws_servicecatalog_portfolio` | +| `ce:anomalymonitor` | `aws_ce_anomaly_monitor` | +| `ce:anomalysubscription` | `aws_ce_anomaly_subscription` | +| `ce:costcategory` | `aws_ce_cost_category` | +| `cleanrooms:configuredtable` | `aws_cleanrooms_configured_table` | +| `cloudformation:stack` | `aws_cloudformation_stack` | +| `cloudformation:stackset` | `aws_cloudformation_stack_set` | +| `cloudfront:distribution` | `aws_cloudfront_distribution` | +| `cloudtrail:eventdatastore` | `aws_cloudtrail_event_data_store` | +| `cloudtrail:trail` | `aws_cloudtrail` | +| `cloudwatch:alarm` | `aws_cloudwatch_metric_alarm` | +| `cloudwatch:metric-stream` | `aws_cloudwatch_metric_stream` | +| `codeartifact:domain` | `aws_codeartifact_domain` | +| `codeartifact:repository` | `aws_codeartifact_repository` | +| `codebuild:project` | `aws_codebuild_project` | +| `codebuild:report-group` | `aws_codebuild_report_group` | +| `codecommit:repository` | `aws_codecommit_repository` | +| `codeconnections:connection` | `aws_codeconnections_connection` | +| `codedeploy:application` | `aws_codedeploy_app` | +| `codedeploy:deploymentconfig` | `aws_codedeploy_deployment_config` | +| `codeguru-profiler:profilingGroup` | `aws_codeguruprofiler_profiling_group` | +| `codeguru-reviewer:association` | `aws_codegurureviewer_repository_association` | +| `codepipeline:actiontype` | `aws_codepipeline_custom_action_type` | +| `codepipeline:pipeline` | `aws_codepipeline` | +| `codepipeline:webhook` | `aws_codepipeline_webhook` | +| `codestar-connections:connection` | `aws_codestarconnections_connection` | +| `codestar-notifications:notificationrule` | `aws_codestarnotifications_notification_rule` | +| `cognito-identity:identitypool` | `aws_cognito_identity_pool` | +| `cognito-idp:userpool` | `aws_cognito_user_pool` | +| `comprehend:document-classifier` | `aws_comprehend_document_classifier` | +| `config:aggregation-authorization` | `aws_config_aggregate_authorization` | +| `config:config-aggregator` | `aws_config_configuration_aggregator` | +| `config:config-rule` | `aws_config_config_rule` | +| `config:conformance-pack` | `aws_config_conformance_pack` | +| `connect:instance` | `aws_connect_instance` | +| `connect:instance/agent` | `aws_connect_user` | +| `connect:instance/contact-flow` | `aws_connect_contact_flow` | +| `connect:instance/flow-module` | `aws_connect_contact_flow_module` | +| `connect:instance/operating-hours` | `aws_connect_hours_of_operation` | +| `connect:instance/queue` | `aws_connect_queue` | +| `connect:instance/routing-profile` | `aws_connect_routing_profile` | +| `connect:instance/security-profile` | `aws_connect_security_profile` | +| `connect:instance/transfer-destination` | `aws_connect_quick_connect` | +| `connect:phone-number` | `aws_connect_phone_number` | +| `cur:definition` | `aws_cur_report_definition` | +| `datasync:task` | `aws_datasync_task` | +| `datazone:domain` | `aws_datazone_domain` | +| `dax:cache` | `aws_dax_cluster` | +| `detective:graph` | `aws_detective_graph` | +| `devicefarm:instanceprofile` | `aws_devicefarm_instance_profile` | +| `devicefarm:project` | `aws_devicefarm_project` | +| `devicefarm:testgrid-project` | `aws_devicefarm_test_grid_project` | +| `dlm:policy` | `aws_dlm_lifecycle_policy` | +| `dms:cert` | `aws_dms_certificate` | +| `dms:endpoint` | `aws_dms_endpoint` | +| `dms:es` | `aws_dms_event_subscription` | +| `dms:rep` | `aws_dms_replication_instance` | +| `dms:replication-config` | `aws_dms_replication_config` | +| `dms:subgrp` | `aws_dms_replication_subnet_group` | +| `dms:task` | `aws_dms_replication_task` | +| `dsql:cluster` | `aws_dsql_cluster` | +| `dynamodb:table` | `aws_dynamodb_table` | +| `ec2:capacity-reservation` | `aws_ec2_capacity_reservation` | +| `ec2:carrier-gateway` | `aws_ec2_carrier_gateway` | +| `ec2:client-vpn-endpoint` | `aws_ec2_client_vpn_endpoint` | +| `ec2:customer-gateway` | `aws_customer_gateway` | +| `ec2:dedicated-host` | `aws_ec2_host` | +| `ec2:dhcp-options` | `aws_vpc_dhcp_options` | +| `ec2:egress-only-internet-gateway` | `aws_egress_only_internet_gateway` | +| `ec2:elastic-ip` | `aws_eip` | +| `ec2:fleet` | `aws_ec2_fleet` | +| `ec2:instance` | `aws_instance` | +| `ec2:instance-connect-endpoint` | `aws_ec2_instance_connect_endpoint` | +| `ec2:internet-gateway` | `aws_internet_gateway` | +| `ec2:ipam` | `aws_vpc_ipam` | +| `ec2:ipam-pool` | `aws_vpc_ipam_pool` | +| `ec2:ipam-resource-discovery` | `aws_vpc_ipam_resource_discovery` | +| `ec2:ipam-resource-discovery-association` | `aws_vpc_ipam_resource_discovery_association` | +| `ec2:ipam-scope` | `aws_vpc_ipam_scope` | +| `ec2:key-pair` | `aws_key_pair` | +| `ec2:launch-template` | `aws_launch_template` | +| `ec2:local-gateway-route-table-vpc-association` | `aws_ec2_local_gateway_route_table_vpc_association` | +| `ec2:natgateway` | `aws_nat_gateway` | +| `ec2:network-acl` | `aws_network_acl` | +| `ec2:network-insights-analysis` | `aws_ec2_network_insights_analysis` | +| `ec2:network-insights-path` | `aws_ec2_network_insights_path` | +| `ec2:network-interface` | `aws_network_interface` | +| `ec2:placement-group` | `aws_placement_group` | +| `ec2:prefix-list` | `aws_ec2_managed_prefix_list` | +| `ec2:route-table` | `aws_route_table` | +| `ec2:security-group` | `aws_security_group` | +| `ec2:subnet` | `aws_subnet` | +| `ec2:traffic-mirror-filter` | `aws_ec2_traffic_mirror_filter` | +| `ec2:traffic-mirror-filter-rule` | `aws_ec2_traffic_mirror_filter_rule` | +| `ec2:traffic-mirror-session` | `aws_ec2_traffic_mirror_session` | +| `ec2:traffic-mirror-target` | `aws_ec2_traffic_mirror_target` | +| `ec2:transit-gateway` | `aws_ec2_transit_gateway` | +| `ec2:transit-gateway-connect-peer` | `aws_ec2_transit_gateway_connect_peer` | +| `ec2:transit-gateway-multicast-domain` | `aws_ec2_transit_gateway_multicast_domain` | +| `ec2:transit-gateway-route-table` | `aws_ec2_transit_gateway_route_table` | +| `ec2:verified-access-endpoint` | `aws_verifiedaccess_endpoint` | +| `ec2:verified-access-group` | `aws_verifiedaccess_group` | +| `ec2:verified-access-instance` | `aws_verifiedaccess_instance` | +| `ec2:verified-access-trust-provider` | `aws_verifiedaccess_trust_provider` | +| `ec2:volume` | `aws_ebs_volume` | +| `ec2:vpc` | `aws_vpc` | +| `ec2:vpc-block-public-access-exclusion` | `aws_vpc_block_public_access_exclusion` | +| `ec2:vpc-endpoint` | `aws_vpc_endpoint` | +| `ec2:vpc-endpoint-service` | `aws_vpc_endpoint_service` | +| `ec2:vpc-flow-log` | `aws_flow_log` | +| `ec2:vpc-peering-connection` | `aws_vpc_peering_connection` | +| `ec2:vpn-connection` | `aws_vpn_connection` | +| `ec2:vpn-gateway` | `aws_vpn_gateway` | +| `ecr-public:repository` | `aws_ecrpublic_repository` | +| `ecr:repository` | `aws_ecr_repository` | +| `ecs:capacity-provider` | `aws_ecs_capacity_provider` | +| `ecs:cluster` | `aws_ecs_cluster` | +| `ecs:service` | `aws_ecs_service` | +| `ecs:task-definition` | `aws_ecs_task_definition` | +| `ecs:task-set` | `aws_ecs_task_set` | +| `eks:access-entry` | `aws_eks_access_entry` | +| `eks:addon` | `aws_eks_addon` | +| `eks:cluster` | `aws_eks_cluster` | +| `eks:fargateprofile` | `aws_eks_fargate_profile` | +| `eks:identityproviderconfig` | `aws_eks_identity_provider_config` | +| `eks:nodegroup` | `aws_eks_node_group` | +| `eks:podidentityassociation` | `aws_eks_pod_identity_association` | +| `elasticache:cluster` | `aws_elasticache_cluster` | +| `elasticache:parametergroup` | `aws_elasticache_parameter_group` | +| `elasticache:replicationgroup` | `aws_elasticache_replication_group` | +| `elasticache:subnetgroup` | `aws_elasticache_subnet_group` | +| `elasticache:user` | `aws_elasticache_user` | +| `elasticache:usergroup` | `aws_elasticache_user_group` | +| `elasticbeanstalk:application` | `aws_elastic_beanstalk_application` | +| `elasticbeanstalk:applicationversion` | `aws_elastic_beanstalk_application_version` | +| `elasticbeanstalk:configurationtemplate` | `aws_elastic_beanstalk_configuration_template` | +| `elasticbeanstalk:environment` | `aws_elastic_beanstalk_environment` | +| `elasticfilesystem:access-point` | `aws_efs_access_point` | +| `elasticfilesystem:file-system` | `aws_efs_file_system` | +| `elasticloadbalancing:listener` | `aws_lb_listener` | +| `elasticloadbalancing:listener-rule` | `aws_lb_listener_rule` | +| `elasticloadbalancing:loadbalancer` | `aws_lb` | +| `elasticloadbalancing:targetgroup` | `aws_lb_target_group` | +| `elasticloadbalancing:truststore` | `aws_lb_trust_store` | +| `elasticmapreduce:cluster` | `aws_emr_cluster` | +| `emr-containers:virtualclusters` | `aws_emrcontainers_virtual_cluster` | +| `emr-serverless:applications` | `aws_emrserverless_application` | +| `events:event-bus` | `aws_cloudwatch_event_bus` | +| `firehose:deliverystream` | `aws_kinesis_firehose_delivery_stream` | +| `fis:experiment-template` | `aws_fis_experiment_template` | +| `fsx:association` | `aws_fsx_data_repository_association` | +| `fsx:storage-virtual-machine` | `aws_fsx_ontap_storage_virtual_machine` | +| `fsx:volume` | `aws_fsx_ontap_volume` | +| `gamelift:alias` | `aws_gamelift_alias` | +| `gamelift:build` | `aws_gamelift_build` | +| `gamelift:fleet` | `aws_gamelift_fleet` | +| `gamelift:gameservergroup` | `aws_gamelift_game_server_group` | +| `gamelift:gamesessionqueue` | `aws_gamelift_game_session_queue` | +| `gamelift:script` | `aws_gamelift_script` | +| `geo:geofence-collection` | `aws_location_geofence_collection` | +| `geo:map` | `aws_location_map` | +| `geo:place-index` | `aws_location_place_index` | +| `geo:route-calculator` | `aws_location_route_calculator` | +| `geo:tracker` | `aws_location_tracker` | +| `globalaccelerator:accelerator` | `aws_globalaccelerator_accelerator` | +| `globalaccelerator:attachment` | `aws_globalaccelerator_cross_account_attachment` | +| `glue:connection` | `aws_glue_connection` | +| `glue:crawler` | `aws_glue_crawler` | +| `glue:dataQualityRuleset` | `aws_glue_data_quality_ruleset` | +| `glue:database` | `aws_glue_catalog_database` | +| `glue:job` | `aws_glue_job` | +| `glue:mlTransform` | `aws_glue_ml_transform` | +| `glue:registry` | `aws_glue_registry` | +| `glue:schema` | `aws_glue_schema` | +| `glue:trigger` | `aws_glue_trigger` | +| `grafana:workspaces` | `aws_grafana_workspace` | +| `guardduty:detector` | `aws_guardduty_detector` | +| `guardduty:detector/filter` | `aws_guardduty_filter` | +| `guardduty:detector/ipset` | `aws_guardduty_ipset` | +| `guardduty:detector/threatintelset` | `aws_guardduty_threatintelset` | +| `guardduty:malware-protection-plan` | `aws_guardduty_malware_protection_plan` | +| `iam:instance-profile` | `aws_iam_instance_profile` | +| `iam:mfa` | `aws_iam_virtual_mfa_device` | +| `iam:oidc-provider` | `aws_iam_openid_connect_provider` | +| `iam:role` | `aws_iam_role` | +| `iam:saml-provider` | `aws_iam_saml_provider` | +| `iam:server-certificate` | `aws_iam_server_certificate` | +| `iam:user` | `aws_iam_user` | +| `imagebuilder:component` | `aws_imagebuilder_component` | +| `imagebuilder:container-recipe` | `aws_imagebuilder_container_recipe` | +| `imagebuilder:distribution-configuration` | `aws_imagebuilder_distribution_configuration` | +| `imagebuilder:image` | `aws_imagebuilder_image` | +| `imagebuilder:image-pipeline` | `aws_imagebuilder_image_pipeline` | +| `imagebuilder:image-recipe` | `aws_imagebuilder_image_recipe` | +| `imagebuilder:infrastructure-configuration` | `aws_imagebuilder_infrastructure_configuration` | +| `imagebuilder:lifecycle-policy` | `aws_imagebuilder_lifecycle_policy` | +| `imagebuilder:workflow` | `aws_imagebuilder_workflow` | +| `inspector2:filter` | `aws_inspector2_filter` | +| `internetmonitor:monitor` | `aws_internetmonitor_monitor` | +| `iot:authorizer` | `aws_iot_authorizer` | +| `iot:billinggroup` | `aws_iot_billing_group` | +| `iot:cacert` | `aws_iot_ca_certificate` | +| `iot:policy` | `aws_iot_policy` | +| `iot:provisioningtemplate` | `aws_iot_provisioning_template` | +| `iot:rolealias` | `aws_iot_role_alias` | +| `iot:rule` | `aws_iot_topic_rule` | +| `iot:thinggroup` | `aws_iot_thing_group` | +| `iot:thingtype` | `aws_iot_thing_type` | +| `ivs:channel` | `aws_ivs_channel` | +| `ivs:playback-key` | `aws_ivs_playback_key_pair` | +| `ivs:recording-configuration` | `aws_ivs_recording_configuration` | +| `kafka:replicator` | `aws_msk_replicator` | +| `kafkaconnect:custom-plugin` | `aws_mskconnect_custom_plugin` | +| `kafkaconnect:worker-configuration` | `aws_mskconnect_worker_configuration` | +| `kendra:index` | `aws_kendra_index` | +| `kendra:index/data-source` | `aws_kendra_data_source` | +| `kinesis:stream` | `aws_kinesis_stream` | +| `kinesis:stream/consumer` | `aws_kinesis_stream_consumer` | +| `kinesisanalytics:application` | `aws_kinesisanalyticsv2_application` | +| `kinesisvideo:stream` | `aws_kinesis_video_stream` | +| `kms:key` | `aws_kms_key` | +| `lambda:code-signing-config` | `aws_lambda_code_signing_config` | +| `lambda:event-source-mapping` | `aws_lambda_event_source_mapping` | +| `lambda:function` | `aws_lambda_function` | +| `lex:bot` | `aws_lex_bot` | +| `lex:bot-alias` | `aws_lex_bot_alias` | +| `license-manager:grant` | `aws_licensemanager_grant` | +| `lightsail:Bucket` | `aws_lightsail_bucket` | +| `lightsail:Certificate` | `aws_lightsail_certificate` | +| `lightsail:ContainerService` | `aws_lightsail_container_service` | +| `lightsail:Disk` | `aws_lightsail_disk` | +| `lightsail:Distribution` | `aws_lightsail_distribution` | +| `lightsail:Domain` | `aws_lightsail_domain` | +| `lightsail:Instance` | `aws_lightsail_instance` | +| `lightsail:LoadBalancer` | `aws_lightsail_lb` | +| `lightsail:StaticIp` | `aws_lightsail_static_ip` | +| `logs:anomaly-detector` | `aws_cloudwatch_log_anomaly_detector` | +| `logs:delivery` | `aws_cloudwatch_log_delivery` | +| `logs:delivery-destination` | `aws_cloudwatch_log_delivery_destination` | +| `logs:delivery-source` | `aws_cloudwatch_log_delivery_source` | +| `logs:destination` | `aws_cloudwatch_log_destination` | +| `logs:log-group` | `aws_cloudwatch_log_group` | +| `medialive:inputSecurityGroup` | `aws_medialive_input_security_group` | +| `medialive:multiplex` | `aws_medialive_multiplex` | +| `memorydb:acl` | `aws_memorydb_acl` | +| `memorydb:cluster` | `aws_memorydb_cluster` | +| `memorydb:parametergroup` | `aws_memorydb_parameter_group` | +| `memorydb:subnetgroup` | `aws_memorydb_subnet_group` | +| `memorydb:user` | `aws_memorydb_user` | +| `mobiletargeting:apps` | `aws_pinpoint_app` | +| `mq:broker` | `aws_mq_broker` | +| `mq:configuration` | `aws_mq_configuration` | +| `network-firewall:firewall` | `aws_networkfirewall_firewall` | +| `network-firewall:firewall-policy` | `aws_networkfirewall_firewall_policy` | +| `network-firewall:stateless-rulegroup` | `aws_networkfirewall_rule_group` | +| `networkmanager:connect-peer` | `aws_networkmanager_connect_peer` | +| `networkmanager:core-network` | `aws_networkmanager_core_network` | +| `networkmanager:device` | `aws_networkmanager_device` | +| `networkmanager:global-network` | `aws_networkmanager_global_network` | +| `networkmanager:link` | `aws_networkmanager_link` | +| `networkmanager:site` | `aws_networkmanager_site` | +| `notifications-contacts:emailcontact` | `aws_notificationscontacts_email_contact` | +| `oam:sink` | `aws_oam_sink` | +| `organizations:account` | `aws_organizations_account` | +| `organizations:ou` | `aws_organizations_organizational_unit` | +| `organizations:resourcepolicy` | `aws_organizations_resource_policy` | +| `osis:pipeline` | `aws_osis_pipeline` | +| `payment-cryptography:key` | `aws_paymentcryptography_key` | +| `pipes:pipe` | `aws_pipes_pipe` | +| `profile:domains` | `aws_customerprofiles_domain` | +| `ram:resource-share` | `aws_ram_resource_share` | +| `rbin:rule` | `aws_rbin_rule` | +| `rds:cev` | `aws_rds_custom_db_engine_version` | +| `rds:cluster` | `aws_docdb_cluster` | +| `rds:db` | `aws_db_instance` | +| `rds:db-proxy` | `aws_db_proxy` | +| `rds:db-proxy-endpoint` | `aws_db_proxy_endpoint` | +| `rds:es` | `aws_db_event_subscription` | +| `rds:global-cluster` | `aws_rds_global_cluster` | +| `rds:og` | `aws_db_option_group` | +| `rds:pg` | `aws_db_parameter_group` | +| `rds:subgrp` | `aws_db_subnet_group` | +| `redshift-serverless:namespace` | `aws_redshiftserverless_namespace` | +| `redshift-serverless:workgroup` | `aws_redshiftserverless_workgroup` | +| `redshift:cluster` | `aws_redshift_cluster` | +| `redshift:eventsubscription` | `aws_redshift_event_subscription` | +| `redshift:integration` | `aws_redshift_integration` | +| `redshift:parametergroup` | `aws_redshift_parameter_group` | +| `redshift:subnetgroup` | `aws_redshift_subnet_group` | +| `resiliencehub:resiliency-policy` | `aws_resiliencehub_resiliency_policy` | +| `resource-groups:group` | `aws_resourcegroups_group` | +| `route53-recovery-control:cluster` | `aws_route53recoverycontrolconfig_cluster` | +| `route53-recovery-control:controlpanel` | `aws_route53recoverycontrolconfig_control_panel` | +| `route53-recovery-control:controlpanel/safetyrule` | `aws_route53recoverycontrolconfig_safety_rule` | +| `route53-recovery-readiness:cell` | `aws_route53recoveryreadiness_cell` | +| `route53-recovery-readiness:readiness-check` | `aws_route53recoveryreadiness_readiness_check` | +| `route53-recovery-readiness:recovery-group` | `aws_route53recoveryreadiness_recovery_group` | +| `route53-recovery-readiness:resource-set` | `aws_route53recoveryreadiness_resource_set` | +| `route53:healthcheck` | `aws_route53_health_check` | +| `route53:hostedzone` | `aws_route53_zone` | +| `route53profiles:profile` | `aws_route53profiles_profile` | +| `route53profiles:profile-association` | `aws_route53profiles_association` | +| `route53resolver:firewall-domain-list` | `aws_route53_resolver_firewall_domain_list` | +| `route53resolver:firewall-rule-group` | `aws_route53_resolver_firewall_rule_group` | +| `route53resolver:firewall-rule-group-association` | `aws_route53_resolver_firewall_rule_group_association` | +| `route53resolver:resolver-endpoint` | `aws_route53_resolver_endpoint` | +| `route53resolver:resolver-query-log-config` | `aws_route53_resolver_query_log_config` | +| `route53resolver:resolver-rule` | `aws_route53_resolver_rule` | +| `rum:appmonitor` | `aws_rum_app_monitor` | +| `s3:accesspoint` | `aws_s3_access_point` | +| `s3:bucket` | `aws_s3_bucket` | +| `s3express:bucket` | `aws_s3_directory_bucket` | +| `sagemaker:app` | `aws_sagemaker_app` | +| `sagemaker:app-image-config` | `aws_sagemaker_app_image_config` | +| `sagemaker:code-repository` | `aws_sagemaker_code_repository` | +| `sagemaker:data-quality-job-definition` | `aws_sagemaker_data_quality_job_definition` | +| `sagemaker:domain` | `aws_sagemaker_domain` | +| `sagemaker:endpoint` | `aws_sagemaker_endpoint` | +| `sagemaker:endpoint-config` | `aws_sagemaker_endpoint_configuration` | +| `sagemaker:feature-group` | `aws_sagemaker_feature_group` | +| `sagemaker:image` | `aws_sagemaker_image` | +| `sagemaker:mlflow-tracking-server` | `aws_sagemaker_mlflow_tracking_server` | +| `sagemaker:model` | `aws_sagemaker_model` | +| `sagemaker:model-package-group` | `aws_sagemaker_model_package_group` | +| `sagemaker:monitoring-schedule` | `aws_sagemaker_monitoring_schedule` | +| `sagemaker:notebook-instance` | `aws_sagemaker_notebook_instance` | +| `sagemaker:notebook-instance-lifecycle-config` | `aws_sagemaker_notebook_instance_lifecycle_configuration` | +| `sagemaker:pipeline` | `aws_sagemaker_pipeline` | +| `sagemaker:project` | `aws_sagemaker_project` | +| `sagemaker:space` | `aws_sagemaker_space` | +| `sagemaker:studio-lifecycle-config` | `aws_sagemaker_studio_lifecycle_config` | +| `sagemaker:user-profile` | `aws_sagemaker_user_profile` | +| `sagemaker:workteam` | `aws_sagemaker_workteam` | +| `scheduler:schedule-group` | `aws_scheduler_schedule_group` | +| `schemas:discoverer` | `aws_schemas_discoverer` | +| `schemas:registry` | `aws_schemas_registry` | +| `schemas:schema` | `aws_schemas_schema` | +| `secretsmanager:secret` | `aws_secretsmanager_secret` | +| `servicecatalog:applications` | `aws_servicecatalogappregistry_application` | +| `servicecatalog:attribute-groups` | `aws_servicecatalogappregistry_attribute_group` | +| `servicediscovery:service` | `aws_service_discovery_service` | +| `ses:configuration-set` | `aws_sesv2_configuration_set` | +| `ses:contact-list` | `aws_sesv2_contact_list` | +| `ses:dedicated-ip-pool` | `aws_sesv2_dedicated_ip_pool` | +| `ses:identity` | `aws_sesv2_email_identity` | +| `signer:signing-profiles` | `aws_signer_signing_profile` | +| `sns:topic` | `aws_sns_topic` | +| `sqs:queue` | `aws_sqs_queue` | +| `ssm-incidents:replication-set` | `aws_ssmincidents_replication_set` | +| `ssm-incidents:response-plan` | `aws_ssmincidents_response_plan` | +| `ssm:association` | `aws_ssm_association` | +| `ssm:document` | `aws_ssm_document` | +| `ssm:maintenancewindow` | `aws_ssm_maintenance_window` | +| `ssm:parameter` | `aws_ssm_parameter` | +| `ssm:patchbaseline` | `aws_ssm_patch_baseline` | +| `states:activity` | `aws_sfn_activity` | +| `states:stateMachine` | `aws_sfn_state_machine` | +| `synthetics:canary` | `aws_synthetics_canary` | +| `synthetics:group` | `aws_synthetics_group` | +| `timestream:database` | `aws_timestreamwrite_database` | +| `timestream:database/table` | `aws_timestreamwrite_table` | +| `timestream:scheduled-query` | `aws_timestreamquery_scheduled_query` | +| `transfer:agreement` | `aws_transfer_agreement` | +| `transfer:certificate` | `aws_transfer_certificate` | +| `transfer:connector` | `aws_transfer_connector` | +| `transfer:profile` | `aws_transfer_profile` | +| `transfer:server` | `aws_transfer_server` | +| `transfer:user` | `aws_transfer_user` | +| `transfer:workflow` | `aws_transfer_workflow` | +| `verifiedpermissions:policy-store` | `aws_verifiedpermissions_policy_store` | +| `vpc-lattice:accesslogsubscription` | `aws_vpclattice_access_log_subscription` | +| `vpc-lattice:service` | `aws_vpclattice_service` | +| `vpc-lattice:service/listener` | `aws_vpclattice_listener` | +| `vpc-lattice:service/listener/rule` | `aws_vpclattice_listener_rule` | +| `vpc-lattice:servicenetwork` | `aws_vpclattice_service_network` | +| `vpc-lattice:servicenetworkserviceassociation` | `aws_vpclattice_service_network_service_association` | +| `vpc-lattice:servicenetworkvpcassociation` | `aws_vpclattice_service_network_vpc_association` | +| `vpc-lattice:targetgroup` | `aws_vpclattice_target_group` | +| `workspaces-web:browserSettings` | `aws_workspacesweb_browser_settings` | +| `workspaces-web:ipAccessSettings` | `aws_workspacesweb_ip_access_settings` | +| `workspaces-web:networkSettings` | `aws_workspacesweb_network_settings` | +| `workspaces-web:portal` | `aws_workspacesweb_portal` | +| `workspaces-web:trustStore` | `aws_workspacesweb_trust_store` | +| `workspaces-web:userAccessLoggingSettings` | `aws_workspacesweb_user_access_logging_settings` | +| `workspaces-web:userSettings` | `aws_workspacesweb_user_settings` | +| `workspaces:connectionalias` | `aws_workspaces_connection_alias` | +| `xray:group` | `aws_xray_group` | +| `xray:sampling-rule` | `aws_xray_sampling_rule` | diff --git a/website/docs/index.html.markdown b/website/docs/index.html.markdown index 71f775d2f0f3..76220ea2136f 100644 --- a/website/docs/index.html.markdown +++ b/website/docs/index.html.markdown @@ -493,6 +493,12 @@ In addition to [generic `provider` arguments](https://www.terraform.io/docs/conf - [`aws_waf_web_acl` resource](/docs/providers/aws/r/waf_web_acl.html) - [`aws_waf_xss_match_set` resource](/docs/providers/aws/r/waf_xss_match_set.html) * `sts_region` - (Optional) AWS Region for STS. If unset, AWS will use the same Region for STS as other non-STS operations. +* `tag_policy_compliance` - (Optional) The severity with which to enforce organizational tagging policies on resources managed by this provider instance. + At this time this only includes compliance with required tag keys by resource type. + Valid values are `error`, `warning`, and `disabled`. + When unset or `disabled`, tag policy compliance will not be enforced by the provider. + Can also be configured with the `TF_AWS_TAG_POLICY_COMPLIANCE` environment variable. + See the [Tag Policy Compliance user guide](./guides/tag-policy-compliance.html.markdown) for additional details. * `token` - (Optional) Session token for validating temporary credentials. Typically provided after successful identity federation or Multi-Factor Authentication (MFA) login. With MFA login, this is the session token provided afterward, not the 6 digit MFA code used to get temporary credentials. Can also be set with the `AWS_SESSION_TOKEN` environment variable. * `token_bucket_rate_limiter_capacity` - (Optional) The capacity of the AWS SDK's token bucket retry rate limiter. If no value is specified then client-side rate limiting is disabled. If a value is specified there is a greater likelihood of `retry quota exceeded` errors being raised. * `use_dualstack_endpoint` - (Optional) Force the provider to resolve endpoints with DualStack capability. Can also be set with the `AWS_USE_DUALSTACK_ENDPOINT` environment variable or in a shared config file (`use_dualstack_endpoint`). diff --git a/website/docs/r/bedrock_guardrail.html.markdown b/website/docs/r/bedrock_guardrail.html.markdown index 8cfe96ca2e59..fc1b0ca8fdab 100644 --- a/website/docs/r/bedrock_guardrail.html.markdown +++ b/website/docs/r/bedrock_guardrail.html.markdown @@ -109,9 +109,15 @@ The `content_policy_config` configuration block supports the following arguments The `filters_config` configuration block supports the following arguments: -* `input_strength` - (Optional) Strength for filters. -* `output_strength` - (Optional) Strength for filters. -* `type` - (Optional) Type of filter in content policy. +* `input_action` - (Optional) Action to take when harmful content is detected. Valid values: `BLOCK`, `NONE`. +* `input_enabled` - (Optional) Toggles guardrail evaluation on input. +* `input_modalities` - (Optional) List of selected input modalities. Valid values: `IMAGE`, `TEXT`. +* `input_strength` - (Optional) Strength for filters. Valid values: `NONE`, `LOW`, `MEDIUM`, `HIGH`. +* `output_action` - (Optional) Action to take when harmful content is detected. Valid values: `BLOCK`, `NONE`. +* `output_enabled` - (Optional) Toggles guardrail evaluation on output. +* `output_modalities` - (Optional) List of selected output modalities. Valid values: `IMAGE`, `TEXT`. +* `output_strength` - (Optional) Strength for filters. Valid values: `NONE`, `LOW`, `MEDIUM`, `HIGH`. +* `type` - (Optional) Type of filter in content policy. Valid Values: `SEXUAL`, `VIOLENCE`, `HATE`, `INSULTS`, `MISCONDUCT`, `PROMPT_ATTACK`. #### Content Tier Config diff --git a/website/docs/r/billing_view.html.markdown b/website/docs/r/billing_view.html.markdown new file mode 100644 index 000000000000..a05cd9a85e1f --- /dev/null +++ b/website/docs/r/billing_view.html.markdown @@ -0,0 +1,105 @@ +--- +subcategory: "Billing" +layout: "aws" +page_title: "AWS: aws_billing_view" +description: |- + Manages an AWS Billing View. +--- + +# Resource: aws_billing_view + +Manages an AWS Billing View. + +## Example Usage + +### Basic Usage + +```terraform +resource "aws_billing_view" "example" { + name = "example" + description = "example description" + source_views = ["arn:aws:billing::123456789012:billingview/example"] +} +``` + +## Argument Reference + +The following arguments are required: + +* `name` - (Required) Name of the custom billing view to be created. +* `source_views` - (Required) List of ARNs of the source data views for the custom billing view. + +The following arguments are optional: + +* `description` - (Optional) Description of the custom billing view. +* `data_filter_expression` - (Optional) Filter Cost Explorer APIs using the expression. Refer to the [data-filter-expression block](#data-filter-expression) documentation for more details. +* `tags` - (Optional) List of key value map specifying tags associated to the billing view being created. + +### data-filter-expression + +A `data-filter-expression` block supports the following: + +* `dimensions` - (Optional) Dimension to use for `expression`. Refer to [#dimensions](#dimensions) for more details. +* `tags` - (Optional) Tags to use for `expression`. Refer to [#tags](#tags) for more details. +* `time_range` - (Optional) Time range to use for `expression`. Refer to [#time-range](#time-range) for more details. + +#### dimensions + +A `dimensions` block supports the following: + +* `key` - (Required) Key of the dimension. Possible values are `LINKED_ACCOUNT`. +* `values` - (Required) List of metadata values that you can use to filter and group your results. + +#### tags + +A `tags` block supports the following: + +* `key` - (Required) Key of the tag. +* `values` - (Required) List of values for the tag. + +#### time-range + +A `time_range` block supports the following: + +* `begin_date_inclusive` - (Required) Inclusive start date of the time range. +* `begin_date_inclusive` - (Required) Inclusive end date of the time range. + +## Attribute Reference + +This resource exports the following attributes in addition to the arguments above: + +* `arn` - ARN of the View. +* `billing_view_type` - Type of billing group. Valid values are PRIMARY|BILLING_GROUP|CUSTOM. +* `created_at` - Timestamp when the billing view was created. +* `derived_view_count` - Number of billing views that use this billing view as a source. +* `owner_account_id` - Account owner of the billing view. +* `source_account_id` - AWS account ID that owns the source billing view, if this is a derived billing view. +* `source_view_count` - Number of source views associated with this billing view. +* `tags_all` - List of key value map specifying tags associated to the billing view. +* `updated_at` - Time when the billing view was last updated. +* `view_definition_last_updated_at` - Timestamp of when the billing view definition was last updated. + +## Timeouts + +[Configuration options](https://developer.hashicorp.com/terraform/language/resources/syntax#operation-timeouts): + +* `create` - (Default `5m`) +* `update` - (Default `5m`) +* `delete` - (Default `5m`) + +## Import + +In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import Billing View using the `arn`. For example: + +```terraform +import { + to = aws_billing_view.example + id = "arn:aws:billing::123456789012:billing-view/example" +} +``` + +Using `terraform import`, import Billing View using the `arn`. For example: + +```console +% terraform import aws_billing_view.example arn:aws:billing::123456789012:billing-view/example +``` diff --git a/website/docs/r/codestarnotifications_notification_rule.html.markdown b/website/docs/r/codestarnotifications_notification_rule.html.markdown index 60e47fa855ea..717acbd10d82 100644 --- a/website/docs/r/codestarnotifications_notification_rule.html.markdown +++ b/website/docs/r/codestarnotifications_notification_rule.html.markdown @@ -68,8 +68,8 @@ This resource supports the following arguments: An `target` block supports the following arguments: -* `address` - (Required) The ARN of notification rule target. For example, a SNS Topic ARN. -* `type` - (Optional) The type of the notification target. Default value is `SNS`. +* `address` - (Required) The ARN of the Amazon Q Developer in chat applications topic or Amazon Q Developer in chat applications client. +* `type` - (Optional) The type of the notification target. Valid values are `SNS`, `AWSChatbotSlack`, and `AWSChatbotMicrosoftTeams`. Default value is `SNS`. ## Attribute Reference diff --git a/website/docs/r/fsx_openzfs_file_system.html.markdown b/website/docs/r/fsx_openzfs_file_system.html.markdown index 6637dcb91e56..b1d39d3b043e 100644 --- a/website/docs/r/fsx_openzfs_file_system.html.markdown +++ b/website/docs/r/fsx_openzfs_file_system.html.markdown @@ -27,7 +27,6 @@ resource "aws_fsx_openzfs_file_system" "test" { The following arguments are required: * `deployment_type` - (Required) Filesystem deployment type. See the [AWS API documentation](https://docs.aws.amazon.com/fsx/latest/APIReference/API_CreateFileSystemOpenZFSConfiguration.html#FSx-Type-CreateFileSystemOpenZFSConfiguration-DeploymentType) for a list of valid values. -* `storage_capacity` - (Required) The storage capacity (GiB) of the file system. Valid values between `64` and `524288`. * `subnet_ids` - (Required) A list of IDs for the subnets that the file system will be accessible from. * `throughput_capacity` - (Required) Throughput (MB/s) of the file system. Valid values depend on `deployment_type`. Must be one of `64`, `128`, `256`, `512`, `1024`, `2048`, `3072`, `4096` for `SINGLE_AZ_1`. Must be one of `160`, `320`, `640`, `1280`, `2560`, `3840`, `5120`, `7680`, `10240` for `SINGLE_AZ_2`. @@ -45,11 +44,13 @@ The following arguments are optional: * `final_backup_tags` - (Optional) A map of tags to apply to the file system's final backup. * `kms_key_id` - (Optional) ARN for the KMS Key to encrypt the file system at rest, Defaults to an AWS managed KMS Key. * `preferred_subnet_id` - (Optional) (Multi-AZ only) Required when `deployment_type` is set to `MULTI_AZ_1`. This specifies the subnet in which you want the preferred file server to be located. +* `read_cache_configuration` - (Optional) Configuration block for optional provisioned SSD read cache on file systems that use the Intelligent-Tiering storage class. Required when `storage_type` is set to `INTELLIGENT_TIERING`. See [`read_cache_configuration` Block](#read_cache_configuration-block) for details. * `root_volume_configuration` - (Optional) The configuration for the root volume of the file system. All other volumes are children or the root volume. See [`root_volume_configuration` Block](#root_volume_configuration-block) for details. * `route_table_ids` - (Optional) (Multi-AZ only) Specifies the route tables in which Amazon FSx creates the rules for routing traffic to the correct file server. You should specify all virtual private cloud (VPC) route tables associated with the subnets in which your clients are located. By default, Amazon FSx selects your VPC's default route table. * `security_group_ids` - (Optional) A list of IDs for the security groups that apply to the specified network interfaces created for file system access. These security groups will apply to all network interfaces. * `skip_final_backup` - (Optional) When enabled, will skip the default final backup taken when the file system is deleted. This configuration must be applied separately before attempting to delete the resource to have the desired behavior. Defaults to `false`. -* `storage_type` - (Optional) The filesystem storage type. Only `SSD` is supported. +* `storage_capacity` - (Optional) The storage capacity (GiB) of the file system. Valid values between `64` and `524288`. Required when `storage_type` is set to `SSD`. Must not be set when `storage_type` is set to `INTELLIGENT_TIERING`. +* `storage_type` - (Optional) The filesystem storage type. Valid values are `SSD` and `INTELLIGENT_TIERING`. `INTELLIGENT_TIERING` requires `deployment_type` to be `MULTI_AZ_1`. * `user_and_group_quotas` - (Optional) - Specify how much storage users or groups can use on the filesystem. Maximum number of items defined by [FSx for OpenZFS Resource quota](https://docs.aws.amazon.com/fsx/latest/OpenZFSGuide/limits.html#limits-openzfs-resources-file-system). See [`user_and_group_quotas` Block](#user_and_group_quotas-block) Below. * `tags` - (Optional) A map of tags to assign to the file system. If configured with a provider [`default_tags` configuration block](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level. * `weekly_maintenance_start_time` - (Optional) The preferred start time (in `d:HH:MM` format) to perform weekly maintenance, in the UTC time zone. @@ -61,6 +62,13 @@ The `disk_iops_configuration` configuration block supports the following argumen * `iops` - (Optional) The total number of SSD IOPS provisioned for the file system. * `mode` - (Optional) Specifies whether the number of IOPS for the file system is using the system. Valid values are `AUTOMATIC` and `USER_PROVISIONED`. Default value is `AUTOMATIC`. +### `read_cache_configuration` Block + +The `read_cache_configuration` configuration block supports the following arguments: + +* `size` - (Optional) Size of the file system's SSD read cache, in gibibytes (GiB). Required when `sizing_mode` is set to `USER_PROVISIONED`. Must not be set when any other `sizing_mode` is used. +* `sizing_mode` - (Optional) Specifies how the provisioned SSD read cache is sized. Valid values are `NO_CACHE`, `USER_PROVISIONED`, and `PROPORTIONAL_TO_THROUGHPUT_CAPACITY`. See the [AWS API documentation](https://docs.aws.amazon.com/fsx/latest/APIReference/API_OpenZFSReadCacheConfiguration.html) for more information. + ### `root_volume_configuration` Block The `root_volume_configuration` configuration block supports the following arguments: diff --git a/website/docs/r/lambda_function.html.markdown b/website/docs/r/lambda_function.html.markdown index f20d24b0fd80..5469b3ef3886 100644 --- a/website/docs/r/lambda_function.html.markdown +++ b/website/docs/r/lambda_function.html.markdown @@ -524,6 +524,7 @@ The following arguments are optional: * `source_kms_key_arn` - (Optional) ARN of the AWS Key Management Service key used to encrypt the function's `.zip` deployment package. Conflicts with `image_uri`. * `tags` - (Optional) Key-value map of tags for the Lambda function. If configured with a provider [`default_tags` configuration block](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level. * `timeout` - (Optional) Amount of time your Lambda Function has to run in seconds. Defaults to 3. Valid between 1 and 900. +* `tenancy_config` - (Optional) Configuration block for Tenancy. [See below](#tenancy_config-configuration-block). * `tracing_config` - (Optional) Configuration block for X-Ray tracing. [See below](#tracing_config-configuration-block). * `vpc_config` - (Optional) Configuration block for VPC. [See below](#vpc_config-configuration-block). @@ -561,6 +562,10 @@ The following arguments are optional: * `apply_on` - (Required) When to apply snap start optimization. Valid value: `PublishedVersions`. +### tenancy_config Configuration Block + +* `tenant_isolation_mode` - (Required) Tenant Isolation Mode. Valid values: `PER_TENANT`. + ### tracing_config Configuration Block * `mode` - (Required) X-Ray tracing mode. Valid values: `Active`, `PassThrough`. diff --git a/website/docs/r/lambda_invocation.html.markdown b/website/docs/r/lambda_invocation.html.markdown index 582d8d35235e..f3b35400bee7 100644 --- a/website/docs/r/lambda_invocation.html.markdown +++ b/website/docs/r/lambda_invocation.html.markdown @@ -173,6 +173,7 @@ The following arguments are optional: * `lifecycle_scope` - (Optional) Lifecycle scope of the resource to manage. Valid values are `CREATE_ONLY` and `CRUD`. Defaults to `CREATE_ONLY`. `CREATE_ONLY` will invoke the function only on creation or replacement. `CRUD` will invoke the function on each lifecycle event, and augment the input JSON payload with additional lifecycle information. * `qualifier` - (Optional) Qualifier (i.e., version) of the Lambda function. Defaults to `$LATEST`. * `region` - (Optional) Region where this resource will be [managed](https://docs.aws.amazon.com/general/latest/gr/rande.html#regional-endpoints). Defaults to the Region set in the [provider configuration](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#aws-configuration-reference). +* `tenant_id` - (Optional) Tenant Id to serve invocations from specified tenant. * `terraform_key` - (Optional) JSON key used to store lifecycle information in the input JSON payload. Defaults to `tf`. This additional key is only included when `lifecycle_scope` is set to `CRUD`. * `triggers` - (Optional) Map of arbitrary keys and values that, when changed, will trigger a re-invocation. To force a re-invocation without changing these keys/values, use the [`terraform taint` command](https://developer.hashicorp.com/terraform/cli/commands/taint). diff --git a/website/docs/r/msk_cluster.html.markdown b/website/docs/r/msk_cluster.html.markdown index 35ad4c1ae792..c1b98eff2825 100644 --- a/website/docs/r/msk_cluster.html.markdown +++ b/website/docs/r/msk_cluster.html.markdown @@ -104,7 +104,7 @@ resource "aws_kinesis_firehose_delivery_stream" "test_stream" { resource "aws_msk_cluster" "example" { cluster_name = "example" - kafka_version = "3.2.0" + kafka_version = "3.8.x" number_of_broker_nodes = 3 broker_node_group_info { @@ -175,7 +175,7 @@ output "bootstrap_brokers_tls" { ```terraform resource "aws_msk_cluster" "example" { cluster_name = "example" - kafka_version = "2.7.1" + kafka_version = "3.8.x" number_of_broker_nodes = 3 broker_node_group_info { @@ -214,6 +214,7 @@ This resource supports the following arguments: * `enhanced_monitoring` - (Optional) Specify the desired enhanced MSK CloudWatch monitoring level. See [Monitoring Amazon MSK with Amazon CloudWatch](https://docs.aws.amazon.com/msk/latest/developerguide/monitoring.html) * `open_monitoring` - (Optional) Configuration block for JMX and Node monitoring for the MSK cluster. See [open_monitoring Argument Reference](#open_monitoring-argument-reference) below. * `logging_info` - (Optional) Configuration block for streaming broker logs to Cloudwatch/S3/Kinesis Firehose. See [logging_info Argument Reference](#logging_info-argument-reference) below. +* `rebalancing` - (Optional) Configuration block for intelligent rebalancing. See [rebalancing Argument Reference](#rebalancing-argument-reference) below. Only applicable to MSK Provisioned clusters with Express brokers. * `storage_mode` - (Optional) Controls storage mode for supported storage tiers. Valid values are: `LOCAL` or `TIERED`. * `tags` - (Optional) A map of tags to assign to the resource. If configured with a provider [`default_tags` configuration block](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level. @@ -336,6 +337,12 @@ This resource supports the following arguments: * `bucket` - (Optional) Name of the S3 bucket to deliver logs to. * `prefix` - (Optional) Prefix to append to the folder name. +### rebalancing Argument Reference + +* `status` - (Required) The status of intelligent rebalancing. Valid values: `ACTIVE`, `PAUSED`. Default is `ACTIVE` for new Express-based clusters. + +~> **NOTE:** Intelligent rebalancing is only available for MSK Provisioned clusters with Express brokers. When enabled, you cannot use third-party rebalancing tools such as Cruise Control. See [AWS MSK Intelligent Rebalancing](https://docs.aws.amazon.com/msk/latest/developerguide/intelligent-rebalancing.html) for more information. + ## Attribute Reference This resource exports the following attributes in addition to the arguments above: diff --git a/website/docs/r/s3_bucket.html.markdown b/website/docs/r/s3_bucket.html.markdown index e0bbca18745d..d3f0878464a1 100644 --- a/website/docs/r/s3_bucket.html.markdown +++ b/website/docs/r/s3_bucket.html.markdown @@ -265,6 +265,8 @@ The `sse_kms_encrypted_objects` configuration block supports the following argum ~> **NOTE:** Currently, changes to the `server_side_encryption_configuration` configuration of *existing* resources cannot be automatically detected by Terraform. To manage changes in encryption of an S3 bucket, use the `aws_s3_bucket_server_side_encryption_configuration` resource instead. If you use `server_side_encryption_configuration` on an `aws_s3_bucket`, Terraform will assume management over the encryption configuration for the S3 bucket, treating additional encryption changes as drift. For this reason, `server_side_encryption_configuration` cannot be mixed with the external `aws_s3_bucket_server_side_encryption_configuration` resource for a given S3 bucket. +~> **NOTE:** [Starting in March 2026](https://docs.aws.amazon.com/AmazonS3/latest/userguide/default-s3-c-encryption-setting-faq.html), Amazon S3 will automatically block server-side encryption with customer-provided keys (SSE-C) for all new buckets. The `blocked_encryption_types` argument is not available in this deprecated configuration block. Use the [`aws_s3_bucket_server_side_encryption_configuration`](/docs/providers/aws/r/s3_bucket_server_side_encryption_configuration.html) resource to manage this behavior for specific buckets. + The `server_side_encryption_configuration` configuration block supports the following argument: * `rule` - (Required) Single object for server-side encryption by default configuration. (documented below) diff --git a/website/docs/r/s3_bucket_server_side_encryption_configuration.html.markdown b/website/docs/r/s3_bucket_server_side_encryption_configuration.html.markdown index d2503a682dd1..08c1ffc21167 100644 --- a/website/docs/r/s3_bucket_server_side_encryption_configuration.html.markdown +++ b/website/docs/r/s3_bucket_server_side_encryption_configuration.html.markdown @@ -12,6 +12,8 @@ Provides a S3 bucket server-side encryption configuration resource. ~> **NOTE:** Destroying an `aws_s3_bucket_server_side_encryption_configuration` resource resets the bucket to [Amazon S3 bucket default encryption](https://docs.aws.amazon.com/AmazonS3/latest/userguide/default-encryption-faq.html). +~> **NOTE:** Starting in March 2026, Amazon S3 will automatically block server-side encryption with customer-provided keys (SSE-C) for all new buckets. Use the `blocked_encryption_types` argument to manage this behavior. For more information, see the [SSE-C changes FAQ](https://docs.aws.amazon.com/AmazonS3/latest/userguide/default-s3-c-encryption-setting-faq.html). + ## Example Usage ```terraform