Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

azapi_resource_action - support sensitive_response_export_values and sensitive_output fields #718

Merged
merged 5 commits into from
Jan 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion .github/workflows/unit-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ jobs:
with:
go-version-file: 'go.mod'
cache: true
- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: latest
terraform_wrapper: false
- run: go generate ./...
- name: git diff
run: |
Expand All @@ -38,7 +43,8 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-go@v2
with:
go-version: '1.21'
go-version-file: 'go.mod'
cache: true
- run: chmod -R +x ./scripts
- run: bash scripts/gogetcookie.sh
- run: make test
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,14 @@
FEATURES:
- **New Ephemeral Resource**: azapi_resource_action

ENHANCEMENTS:
- `azapi_resource_action` resource, data source: Support `sensitive_response_export_values` field, which is used to specify the sensitive fields to export.
- `azaapi_resource_action` resource, data source: Support `sensitive_output` field, which is a sensitive computed field that contains the fields exported by `sensitive_response_export_values`.

BUG FIXES:
- Fix a bug that query parameters and headers don't work properly with unknown values


## v2.2.0

ENHANCEMENTS:
Expand Down
42 changes: 42 additions & 0 deletions docs/data-sources/resource_action.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,33 @@ data "azapi_resource_action" "example" {

To learn more about JMESPath, visit [JMESPath](https://jmespath.org/).
- `retry` (Attributes) The retry block supports the following arguments: (see [below for nested schema](#nestedatt--retry))
- `sensitive_response_export_values` (Dynamic) The attribute can accept either a list or a map.

- **List**: A list of paths that need to be exported from the response body. Setting it to `["*"]` will export the full response body. Here's an example. If it sets to `["properties.loginServer", "properties.policies.quarantinePolicy.status"]`, it will set the following HCL object to the computed property sensitive_output.

```text
{
properties = {
loginServer = "registry1.azurecr.io"
policies = {
quarantinePolicy = {
status = "disabled"
}
}
}
}
```

- **Map**: A map where the key is the name for the result and the value is a JMESPath query string to filter the response. Here's an example. If it sets to `{"login_server": "properties.loginServer", "quarantine_status": "properties.policies.quarantinePolicy.status"}`, it will set the following HCL object to the computed property sensitive_output.

```text
{
"login_server" = "registry1.azurecr.io"
"quarantine_status" = "disabled"
}
```

To learn more about JMESPath, visit [JMESPath](https://jmespath.org/).
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))

### Read-Only
Expand All @@ -106,6 +133,21 @@ To learn more about JMESPath, visit [JMESPath](https://jmespath.org/).
value = data.azapi_resource_action.example.output.properties.policies.quarantinePolicy.status
}
```
- `sensitive_output` (Dynamic, Sensitive) The output HCL object containing the properties specified in `sensitive_response_export_values`. Here are some examples to use the values.

```terraform
// it will output "registry1.azurecr.io"
output "login_server" {
value = data.azapi_resource_action.example.sensitive_output.properties.loginServer
sensitive = true
}

// it will output "disabled"
output "quarantine_policy" {
value = data.azapi_resource_action.example.sensitive_output.properties.policies.quarantinePolicy.status
sensitive = true
}
```

<a id="nestedatt--retry"></a>
### Nested Schema for `retry`
Expand Down
2 changes: 1 addition & 1 deletion docs/guides/feature_convert_arm_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -307,4 +307,4 @@ import {
id = "/subscriptions/000000/resourceGroups/example-rg/providers/Microsoft.CognitiveServices/accounts/terraform?api-version=2024-10-01"
to = azapi_resource.account
}
```
```
4 changes: 2 additions & 2 deletions docs/guides/feature_jmes_query.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ data "azapi_resource" "virtualMachine" {
name = "myVirtualMachine"
parent_id = "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myResourceGroup"
response_export_values = {
admin = "osProfile.adminUsername"
admin = "osProfile.adminUsername"
ssh_key = "osProfile.linuxConfiguration.ssh.publicKeys[0].keyData"
}
}
Expand Down Expand Up @@ -228,4 +228,4 @@ resource "azapi_resource" "roleAssignment" {
}
}
}
```
```
2 changes: 1 addition & 1 deletion docs/guides/feature_list_resources.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,4 +120,4 @@ output "vmIds" {
}
```

It uses the `response_export_values` attribute to specify the `JMESPath` query to filter virtual machines by location. More details about using `JMESPath` query language to filter resources can be found [here](./feature_jmes_query.html).
It uses the `response_export_values` attribute to specify the `JMESPath` query to filter virtual machines by location. More details about using `JMESPath` query language to filter resources can be found [here](./feature_jmes_query.html).
8 changes: 4 additions & 4 deletions docs/guides/feature_migrate_from_azurerm.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Please add the necessary terraform code to deploy the resources in the root modu

provider "azurerm" {
features {}

subscription_id = "00000000-0000-0000-0000-000000000000"
}

Expand All @@ -46,7 +46,7 @@ provider "azurerm" {
location = "eastus"
resource_group_name = "heng-aks" // name of an existing resource group
name = "henglutest"
lock = { // enable the lock
lock = { // enable the lock
kind = "CanNotDelete"
name = "mylock"
}
Expand Down Expand Up @@ -145,7 +145,7 @@ resource "azapi_resource" "lock_this" {
body = {
properties = {
level = var.lock.kind
notes =var.lock.kind == "CanNotDelete" ? "Cannot delete the resource or its child resources." : "Cannot delete or modify the resource or its child resources."
notes = var.lock.kind == "CanNotDelete" ? "Cannot delete the resource or its child resources." : "Cannot delete or modify the resource or its child resources."
}
}
ignore_casing = false
Expand Down Expand Up @@ -228,4 +228,4 @@ The migration flow supports migrating multiple resources at the same time. You c

### How about migrating resources from azapi to azurerm?

The `azurerm` provider doesn't support `moved` block yet. The migration will support migrating resources from `azapi` to `azurerm` in the future.
The `azurerm` provider doesn't support `moved` block yet. The migration will support migrating resources from `azapi` to `azurerm` in the future.
2 changes: 1 addition & 1 deletion docs/guides/feature_replacement_triggers.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,4 @@ resource "azapi_resource" "publicIPAddress" {
"zones",
]
}
```
```
42 changes: 42 additions & 0 deletions docs/resources/resource_action.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,33 @@ description: |-

To learn more about JMESPath, visit [JMESPath](https://jmespath.org/).
- `retry` (Attributes) The retry block supports the following arguments: (see [below for nested schema](#nestedatt--retry))
- `sensitive_response_export_values` (Dynamic) The attribute can accept either a list or a map.

- **List**: A list of paths that need to be exported from the response body. Setting it to `["*"]` will export the full response body. Here's an example. If it sets to `["properties.loginServer", "properties.policies.quarantinePolicy.status"]`, it will set the following HCL object to the computed property output.

```text
{
properties = {
loginServer = "registry1.azurecr.io"
policies = {
quarantinePolicy = {
status = "disabled"
}
}
}
}
```

- **Map**: A map where the key is the name for the result and the value is a JMESPath query string to filter the response. Here's an example. If it sets to `{"login_server": "properties.loginServer", "quarantine_status": "properties.policies.quarantinePolicy.status"}`, it will set the following HCL object to the computed property output.

```text
{
"login_server" = "registry1.azurecr.io"
"quarantine_status" = "disabled"
}
```

To learn more about JMESPath, visit [JMESPath](https://jmespath.org/).
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
- `when` (String) When to perform the action, value must be one of: `apply`, `destroy`. Default is `apply`.

Expand All @@ -127,6 +154,21 @@ To learn more about JMESPath, visit [JMESPath](https://jmespath.org/).
value = azapi_resource_action.example.output.properties.policies.quarantinePolicy.status
}
```
- `sensitive_output` (Dynamic, Sensitive) The output HCL object containing the properties specified in `sensitive_response_export_values`. Here are some examples to use the values.

```terraform
// it will output "registry1.azurecr.io"
output "login_server" {
value = azapi_resource_action.example.sensitive_output.properties.loginServer
sensitive = true
}

// it will output "disabled"
output "quarantine_policy" {
value = azapi_resource_action.example.sensitive_output.properties.policies.quarantinePolicy.status
sensitive = true
}
```

<a id="nestedatt--retry"></a>
### Nested Schema for `retry`
Expand Down
23 changes: 23 additions & 0 deletions internal/docstrings/output.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,26 @@ const (
func Output(res string) string {
return addBackquotes(strings.ReplaceAll(outputStr, "RESOURCE", res))
}

const (
sensitiveOutputStr = `The output HCL object containing the properties specified in %ssensitive_response_export_values%s. Here are some examples to use the values.

%s%s%sterraform
// it will output "registry1.azurecr.io"
output "login_server" {
value = RESOURCE.example.sensitive_output.properties.loginServer
sensitive = true
}

// it will output "disabled"
output "quarantine_policy" {
value = RESOURCE.example.sensitive_output.properties.policies.quarantinePolicy.status
sensitive = true
}
%s%s%s
`
)

func SensitiveOutput(res string) string {
return addBackquotes(strings.ReplaceAll(sensitiveOutputStr, "RESOURCE", res))
}
34 changes: 34 additions & 0 deletions internal/docstrings/response_export_values.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,35 @@ const (
}
%s%s%s

To learn more about JMESPath, visit [JMESPath](https://jmespath.org/).
`

sensitiveResponseExportValuesStr = `The attribute can accept either a list or a map.

- **List**: A list of paths that need to be exported from the response body. Setting it to %s["*"]%s will export the full response body. Here's an example. If it sets to %s["properties.loginServer", "properties.policies.quarantinePolicy.status"]%s, it will set the following HCL object to the computed property sensitive_output.

%s%s%stext
{
properties = {
loginServer = "registry1.azurecr.io"
policies = {
quarantinePolicy = {
status = "disabled"
}
}
}
}
%s%s%s

- **Map**: A map where the key is the name for the result and the value is a JMESPath query string to filter the response. Here's an example. If it sets to %s{"login_server": "properties.loginServer", "quarantine_status": "properties.policies.quarantinePolicy.status"}%s, it will set the following HCL object to the computed property sensitive_output.

%s%s%stext
{
"login_server" = "registry1.azurecr.io"
"quarantine_status" = "disabled"
}
%s%s%s

To learn more about JMESPath, visit [JMESPath](https://jmespath.org/).
`

Expand Down Expand Up @@ -88,3 +117,8 @@ func ResponseExportValues() string {
func ResponseExportValuesForResourceList() string {
return addBackquotes(responseExportValuesForResourceListStr)
}

// SensitiveResponseExportValues returns the docstring for the response_export_values schema attribute.
func SensitiveResponseExportValues() string {
return addBackquotes(sensitiveResponseExportValuesStr)
}
44 changes: 32 additions & 12 deletions internal/services/azapi_resource_action_data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,20 @@ import (
)

type ResourceActionDataSourceModel struct {
ID types.String `tfsdk:"id"`
ResourceID types.String `tfsdk:"resource_id"`
Type types.String `tfsdk:"type"`
Action types.String `tfsdk:"action"`
Method types.String `tfsdk:"method"`
Body types.Dynamic `tfsdk:"body"`
ResponseExportValues types.Dynamic `tfsdk:"response_export_values"`
Output types.Dynamic `tfsdk:"output"`
Timeouts timeouts.Value `tfsdk:"timeouts"`
Retry retry.RetryValue `tfsdk:"retry"`
Headers types.Map `tfsdk:"headers"`
QueryParameters types.Map `tfsdk:"query_parameters"`
ID types.String `tfsdk:"id"`
ResourceID types.String `tfsdk:"resource_id"`
Type types.String `tfsdk:"type"`
Action types.String `tfsdk:"action"`
Method types.String `tfsdk:"method"`
Body types.Dynamic `tfsdk:"body"`
ResponseExportValues types.Dynamic `tfsdk:"response_export_values"`
SensitiveResponseExportValues types.Dynamic `tfsdk:"sensitive_response_export_values"`
Output types.Dynamic `tfsdk:"output"`
SensitiveOutput types.Dynamic `tfsdk:"sensitive_output"`
Timeouts timeouts.Value `tfsdk:"timeouts"`
Retry retry.RetryValue `tfsdk:"retry"`
Headers types.Map `tfsdk:"headers"`
QueryParameters types.Map `tfsdk:"query_parameters"`
}

type ResourceActionDataSource struct {
Expand Down Expand Up @@ -103,11 +105,22 @@ func (r *ResourceActionDataSource) Schema(ctx context.Context, request datasourc
MarkdownDescription: docstrings.ResponseExportValues(),
},

"sensitive_response_export_values": schema.DynamicAttribute{
Optional: true,
MarkdownDescription: docstrings.SensitiveResponseExportValues(),
},

"output": schema.DynamicAttribute{
Computed: true,
MarkdownDescription: docstrings.Output("data.azapi_resource_action"),
},

"sensitive_output": schema.DynamicAttribute{
Computed: true,
Sensitive: true,
MarkdownDescription: docstrings.SensitiveOutput("data.azapi_resource_action"),
},

"retry": retry.SingleNestedAttribute(ctx),

"headers": schema.MapAttribute{
Expand Down Expand Up @@ -198,5 +211,12 @@ func (r *ResourceActionDataSource) Read(ctx context.Context, request datasource.
}
model.Output = output

sensitiveOutput, err := buildOutputFromBody(responseBody, model.SensitiveResponseExportValues, nil)
if err != nil {
response.Diagnostics.AddError("Failed to build sensitive output", err.Error())
return
}
model.SensitiveOutput = sensitiveOutput

response.Diagnostics.Append(response.State.Set(ctx, &model)...)
}
25 changes: 25 additions & 0 deletions internal/services/azapi_resource_action_data_source_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,18 @@ func TestAccActionDataSource_queryParameters(t *testing.T) {
})
}

func TestAccActionDataSource_sensitiveOutput(t *testing.T) {
data := acceptance.BuildTestData(t, "data.azapi_resource_action", "test")
r := ActionDataSource{}

data.DataSourceTest(t, []resource.TestStep{
{
Config: r.sensitiveOutput(data),
Check: resource.ComposeTestCheckFunc(),
},
})
}

func (r ActionDataSource) basic(data acceptance.TestData) string {
return fmt.Sprintf(`
%s
Expand Down Expand Up @@ -142,3 +154,16 @@ data "azapi_resource_action" "test" {
response_export_values = ["*"]
}`
}

func (r ActionDataSource) sensitiveOutput(data acceptance.TestData) string {
return fmt.Sprintf(`
%s

data "azapi_resource_action" "test" {
type = "Microsoft.Automation/automationAccounts@2023-11-01"
resource_id = azapi_resource.test.id
action = "listKeys"
sensitive_response_export_values = ["*"]
}
`, GenericResource{}.defaultTag(data))
}
Loading
Loading