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

New resource: azurerm_managed_application #6386

Merged
merged 11 commits into from Apr 30, 2020

Conversation

neil-yechenwei
Copy link
Contributor

This PR is the implement of the issue #5294

Copy link
Collaborator

@katbyte katbyte left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@neil-yechenwei,

I've left some comments inline detailing some schema changes i'd like to see. I don't think there is any value to converting the param map into json and then back. Lets just keep it as a map for terraform and also generate the target resource group id ourselvs. thanks!

Comment on lines 158 to 159
expandedParams, err := structure.ExpandJsonFromString(v.(string))
if err != nil {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could we merge these two lines?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems I cannot do this since "expandedParams" variable is used in line 163

}, false),
},

"managed_resource_group_id": {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

COuld we make this

Suggested change
"managed_resource_group_id": {
"target_resource_group_name": {

and generate the id in code?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated

Comment on lines 219 to 227
for _, v := range paramsVal {
if v != nil {
delete(v.(map[string]interface{}), "type")
}
}
json, err := structure.FlattenJsonToString(paramsVal)
if err != nil {
return fmt.Errorf("failed to serialize JSON from Parameters: %+v", err)
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given this is a map already we def shouldn't be converting it to json for terraform

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated

@neil-yechenwei
Copy link
Contributor Author

@katbyte , thanks for your comments. I've updated code.

@ghost ghost removed the waiting-response label Apr 16, 2020

* `kind` - (Required) The kind of the managed application. Possible values are `MarketPlace` and `ServiceCatalog`.

* `target_resource_group_name` - (Required) The name of the target resource group which includes resources managed by Managed Application.
Copy link

@seiffert seiffert Apr 17, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you consider naming this managed_resource_group_name? I haven't heard this to be referred to as "target resource group" yet and "managed resource group" would be consistent with az as well:

$ az managedapp create --help

Command
    az managedapp create : Create a managed application.

Arguments
    --kind              [Required] : The managed application kind. can be marketplace or
                                     servicecatalog.
    --managed-rg-id -m  [Required] : The resource group managed by the managed application.
    --name -n           [Required] : The managed application name.
    --resource-group -g [Required] : The resource group of the managed application.
...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@katbyte . I think what seiffert suggests is reasonable. I found generally it would be named as "managed_resource_group_name" in Azure side after went through the related docs. I think it would be more friendly to azure users. How do you think? If it's fine, I will update it to "managed_resource_group_name"?

Copy link
Collaborator

@katbyte katbyte Apr 20, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think the API's name is good or clear as to what it is (or if it should be created first) but i'll leave it up to you @neil-yechenwei - please make sure the docs are clear what it means either way

the CLi tool is auto generated from swagger and often carries over tragic names & descriptions @seiffert - we often will change/rename properties so they are more obvious as to what they do ie target resource group implies the resource will act upon that group. However in this case its not as egregous as i've seen elsewhere so i'll leave it up to the PR author.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks both. I updated it as "managed_resource_group_name" and updated the document for the description.


The following attributes are exported:

* `id` - The ID of the Managed Application.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe it would be convenient to expose the app's outputs as well. Do you think we could add that from the beginning?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According by kt's previous comments, suggests to not expose outputs from the beginning. Because compute attribute is easily to be added. So suggests to expose them when user asks for. And we don't need to maintain the outputs user doesn't need. And I think all of this app's outputs are unnecessary to user and other resources.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are the app outputs you would like to see @seiffert and in what instance would they be sueful?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the late response. The app outputs can be anything the app publisher decides to output, so this would need to be a generic key/value map.

Outputs could be URLs to a management interface deployed as part of the app or also just configuration values for clients to use the app. E.g. if you would deploy a managed app that contains a database server, the server name could be an output of the app. By making it an attribute of the resource, the server name could be used to provision the databases in that server.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of course, this functionality can also be developed in a future PR. I was just looking at this for a potential use case of our team where outputs would be good to have.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ahh thanks for explaining that makes a lot of sense, @neil-yechenwei could we get an managed_app_outputs map as suggested?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added

Copy link
Collaborator

@katbyte katbyte left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @neil-yechenwei,

Looks like we have twot est failures:

------- Stdout: -------
=== RUN   TestAccAzureRMManagedApplication_requiresImport
=== PAUSE TestAccAzureRMManagedApplication_requiresImport
=== CONT  TestAccAzureRMManagedApplication_requiresImport
--- FAIL: TestAccAzureRMManagedApplication_requiresImport (157.71s)
    testing.go:633: Step 1, expected error:
        
        config is invalid: 2 problems:
        
        - Missing required argument: The argument "kind" is required, but no definition was found.
        - Missing required argument: The argument "managed_resource_group_name" is required, but no definition was found.

and

Test Failed

------- Stdout: -------
=== RUN   TestAccAzureRMManagedApplication_complete
=== PAUSE TestAccAzureRMManagedApplication_complete
=== CONT  TestAccAzureRMManagedApplication_complete
--- FAIL: TestAccAzureRMManagedApplication_complete (79.86s)
    testing.go:640: Step 0 error: errors during apply:
        
        Error: failed to create Managed Application "acctestCompleteManagedApp200421003449886326" (Resource Group "acctestRG-mapp-200421003449886326"): managedapplications.ApplicationsClient#CreateOrUpdate: Failure sending request: StatusCode=400 -- Original Error: Code="ResourcePurchaseValidationFailed" Message="User failed validation to purchase resources. Error message: 'Legal terms have not been accepted for this item on this subscription: '1a6092a6-137e-4025-9a7c-ef77f76f2c02'. To accept legal terms using PowerShell, please use Get-AzureRmMarketplaceTerms and Set-AzureRmMarketplaceTerms API(https://go.microsoft.com/fwlink/?linkid=862451), to accept the terms using Azure CLI, please use az vm image accpet-terms (https://go.microsoft.com/fwlink/?linkid=2110637) or deploy via the Azure portal to accept the terms'"
        
          on /opt/teamcity-agent/temp/buildTmp/tf-test793218955/main.tf line 35:
          (source code not available)
  • could you update the docs to include an example of how to accept the managed applications terms, and by proxy the command i need to run to enable the tests on our subscription 🙂


* `location` - (Required) Specifies the supported Azure location where the resource exists. Changing this forces a new resource to be created.

* `kind` - (Required) The kind of the managed application. Possible values are `MarketPlace` and `ServiceCatalog`. Changing this forces a new resource to be created.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* `kind` - (Required) The kind of the managed application. Possible values are `MarketPlace` and `ServiceCatalog`. Changing this forces a new resource to be created.
* `kind` - (Required) The kind of the managed application to deply. Possible values are `MarketPlace` and `ServiceCatalog`. Changing this forces a new resource to be created.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated


* `kind` - (Required) The kind of the managed application. Possible values are `MarketPlace` and `ServiceCatalog`. Changing this forces a new resource to be created.

* `managed_resource_group_name` - (Required) The name of the target resource group which holds all the resources that are required by the managed application. Changing this forces a new resource to be created.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be

Suggested change
* `managed_resource_group_name` - (Required) The name of the target resource group which holds all the resources that are required by the managed application. Changing this forces a new resource to be created.
* `managed_resource_group_name` - (Required) The name of the target resource group where all the resources deployed by the managed application will reside. Changing this forces a new resource to be created.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated


* `managed_resource_group_name` - (Required) The name of the target resource group which holds all the resources that are required by the managed application. Changing this forces a new resource to be created.

* `application_definition_id` - (Optional) The fully qualified path of managed application definition ID.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* `application_definition_id` - (Optional) The fully qualified path of managed application definition ID.
* `application_definition_id` - (Optional) The application definition ID to deply.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated


* `application_definition_id` - (Optional) The fully qualified path of managed application definition ID.

* `parameters` - (Optional) The name and value pairs that define the managed application parameters.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* `parameters` - (Optional) The name and value pairs that define the managed application parameters.
* `parameters` - (Optional) A mapping of name and value pairs to pass to the managed application as parameters.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated


* `version` - (Required) Specifies the version of the plan from the marketplace.

* `promotion_code` - (Optional) Specifies the promotion code of the plan.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* `promotion_code` - (Optional) Specifies the promotion code of the plan.
* `promotion_code` - (Optional) Specifies the promotion code to use with the plan.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated

@neil-yechenwei
Copy link
Contributor Author

neil-yechenwei commented Apr 21, 2020

@katbyte , thanks for your comments. For test case "TestAccAzureRMManagedApplication_requiresImport" failure, I've fixed. For test case "TestAccAzureRMManagedApplication_complete", I've supplement the description about how to accept terms while plan is specified. So before you run this test case, you have to run command Set-AzContext -SubscriptionId "<insert your subscription id>"; Get-AzMarketplaceTerms -Publisher "cisco" -Product "meraki-vmx" -Name "meraki-vmx100" | Set-AzMarketplaceTerms -Accept first.

My test results:

=== RUN   TestAccAzureRMManagedApplication_requiresImport
=== PAUSE TestAccAzureRMManagedApplication_requiresImport
=== CONT  TestAccAzureRMManagedApplication_requiresImport
--- PASS: TestAccAzureRMManagedApplication_requiresImport (572.98s)
PASS

=== RUN   TestAccAzureRMManagedApplication_complete
=== PAUSE TestAccAzureRMManagedApplication_complete
=== CONT  TestAccAzureRMManagedApplication_complete
--- PASS: TestAccAzureRMManagedApplication_complete (1416.08s)
PASS

@ghost ghost removed the waiting-response label Apr 21, 2020
Copy link
Collaborator

@katbyte katbyte left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @neil-yechenwei, just a couple more comments to address and this should be good 🙂

}

if v, ok := d.GetOk("managed_resource_group_name"); ok {
targetResourceGroupId := fmt.Sprintf("/subscriptions/%s/resourceGroups/%s", meta.(*clients.Client).Account.SubscriptionId, v)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to target a resource group in a different subscription?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope. According by previous test results, they must be in the same subscription otherwise it would threw error message which instructs they must be in the same subscription.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cool thanks!

Comment on lines 154 to 156
a := v.(string)
b := utils.String(a)
parameters.ApplicationDefinitionID = b
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could we just do this

Suggested change
a := v.(string)
b := utils.String(a)
parameters.ApplicationDefinitionID = b
parameters.ApplicationDefinitionID = utils.String(v.(string))

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated

return fmt.Errorf("setting `plan`: %+v", err)
}
if props := resp.ApplicationProperties; props != nil {
parsedManagedResourceGroupID := strings.Split(*props.ManagedResourceGroupID, "/")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could we use the resource group parse id function here maybe?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated


The following attributes are exported:

* `id` - The ID of the Managed Application.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ahh thanks for explaining that makes a lot of sense, @neil-yechenwei could we get an managed_app_outputs map as suggested?


* `promotion_code` - (Optional) Specifies the promotion code to use with the plan.

~> **NOTE:** When `plan` is specified, legal terms must be accepted for this item on this subscription before creating the Managed Application. For example, to accept the terms using PowerShell, please use `Set-AzContext -SubscriptionId "00000000-0000-0000-0000-000000000000"; Get-AzMarketplaceTerms -Publisher "cisco" -Product "meraki-vmx" -Name "meraki-vmx100" | Set-AzMarketplaceTerms -Accept`.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could we make this a bit more generic

Suggested change
~> **NOTE:** When `plan` is specified, legal terms must be accepted for this item on this subscription before creating the Managed Application. For example, to accept the terms using PowerShell, please use `Set-AzContext -SubscriptionId "00000000-0000-0000-0000-000000000000"; Get-AzMarketplaceTerms -Publisher "cisco" -Product "meraki-vmx" -Name "meraki-vmx100" | Set-AzMarketplaceTerms -Accept`.
~> **NOTE:** When `plan` is specified, legal terms must be accepted for this item on this subscription before creating the Managed Application. For example, to accept the terms using PowerShell, please use `Set-AzContext -SubscriptionId "00000000-0000-0000-0000-000000000000"; Get-AzMarketplaceTerms -Publisher "plan-publisher" -Product "plan-product" -Name "plan-name" | Set-AzMarketplaceTerms -Accept`.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated

@neil-yechenwei
Copy link
Contributor Author

@katbyte , Thanks for your comments. I've updated code.

@katbyte katbyte added this to the v2.8.0 milestone Apr 29, 2020
Copy link
Collaborator

@katbyte katbyte left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @neil-yechenwei, hope you don't mind but i pushed a change to use the marketplae agreement resource as i couldn't get powershell to work 😅

either way LGTM now!

@katbyte katbyte merged commit d1e3d76 into hashicorp:master Apr 30, 2020
katbyte added a commit that referenced this pull request Apr 30, 2020
@ghost
Copy link

ghost commented May 1, 2020

This has been released in version 2.8.0 of the provider. Please see the Terraform documentation on provider versioning or reach out if you need any assistance upgrading. As an example:

provider "azurerm" {
    version = "~> 2.8.0"
}
# ... other configuration ...

@ghost
Copy link

ghost commented May 30, 2020

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.

If you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. If you feel I made an error 🤖 🙉 , please reach out to my human friends 👉 hashibot-feedback@hashicorp.com. Thanks!

@hashicorp hashicorp locked and limited conversation to collaborators May 30, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants