-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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_api_management
#1516
Conversation
Regarding the issue (#1520) where subnet used by Has this happend with other Azure Terraform resources? It's strange that it takes 30-50 minutes to create the API Mangement resource in Azure, but only seconds to delete it... |
As requested by @tombuildsstuff I've registered an issue for the subnet issue at Azure/azure-sdk-for-go#2199 |
@torresdal awesome, thanks - I'm taking a look through this at the moment :) |
We've had this in a few cases, Virtual Network Gateway's and Application Gateway's - in both of these cases the API affects the entire resource and as such we were blocked from shipping them until they were fixed*. However in this instance this is an optional field, as such I think we should be able to ship the rest of the resource and then add the subnet support back in when the API is fixed; what do you think? [* Unfortunately we didn't realise the scale of the Application Gateway bug until after we'd shipped it - and now we've shipped it so it's hard to pull from the provider (it's causing us a lot of pain internally, since it's breaking our acceptance tests nightly / leaving test resources kicking around which fill our quota's).] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hey @torresdal
Thanks for opening this PR :)
I've taken a look and left some comments inline, but this is off to a good start - whilst I've added a number of comments most of them are pretty similar.
The main thing we need to think about in this case is going to be the Subnet issue you've referenced. Given this is an optional field I think it'd be best to remove this field for the moment and then add it back in once the API's fixed (thanks for raising that as a bug in the SDK repository too!)
Thanks!
Computed: true, | ||
}, | ||
|
||
"sku": apiManagementDataSourceSkuSchema(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we in-line this function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, but just to make sure I understand your preference, since I see you have not mentioned apiManagementDataSourceCertificateInfoSchema
. What I've done is create funcs for schemas that are used multiple locations. Both apiManagementDataSourceSkuSchema
and apiManagementDataSourceCertificateInfoSchema
is used twice in the overall data source schema.
If this is not a good practice here (or in general 😃 ) I'll inline them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tbh in this case I think we could probably remove the second SKU in the data source, since we've also removed it from the resource (which is why I originally posted this)
(in general we tend to follow the Go guidelines of duplicating code the first time, and then refactoring it into a method - but it's mostly a gut feeling based on where something's likely to diverge, in this case I'd argue it probably wouldn't since it's the same object in both cases)
d.Set("publisher_name", props.PublisherName) | ||
|
||
d.Set("notification_sender_email", props.NotificationSenderEmail) | ||
d.Set("created", props.CreatedAtUtc.Local().Format(time.RFC3339)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can remove .Local()
from this?
d.Set("vnet_type", string(props.VirtualNetworkType)) | ||
d.Set("custom_properties", &props.CustomProperties) | ||
|
||
err, hostnameConfigurations := flattenApiManagementHostnameConfigurations(d, props.HostnameConfigurations) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in general we invert these (e.g. hostnameConfigurations, err := ...
) can we flip this to match?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also can we duplicate this method for the Data Source, since they can diverge over time
return fmt.Errorf("Error setting `additional_location`: %+v", err) | ||
} | ||
|
||
err, certificates := flattenApiManagementCertificates(d, props.Certificates) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(same here)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also can we duplicate this method for the Data Source, since they can diverge over time
return fmt.Errorf("Error setting `hostname_configuration`: %+v", err) | ||
} | ||
|
||
additionalLocations := flattenApiManagementAdditionalLocations(props.AdditionalLocations) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we duplicate this method for the Data Source, since they can diverge over time
website/azurerm.erb
Outdated
<a href="#">API Management Resources</a> | ||
<ul class="nav nav-visible"> | ||
|
||
<li<%= sidebar_current("docs-azurerm-datasource-azurerm_api_management-x") %>> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor can we change the underscores to dashes here?
|
||
* `vnet_subnet_id` - The full resource ID of a subnet in a virtual network where the API Management service is deployed. | ||
|
||
* `vnet_type` - The type of VPN in which API Managemet service needs to be configured in. None (Default Value) means the API Management service is not part of any Virtual Network, External means the API Management deployment is set up inside a Virtual Network having an Internet Facing Endpoint, and Internal means that API Management deployment is setup inside a Virtual Network having an Intranet Facing Endpoint only. Possible values include: `VirtualNetworkTypeNone`, `VirtualNetworkTypeExternal`, `VirtualNetworkTypeInternal`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we change VirtualNetworkTypeNone
-> None
, VirtualNetworkTypeExternal
-> External
and VirtualNetworkTypeInternal
-> Internal?
--- | ||
layout: "azurerm" | ||
page_title: "Azure Resource Manager: azurerm_api_management" | ||
sidebar_current: "docs-azurerm-resource-api-management" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we add the suffix -x
to match the sidebar?
|
||
Create a Api Management component. | ||
|
||
-> **Note:** When `azurerm_api_management` service has dependencies on one or more `azurerm_subnet` resources, referenced using `vnet_subnet_id` or `additional_location.*.vnet_subnet_id` - the `azurerm_subnet`s will fail to be destroyed because of an issue in Azure where a reference to the `azurerm_api_management` service is left behind after its destruction. The `azurerm_api_management` service will eventually be released from `azurerm_subnet`, but it could take hours. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So as mentioned on the main page, we're going to need to remove the ability for API Management Instances to be attached to Virtual Networks until this is fixed by Azure (unfortunately) - as such can we remove this for the moment?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we replace this with an explanation for why Virtual Networks is not supported at the moment?
|
||
* `vnet_subnet_id` - (Optional) The full resource ID of a subnet in a virtual network where the API Management service is deployed. | ||
|
||
* `vnet_type` - (Optional) The type of VPN in which API Managemet service needs to be configured in. None (Default Value) means the API Management service is not part of any Virtual Network, External means the API Management deployment is set up inside a Virtual Network having an Internet Facing Endpoint, and Internal means that API Management deployment is setup inside a Virtual Network having an Intranet Facing Endpoint only. Possible values include: `VirtualNetworkTypeNone`, `VirtualNetworkTypeExternal`, `VirtualNetworkTypeInternal`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we update VirtualNetworkTypeNone
-> None
, VirtualNetworkTypeExternal
-> External
and VirtualNetworkTypeInternal
-> Internal
?
Thanks for pointing out lots of useful improvements in your review @tombuildsstuff! I believe everything should now be up to date. In addition:
I left you a few comments on a couple of your suggestions (inlining schema function and if we should document why we currently don't support Virtual Networks). |
1609203
to
bc4d7d6
Compare
Anything else I can do before this get merged @tombuildsstuff? Also, what is your preference regarding changes in master that needs to be resolved in the pull-request branch - merge or rebase? |
hey @torresdal Sorry for the delay in re-reviewing this - I'd started reviewing this and forgot to hit submit; let me check if the comments are still valid and re-submit this; apologies for the delay here!
Rebasing is generally preferred from our side if possible, but we're fairly flexible here :) Thanks! |
@torresdal actually I've just noticed the vendoring here, so I'm going to rebase this & push a commit to resolve that; hope you don't mind! |
eb0a81e
to
c9c9df2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hey @torresdal
Thanks for pushing the latest updates - apologies for the delay in re-reviewing this! I've pushed a commit to fix a vendoring issue I noticed and to rebase this on top of master (I hope you don't mind!)
In general this is looking pretty good - there's a few common issues throughout this (mostly to do with not starting at the 0
index for arrays) which I've tried to highlight at each instance - if we can fix up the comments then we should be able to run the tests :)
Thanks!
} | ||
|
||
if sku := resp.Sku; sku != nil { | ||
d.Set("sku", flattenDataSourceApiManagementServiceSku(sku)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
given this is a complex object, can we check for errors when setting this? e.g.
if err := d.Set("sku", flattenDataSourceApiManagementServiceSku(sku)); err != nil {
return fmt.Errorf("Error flattening `sku`: %+v", err)
}
} | ||
|
||
certificate["thumbprint"] = *cert.Thumbprint | ||
certificate["subject"] = *cert.Subject |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there's a potential crash on these two properties, can we nil-check around them?
|
||
if profile != nil { | ||
sku["name"] = string(profile.Name) | ||
sku["capacity"] = *profile.Capacity |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we wrap this in a nil-check to work around the crash here?
} | ||
|
||
func flattenDataSourceApiManagementAdditionalLocations(props *[]apimanagement.AdditionalLocation) []interface{} { | ||
additional_locations := make([]interface{}, 0, 1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we remove the , 1
here? as-is this'll add a blank item at the start of the locations
|
||
func flattenDataSourceApiManagementCertificate(cert *apimanagement.CertificateInformation) []interface{} { | ||
certificate := make(map[string]interface{}, 2) | ||
certInfos := make([]interface{}, 0, 1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we remove the , 1
here, since this'll add a blank item to the start of the array (technically you're setting the starting point of the array to position 1, which will be the second item in the array)
d.Set("management_api_url", props.ManagementAPIURL) | ||
d.Set("scm_url", props.ScmURL) | ||
d.Set("static_ips", props.StaticIps) | ||
d.Set("custom_properties", &props.CustomProperties) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rather than setting these directly (which will result in a set error) - could we add a flatten function for this (as below) and convert this list to a map[string]interface{}
rather than setting map[string]string
here?
certificates := flattenApiManagementCertificates(d, props.Certificates) | ||
|
||
if err != nil { | ||
return err |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could we wrap this to explain what failed, e.g.
return fmt.Errorf("Error flattening `certificate`: %+v", err)
hostnameConfigurations, err := flattenApiManagementHostnameConfigurations(d, props.HostnameConfigurations) | ||
|
||
if err != nil { | ||
return err |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could we wrap this to explain what failed, e.g.
return fmt.Errorf("Error flattening `hostname_configuration `: %+v", err)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we get this done?
d.Set("publisher_name", props.PublisherName) | ||
|
||
d.Set("notification_sender_email", props.NotificationSenderEmail) | ||
d.Set("created", props.CreatedAtUtc.Format(time.RFC3339)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we remove the creation date, I can't think when this would be likely to be used within Terraform?
|
||
"created": { | ||
Type: schema.TypeString, | ||
Computed: true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we remove the creation date, I can't think when this would be likely to be used within Terraform?
I believe I've addressed all the requested changes by @tombuildsstuff now (thanks for a thorough review btw!), so hopefully this should be ready to move on. |
@jeffreyCline Any chance you could do a final review? Thanks. |
94ab8b6
to
771afcf
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @torresdal,
Thank you for all the updates and patience with the review process. I have left a fair number of comments inline with the major ones being:
- moving the import tests to the standard ones
- changing how your passing along the ert and cert password values. I don't think using the index is wise as that can change outside of terraform.
- there are multiple tests failing that need to be fixed
I'll do my best to review this asap after these changes have been made.
- refactoring to make the hostname configurations & security block parsing clearer - default values for the security block - making name and capacity in the sku block required - moving the validation test to where the validate function is - removing crash points & ensuring we set an empty list where required - registering the `Microsoft.ApiManagement` resource provider
- Moving validation into the validation package - Renaming `hostname_configurations` to `hostname_configuration` to better match the Terraform structure - Ensuring we always set hostname_configurations - Setting default values for the `security` block - Fixing the conflicts_with. rewriting the docs
249404a
to
c69342b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hey @torresdal
Thanks for all the work on this PR - I've taken a look through and left a few remaining comments (which I'm going to push a commit to fix) - but this now otherwise LGTM, I'll kick off the tests shortly 👍
Thanks!
dismissing since changes have been pushed / this is now out of date
Nice work! Is this one already available for us 'normal users'? I dont' see it on the terraform site and my idea tf-plugin doesn't recognize it... (running terraform-provider-azurerm_v1.16.0_x4). |
@kumlien Looks like its scheduled to be in version 1.17.0. https://github.com/terraform-providers/terraform-provider-azurerm/blob/master/CHANGELOG.md |
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! |
Added a new resource for API Management as requested in #1177. Contains the resource, tests and documentation.
ISSUE: It's marked as WIP since there is currently an issue with how the azure-sdk-for-go (or more likely Azure itself) handles deletion of the service when there are associated subnets. Basically the subnets fail to delete because it's still in use by the API Management service, even though it is deleted. I will create a separate issue for this and link back, but any pointers would be appreciated 👍
Because of the issue mentioned above, the integration test
TestAccAzureRMApiManagement_complete
currently fail.