Closed stutommi closed 2 years ago
@brwilkinson -- do you happen to have any context on this one?
Sure, I'll take a look.
Okay I did post the response; however I will do some more testing first and then re-update the thread.
given I posted the response, I figured I would add back in these comments, until I can provide an update.
Hi @stutommi
A few recommendations before we get started.
1) the APIM extension for vscode is really useful for managing/testing api's 2) I would also take a look at the git feature to get familar with pulling down the code from APIM as well. 1) https://docs.microsoft.com/en-us/azure/api-management/api-management-configuration-repository-git
I think we can make it work in Bicep, however I am skeptical about how practical this is based on other tools such as the VSCode extension or even the the Developer Portal for managing/Testing the API's, plus like I said I recommend using the Git feature. I guess it just depends on your use case.
So I was able to clone these to new revisions (as seen below), however I realized that I had not cloned all of the related Operations. that go along with them.
Let me take another look at that part. I can definitely clone them all individually by name, however I think this process only make sense if I can list them all for a given API and then clone them that way. Without having to maintain a list of each operation e.g. GET/SET etc etc. for each api operation.
Okay I made the update.... I figured I would just start with passing in the operation names, since that is enough to get a feel if this would even be useful for you to test.
This is what you pass in...
Sample link: https://github.com/brwilkinson/AzureDeploymentFramework/blob/main/ADF/bicep/APIM-API.bicep
param apim object = {
name: 'ACU1-BRW-AOA-T5-apim01'
}
param apis array = [
{
name: 'echo-api'
clonefrom: '1'
cloneto: '5'
addrevisiondescriptionprefix: 'test new revision'
Operations: [
'create-resource'
'modify-resource'
'remove-resource'
'retrieve-header-only'
'retrieve-resource'
'retrieve-resource-cached'
]
}
]
module getApiCurrent 'APIM-API-Get.bicep' = [for (api, index) in apis: {
name: 'dpGetAPI-CurrentRev-${api.name}'
params: {
apim: apim
api: api
}
}]
module setNewRevision 'APIM-API-Clone.bicep' = [for (api, index) in apis: {
name: 'dpCreateClone-${api.name}-rev${api.cloneto}'
params: {
apim: apim
api: getApiCurrent[index].outputs.currentapi.properties
operations: getApiCurrent[index].outputs.currentapioperations
apinew: api
operationNames: api.Operations
}
}]
output current array = [for (api, index) in apis: getApiCurrent[index]]
output newrevision array = [for (api, index) in apis: setNewRevision[index]]
Sample link: https://github.com/brwilkinson/AzureDeploymentFramework/blob/main/ADF/bicep/APIM-API-Get.bicep
This now gets:
param api object
param apim object
var revisionName = api.clonefrom == '1' ? api.name : '${api.name};rev=${api.clonefrom}'
resource APIM 'Microsoft.ApiManagement/service@2021-04-01-preview' existing = {
name: apim.name
}
resource API 'Microsoft.ApiManagement/service/apis@2021-04-01-preview' existing = {
name: revisionName
parent: APIM
}
resource APIOperations 'Microsoft.ApiManagement/service/apis/operations@2021-04-01-preview' existing = [for (op, index) in api.Operations : {
name: op
parent: API
}]
output currentapi object = API
output currentapioperations array = [for (item, index) in api.Operations : APIOperations[index]]
Sample link: https://github.com/brwilkinson/AzureDeploymentFramework/blob/main/ADF/bicep/APIM-API-Clone.bicep
This now clones both of the:
param apinew object
param api object
param apim object
param operations array
param operationNames array
resource APIM 'Microsoft.ApiManagement/service@2021-04-01-preview' existing = {
name: apim.name
}
resource API 'Microsoft.ApiManagement/service/apis@2021-04-01-preview' = {
name: '${apinew.name};rev=${apinew.cloneto}'
parent: APIM
properties: {
displayName: api.displayName
apiRevision: apinew.cloneto
subscriptionRequired: api.subscriptionrequired
serviceUrl: api.serviceUrl
path: api.path
protocols: api.protocols
apiRevisionDescription: '${apinew.addrevisiondescriptionprefix} ${apinew.cloneto} from: rev=${apinew.clonefrom}'
}
}
resource APIOperations 'Microsoft.ApiManagement/service/apis/operations@2021-04-01-preview' = [for (op, index) in operations : {
name: operationNames[index]
parent: API
properties: op.properties
}]
output currentapi object = API
It would be nice if I could just use the API Name and revision to lookup the Operations, then clone them, without having to manage that list of operations. I will have a look into that.
I am happy with this solution, I clone down ALL of the APIM configuration locally via the source control option and I have tested with diffs on the clone from and clone to and I am happy this should work well. However, let me know how it goes for you.
Hi @brwilkinson!
Thanks for the great effort on making the example, there a lot new stuff for me to digest. For the practical application, I think it would be good for me to describe the kind of revision handling I'm most interested in.
Let's take a following scenario:
I would want the APIM API deployment happen, whenever either API policy, openapi or any files regarding API deployment (=bicep files) change. Whenever this happens, I would like a new revision to be generated for API in Api management, and most preferable be instantly promoted to current revision. The older revision would stick around, allowing possible manual rollback (handled from Azure portal).
The main thing would be, There would always be new revision after CI/CD deployment (if necessary files have changed) set as new current, and previous revision would be still be around for rollback.
Can you figure out any way of making this happen easily with Bicep? I know this can be handled with Powershell scripting, but I'm trying to find a way of implementing it with bicep. Would you think this kind of flow that I'm describing would be better handled with some other way than bicep?
okay, that all sounds good.
One clarification, are you pushing/pulling any changes via the APIM integrated source control? Or was that in a different/external repo?
No APIM integrated source control in use! I haven't stumbled upon it before, look interesting (and a totally different flow). The note on the docs looks a bit scary though:
This feature is designed to work with API Management services that have a small/medium configuration. Services with large number of configuration elements (APIs, Operations, Schemas etc.) may experience unexpected failures when processing Git commands. If you encounter such failures, please reduce the size of your service configuration and try again. Contact support if you need assistance.
okay, thanks for confirming... in that case everything is push and you don't need to pull any changes from APIM back out to keep them in sync.
So I think the above solution may work for you, however instead of reading and cloning the previous revision and operations via the APIM-API-Get.bicep
, you should already have enough information to populate those values in the new revision.
Thanks for the help, great stuff! :)
Just a follow up: It's not possible to set newly created revision as current at the time of deployment, so I changed my flow a bit, seems to be working:
On every new deployment, update always present revision called "latest" (which is always set as current revision), and create a rollback revision (with an identifiable revision name tied to the CI/CD deployment) that is not current. This enables rollback versions while having the newest deployment revision also as current one (in the latest-revision). Only problem I find with this is pollution of revisions if new api specs are deployed often. I have no idea how consuming it is for APIM-instance if every API gets filled with rollback revisions. You can of course always delete them manually, but that's one manual process one would like to avoid.
I'll leave this still open if you have any comments @brwilkinson, but I'm very happy with things you showed and found an answer to my own implementation.
Thanks alot!
I'll move this over to the 'discussions' page for now, instead of just closing out the issue.
Update, I decided not to, since I don't think it will take the history over.
Thanks @stutommi I will mark as resolved, glad you found a working solution for your needs.
Is your feature request related to a problem? Please describe. I have a problem understanding how to deal with API Management revisions using bicep. There is a great example about API Management deployment in examples, but it doesn't really address revision handling in anyway.
When I try it using for example the following block:
properties apiRevision and isCurrent seem to be ignored, and I'll always end up with no revision (= default revision "1" is created).
Describe the solution you'd like I would like to see how bicep can be used to handle creation of new revisions.